Start adding implementations for runtime-provided native methods.
The library can't do everything...
Change-Id: Ib808c00570c7214aeb2ca058b1a66cacbeb372f1
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 8fb1618..b222b94 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -50,8 +50,6 @@
method->SetInvokeStub(reinterpret_cast<Method::InvokeStub*>(region.pointer()));
}
-namespace {
-
/*
* Add a local reference for an object to the current stack frame. When
* the native function returns, the reference will be discarded.
@@ -65,12 +63,13 @@
* passed in), or NULL on failure.
*/
template<typename T>
-T AddLocalReference(ScopedJniThreadState& ts, Object* obj) {
+T AddLocalReference(JNIEnv* public_env, Object* obj) {
if (obj == NULL) {
return NULL;
}
- IndirectReferenceTable& locals = ts.Env()->locals;
+ JNIEnvExt* env = reinterpret_cast<JNIEnvExt*>(public_env);
+ IndirectReferenceTable& locals = env->locals;
uint32_t cookie = IRT_FIRST_SEGMENT; // TODO
IndirectRef ref = locals.Add(cookie, obj);
@@ -83,7 +82,7 @@
}
#if 0 // TODO: fix this to understand PushLocalFrame, so we can turn it on.
- if (ts.Env()->check_jni) {
+ if (env->check_jni) {
size_t entry_count = locals.Capacity();
if (entry_count > 16) {
std::string class_descriptor(PrettyDescriptor(obj->GetClass()->GetDescriptor()));
@@ -96,7 +95,7 @@
}
#endif
- if (ts.Env()->work_around_app_jni_bugs) {
+ if (env->work_around_app_jni_bugs) {
// Hand out direct pointers to support broken old apps.
return reinterpret_cast<T>(obj);
}
@@ -104,6 +103,20 @@
return reinterpret_cast<T>(ref);
}
+// For external use.
+template<typename T>
+T Decode(JNIEnv* public_env, jobject obj) {
+ JNIEnvExt* env = reinterpret_cast<JNIEnvExt*>(public_env);
+ return reinterpret_cast<T>(env->self->DecodeJObject(obj));
+}
+// Explicit instantiations.
+template Class* Decode<Class*>(JNIEnv*, jobject);
+template ClassLoader* Decode<ClassLoader*>(JNIEnv*, jobject);
+template Object* Decode<Object*>(JNIEnv*, jobject);
+template String* Decode<String*>(JNIEnv*, jobject);
+
+namespace {
+
jweak AddWeakGlobalReference(ScopedJniThreadState& ts, Object* obj) {
if (obj == NULL) {
return NULL;
@@ -115,6 +128,7 @@
return reinterpret_cast<jweak>(ref);
}
+// For internal use.
template<typename T>
T Decode(ScopedJniThreadState& ts, jobject obj) {
return reinterpret_cast<T>(ts.Self()->DecodeJObject(obj));
@@ -364,7 +378,7 @@
JniT NewPrimitiveArray(ScopedJniThreadState& ts, jsize length) {
CHECK_GE(length, 0); // TODO: ReportJniError
ArtT* result = ArtT::Alloc(length);
- return AddLocalReference<JniT>(ts, result);
+ return AddLocalReference<JniT>(ts.Env(), result);
}
template <typename ArrayT, typename CArrayT, typename ArtArrayT>
@@ -634,7 +648,7 @@
// TODO: need to get the appropriate ClassLoader.
const ClassLoader* cl = ts.Self()->GetClassLoaderOverride();
Class* c = class_linker->FindClass(descriptor, cl);
- return AddLocalReference<jclass>(ts, c);
+ return AddLocalReference<jclass>(env, c);
}
static jmethodID FromReflectedMethod(JNIEnv* env, jobject java_method) {
@@ -652,25 +666,25 @@
static jobject ToReflectedMethod(JNIEnv* env, jclass, jmethodID mid, jboolean) {
ScopedJniThreadState ts(env);
Method* method = DecodeMethod(ts, mid);
- return AddLocalReference<jobject>(ts, method);
+ return AddLocalReference<jobject>(env, method);
}
static jobject ToReflectedField(JNIEnv* env, jclass, jfieldID fid, jboolean) {
ScopedJniThreadState ts(env);
Field* field = DecodeField(ts, fid);
- return AddLocalReference<jobject>(ts, field);
+ return AddLocalReference<jobject>(env, field);
}
static jclass GetObjectClass(JNIEnv* env, jobject java_object) {
ScopedJniThreadState ts(env);
Object* o = Decode<Object*>(ts, java_object);
- return AddLocalReference<jclass>(ts, o->GetClass());
+ return AddLocalReference<jclass>(env, o->GetClass());
}
static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
ScopedJniThreadState ts(env);
Class* c = Decode<Class*>(ts, java_class);
- return AddLocalReference<jclass>(ts, c->GetSuperClass());
+ return AddLocalReference<jclass>(env, c->GetSuperClass());
}
static jboolean IsAssignableFrom(JNIEnv* env, jclass java_class1, jclass java_class2) {
@@ -746,7 +760,7 @@
Throwable* original_exception = self->GetException();
self->ClearException();
- ScopedLocalRef<jthrowable> exception(env, AddLocalReference<jthrowable>(ts, original_exception));
+ ScopedLocalRef<jthrowable> exception(env, AddLocalReference<jthrowable>(env, original_exception));
ScopedLocalRef<jclass> exception_class(env, env->GetObjectClass(exception.get()));
jmethodID mid = env->GetMethodID(exception_class.get(), "printStackTrace", "()V");
if (mid == NULL) {
@@ -772,7 +786,7 @@
} else {
// TODO: if adding a local reference failing causes the VM to abort
// then the following check will never occur.
- jthrowable localException = AddLocalReference<jthrowable>(ts, exception);
+ jthrowable localException = AddLocalReference<jthrowable>(env, exception);
if (localException == NULL) {
// We were unable to add a new local reference, and threw a new
// exception. We can't return "exception", because it's not a
@@ -903,7 +917,7 @@
if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c)) {
return NULL;
}
- return AddLocalReference<jobject>(ts, c->AllocObject());
+ return AddLocalReference<jobject>(env, c->AllocObject());
}
static jobject NewObject(JNIEnv* env, jclass clazz, jmethodID mid, ...) {
@@ -922,7 +936,7 @@
return NULL;
}
Object* result = c->AllocObject();
- jobject local_result = AddLocalReference<jobject>(ts, result);
+ jobject local_result = AddLocalReference<jobject>(env, result);
CallNonvirtualVoidMethodV(env, local_result, java_class, mid, args);
return local_result;
}
@@ -934,7 +948,7 @@
return NULL;
}
Object* result = c->AllocObject();
- jobject local_result = AddLocalReference<jobjectArray>(ts, result);
+ jobject local_result = AddLocalReference<jobjectArray>(env, result);
CallNonvirtualVoidMethodA(env, local_result, java_class, mid, args);
return local_result;
}
@@ -955,19 +969,19 @@
va_start(ap, mid);
JValue result = InvokeVirtualOrInterfaceWithVarArgs(ts, obj, mid, ap);
va_end(ap);
- return AddLocalReference<jobject>(ts, result.l);
+ return AddLocalReference<jobject>(env, result.l);
}
static jobject CallObjectMethodV(JNIEnv* env, jobject obj, jmethodID mid, va_list args) {
ScopedJniThreadState ts(env);
JValue result = InvokeVirtualOrInterfaceWithVarArgs(ts, obj, mid, args);
- return AddLocalReference<jobject>(ts, result.l);
+ return AddLocalReference<jobject>(env, result.l);
}
static jobject CallObjectMethodA(JNIEnv* env, jobject obj, jmethodID mid, jvalue* args) {
ScopedJniThreadState ts(env);
JValue result = InvokeVirtualOrInterfaceWithJValues(ts, obj, mid, args);
- return AddLocalReference<jobject>(ts, result.l);
+ return AddLocalReference<jobject>(env, result.l);
}
static jboolean CallBooleanMethod(JNIEnv* env, jobject obj, jmethodID mid, ...) {
@@ -1146,7 +1160,7 @@
va_list ap;
va_start(ap, mid);
JValue result = InvokeWithVarArgs(ts, obj, mid, ap);
- jobject local_result = AddLocalReference<jobject>(ts, result.l);
+ jobject local_result = AddLocalReference<jobject>(env, result.l);
va_end(ap);
return local_result;
}
@@ -1155,14 +1169,14 @@
jobject obj, jclass clazz, jmethodID mid, va_list args) {
ScopedJniThreadState ts(env);
JValue result = InvokeWithVarArgs(ts, obj, mid, args);
- return AddLocalReference<jobject>(ts, result.l);
+ return AddLocalReference<jobject>(env, result.l);
}
static jobject CallNonvirtualObjectMethodA(JNIEnv* env,
jobject obj, jclass clazz, jmethodID mid, jvalue* args) {
ScopedJniThreadState ts(env);
JValue result = InvokeWithJValues(ts, obj, mid, args);
- return AddLocalReference<jobject>(ts, result.l);
+ return AddLocalReference<jobject>(env, result.l);
}
static jboolean CallNonvirtualBooleanMethod(JNIEnv* env,
@@ -1379,13 +1393,13 @@
ScopedJniThreadState ts(env);
Object* o = Decode<Object*>(ts, obj);
Field* f = DecodeField(ts, fid);
- return AddLocalReference<jobject>(ts, f->GetObject(o));
+ return AddLocalReference<jobject>(env, f->GetObject(o));
}
static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
ScopedJniThreadState ts(env);
Field* f = DecodeField(ts, fid);
- return AddLocalReference<jobject>(ts, f->GetObject(NULL));
+ return AddLocalReference<jobject>(env, f->GetObject(NULL));
}
static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
@@ -1549,7 +1563,7 @@
va_list ap;
va_start(ap, mid);
JValue result = InvokeWithVarArgs(ts, NULL, mid, ap);
- jobject local_result = AddLocalReference<jobject>(ts, result.l);
+ jobject local_result = AddLocalReference<jobject>(env, result.l);
va_end(ap);
return local_result;
}
@@ -1558,14 +1572,14 @@
jclass clazz, jmethodID mid, va_list args) {
ScopedJniThreadState ts(env);
JValue result = InvokeWithVarArgs(ts, NULL, mid, args);
- return AddLocalReference<jobject>(ts, result.l);
+ return AddLocalReference<jobject>(env, result.l);
}
static jobject CallStaticObjectMethodA(JNIEnv* env,
jclass clazz, jmethodID mid, jvalue* args) {
ScopedJniThreadState ts(env);
JValue result = InvokeWithJValues(ts, NULL, mid, args);
- return AddLocalReference<jobject>(ts, result.l);
+ return AddLocalReference<jobject>(env, result.l);
}
static jboolean CallStaticBooleanMethod(JNIEnv* env,
@@ -1763,7 +1777,7 @@
return NULL;
}
String* result = String::AllocFromUtf16(char_count, chars);
- return AddLocalReference<jstring>(ts, result);
+ return AddLocalReference<jstring>(env, result);
}
static jstring NewStringUTF(JNIEnv* env, const char* utf) {
@@ -1772,7 +1786,7 @@
return NULL;
}
String* result = String::AllocFromModifiedUtf8(utf);
- return AddLocalReference<jstring>(ts, result);
+ return AddLocalReference<jstring>(env, result);
}
static jsize GetStringLength(JNIEnv* env, jstring java_string) {
@@ -1870,7 +1884,7 @@
static jobject GetObjectArrayElement(JNIEnv* env, jobjectArray java_array, jsize index) {
ScopedJniThreadState ts(env);
ObjectArray<Object>* array = Decode<ObjectArray<Object>*>(ts, java_array);
- return AddLocalReference<jobject>(ts, array->Get(index));
+ return AddLocalReference<jobject>(env, array->Get(index));
}
static void SetObjectArrayElement(JNIEnv* env,
@@ -1941,7 +1955,7 @@
result->Set(i, initial_object);
}
}
- return AddLocalReference<jobjectArray>(ts, result);
+ return AddLocalReference<jobjectArray>(env, result);
}
static jshortArray NewShortArray(JNIEnv* env, jsize length) {