aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoonas Reynders <joonas.reynders@iki.fi>2012-01-29 18:42:16 +0200
committerPekka Enberg <penberg@kernel.org>2012-01-29 19:12:17 +0200
commit3180779548d06ff5e98af3a930518e29f7372c9c (patch)
tree4e18f457805c03ca0bffea42fe5cafa8c8cbbd7d
parent9dfc6264e493267b174b731a62f0dc6c46f2894d (diff)
downloadjato-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.java18
-rw-r--r--test/functional/jni/jnitest.c37
-rw-r--r--vm/jni-interface.c31
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();