[vmkit-commits] [PATCH] Various patches
Nicolas Geoffray
nicolas.geoffray at gmail.com
Sun Oct 23 23:36:50 PDT 2011
And some comments on the JNI methods. Code looks good, feel free to apply
once all the comments are addressed (especially the one on the Throw
method).
>From 0b2f106489d221af52509ee794130a0e946d1186 Mon Sep 17 00:00:00 2001
From: Will Dietz <w at wdtz.org>
Date: Fri, 14 Oct 2011 05:47:10 -0500
Subject: [PATCH] Jni.cpp: DefineClass,GetSuperClass,Throw, misc String
functions.
---
lib/J3/VMCore/Jni.cpp | 116
+++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 99 insertions(+), 17 deletions(-)
diff --git a/lib/J3/VMCore/Jni.cpp b/lib/J3/VMCore/Jni.cpp
index 5e76931..10c71ed 100644
--- a/lib/J3/VMCore/Jni.cpp
+++ b/lib/J3/VMCore/Jni.cpp
@@ -20,6 +20,7 @@
#include "JavaTypes.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"
+#include "Reader.h"
using namespace j3;
@@ -51,10 +52,30 @@ jint GetVersion(JNIEnv *env) {
}
-jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
- const jbyte *buf, jsize bufLen) {
- NYI();
- abort();
+jclass DefineClass(JNIEnv *env, const char *name, jobject _loader,
+ const jbyte *buf, jsize len) {
+ BEGIN_JNI_EXCEPTION
+
+ JavaObject * loader = _loader ? *(JavaObject**)_loader : 0;
+ llvm_gcroot(loader, 0);
+
+ jclass res;
+
+ Jnjvm* vm = JavaThread::get()->getJVM();
+ JnjvmClassLoader* JCL = NULL;
+ JCL = JnjvmClassLoader::getJnjvmLoaderFromJavaObject(loader, vm);
Merge the two lines above.
+
+ ClassBytes * bytes = new (JCL->allocator, len) ClassBytes(len);
+ memcpy(bytes->elements,buf,len);
+ const UTF8* utfName = JCL->asciizConstructUTF8(name);
+ UserClass *cl = JCL->constructClass(utfName, bytes);
+
+ if (cl) res = (jclass)cl->getClassDelegateePtr(vm);
+
+ RETURN_FROM_JNI(res);
+
+ END_JNI_EXCEPTION
+
return 0;
}
@@ -109,9 +130,25 @@ jmethodID FromReflectedMethod(JNIEnv *env, jobject
method) {
jclass GetSuperclass(JNIEnv *env, jclass sub) {
- NYI();
- abort();
- return 0;
+ BEGIN_JNI_EXCEPTION
+
+ JavaObject* res = 0;
res should be a jclass. You're returning a JNI ref, not a JavaObject.
+ JavaObject* Cl = *(JavaObject**)sub;
+ llvm_gcroot(Cl, 0);
+ llvm_gcroot(res, 0);
+
+ Jnjvm* vm = JavaThread::get()->getJVM();
+ UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
+ if (cl->isInterface()) res = 0;
+ else {
+ if (cl->getSuper()) res =
(JavaObject*)cl->getSuper()->getClassDelegateePtr(vm);
+ else res = 0;
You could save some lines by just doing:
if (!cl->isInterface() && cl->getSuper() != NULL) {
res = (jcass)cl->getSuper()->getClassDelegateePtr(vm);
}
+ }
+ RETURN_FROM_JNI((jclass)res);
+
+ END_JNI_EXCEPTION
+
+ RETURN_FROM_JNI(0);
}
@@ -141,8 +178,10 @@ jboolean IsAssignableFrom(JNIEnv *env, jclass _sub,
jclass _sup) {
jint Throw(JNIEnv *env, jthrowable obj) {
- NYI();
- abort();
+ BEGIN_JNI_EXCEPTION
+ JavaThread::get()->throwException(*(JavaObject**)obj);
You must set JavaThread::get()->pendingException instead of throwing
directly. Throwing directly will make you do a longjmp, to a previous CATCH
clause, and this is not what the JNI spec says. Take a look at what ThrowNew
does in the same file.
+
+ END_JNI_EXCEPTION
return 0;
}
@@ -2831,10 +2870,17 @@ jstring NewStringUTF(JNIEnv *env, const char *bytes)
{
}
-jsize GetStringUTFLength (JNIEnv *env, jstring string) {
- NYI();
- abort();
- return 0;
+jsize GetStringUTFLength (JNIEnv *env, jstring string) {
+ BEGIN_JNI_EXCEPTION
+ JavaThread* th = JavaThread::get();
+
+ JavaString * s = *(JavaString**)string;
+ llvm_gcroot(s, 0);
+ // TODO: Review why this is! (Especially coupled with +1 in
StringUTFRegion)
Remove the TODO?
+ RETURN_FROM_JNI(s->count);
+ END_JNI_EXCEPTION
+
+ RETURN_FROM_JNI(0)
}
@@ -3779,15 +3825,51 @@ jint GetJavaVM(JNIEnv *env, JavaVM **vm) {
void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
jchar *buf) {
- NYI();
- abort();
+ BEGIN_JNI_EXCEPTION
+
+ JavaString * s = *(JavaString**)str;
+ llvm_gcroot(s, 0);
+ UserClass * cl = JavaObject::getClass(s)->asClass();
+ const UTF8 * utf = JavaString::javaToInternal(s,
cl->classLoader->hashUTF8);
+
+ ssize_t end = start+len;
+ if (end > utf->size) {
+ assert(0 && "Throw string out of bounds exception here!");
+ }
+
+ Jnjvm* vm = JavaThread::get()->getJVM();
+ UTF8Map* map = vm->bootstrapLoader->hashUTF8;
+
+ const UTF8 * result = utf->extract(map, start, start + len);
+ assert(result->size == len);
+ for(sint32 i = 0; i < len; ++i)
+ buf[i] = result->elements[i];
+
+ RETURN_VOID_FROM_JNI;
+ END_JNI_EXCEPTION
+ RETURN_VOID_FROM_JNI;
}
void GetStringUTFRegion(JNIEnv* env, jstring str, jsize start, jsize len,
char *buf) {
- NYI();
- abort();
+ BEGIN_JNI_EXCEPTION
+
+ JavaString * s = *(JavaString**)str;
+ llvm_gcroot(s, 0);
+
+ int end = start+len;
+ if (end > s->count) {
+ assert(0 && "Throw string out of bounds exception here!");
+ }
+
+ char * internalStr = JavaString::strToAsciiz(s);
+ assert((int)strlen(internalStr) == len);
+ memcpy(buf, internalStr, len + 1);
+
+ RETURN_VOID_FROM_JNI;
+ END_JNI_EXCEPTION
+ RETURN_VOID_FROM_JNI;
}
--
1.7.5.1
On Mon, Oct 24, 2011 at 12:53 AM, Will Dietz <willdtz at gmail.com> wrote:
> Sorry for the noise, just to try to stay on top of things (maybe
> sending all these patches in 1 thread was a bad idea...I was trying to
> *avoid* unnecessary clutter!)
>
> Patches outstanding:
>
> 4 (updated version attached addressing cast, printf, and NATIVE_JNI
> issues mentioned)
>
> 5, 6 --approved as-is, should I commit these?
>
> 7-- the "+1" is unnecessary as far as I can tell upon looking into it
> further--the function should return the strlen, not the space needed
> for a buffer containing the string. Sorry for the confusion. Updated
> version also attached.
>
> 8-- the registerNatives patch, which was sent in previous email.
>
> Thanks again! :)
>
> ~Will
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/vmkit-commits/attachments/20111024/eae318a2/attachment.html>
More information about the vmkit-commits
mailing list