diff options
author | Brian Carlstrom <bdc@google.com> | 2014-09-07 23:52:02 -0700 |
---|---|---|
committer | Brian Carlstrom <bdc@google.com> | 2014-09-08 10:26:09 -0700 |
commit | 58e5e5d12d5dc55e09088d6bf8d51e4313248a13 (patch) | |
tree | 50a92e3f5552aa5174ae54c645f579c40a30cf0b /test/004-JniTest | |
parent | 165542588f5b8851d681a901580a277196d752d4 (diff) | |
download | art-58e5e5d12d5dc55e09088d6bf8d51e4313248a13.tar.gz art-58e5e5d12d5dc55e09088d6bf8d51e4313248a13.tar.bz2 art-58e5e5d12d5dc55e09088d6bf8d51e4313248a13.zip |
Add CallNonvirtual test
Change-Id: If0cbfc587cb8fe5d47fda1149629954080dd0f6f
Diffstat (limited to 'test/004-JniTest')
-rw-r--r-- | test/004-JniTest/expected.txt | 29 | ||||
-rw-r--r-- | test/004-JniTest/jni_test.cc | 195 | ||||
-rw-r--r-- | test/004-JniTest/src/Main.java | 57 |
3 files changed, 272 insertions, 9 deletions
diff --git a/test/004-JniTest/expected.txt b/test/004-JniTest/expected.txt index e69de29bb2..49d9cc0d5a 100644 --- a/test/004-JniTest/expected.txt +++ b/test/004-JniTest/expected.txt @@ -0,0 +1,29 @@ +Super.<init> +Super.<init> +Subclass.<init> +Super.<init> +Super.<init> +Subclass.<init> +Super.<init> +RUNNING super object, super class, super nonstatic +Super.nonstaticMethod +PASSED super object, super class, super nonstatic +Super.<init> +RUNNING super object, sub class, super nonstatic +Super.nonstaticMethod +PASSED super object, sub class, super nonstatic +Super.<init> +Subclass.<init> +RUNNING sub object, super class, super nonstatic +Super.nonstaticMethod +PASSED sub object, super class, super nonstatic +Super.<init> +Subclass.<init> +RUNNING sub object, sub class, super nonstatic +Super.nonstaticMethod +PASSED sub object, sub class, super nonstatic +Super.<init> +Subclass.<init> +RUNNING sub object, sub class, sub nonstatic +Subclass.nonstaticMethod +PASSED sub object, sub class, sub nonstatic diff --git a/test/004-JniTest/jni_test.cc b/test/004-JniTest/jni_test.cc index f5a1d65ac1..6fc4484731 100644 --- a/test/004-JniTest/jni_test.cc +++ b/test/004-JniTest/jni_test.cc @@ -353,3 +353,198 @@ static void testShallowGetStackClass2(JNIEnv* env) { extern "C" JNIEXPORT void JNICALL Java_Main_nativeTestShallowGetStackClass2(JNIEnv* env, jclass) { PthreadHelper(&testShallowGetStackClass2); } + +class JniCallNonvirtualVoidMethodTest { + public: + explicit JniCallNonvirtualVoidMethodTest(JNIEnv* env) + : env_(env), + check_jni_ri_(true), + check_jni_android_(true), + super_(GetClass("JniCallNonvirtualTest")), + sub_(GetClass("JniCallNonvirtualTestSubclass")), + super_constructor_(GetMethodID(super_, true, "<init>")), + super_static_(GetMethodID(super_, false, "staticMethod")), + super_nonstatic_(GetMethodID(super_, true, "nonstaticMethod")), + sub_constructor_(GetMethodID(sub_, true, "<init>")), + sub_static_(GetMethodID(sub_, false, "staticMethod")), + sub_nonstatic_(GetMethodID(sub_, true, "nonstaticMethod")), + super_field_(GetFieldID(super_, "nonstaticMethodSuperCalled")), + sub_field_(GetFieldID(super_, "nonstaticMethodSubCalled")) {} + + void Test() { + TestStaticCallNonvirtualMethod(); + TestNewObject(); + TestnonstaticCallNonvirtualMethod(); + } + + JNIEnv* const env_; + + bool const check_jni_ri_; + bool const check_jni_android_; + + jclass const super_; + jclass const sub_; + + jmethodID const super_constructor_; + jmethodID const super_static_; + jmethodID const super_nonstatic_; + jmethodID const sub_constructor_; + jmethodID const sub_static_; + jmethodID const sub_nonstatic_; + + jfieldID const super_field_; + jfieldID const sub_field_; + + private: + jclass GetClass(const char* class_name) { + jclass c = env_->FindClass(class_name); + if (env_->ExceptionCheck()) { + env_->ExceptionDescribe(); + env_->FatalError(__FUNCTION__); + } + assert(!env_->ExceptionCheck()); + assert(c != nullptr); + return c; + } + + jmethodID GetMethodID(jclass c, bool nonstatic, const char* method_name) { + jmethodID m = ((nonstatic) ? + env_->GetMethodID(c, method_name, "()V") : + env_->GetStaticMethodID(c, method_name, "()V")); + if (env_->ExceptionCheck()) { + env_->ExceptionDescribe(); + env_->FatalError(__FUNCTION__); + } + assert(m != nullptr); + return m; + } + + jobject CallConstructor(jclass c, jmethodID m) { + jobject o = env_->NewObject(c, m); + if (env_->ExceptionCheck()) { + env_->ExceptionDescribe(); + env_->FatalError(__FUNCTION__); + } + assert(o != nullptr); + return o; + } + + void CallMethod(jobject o, jclass c, jmethodID m, bool nonstatic, const char* test_case) { + printf("RUNNING %s\n", test_case); + env_->CallNonvirtualVoidMethod(o, c, m); + bool exception_check = env_->ExceptionCheck(); + if (c == nullptr || !nonstatic) { + if (!exception_check) { + printf("FAILED %s due to missing exception\n", test_case); + env_->FatalError("Expected NullPointerException with null jclass"); + } + env_->ExceptionClear(); + } else if (exception_check) { + printf("FAILED %s due to pending exception\n", test_case); + env_->ExceptionDescribe(); + env_->FatalError(test_case); + } + printf("PASSED %s\n", test_case); + } + + jfieldID GetFieldID(jclass c, const char* field_name) { + jfieldID m = env_->GetFieldID(c, field_name, "Z"); + if (env_->ExceptionCheck()) { + env_->ExceptionDescribe(); + env_->FatalError(__FUNCTION__); + } + assert(m != nullptr); + return m; + } + + jboolean GetBooleanField(jobject o, jfieldID f) { + jboolean b = env_->GetBooleanField(o, f); + if (env_->ExceptionCheck()) { + env_->ExceptionDescribe(); + env_->FatalError(__FUNCTION__); + } + return b; + } + + void TestStaticCallNonvirtualMethod() { + if (!check_jni_ri_&& !check_jni_android_) { + CallMethod(nullptr, nullptr, super_static_, false, "null object, null class, super static"); + } + if (!check_jni_android_) { + CallMethod(nullptr, super_, super_static_, false, "null object, super class, super static"); + } + if (!check_jni_android_) { + CallMethod(nullptr, sub_, super_static_, false, "null object, sub class, super static"); + } + + if (!check_jni_ri_ && !check_jni_android_) { + CallMethod(nullptr, nullptr, sub_static_, false, "null object, null class, sub static"); + } + if (!check_jni_android_) { + CallMethod(nullptr, sub_, sub_static_, false, "null object, super class, sub static"); + } + if (!check_jni_android_) { + CallMethod(nullptr, super_, sub_static_, false, "null object, super class, sub static"); + } + } + + void TestNewObject() { + jobject super_super = CallConstructor(super_, super_constructor_); + jobject super_sub = CallConstructor(super_, sub_constructor_); + jobject sub_super = CallConstructor(sub_, super_constructor_); + jobject sub_sub = CallConstructor(sub_, sub_constructor_); + + assert(env_->IsInstanceOf(super_super, super_)); + assert(!env_->IsInstanceOf(super_super, sub_)); + + // Note that even though we called (and ran) the subclass + // constructor, we are not the subclass. + assert(env_->IsInstanceOf(super_sub, super_)); + assert(!env_->IsInstanceOf(super_sub, sub_)); + + // Note that even though we called the superclass constructor, we + // are still the subclass. + assert(env_->IsInstanceOf(sub_super, super_)); + assert(env_->IsInstanceOf(sub_super, sub_)); + + assert(env_->IsInstanceOf(sub_sub, super_)); + assert(env_->IsInstanceOf(sub_sub, sub_)); + } + + void TestnonstaticCallNonvirtualMethod(bool super_object, bool super_class, bool super_method, const char* test_case) { + if (check_jni_android_) { + if (super_object && !super_method) { + return; // We don't allow a call with sub class method on the super class instance. + } + if (super_class && !super_method) { + return; // We don't allow a call with the sub class method with the super class argument. + } + } + jobject o = ((super_object) ? + CallConstructor(super_, super_constructor_) : + CallConstructor(sub_, sub_constructor_)); + jclass c = (super_class) ? super_ : sub_; + jmethodID m = (super_method) ? super_nonstatic_ : sub_nonstatic_; + CallMethod(o, c, m, true, test_case); + jboolean super_field = GetBooleanField(o, super_field_); + jboolean sub_field = GetBooleanField(o, sub_field_); + assert(super_field == super_method); + assert(sub_field != super_method); + } + + void TestnonstaticCallNonvirtualMethod() { + TestnonstaticCallNonvirtualMethod(true, true, true, "super object, super class, super nonstatic"); + TestnonstaticCallNonvirtualMethod(true, false, true, "super object, sub class, super nonstatic"); + TestnonstaticCallNonvirtualMethod(true, false, false, "super object, sub class, sub nonstatic"); + TestnonstaticCallNonvirtualMethod(true, true, false, "super object, super class, sub nonstatic"); + + TestnonstaticCallNonvirtualMethod(false, true, true, "sub object, super class, super nonstatic"); + TestnonstaticCallNonvirtualMethod(false, false, true, "sub object, sub class, super nonstatic"); + TestnonstaticCallNonvirtualMethod(false, false, false, "sub object, sub class, sub nonstatic"); + TestnonstaticCallNonvirtualMethod(false, true, false, "sub object, super class, sub nonstatic"); + } +}; + +extern "C" void JNICALL Java_Main_testCallNonvirtual(JNIEnv* env, jclass) { + JniCallNonvirtualVoidMethodTest(env).Test(); +} diff --git a/test/004-JniTest/src/Main.java b/test/004-JniTest/src/Main.java index 5884bc0e2b..8e9201056e 100644 --- a/test/004-JniTest/src/Main.java +++ b/test/004-JniTest/src/Main.java @@ -32,6 +32,7 @@ public class Main { testIsAssignableFromOnPrimitiveTypes(); testShallowGetCallingClassLoader(); testShallowGetStackClass2(); + testCallNonvirtual(); } private static native void testFindClassOnAttachedNativeThread(); @@ -94,7 +95,7 @@ public class Main { // Test sign-extension for values < 32b - native static byte byteMethod(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, + static native byte byteMethod(byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8, byte b9, byte b10); private static void testByteMethod() { @@ -109,7 +110,7 @@ public class Main { } } - native static short shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7, + private static native short shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7, short s8, short s9, short s10); private static void testShortMethod() { @@ -126,7 +127,7 @@ public class Main { // Test zero-extension for values < 32b - native static boolean booleanMethod(boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7, + private static native boolean booleanMethod(boolean b1, boolean b2, boolean b3, boolean b4, boolean b5, boolean b6, boolean b7, boolean b8, boolean b9, boolean b10); private static void testBooleanMethod() { @@ -139,7 +140,7 @@ public class Main { } } - native static char charMethod(char c1, char c2, char c3, char c4, char c5, char c6, char c7, + private static native char charMethod(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10); private static void testCharMethod() { @@ -168,17 +169,55 @@ public class Main { } } - native static boolean nativeIsAssignableFrom(Class<?> from, Class<?> to); + private static native boolean nativeIsAssignableFrom(Class<?> from, Class<?> to); - static void testShallowGetCallingClassLoader() { + private static void testShallowGetCallingClassLoader() { nativeTestShallowGetCallingClassLoader(); } - native static void nativeTestShallowGetCallingClassLoader(); + private native static void nativeTestShallowGetCallingClassLoader(); - static void testShallowGetStackClass2() { + private static void testShallowGetStackClass2() { nativeTestShallowGetStackClass2(); } - native static void nativeTestShallowGetStackClass2(); + private static native void nativeTestShallowGetStackClass2(); + + private static native void testCallNonvirtual(); +} + +class JniCallNonvirtualTest { + public boolean nonstaticMethodSuperCalled = false; + public boolean nonstaticMethodSubCalled = false; + + private static native void testCallNonvirtual(); + + public JniCallNonvirtualTest() { + System.out.println("Super.<init>"); + } + + public static void staticMethod() { + System.out.println("Super.staticMethod"); + } + + public void nonstaticMethod() { + System.out.println("Super.nonstaticMethod"); + nonstaticMethodSuperCalled = true; + } +} + +class JniCallNonvirtualTestSubclass extends JniCallNonvirtualTest { + + public JniCallNonvirtualTestSubclass() { + System.out.println("Subclass.<init>"); + } + + public static void staticMethod() { + System.out.println("Subclass.staticMethod"); + } + + public void nonstaticMethod() { + System.out.println("Subclass.nonstaticMethod"); + nonstaticMethodSubCalled = true; + } } |