diff options
| author | 2011-08-22 16:59:20 -0700 | |
|---|---|---|
| committer | 2011-08-22 16:59:20 -0700 | |
| commit | 885c3bd4d7adcc7f60f656b4f7247e7065feadf3 (patch) | |
| tree | 795774b8a63c9d0d52b9652de88f15da085efa61 /src | |
| parent | bd9359912e5398799f60649b86ae80644ec72627 (diff) | |
Implement field access (and a few other bits and bobs).
Change-Id: I837eb0ae4af8e314761bb42d3405f05b7a79573e
Diffstat (limited to 'src')
| -rw-r--r-- | src/class_linker_test.cc | 8 | ||||
| -rw-r--r-- | src/common_test.h | 43 | ||||
| -rw-r--r-- | src/jni_internal.cc | 334 | ||||
| -rw-r--r-- | src/jni_internal_test.cc | 105 | ||||
| -rw-r--r-- | src/object.cc | 7 |
5 files changed, 305 insertions, 192 deletions
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc index 4fb433feb9..7d5a44764d 100644 --- a/src/class_linker_test.cc +++ b/src/class_linker_test.cc @@ -14,8 +14,12 @@ class ClassLinkerTest : public CommonTest { protected: void AssertNonExistentClass(const StringPiece& descriptor) { EXPECT_TRUE(class_linker_->FindSystemClass(descriptor) == NULL); - EXPECT_TRUE(Thread::Current()->IsExceptionPending()); - Thread::Current()->ClearException(); + Thread* self = Thread::Current(); + EXPECT_TRUE(self->IsExceptionPending()); + Object* exception = self->GetException(); + self->ClearException(); + Class* exception_class = class_linker_->FindSystemClass("Ljava/lang/NoClassDefFoundError;"); + EXPECT_TRUE(exception->InstanceOf(exception_class)); } void AssertPrimitiveClass(const StringPiece& descriptor) { diff --git a/src/common_test.h b/src/common_test.h index d562226427..a405ce512c 100644 --- a/src/common_test.h +++ b/src/common_test.h @@ -197,6 +197,49 @@ static const char kStatics[] = "ABwBAAAFAAAAAwAAAGwBAAAGAAAAAQAAAIQBAAABIAAAAgAAAKQBAAACIAAAHAAAADwCAAADIAAA" "AgAAAOICAAAAIAAAAQAAAPUCAAAAEAAAAQAAABwDAAA="; +// class AllFields { +// static boolean sZ; +// static byte sB; +// static char sC; +// static double sD; +// static float sF; +// static int sI; +// static long sJ; +// static short sS; +// static Object sObject; +// static Object[] sObjectArray; +// +// boolean iZ; +// byte iB; +// char iC; +// double iD; +// float iF; +// int iI; +// long iJ; +// short iS; +// Object iObject; +// Object[] iObjectArray; +// } +static const char kAllFields[] = + "ZGV4CjAzNQCdaMDlt1s2Pw65nbVCJcCcZcmroYXvMF/AAwAAcAAAAHhWNBIAAAAAAAAAACwDAAAi" + "AAAAcAAAAAwAAAD4AAAAAQAAACgBAAAUAAAANAEAAAIAAADUAQAAAQAAAOQBAAC8AQAABAIAABwC" + "AAAkAgAANAIAADcCAAA6AgAAPQIAAEACAABDAgAARgIAAFMCAABnAgAAagIAAG0CAABwAgAAhQIA" + "AIkCAACNAgAAkQIAAJUCAACZAgAAnQIAAKYCAAC0AgAAuAIAALwCAADAAgAAxAIAAMgCAADMAgAA" + "0AIAANQCAADdAgAA6wIAAO8CAAACAAAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACQAAAAoAAAAL" + "AAAADAAAAA0AAAALAAAACQAAAAAAAAAGAAAADgAAAAYAAQAPAAAABgACABAAAAAGAAMAEQAAAAYA" + "BAASAAAABgAFABMAAAAGAAcAFAAAAAYACwAVAAAABgAIABYAAAAGAAoAFwAAAAYAAAAYAAAABgAB" + "ABkAAAAGAAIAGgAAAAYAAwAbAAAABgAEABwAAAAGAAUAHQAAAAYABwAeAAAABgALAB8AAAAGAAgA" + "IAAAAAYACgAhAAAABgAAAAAAAAAHAAAAAAAAAAYAAAAAAAAABwAAAAAAAAABAAAAAAAAAPgCAAAA" + "AAAAAQABAAEAAADzAgAABAAAAHAQAQAAAA4ABjxpbml0PgAOQWxsRmllbGRzLmphdmEAAUIAAUMA" + "AUQAAUYAAUkAAUoAC0xBbGxGaWVsZHM7ABJMamF2YS9sYW5nL09iamVjdDsAAVMAAVYAAVoAE1tM" + "amF2YS9sYW5nL09iamVjdDsAAmlCAAJpQwACaUQAAmlGAAJpSQACaUoAB2lPYmplY3QADGlPYmpl" + "Y3RBcnJheQACaVMAAmlaAAJzQgACc0MAAnNEAAJzRgACc0kAAnNKAAdzT2JqZWN0AAxzT2JqZWN0" + "QXJyYXkAAnNTAAJzWgADAAcOAAoKAQAKCAEIAQgBCAEIAQgBCAEIAQgBCAAAAQABAAEAAQABAAEA" + "AQABAAEAAICABIQEAAAMAAAAAAAAAAEAAAAAAAAAAQAAACIAAABwAAAAAgAAAAwAAAD4AAAAAwAA" + "AAEAAAAoAQAABAAAABQAAAA0AQAABQAAAAIAAADUAQAABgAAAAEAAADkAQAAASAAAAEAAAAEAgAA" + "AiAAACIAAAAcAgAAAyAAAAEAAADzAgAAACAAAAEAAAD4AgAAABAAAAEAAAAsAwAA"; + + // class Main { // public static void main(String args[]) { // } diff --git a/src/jni_internal.cc b/src/jni_internal.cc index a892a28798..243a29d6d8 100644 --- a/src/jni_internal.cc +++ b/src/jni_internal.cc @@ -582,10 +582,10 @@ class JNI { 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 @@ class JNI { 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 @@ class JNI { 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 @@ class JNI { 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 @@ class JNI { 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); diff --git a/src/jni_internal_test.cc b/src/jni_internal_test.cc index 9043bcdeb3..62f606821d 100644 --- a/src/jni_internal_test.cc +++ b/src/jni_internal_test.cc @@ -19,6 +19,21 @@ class JniInternalTest : public CommonTest { JNIEnv* env_; }; +TEST_F(JniInternalTest, AllocObject) { + jclass c = env_->FindClass("java/lang/String"); + ASSERT_TRUE(c != NULL); + jobject o = env_->AllocObject(c); + ASSERT_TRUE(o != NULL); + + // We have an instance of the class we asked for... + ASSERT_TRUE(env_->IsInstanceOf(o, c)); + // ...whose fields haven't been initialized because + // we didn't call a constructor. + ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "count", "I"))); + ASSERT_EQ(0, env_->GetIntField(o, env_->GetFieldID(c, "offset", "I"))); + ASSERT_TRUE(env_->GetObjectField(o, env_->GetFieldID(c, "value", "[C")) == NULL); +} + TEST_F(JniInternalTest, GetVersion) { ASSERT_EQ(JNI_VERSION_1_6, env_->GetVersion()); } @@ -303,6 +318,15 @@ TEST_F(JniInternalTest, GetArrayLength) { // Already tested in NewObjectArray/NewPrimitiveArray. } +TEST_F(JniInternalTest, GetSuperclass) { + jclass object_class = env_->FindClass("java/lang/Object"); + ASSERT_TRUE(object_class != NULL); + jclass string_class = env_->FindClass("java/lang/String"); + ASSERT_TRUE(string_class != NULL); + ASSERT_TRUE(env_->IsSameObject(object_class, env_->GetSuperclass(string_class))); + ASSERT_TRUE(env_->GetSuperclass(object_class) == NULL); +} + TEST_F(JniInternalTest, NewStringUTF) { EXPECT_TRUE(env_->NewStringUTF(NULL) == NULL); EXPECT_TRUE(env_->NewStringUTF("") != NULL); @@ -331,6 +355,87 @@ TEST_F(JniInternalTest, SetObjectArrayElement) { // TODO: check ArrayStoreException thrown for bad types. } +#define EXPECT_STATIC_PRIMITIVE_FIELD(type, field_name, sig, value1, value2) \ + do { \ + jfieldID fid = env_->GetStaticFieldID(c, field_name, sig); \ + EXPECT_TRUE(fid != NULL); \ + env_->SetStatic ## type ## Field(c, fid, value1); \ + EXPECT_EQ(value1, env_->GetStatic ## type ## Field(c, fid)); \ + env_->SetStatic ## type ## Field(c, fid, value2); \ + EXPECT_EQ(value2, env_->GetStatic ## type ## Field(c, fid)); \ + } while (false) + +#define EXPECT_PRIMITIVE_FIELD(instance, type, field_name, sig, value1, value2) \ + do { \ + jfieldID fid = env_->GetFieldID(c, field_name, sig); \ + EXPECT_TRUE(fid != NULL); \ + env_->Set ## type ## Field(instance, fid, value1); \ + EXPECT_EQ(value1, env_->Get ## type ## Field(instance, fid)); \ + env_->Set ## type ## Field(instance, fid, value2); \ + EXPECT_EQ(value2, env_->Get ## type ## Field(instance, fid)); \ + } while (false) + + +TEST_F(JniInternalTest, GetPrimitiveField_SetPrimitiveField) { + scoped_ptr<DexFile> dex(OpenDexFileBase64(kAllFields, "kAllFields")); + PathClassLoader* class_loader = AllocPathClassLoader(dex.get()); + Thread::Current()->SetClassLoaderOverride(class_loader); + + jclass c = env_->FindClass("AllFields"); + ASSERT_TRUE(c != NULL); + jobject o = env_->AllocObject(c); + ASSERT_TRUE(o != NULL); + + EXPECT_STATIC_PRIMITIVE_FIELD(Boolean, "sZ", "Z", true, false); + EXPECT_STATIC_PRIMITIVE_FIELD(Byte, "sB", "B", 1, 2); + EXPECT_STATIC_PRIMITIVE_FIELD(Char, "sC", "C", 'a', 'b'); + EXPECT_STATIC_PRIMITIVE_FIELD(Double, "sD", "D", 1.0, 2.0); + EXPECT_STATIC_PRIMITIVE_FIELD(Float, "sF", "F", 1.0, 2.0); + EXPECT_STATIC_PRIMITIVE_FIELD(Int, "sI", "I", 1, 2); + EXPECT_STATIC_PRIMITIVE_FIELD(Long, "sJ", "J", 1, 2); + EXPECT_STATIC_PRIMITIVE_FIELD(Short, "sS", "S", 1, 2); + + EXPECT_PRIMITIVE_FIELD(o, Boolean, "iZ", "Z", true, false); + EXPECT_PRIMITIVE_FIELD(o, Byte, "iB", "B", 1, 2); + EXPECT_PRIMITIVE_FIELD(o, Char, "iC", "C", 'a', 'b'); + EXPECT_PRIMITIVE_FIELD(o, Double, "iD", "D", 1.0, 2.0); + EXPECT_PRIMITIVE_FIELD(o, Float, "iF", "F", 1.0, 2.0); + EXPECT_PRIMITIVE_FIELD(o, Int, "iI", "I", 1, 2); + EXPECT_PRIMITIVE_FIELD(o, Long, "iJ", "J", 1, 2); + EXPECT_PRIMITIVE_FIELD(o, Short, "iS", "S", 1, 2); +} + +TEST_F(JniInternalTest, GetObjectField_SetObjectField) { + scoped_ptr<DexFile> dex(OpenDexFileBase64(kAllFields, "kAllFields")); + PathClassLoader* class_loader = AllocPathClassLoader(dex.get()); + Thread::Current()->SetClassLoaderOverride(class_loader); + + jclass c = env_->FindClass("AllFields"); + ASSERT_TRUE(c != NULL); + jobject o = env_->AllocObject(c); + ASSERT_TRUE(o != NULL); + + jstring s1 = env_->NewStringUTF("hello"); + ASSERT_TRUE(s1 != NULL); + jstring s2 = env_->NewStringUTF("world"); + ASSERT_TRUE(s2 != NULL); + + jfieldID s_fid = env_->GetStaticFieldID(c, "sObject", "Ljava/lang/Object;"); + ASSERT_TRUE(s_fid != NULL); + jfieldID i_fid = env_->GetFieldID(c, "iObject", "Ljava/lang/Object;"); + ASSERT_TRUE(i_fid != NULL); + + env_->SetStaticObjectField(c, s_fid, s1); + ASSERT_TRUE(env_->IsSameObject(s1, env_->GetStaticObjectField(c, s_fid))); + env_->SetStaticObjectField(c, s_fid, s2); + ASSERT_TRUE(env_->IsSameObject(s2, env_->GetStaticObjectField(c, s_fid))); + + env_->SetObjectField(o, i_fid, s1); + ASSERT_TRUE(env_->IsSameObject(s1, env_->GetObjectField(o, i_fid))); + env_->SetObjectField(o, i_fid, s2); + ASSERT_TRUE(env_->IsSameObject(s2, env_->GetObjectField(o, i_fid))); +} + TEST_F(JniInternalTest, NewLocalRef_NULL) { EXPECT_TRUE(env_->NewLocalRef(NULL) == NULL); } diff --git a/src/object.cc b/src/object.cc index 93166602d8..6a349ac917 100644 --- a/src/object.cc +++ b/src/object.cc @@ -226,7 +226,6 @@ int8_t Field::GetByte(const Object* object) const { void Field::SetByte(Object* object, int8_t b) const { CHECK_EQ(GetType(), 'B'); - CHECK(IsStatic()); Set32(object, b); } @@ -237,7 +236,6 @@ uint16_t Field::GetChar(const Object* object) const { void Field::SetChar(Object* object, uint16_t c) const { CHECK_EQ(GetType(), 'C'); - CHECK(IsStatic()); Set32(object, c); } @@ -248,7 +246,6 @@ uint16_t Field::GetShort(const Object* object) const { void Field::SetShort(Object* object, uint16_t s) const { CHECK_EQ(GetType(), 'S'); - CHECK(IsStatic()); Set32(object, s); } @@ -259,7 +256,6 @@ int32_t Field::GetInt(const Object* object) const { void Field::SetInt(Object* object, int32_t i) const { CHECK_EQ(GetType(), 'I'); - CHECK(IsStatic()); Set32(object, i); } @@ -270,7 +266,6 @@ int64_t Field::GetLong(const Object* object) const { void Field::SetLong(Object* object, int64_t j) const { CHECK_EQ(GetType(), 'J'); - CHECK(IsStatic()); Set64(object, j); } @@ -283,7 +278,6 @@ float Field::GetFloat(const Object* object) const { void Field::SetFloat(Object* object, float f) const { CHECK_EQ(GetType(), 'F'); - CHECK(IsStatic()); JValue float_bits; float_bits.f = f; Set32(object, float_bits.i); @@ -298,7 +292,6 @@ double Field::GetDouble(const Object* object) const { void Field::SetDouble(Object* object, double d) const { CHECK_EQ(GetType(), 'D'); - CHECK(IsStatic()); JValue double_bits; double_bits.d = d; Set64(object, double_bits.j); |