[vmkit-commits] [PATCH] Impl JVM_NewInstanceFromConstructor

Will Dietz wdietz2 at illinois.edu
Thu Nov 3 07:29:26 PDT 2011


Inlined below.

~Will

>From 6a870bd12c931552d7979ef216f3d0ff73bd306d Mon Sep 17 00:00:00 2001
From: Will Dietz <w at wdtz.org>
Date: Wed, 2 Nov 2011 22:24:03 -0500
Subject: [PATCH 09/17] Impl JVM_NewInstanceFromConstructor

---
 lib/J3/ClassLib/OpenJDK/OpenJDK.inc |   72 ++++++++++++++++++++++++++++++++++-
 1 files changed, 71 insertions(+), 1 deletions(-)

diff --git a/lib/J3/ClassLib/OpenJDK/OpenJDK.inc
b/lib/J3/ClassLib/OpenJDK/OpenJDK.inc
index 9c5fb93..31ea42d 100644
--- a/lib/J3/ClassLib/OpenJDK/OpenJDK.inc
+++ b/lib/J3/ClassLib/OpenJDK/OpenJDK.inc
@@ -1566,7 +1566,77 @@ JVM_InvokeMethod(JNIEnv *env, jobject method,
jobject _obj, jobjectArray args0)
  */
 JNIEXPORT jobject JNICALL
 JVM_NewInstanceFromConstructor(JNIEnv *env, jobject _c, jobjectArray args0) {
-  NYI();
+  ArrayObject * args = 0;
+  JavaObjectConstructor * c = 0;
+  JavaObject * res = 0;
+  JavaObject* excp = 0;
+  llvm_gcroot(args, 0);
+  llvm_gcroot(c, 0);
+  llvm_gcroot(res, 0);
+  llvm_gcroot(excp, 0);
+  BEGIN_JNI_EXCEPTION
+
+  Jnjvm* vm = JavaThread::get()->getJVM();
+  c = *(JavaObjectConstructor**)_c;
+  if (args0) args = *(ArrayObject**)args0;
+
+  UserClass* cl = JavaObjectConstructor::getClass(c);
+  JavaMethod * meth = JavaObjectConstructor::getInternalMethod(c);
+  assert(cl && meth);
+
+
+  sint32 nbArgs = args ? ArrayObject::getSize(args) : 0;
+  Signdef* sign = meth->getSignature();
+  sint32 size = sign->nbArguments;
+
+  if (isAbstract(cl->access)) vm->instantiationException(cl);
+
+  mvm::ThreadAllocator allocator;
+  // Allocate a buffer to store the arguments.
+  jvalue* buf = size ?
+      (jvalue*)allocator.Allocate(size * sizeof(jvalue)) : NULL;
+
+  if (nbArgs == size) {
+    cl->initialiseClass(vm);
+    res = cl->doNew(vm);
+
+    JavaObject** ptr = (JavaObject**)ArrayObject::getElements(args);
+    Typedef* const* arguments = sign->getArgumentsType();
+    // Store the arguments, unboxing primitives if necessary.
+    for (sint32 i = 0; i < size; ++i) {
+      JavaObject::decapsulePrimitive(ptr[i], vm, &buf[i], arguments[i]);
+      if (!arguments[i]->isPrimitive()) {
+        buf[i].l = reinterpret_cast<jobject>(&ptr[i]);
+      }
+    }
+
+    JavaThread* th = JavaThread::get();
+    TRY {
+      meth->invokeIntSpecialBuf(vm, cl, res, buf);
+    } CATCH {
+      excp = th->getJavaException();
+    } END_CATCH;
+    if (excp) {
+      if (JavaObject::getClass(excp)->isAssignableFrom(vm->upcalls->newException))
{
+        th->clearException();
+        // If it's an exception, we encapsule it in an
+        // invocationTargetException
+        vm->invocationTargetException(excp);
+      } else {
+        // If it's an error, throw it again.
+        th->throwPendingException();
+      }
+      res = NULL;
+    }
+  } else {
+    vm->illegalArgumentException("wrong number of arguments");
+  }
+
+  RETURN_FROM_JNI((jobject)th->pushJNIRef(res));
+
+  END_JNI_EXCEPTION
+
+  return 0;
 }

 /*
-- 
1.7.5.1



More information about the vmkit-commits mailing list