Implement field access (and a few other bits and bobs).
Change-Id: I837eb0ae4af8e314761bb42d3405f05b7a79573e
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index a892a28..243a29d 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -582,10 +582,10 @@
return AddLocalReference<jobject>(ts, field);
}
- static jclass GetSuperclass(JNIEnv* env, jclass sub) {
+ static jclass GetSuperclass(JNIEnv* env, jclass java_class) {
ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return NULL;
+ Class* c = Decode<Class*>(ts, java_class);
+ return AddLocalReference<jclass>(ts, c->GetSuperClass());
}
static jboolean IsAssignableFrom(JNIEnv* env, jclass sub, jclass sup) {
@@ -749,10 +749,13 @@
return 0;
}
- static jobject AllocObject(JNIEnv* env, jclass clazz) {
+ static jobject AllocObject(JNIEnv* env, jclass java_class) {
ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return NULL;
+ Class* c = Decode<Class*>(ts, java_class);
+ if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c)) {
+ return NULL;
+ }
+ return AddLocalReference<jobject>(ts, c->NewInstance());
}
static jobject NewObject(JNIEnv* env, jclass clazz, jmethodID methodID, ...) {
@@ -764,23 +767,27 @@
return result;
}
- static jobject NewObjectV(JNIEnv* env,
- jclass clazz, jmethodID methodID, va_list args) {
+ static jobject NewObjectV(JNIEnv* env, jclass java_class, jmethodID methodID, va_list args) {
ScopedJniThreadState ts(env);
- Class* klass = Decode<Class*>(ts, clazz);
- Object* result = klass->NewInstance();
+ Class* c = Decode<Class*>(ts, java_class);
+ if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c)) {
+ return NULL;
+ }
+ Object* result = c->NewInstance();
jobject local_result = AddLocalReference<jobject>(ts, result);
- CallNonvirtualVoidMethodV(env, local_result, clazz, methodID, args);
+ CallNonvirtualVoidMethodV(env, local_result, java_class, methodID, args);
return local_result;
}
- static jobject NewObjectA(JNIEnv* env,
- jclass clazz, jmethodID methodID, jvalue* args) {
+ static jobject NewObjectA(JNIEnv* env, jclass java_class, jmethodID methodID, jvalue* args) {
ScopedJniThreadState ts(env);
- Class* klass = Decode<Class*>(ts, clazz);
- Object* result = klass->NewInstance();
+ Class* c = Decode<Class*>(ts, java_class);
+ if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c)) {
+ return NULL;
+ }
+ Object* result = c->NewInstance();
jobject local_result = AddLocalReference<jobjectArray>(ts, result);
- CallNonvirtualVoidMethodA(env, local_result, clazz, methodID, args);
+ CallNonvirtualVoidMethodA(env, local_result, java_class, methodID, args);
return local_result;
}
@@ -1245,103 +1252,172 @@
return FindFieldID(ts, c, name, sig, true);
}
- static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fieldID) {
+ static jobject GetObjectField(JNIEnv* env, jobject obj, jfieldID fid) {
ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return NULL;
+ Object* o = Decode<Object*>(ts, obj);
+ Field* f = DecodeField(ts, fid);
+ return AddLocalReference<jobject>(ts, f->GetObject(o));
}
- static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fieldID) {
+ static jobject GetStaticObjectField(JNIEnv* env, jclass, jfieldID fid) {
ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return JNI_FALSE;
+ Field* f = DecodeField(ts, fid);
+ return AddLocalReference<jobject>(ts, f->GetObject(NULL));
}
- static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fieldID) {
+ static void SetObjectField(JNIEnv* env, jobject java_object, jfieldID fid, jobject java_value) {
ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return 0;
+ Object* o = Decode<Object*>(ts, java_object);
+ Object* v = Decode<Object*>(ts, java_value);
+ Field* f = DecodeField(ts, fid);
+ f->SetObject(o, v);
}
- static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fieldID) {
+ static void SetStaticObjectField(JNIEnv* env, jclass, jfieldID fid, jobject java_value) {
ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return 0;
+ Object* v = Decode<Object*>(ts, java_value);
+ Field* f = DecodeField(ts, fid);
+ f->SetObject(NULL, v);
}
- static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fieldID) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return 0;
+#define GET_PRIMITIVE_FIELD(fn, instance) \
+ ScopedJniThreadState ts(env); \
+ Object* o = Decode<Object*>(ts, instance); \
+ Field* f = DecodeField(ts, fid); \
+ return f->fn(o)
+
+#define SET_PRIMITIVE_FIELD(fn, instance, value) \
+ ScopedJniThreadState ts(env); \
+ Object* o = Decode<Object*>(ts, instance); \
+ Field* f = DecodeField(ts, fid); \
+ f->fn(o, value)
+
+ static jboolean GetBooleanField(JNIEnv* env, jobject obj, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetBoolean, obj);
}
- static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fieldID) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return 0;
+ static jbyte GetByteField(JNIEnv* env, jobject obj, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetByte, obj);
}
- static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fieldID) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return 0;
+ static jchar GetCharField(JNIEnv* env, jobject obj, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetChar, obj);
}
- static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fieldID) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return 0;
+ static jshort GetShortField(JNIEnv* env, jobject obj, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetShort, obj);
}
- static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fieldID) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return 0;
+ static jint GetIntField(JNIEnv* env, jobject obj, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetInt, obj);
}
- static void SetObjectField(JNIEnv* env, jobject obj, jfieldID fieldID, jobject val) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
+ static jlong GetLongField(JNIEnv* env, jobject obj, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetLong, obj);
}
- static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fieldID, jboolean val) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
+ static jfloat GetFloatField(JNIEnv* env, jobject obj, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetFloat, obj);
}
- static void SetByteField(JNIEnv* env, jobject obj, jfieldID fieldID, jbyte val) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
+ static jdouble GetDoubleField(JNIEnv* env, jobject obj, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetDouble, obj);
}
- static void SetCharField(JNIEnv* env, jobject obj, jfieldID fieldID, jchar val) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
+ static jboolean GetStaticBooleanField(JNIEnv* env, jclass clazz, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetBoolean, NULL);
}
- static void SetShortField(JNIEnv* env, jobject obj, jfieldID fieldID, jshort val) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
+ static jbyte GetStaticByteField(JNIEnv* env, jclass clazz, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetByte, NULL);
}
- static void SetIntField(JNIEnv* env, jobject obj, jfieldID fieldID, jint val) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
+ static jchar GetStaticCharField(JNIEnv* env, jclass clazz, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetChar, NULL);
}
- static void SetLongField(JNIEnv* env, jobject obj, jfieldID fieldID, jlong val) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
+ static jshort GetStaticShortField(JNIEnv* env, jclass clazz, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetShort, NULL);
}
- static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fieldID, jfloat val) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
+ static jint GetStaticIntField(JNIEnv* env, jclass clazz, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetInt, NULL);
}
- static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fieldID, jdouble val) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
+ static jlong GetStaticLongField(JNIEnv* env, jclass clazz, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetLong, NULL);
+ }
+
+ static jfloat GetStaticFloatField(JNIEnv* env, jclass clazz, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetFloat, NULL);
+ }
+
+ static jdouble GetStaticDoubleField(JNIEnv* env, jclass clazz, jfieldID fid) {
+ GET_PRIMITIVE_FIELD(GetDouble, NULL);
+ }
+
+ static void SetBooleanField(JNIEnv* env, jobject obj, jfieldID fid, jboolean v) {
+ SET_PRIMITIVE_FIELD(SetBoolean, obj, v);
+ }
+
+ static void SetByteField(JNIEnv* env, jobject obj, jfieldID fid, jbyte v) {
+ SET_PRIMITIVE_FIELD(SetByte, obj, v);
+ }
+
+ static void SetCharField(JNIEnv* env, jobject obj, jfieldID fid, jchar v) {
+ SET_PRIMITIVE_FIELD(SetChar, obj, v);
+ }
+
+ static void SetFloatField(JNIEnv* env, jobject obj, jfieldID fid, jfloat v) {
+ SET_PRIMITIVE_FIELD(SetFloat, obj, v);
+ }
+
+ static void SetDoubleField(JNIEnv* env, jobject obj, jfieldID fid, jdouble v) {
+ SET_PRIMITIVE_FIELD(SetDouble, obj, v);
+ }
+
+ static void SetIntField(JNIEnv* env, jobject obj, jfieldID fid, jint v) {
+ SET_PRIMITIVE_FIELD(SetInt, obj, v);
+ }
+
+ static void SetLongField(JNIEnv* env, jobject obj, jfieldID fid, jlong v) {
+ SET_PRIMITIVE_FIELD(SetLong, obj, v);
+ }
+
+ static void SetShortField(JNIEnv* env, jobject obj, jfieldID fid, jshort v) {
+ SET_PRIMITIVE_FIELD(SetShort, obj, v);
+ }
+
+ static void SetStaticBooleanField(JNIEnv* env, jclass, jfieldID fid, jboolean v) {
+ SET_PRIMITIVE_FIELD(SetBoolean, NULL, v);
+ }
+
+ static void SetStaticByteField(JNIEnv* env, jclass, jfieldID fid, jbyte v) {
+ SET_PRIMITIVE_FIELD(SetByte, NULL, v);
+ }
+
+ static void SetStaticCharField(JNIEnv* env, jclass, jfieldID fid, jchar v) {
+ SET_PRIMITIVE_FIELD(SetChar, NULL, v);
+ }
+
+ static void SetStaticFloatField(JNIEnv* env, jclass, jfieldID fid, jfloat v) {
+ SET_PRIMITIVE_FIELD(SetFloat, NULL, v);
+ }
+
+ static void SetStaticDoubleField(JNIEnv* env, jclass, jfieldID fid, jdouble v) {
+ SET_PRIMITIVE_FIELD(SetDouble, NULL, v);
+ }
+
+ static void SetStaticIntField(JNIEnv* env, jclass, jfieldID fid, jint v) {
+ SET_PRIMITIVE_FIELD(SetInt, NULL, v);
+ }
+
+ static void SetStaticLongField(JNIEnv* env, jclass, jfieldID fid, jlong v) {
+ SET_PRIMITIVE_FIELD(SetLong, NULL, v);
+ }
+
+ static void SetStaticShortField(JNIEnv* env, jclass, jfieldID fid, jshort v) {
+ SET_PRIMITIVE_FIELD(SetShort, NULL, v);
}
static jobject CallStaticObjectMethod(JNIEnv* env,
@@ -1558,114 +1634,6 @@
InvokeWithJValues(ts, NULL, methodID, args);
}
- static jobject GetStaticObjectField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return NULL;
- }
-
- static jboolean GetStaticBooleanField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return JNI_FALSE;
- }
-
- static jbyte GetStaticByteField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return 0;
- }
-
- static jchar GetStaticCharField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return 0;
- }
-
- static jshort GetStaticShortField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return 0;
- }
-
- static jint GetStaticIntField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return 0;
- }
-
- static jlong GetStaticLongField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return 0;
- }
-
- static jfloat GetStaticFloatField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return 0;
- }
-
- static jdouble GetStaticDoubleField(JNIEnv* env, jclass clazz, jfieldID fieldID) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- return 0;
- }
-
- static void SetStaticObjectField(JNIEnv* env,
- jclass clazz, jfieldID fieldID, jobject value) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- }
-
- static void SetStaticBooleanField(JNIEnv* env,
- jclass clazz, jfieldID fieldID, jboolean value) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- }
-
- static void SetStaticByteField(JNIEnv* env,
- jclass clazz, jfieldID fieldID, jbyte value) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- }
-
- static void SetStaticCharField(JNIEnv* env,
- jclass clazz, jfieldID fieldID, jchar value) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- }
-
- static void SetStaticShortField(JNIEnv* env,
- jclass clazz, jfieldID fieldID, jshort value) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- }
-
- static void SetStaticIntField(JNIEnv* env,
- jclass clazz, jfieldID fieldID, jint value) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- }
-
- static void SetStaticLongField(JNIEnv* env,
- jclass clazz, jfieldID fieldID, jlong value) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- }
-
- static void SetStaticFloatField(JNIEnv* env,
- jclass clazz, jfieldID fieldID, jfloat value) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- }
-
- static void SetStaticDoubleField(JNIEnv* env,
- jclass clazz, jfieldID fieldID, jdouble value) {
- ScopedJniThreadState ts(env);
- UNIMPLEMENTED(FATAL);
- }
-
static jstring NewString(JNIEnv* env, const jchar* unicode, jsize len) {
ScopedJniThreadState ts(env);
UNIMPLEMENTED(FATAL);