Preliminary implementation of the JNI invocation interface.
Change-Id: Ib144cb887864cd232a8cb8167b20d1540829a6a5
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 74f8961..6c6f493 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -1,7 +1,13 @@
// Copyright 2011 Google Inc. All Rights Reserved.
#include "jni_internal.h"
+
+#include <vector>
+#include <utility>
+
#include "logging.h"
+#include "runtime.h"
+#include "thread.h"
namespace art {
@@ -18,4 +24,120 @@
monitor_exit_ = &JniMonitorExit;
}
+extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, void** p_env, void* vm_args) {
+ const JavaVMInitArgs* args = static_cast<JavaVMInitArgs*>(vm_args);
+ if (args->version < JNI_VERSION_1_2) {
+ return JNI_EVERSION;
+ }
+ Runtime::Options options;
+ for (int i = 0; i < args->nOptions; ++i) {
+ JavaVMOption* option = &args->options[i];
+ options.push_back(std::make_pair(option->optionString, option->extraInfo));
+ }
+ bool ignore_unrecognized = args->ignoreUnrecognized;
+ scoped_ptr<Runtime> runtime(Runtime::Create(options, ignore_unrecognized));
+ if (runtime == NULL) {
+ return JNI_ERR;
+ } else {
+ *p_env = reinterpret_cast<JNIEnv*>(Thread::Current()->GetJniEnv());
+ *p_vm = reinterpret_cast<JavaVM*>(runtime.release());
+ return JNI_OK;
+ }
+}
+
+extern "C" jint JNI_GetCreatedJavaVMs(JavaVM** vmBuf, jsize bufLen,
+ jsize* nVMs) {
+ Runtime* runtime = Runtime::Current();
+ if (runtime == NULL) {
+ *nVMs = 0;
+ } else {
+ *nVMs = 1;
+ vmBuf[0] = reinterpret_cast<JavaVM*>(runtime);
+ }
+ return JNI_OK;
+}
+
+// Historically unsupported.
+extern "C" jint JNI_GetDefaultJavaVMInitArgs(void* vm_args) {
+ return JNI_ERR;
+}
+
+jint JniInvoke::DestroyJavaVM(JavaVM* vm) {
+ if (vm == NULL) {
+ return JNI_ERR;
+ } else {
+ Runtime* runtime = reinterpret_cast<Runtime*>(vm);
+ delete runtime;
+ return JNI_OK;
+ }
+}
+
+jint JniInvoke::AttachCurrentThread(JavaVM* vm, JNIEnv** p_env,
+ void* thr_args) {
+ if (vm == NULL || p_env == NULL) {
+ return JNI_ERR;
+ }
+ Runtime* runtime = reinterpret_cast<Runtime*>(vm);
+ JniEnvironment** jni_env = reinterpret_cast<JniEnvironment**>(p_env);
+ const char* name = NULL;
+ if (thr_args != NULL) {
+ // TODO: check version
+ name = static_cast<JavaVMAttachArgs*>(thr_args)->name;
+ // TODO: thread group
+ }
+ bool success = runtime->AttachCurrentThread(name, jni_env);
+ if (!success) {
+ return JNI_ERR;
+ } else {
+ return JNI_OK;
+ }
+}
+
+jint JniInvoke::DetachCurrentThread(JavaVM* vm) {
+ if (vm == NULL) {
+ return JNI_ERR;
+ } else {
+ Runtime* runtime = reinterpret_cast<Runtime*>(vm);
+ runtime->DetachCurrentThread();
+ return JNI_OK;
+ }
+}
+
+jint JniInvoke::GetEnv(JavaVM *vm, void **env, jint version) {
+ if (version < JNI_VERSION_1_1 || version > JNI_VERSION_1_6) {
+ return JNI_EVERSION;
+ }
+ if (vm == NULL || env == NULL) {
+ return JNI_ERR;
+ }
+ Thread* thread = Thread::Current();
+ if (thread == NULL) {
+ *env = NULL;
+ return JNI_EDETACHED;
+ }
+ *env = thread->GetJniEnv();
+ return JNI_OK;
+}
+
+jint JniInvoke::AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env,
+ void* thr_args) {
+ if (vm == NULL || p_env == NULL) {
+ return JNI_ERR;
+ }
+ Runtime* runtime = reinterpret_cast<Runtime*>(vm);
+ JniEnvironment** jni_env = reinterpret_cast<JniEnvironment**>(p_env);
+ const char* name = NULL;
+ if (thr_args != NULL) {
+ // TODO: check version
+ name = static_cast<JavaVMAttachArgs*>(thr_args)->name;
+ // TODO: thread group
+ }
+ bool success = runtime->AttachCurrentThreadAsDaemon(name, jni_env);
+ if (!success) {
+ return JNI_ERR;
+ } else {
+ return JNI_OK;
+ }
+}
+
} // namespace art