diff options
author | Jeff Hao <jeffhao@google.com> | 2015-05-19 20:30:23 -0700 |
---|---|---|
committer | Jeff Hao <jeffhao@google.com> | 2015-05-20 18:32:14 -0700 |
commit | 15e9ad1d028d7f12cb598b075453173532a00d91 (patch) | |
tree | f31edd7f7e10d8372c452229b4f9eb749647864f /test/004-JniTest | |
parent | 5d52f3dca52548f4a4598abd06432cad3dca6b8a (diff) | |
download | art-15e9ad1d028d7f12cb598b075453173532a00d91.tar.gz art-15e9ad1d028d7f12cb598b075453173532a00d91.tar.bz2 art-15e9ad1d028d7f12cb598b075453173532a00d91.zip |
Intercept JNI invocation of String.<init> methods.
libmono uses JNI AllocObject and CallNonvirtualVoidMethod to create and
initialize a string instead of using the recommended NewObject. This
change adds an intercept to change the String.<init> call to a
StringFactory call instead. Then, it uses the object id of the original
string object referrer and maps it to the result of the StringFactory.
Bug: 21288130
Change-Id: Ib4db402c178bc37188d5c5faf30b6e4fdc747b17
Diffstat (limited to 'test/004-JniTest')
-rw-r--r-- | test/004-JniTest/jni_test.cc | 63 |
1 files changed, 50 insertions, 13 deletions
diff --git a/test/004-JniTest/jni_test.cc b/test/004-JniTest/jni_test.cc index cdc546155d..1ec0cf2d43 100644 --- a/test/004-JniTest/jni_test.cc +++ b/test/004-JniTest/jni_test.cc @@ -550,21 +550,58 @@ extern "C" void JNICALL Java_Main_testCallNonvirtual(JNIEnv* env, jclass) { } extern "C" JNIEXPORT void JNICALL Java_Main_testNewStringObject(JNIEnv* env, jclass) { - const char* string = "Test"; - int length = strlen(string); jclass c = env->FindClass("java/lang/String"); - assert(c != NULL); - jmethodID method = env->GetMethodID(c, "<init>", "([B)V"); - assert(method != NULL); + assert(c != nullptr); + + jmethodID mid1 = env->GetMethodID(c, "<init>", "()V"); + assert(mid1 != nullptr); + assert(!env->ExceptionCheck()); + jmethodID mid2 = env->GetMethodID(c, "<init>", "([B)V"); + assert(mid2 != nullptr); + assert(!env->ExceptionCheck()); + jmethodID mid3 = env->GetMethodID(c, "<init>", "([C)V"); + assert(mid3 != nullptr); + assert(!env->ExceptionCheck()); + jmethodID mid4 = env->GetMethodID(c, "<init>", "(Ljava/lang/String;)V"); + assert(mid4 != nullptr); assert(!env->ExceptionCheck()); - jbyteArray array = env->NewByteArray(length); - env->SetByteArrayRegion(array, 0, length, reinterpret_cast<const jbyte*>(string)); - jobject o = env->NewObject(c, method, array); - assert(o != NULL); - jstring s = reinterpret_cast<jstring>(o); - assert(env->GetStringLength(s) == length); - assert(env->GetStringUTFLength(s) == length); + + const char* test_array = "Test"; + int byte_array_length = strlen(test_array); + jbyteArray byte_array = env->NewByteArray(byte_array_length); + env->SetByteArrayRegion(byte_array, 0, byte_array_length, reinterpret_cast<const jbyte*>(test_array)); + + // Test NewObject + jstring s = reinterpret_cast<jstring>(env->NewObject(c, mid2, byte_array)); + assert(s != nullptr); + assert(env->GetStringLength(s) == byte_array_length); + assert(env->GetStringUTFLength(s) == byte_array_length); const char* chars = env->GetStringUTFChars(s, nullptr); - assert(strcmp(string, chars) == 0); + assert(strcmp(test_array, chars) == 0); env->ReleaseStringUTFChars(s, chars); + + // Test AllocObject and Call(Nonvirtual)VoidMethod + jstring s1 = reinterpret_cast<jstring>(env->AllocObject(c)); + assert(s1 != nullptr); + jstring s2 = reinterpret_cast<jstring>(env->AllocObject(c)); + assert(s2 != nullptr); + jstring s3 = reinterpret_cast<jstring>(env->AllocObject(c)); + assert(s3 != nullptr); + jstring s4 = reinterpret_cast<jstring>(env->AllocObject(c)); + assert(s4 != nullptr); + + jcharArray char_array = env->NewCharArray(5); + jstring string_arg = env->NewStringUTF("helloworld"); + + // With Var Args + env->CallVoidMethod(s1, mid1); + env->CallNonvirtualVoidMethod(s2, c, mid2, byte_array); + + // With JValues + jvalue args3[1]; + args3[0].l = char_array; + jvalue args4[1]; + args4[0].l = string_arg; + env->CallVoidMethodA(s3, mid3, args3); + env->CallNonvirtualVoidMethodA(s4, c, mid4, args4); } |