diff options
author | Joonas Reynders <joonas.reynders@iki.fi> | 2012-01-29 18:42:16 +0200 |
---|---|---|
committer | Pekka Enberg <penberg@kernel.org> | 2012-01-29 19:12:17 +0200 |
commit | 3180779548d06ff5e98af3a930518e29f7372c9c (patch) | |
tree | 4e18f457805c03ca0bffea42fe5cafa8c8cbbd7d | |
parent | 9dfc6264e493267b174b731a62f0dc6c46f2894d (diff) | |
download | jato-3180779548d06ff5e98af3a930518e29f7372c9c.tar.gz |
Add implementation and tests for JNI function NewObjectV
Signed-off-by: Joonas Reynders <joonas.reynders@iki.fi>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
-rw-r--r-- | test/functional/java/lang/JNITest.java | 18 | ||||
-rw-r--r-- | test/functional/jni/jnitest.c | 37 | ||||
-rw-r--r-- | vm/jni-interface.c | 31 |
3 files changed, 80 insertions, 6 deletions
diff --git a/test/functional/java/lang/JNITest.java b/test/functional/java/lang/JNITest.java index cdc89b58..b5e03688 100644 --- a/test/functional/java/lang/JNITest.java +++ b/test/functional/java/lang/JNITest.java @@ -97,6 +97,7 @@ public class JNITest extends TestCase { native static public boolean testAllocObject(Class<?> clazz); native static public Object testNewObject(Class<?> clazz, String constructorSignature, Object args); native static public Object testNewObjectA(Class<?> clazz, String constructorSignature, Object args); + native static public Object testNewObjectV(Class<?> clazz, String constructorSignature, Object args); native static public boolean isInstanceOf(Object obj, Class<?> clazz); private static JNITest jniTest = new JNITest(); @@ -342,7 +343,23 @@ public class JNITest extends TestCase { testNewObjectA(ClassLoader.class, "()V", null); } }, InstantiationException.class); + } + + public static void testNewObjectV() { + assertEquals("test", testNewObjectV(String.class, "(Ljava/lang/String;)V", "test")); + assertEquals("test", testNewObjectV(String.class, "([C)V", "test".toCharArray())); + assertThrows(new Block() { + public void run() throws Throwable { + testNewObjectV(Runnable.class, "()V", null); + } + }, InstantiationException.class); + + assertThrows(new Block() { + public void run() throws Throwable { + testNewObjectV(ClassLoader.class, "()V", null); + } + }, InstantiationException.class); } public static void testIsInstanceOf() { @@ -375,6 +392,7 @@ public class JNITest extends TestCase { testAllocObject(); testNewObject(); testNewObjectA(); + testNewObjectV(); testIsInstanceOf(); } } diff --git a/test/functional/jni/jnitest.c b/test/functional/jni/jnitest.c index b4b8ad82..82642bbc 100644 --- a/test/functional/jni/jnitest.c +++ b/test/functional/jni/jnitest.c @@ -704,6 +704,43 @@ JNIEXPORT jobject JNICALL Java_java_lang_JNITest_testNewObjectA(JNIEnv *env, jcl } } +static jobject callNewObjectV(JNIEnv *env, jclass clazzToAlloc, jmethodID methodID, ...) +{ + va_list args; + jobject jobj; + + va_start(args, methodID); + jobj = ((*env)->NewObjectV(env, clazzToAlloc, methodID, args)); + va_end(args); + + return jobj; +} + +/* + * Class: java_lang_JNITest + * Method: testNewObjectV + * Signature: ((Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL Java_java_lang_JNITest_testNewObjectV(JNIEnv *env, jclass clazz, jclass clazzToAlloc, jstring constructorSig, jobject args) +{ + char *constructorSigStr; + jboolean iscopy; + + constructorSigStr = (char *) (*env)->GetStringUTFChars(env, constructorSig, &iscopy); + if (constructorSigStr == NULL) { + return NULL; /* OutOfMemoryError */ + } + + jmethodID methodID = (*env)->GetMethodID(env, clazzToAlloc, "<init>", constructorSigStr); + if (methodID == NULL) + return NULL; + + if (args != NULL) + return callNewObjectV(env, clazzToAlloc, methodID, args); + else + return ((*env)->NewObjectV(env, clazzToAlloc, methodID, NULL)); +} + /* * Class: java_lang_JNITest * Method: isInstanceOf diff --git a/vm/jni-interface.c b/vm/jni-interface.c index 0c2321fc..7115a204 100644 --- a/vm/jni-interface.c +++ b/vm/jni-interface.c @@ -543,12 +543,6 @@ static jobject JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...) return obj; } -static jobject JNI_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) -{ - JNI_NOT_IMPLEMENTED; - return 0; -} - static jobject JNI_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args) { struct vm_class *vmc; @@ -576,6 +570,31 @@ static jobject JNI_NewObjectA(JNIEnv *env, jclass clazz, jmethodID methodID, con return result; } +static jobject JNI_NewObjectV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args) +{ + enter_vm_from_jni(); + + struct vm_object *obj; + struct vm_class *class; + + if (!vm_object_is_instance_of(clazz, vm_java_lang_Class)) + return NULL; + + class = vm_class_get_class_from_class_object(clazz); + check_null(class); + + if (vm_class_is_interface(class) || vm_class_is_abstract(class)) { + signal_new_exception(vm_java_lang_InstantiationException, NULL); + return NULL; + } + + obj = vm_object_alloc(class); + + vm_call_method_this_v(methodID, obj, args, NULL); + + return obj; +} + static jclass JNI_GetObjectClass(JNIEnv *env, jobject obj) { enter_vm_from_jni(); |