/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <vector>

#include "art_method-inl.h"
#include "base/logging.h"
#include "jni.h"

namespace art {

static JavaVM* jvm = nullptr;

static jint Java_Main_intFastNativeMethod(JNIEnv*, jclass, jint a, jint b, jint c);
static jint Java_Main_intCriticalNativeMethod(jint a, jint b, jint c);

static JNINativeMethod sMainMethods[] = {
  {"intFastNativeMethod", "(III)I", reinterpret_cast<void*>(Java_Main_intFastNativeMethod) },
  {"intCriticalNativeMethod", "(III)I", reinterpret_cast<void*>(Java_Main_intCriticalNativeMethod) },
};

extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void*) {
  CHECK(vm != nullptr);
  CHECK(jvm == nullptr);
  jvm = vm;
  std::cout << "JNI_OnLoad called" << std::endl;

  return JNI_VERSION_1_6;
}

extern "C" JNIEXPORT void JNI_OnUnload(JavaVM*, void*) {
  // std::cout since LOG(INFO) adds extra stuff like pid.
  std::cout << "JNI_OnUnload called" << std::endl;
  // Clear jvm for CHECK in test 004-JniTest.
  jvm = nullptr;
}

static void* AttachHelper(void* arg) {
  CHECK(jvm != nullptr);

  JNIEnv* env = nullptr;
  JavaVMAttachArgs args = { JNI_VERSION_1_6, __FUNCTION__, nullptr };
  int attach_result = jvm->AttachCurrentThread(&env, &args);
  CHECK_EQ(attach_result, 0);

  typedef void (*Fn)(JNIEnv*);
  Fn fn = reinterpret_cast<Fn>(arg);
  fn(env);

  int detach_result = jvm->DetachCurrentThread();
  CHECK_EQ(detach_result, 0);
  return nullptr;
}

static void PthreadHelper(void (*fn)(JNIEnv*)) {
  pthread_t pthread;
  int pthread_create_result = pthread_create(&pthread, nullptr, AttachHelper,
                                             reinterpret_cast<void*>(fn));
  CHECK_EQ(pthread_create_result, 0);
  int pthread_join_result = pthread_join(pthread, nullptr);
  CHECK_EQ(pthread_join_result, 0);
}

static void testFindClassOnAttachedNativeThread(JNIEnv* env) {
  jclass clazz = env->FindClass("Main");
  CHECK(clazz != nullptr);
  CHECK(!env->ExceptionCheck());

  jobjectArray array = env->NewObjectArray(0, clazz, nullptr);
  CHECK(array != nullptr);
  CHECK(!env->ExceptionCheck());
}

// http://b/10994325
extern "C" JNIEXPORT void JNICALL Java_Main_testFindClassOnAttachedNativeThread(JNIEnv*, jclass) {
  PthreadHelper(&testFindClassOnAttachedNativeThread);
}

static void testFindFieldOnAttachedNativeThread(JNIEnv* env) {
  jclass clazz = env->FindClass("Main");
  CHECK(clazz != nullptr);
  CHECK(!env->ExceptionCheck());

  jfieldID field = env->GetStaticFieldID(clazz, "testFindFieldOnAttachedNativeThreadField", "Z");
  CHECK(field != nullptr);
  CHECK(!env->ExceptionCheck());

  env->SetStaticBooleanField(clazz, field, JNI_TRUE);
}

extern "C" JNIEXPORT void JNICALL Java_Main_testFindFieldOnAttachedNativeThreadNative(JNIEnv*,
                                                                                      jclass) {
  PthreadHelper(&testFindFieldOnAttachedNativeThread);
}

static void testReflectFieldGetFromAttachedNativeThread(JNIEnv* env) {
  jclass clazz = env->FindClass("Main");
  CHECK(clazz != nullptr);
  CHECK(!env->ExceptionCheck());

  jclass class_clazz = env->FindClass("java/lang/Class");
  CHECK(class_clazz != nullptr);
  CHECK(!env->ExceptionCheck());

  jmethodID getFieldMetodId = env->GetMethodID(class_clazz, "getField",
                                               "(Ljava/lang/String;)Ljava/lang/reflect/Field;");
  CHECK(getFieldMetodId != nullptr);
  CHECK(!env->ExceptionCheck());

  jstring field_name = env->NewStringUTF("testReflectFieldGetFromAttachedNativeThreadField");
  CHECK(field_name != nullptr);
  CHECK(!env->ExceptionCheck());

  jobject field = env->CallObjectMethod(clazz, getFieldMetodId, field_name);
  CHECK(field != nullptr);
  CHECK(!env->ExceptionCheck());

  jclass field_clazz = env->FindClass("java/lang/reflect/Field");
  CHECK(field_clazz != nullptr);
  CHECK(!env->ExceptionCheck());

  jmethodID getBooleanMetodId = env->GetMethodID(field_clazz, "getBoolean",
                                                 "(Ljava/lang/Object;)Z");
  CHECK(getBooleanMetodId != nullptr);
  CHECK(!env->ExceptionCheck());

  jboolean value = env->CallBooleanMethod(field, getBooleanMetodId, /* ignored */ clazz);
  CHECK(value == false);
  CHECK(!env->ExceptionCheck());
}

// http://b/15539150
extern "C" JNIEXPORT void JNICALL Java_Main_testReflectFieldGetFromAttachedNativeThreadNative(
    JNIEnv*, jclass) {
  PthreadHelper(&testReflectFieldGetFromAttachedNativeThread);
}


// http://b/11243757
extern "C" JNIEXPORT void JNICALL Java_Main_testCallStaticVoidMethodOnSubClassNative(JNIEnv* env,
                                                                                     jclass) {
  jclass super_class = env->FindClass("Main$testCallStaticVoidMethodOnSubClass_SuperClass");
  CHECK(super_class != nullptr);

  jmethodID execute = env->GetStaticMethodID(super_class, "execute", "()V");
  CHECK(execute != nullptr);

  jclass sub_class = env->FindClass("Main$testCallStaticVoidMethodOnSubClass_SubClass");
  CHECK(sub_class != nullptr);

  env->CallStaticVoidMethod(sub_class, execute);
}

extern "C" JNIEXPORT jobject JNICALL Java_Main_testGetMirandaMethodNative(JNIEnv* env, jclass) {
  jclass abstract_class = env->FindClass("Main$testGetMirandaMethod_MirandaAbstract");
  CHECK(abstract_class != nullptr);
  jmethodID miranda_method = env->GetMethodID(abstract_class, "inInterface", "()Z");
  CHECK(miranda_method != nullptr);
  return env->ToReflectedMethod(abstract_class, miranda_method, JNI_FALSE);
}

// https://code.google.com/p/android/issues/detail?id=63055
extern "C" void JNICALL Java_Main_testZeroLengthByteBuffers(JNIEnv* env, jclass) {
  std::vector<uint8_t> buffer(1);
  jobject byte_buffer = env->NewDirectByteBuffer(&buffer[0], 0);
  CHECK(byte_buffer != nullptr);
  CHECK(!env->ExceptionCheck());

  CHECK_EQ(env->GetDirectBufferAddress(byte_buffer), &buffer[0]);
  CHECK_EQ(env->GetDirectBufferCapacity(byte_buffer), 0);
}

constexpr size_t kByteReturnSize = 7;
jbyte byte_returns[kByteReturnSize] = { 0, 1, 2, 127, -1, -2, -128 };

extern "C" jbyte JNICALL Java_Main_byteMethod(JNIEnv*, jclass, jbyte b1, jbyte b2,
                                              jbyte b3, jbyte b4, jbyte b5, jbyte b6,
                                              jbyte b7, jbyte b8, jbyte b9, jbyte b10) {
  // We use b1 to drive the output.
  CHECK_EQ(b2, 2);
  CHECK_EQ(b3, -3);
  CHECK_EQ(b4, 4);
  CHECK_EQ(b5, -5);
  CHECK_EQ(b6, 6);
  CHECK_EQ(b7, -7);
  CHECK_EQ(b8, 8);
  CHECK_EQ(b9, -9);
  CHECK_EQ(b10, 10);

  CHECK_LE(0, b1);
  CHECK_LT(b1, static_cast<jbyte>(kByteReturnSize));

  return byte_returns[b1];
}

constexpr size_t kShortReturnSize = 9;
jshort short_returns[kShortReturnSize] = { 0, 1, 2, 127, 32767, -1, -2, -128,
    static_cast<jshort>(0x8000) };
// The weird static_cast is because short int is only guaranteed down to -32767, not Java's -32768.

extern "C" jshort JNICALL Java_Main_shortMethod(JNIEnv*, jclass, jshort s1, jshort s2,
                                                jshort s3, jshort s4, jshort s5, jshort s6,
                                                jshort s7, jshort s8, jshort s9, jshort s10) {
  // We use s1 to drive the output.
  CHECK_EQ(s2, 2);
  CHECK_EQ(s3, -3);
  CHECK_EQ(s4, 4);
  CHECK_EQ(s5, -5);
  CHECK_EQ(s6, 6);
  CHECK_EQ(s7, -7);
  CHECK_EQ(s8, 8);
  CHECK_EQ(s9, -9);
  CHECK_EQ(s10, 10);

  CHECK_LE(0, s1);
  CHECK_LT(s1, static_cast<jshort>(kShortReturnSize));

  return short_returns[s1];
}

extern "C" jboolean JNICALL Java_Main_booleanMethod(JNIEnv*, jclass, jboolean b1,
                                                    jboolean b2, jboolean b3, jboolean b4,
                                                    jboolean b5, jboolean b6, jboolean b7,
                                                    jboolean b8, jboolean b9, jboolean b10) {
  // We use b1 to drive the output.
  CHECK_EQ(b2, JNI_TRUE);
  CHECK_EQ(b3, JNI_FALSE);
  CHECK_EQ(b4, JNI_TRUE);
  CHECK_EQ(b5, JNI_FALSE);
  CHECK_EQ(b6, JNI_TRUE);
  CHECK_EQ(b7, JNI_FALSE);
  CHECK_EQ(b8, JNI_TRUE);
  CHECK_EQ(b9, JNI_FALSE);
  CHECK_EQ(b10, JNI_TRUE);

  CHECK(b1 == JNI_TRUE || b1 == JNI_FALSE);
  return b1;
}

constexpr size_t kCharReturnSize = 8;
jchar char_returns[kCharReturnSize] = { 0, 1, 2, 127, 255, 256, 15000, 34000 };

extern "C" jchar JNICALL Java_Main_charMethod(JNIEnv*, jclass, jchar c1, jchar c2,
                                              jchar c3, jchar c4, jchar c5, jchar c6, jchar c7,
                                              jchar c8, jchar c9, jchar c10) {
  // We use c1 to drive the output.
  CHECK_EQ(c2, 'a');
  CHECK_EQ(c3, 'b');
  CHECK_EQ(c4, 'c');
  CHECK_EQ(c5, '0');
  CHECK_EQ(c6, '1');
  CHECK_EQ(c7, '2');
  CHECK_EQ(c8, 1234);
  CHECK_EQ(c9, 2345);
  CHECK_EQ(c10, 3456);

  CHECK_LT(c1, static_cast<jchar>(kCharReturnSize));

  return char_returns[c1];
}

extern "C" JNIEXPORT void JNICALL Java_Main_removeLocalObject(JNIEnv* env, jclass, jclass o) {
  // Delete the arg to see if it crashes.
  env->DeleteLocalRef(o);
}

extern "C" JNIEXPORT jboolean JNICALL Java_Main_nativeIsAssignableFrom(JNIEnv* env, jclass,
                                                                       jclass from, jclass to) {
  return env->IsAssignableFrom(from, to);
}

static void testShallowGetCallingClassLoader(JNIEnv* env) {
  // Test direct call.
  {
    jclass vmstack_clazz = env->FindClass("dalvik/system/VMStack");
    CHECK(vmstack_clazz != nullptr);
    CHECK(!env->ExceptionCheck());

    jmethodID getCallingClassLoaderMethodId = env->GetStaticMethodID(vmstack_clazz,
                                                                     "getCallingClassLoader",
                                                                     "()Ljava/lang/ClassLoader;");
    CHECK(getCallingClassLoaderMethodId != nullptr);
    CHECK(!env->ExceptionCheck());

    jobject class_loader = env->CallStaticObjectMethod(vmstack_clazz,
                                                       getCallingClassLoaderMethodId);
    CHECK(class_loader == nullptr);
    CHECK(!env->ExceptionCheck());
  }

  // Test one-level call. Use System.loadLibrary().
  {
    jclass system_clazz = env->FindClass("java/lang/System");
    CHECK(system_clazz != nullptr);
    CHECK(!env->ExceptionCheck());

    jmethodID loadLibraryMethodId = env->GetStaticMethodID(system_clazz, "loadLibrary",
                                                           "(Ljava/lang/String;)V");
    CHECK(loadLibraryMethodId != nullptr);
    CHECK(!env->ExceptionCheck());

    // Create a string object.
    jobject library_string = env->NewStringUTF("non_existing_library");
    CHECK(library_string != nullptr);
    CHECK(!env->ExceptionCheck());

    env->CallStaticVoidMethod(system_clazz, loadLibraryMethodId, library_string);
    CHECK(env->ExceptionCheck());

    // We expect UnsatisfiedLinkError.
    jthrowable thrown = env->ExceptionOccurred();
    env->ExceptionClear();

    jclass unsatisfied_link_error_clazz = env->FindClass("java/lang/UnsatisfiedLinkError");
    jclass thrown_class = env->GetObjectClass(thrown);
    CHECK(env->IsSameObject(unsatisfied_link_error_clazz, thrown_class));
  }
}

// http://b/16867274
extern "C" JNIEXPORT void JNICALL Java_Main_nativeTestShallowGetCallingClassLoader(JNIEnv*,
                                                                                   jclass) {
  PthreadHelper(&testShallowGetCallingClassLoader);
}

static void testShallowGetStackClass2(JNIEnv* env) {
  jclass vmstack_clazz = env->FindClass("dalvik/system/VMStack");
  CHECK(vmstack_clazz != nullptr);
  CHECK(!env->ExceptionCheck());

  // Test direct call.
  {
    jmethodID getStackClass2MethodId = env->GetStaticMethodID(vmstack_clazz, "getStackClass2",
                                                              "()Ljava/lang/Class;");
    CHECK(getStackClass2MethodId != nullptr);
    CHECK(!env->ExceptionCheck());

    jobject caller_class = env->CallStaticObjectMethod(vmstack_clazz, getStackClass2MethodId);
    CHECK(caller_class == nullptr);
    CHECK(!env->ExceptionCheck());
  }

  // Test one-level call. Use VMStack.getStackClass1().
  {
    jmethodID getStackClass1MethodId = env->GetStaticMethodID(vmstack_clazz, "getStackClass1",
                                                              "()Ljava/lang/Class;");
    CHECK(getStackClass1MethodId != nullptr);
    CHECK(!env->ExceptionCheck());

    jobject caller_class = env->CallStaticObjectMethod(vmstack_clazz, getStackClass1MethodId);
    CHECK(caller_class == nullptr);
    CHECK(!env->ExceptionCheck());
  }

  // For better testing we would need to compile against libcore and have a two-deep stack
  // ourselves.
}

extern "C" JNIEXPORT void JNICALL Java_Main_nativeTestShallowGetStackClass2(JNIEnv*, 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__);
    }
    CHECK(!env_->ExceptionCheck());
    CHECK(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__);
    }
    CHECK(m != nullptr);
    return m;
  }

  jobject CallConstructor(jclass c, jmethodID m) {
    jobject o = env_->NewObject(c, m);
    if (env_->ExceptionCheck()) {
      env_->ExceptionDescribe();
      env_->FatalError(__FUNCTION__);
    }
    CHECK(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__);
    }
    CHECK(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_);

    CHECK(env_->IsInstanceOf(super_super, super_));
    CHECK(!env_->IsInstanceOf(super_super, sub_));

    // Note that even though we called (and ran) the subclass
    // constructor, we are not the subclass.
    CHECK(env_->IsInstanceOf(super_sub, super_));
    CHECK(!env_->IsInstanceOf(super_sub, sub_));

    // Note that even though we called the superclass constructor, we
    // are still the subclass.
    CHECK(env_->IsInstanceOf(sub_super, super_));
    CHECK(env_->IsInstanceOf(sub_super, sub_));

    CHECK(env_->IsInstanceOf(sub_sub, super_));
    CHECK(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_);
    CHECK_EQ(super_field, super_method);
    CHECK_NE(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();
}

extern "C" JNIEXPORT void JNICALL Java_Main_testNewStringObject(JNIEnv* env, jclass) {
  jclass c = env->FindClass("java/lang/String");
  CHECK(c != nullptr);

  jmethodID mid1 = env->GetMethodID(c, "<init>", "()V");
  CHECK(mid1 != nullptr);
  CHECK(!env->ExceptionCheck());
  jmethodID mid2 = env->GetMethodID(c, "<init>", "([B)V");
  CHECK(mid2 != nullptr);
  CHECK(!env->ExceptionCheck());
  jmethodID mid3 = env->GetMethodID(c, "<init>", "([C)V");
  CHECK(mid3 != nullptr);
  CHECK(!env->ExceptionCheck());
  jmethodID mid4 = env->GetMethodID(c, "<init>", "(Ljava/lang/String;)V");
  CHECK(mid4 != nullptr);
  CHECK(!env->ExceptionCheck());

  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));
  CHECK(s != nullptr);
  CHECK_EQ(env->GetStringLength(s), byte_array_length);
  CHECK_EQ(env->GetStringUTFLength(s), byte_array_length);
  const char* chars = env->GetStringUTFChars(s, nullptr);
  CHECK_EQ(strcmp(test_array, chars), 0);
  env->ReleaseStringUTFChars(s, chars);

  // Test AllocObject and Call(Nonvirtual)VoidMethod
  jstring s1 = reinterpret_cast<jstring>(env->AllocObject(c));
  CHECK(s1 != nullptr);
  jstring s2 = reinterpret_cast<jstring>(env->AllocObject(c));
  CHECK(s2 != nullptr);
  jstring s3 = reinterpret_cast<jstring>(env->AllocObject(c));
  CHECK(s3 != nullptr);
  jstring s4 = reinterpret_cast<jstring>(env->AllocObject(c));
  CHECK(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);

  // Test with global and weak global references
  jstring s5 = reinterpret_cast<jstring>(env->AllocObject(c));
  CHECK(s5 != nullptr);
  s5 = reinterpret_cast<jstring>(env->NewGlobalRef(s5));
  jstring s6 = reinterpret_cast<jstring>(env->AllocObject(c));
  CHECK(s6 != nullptr);
  s6 = reinterpret_cast<jstring>(env->NewWeakGlobalRef(s6));

  env->CallVoidMethod(s5, mid1);
  env->CallNonvirtualVoidMethod(s6, c, mid2, byte_array);
  CHECK_EQ(env->GetStringLength(s5), 0);
  CHECK_EQ(env->GetStringLength(s6), byte_array_length);
  const char* chars6 = env->GetStringUTFChars(s6, nullptr);
  CHECK_EQ(strcmp(test_array, chars6), 0);
  env->ReleaseStringUTFChars(s6, chars6);
}

extern "C" JNIEXPORT jlong JNICALL Java_Main_testGetMethodID(JNIEnv* env, jclass, jclass c) {
  return reinterpret_cast<jlong>(env->GetMethodID(c, "a", "()V"));
}

extern "C" JNIEXPORT void JNICALL Java_Main_enterJniCriticalSection(JNIEnv* env, jclass,
                                                                    jint arraySize,
                                                                    jbyteArray array0,
                                                                    jbyteArray array1) {
  for (int i = 0; i < 50000; ++i) {
    char* data0 = reinterpret_cast<char*>(env->GetPrimitiveArrayCritical(array0, nullptr));
    char* data1 = reinterpret_cast<char*>(env->GetPrimitiveArrayCritical(array1, nullptr));
    bool up = i % 2 == 0;
    for (int j = 0; j < arraySize; ++j) {
      if (up) {
        data1[j] = data0[j] + 1;
      } else {
        data0[j] = data1[j] + 1;
      }
    }
    env->ReleasePrimitiveArrayCritical(array1, data1, 0);
    env->ReleasePrimitiveArrayCritical(array0, data0, 0);
  }
}

class JniCallDefaultMethodsTest {
 public:
  explicit JniCallDefaultMethodsTest(JNIEnv* env)
      : env_(env), concrete_class_(env_->FindClass("ConcreteClass")) {
    CHECK(!env_->ExceptionCheck());
    CHECK(concrete_class_ != nullptr);
  }

  void Test() {
    TestCalls("ConcreteClass", { "JniCallNonOverridenDefaultMethod",
                                 "JniCallOverridenDefaultMethod",
                                 "JniCallOverridenDefaultMethodWithSuper",
                                 "JniCallOverridenAbstractMethod",
                                 "JniCallConflictDefaultMethod",
                                 "JniCallSoftConflictMethod" });
    TestCalls("DefaultInterface", { "JniCallNonOverridenDefaultMethod",
                                    "JniCallOverridenDefaultMethod",
                                    "JniCallOverridenAbstractMethod",
                                    "JniCallConflictDefaultMethod",
                                    "JniCallSoftConflictMethod" });
    TestCalls("AbstractInterface", { "JniCallSoftConflictMethod" });
    TestCalls("ConflictInterface", { "JniCallConflictDefaultMethod" });
  }

 private:
  void TestCalls(const char* declaring_class, std::vector<const char*> methods) {
    jmethodID new_method = env_->GetMethodID(concrete_class_, "<init>", "()V");
    jobject obj = env_->NewObject(concrete_class_, new_method);
    CHECK(!env_->ExceptionCheck());
    CHECK(obj != nullptr);
    jclass decl_class = env_->FindClass(declaring_class);
    CHECK(!env_->ExceptionCheck());
    CHECK(decl_class != nullptr);
    for (const char* method : methods) {
      jmethodID method_id = env_->GetMethodID(decl_class, method, "()V");
      CHECK(!env_->ExceptionCheck());
      printf("Calling method %s->%s on object of type ConcreteClass\n", declaring_class, method);
      env_->CallVoidMethod(obj, method_id);
      if (env_->ExceptionCheck()) {
        jthrowable thrown = env_->ExceptionOccurred();
        env_->ExceptionClear();
        jmethodID to_string = env_->GetMethodID(
            env_->FindClass("java/lang/Object"), "toString", "()Ljava/lang/String;");
        jstring exception_string = (jstring) env_->CallObjectMethod(thrown, to_string);
        CHECK(!env_->ExceptionCheck());
        const char* exception_string_utf8 = env_->GetStringUTFChars(exception_string, nullptr);
        CHECK(!env_->ExceptionCheck());
        CHECK(exception_string_utf8 != nullptr);
        printf("EXCEPTION OCCURED: %s\n", exception_string_utf8);
        env_->ReleaseStringUTFChars(exception_string, exception_string_utf8);
      }
    }
  }

  JNIEnv* env_;
  jclass concrete_class_;
};

extern "C" JNIEXPORT void JNICALL Java_Main_testCallDefaultMethods(JNIEnv* env) {
  JniCallDefaultMethodsTest(env).Test();
}

static void InvokeSpecificMethod(JNIEnv* env, jobject obj, const char* method) {
  jclass lambda_class = env->FindClass("LambdaInterface");
  CHECK(!env->ExceptionCheck());
  CHECK(lambda_class != nullptr);
  jmethodID method_id = env->GetMethodID(lambda_class, method, "()V");
  CHECK(!env->ExceptionCheck());
  env->CallVoidMethod(obj, method_id);
  CHECK(!env->ExceptionCheck());
}

extern "C" JNIEXPORT void JNICALL Java_Main_testInvokeLambdaDefaultMethod(
    JNIEnv* e, jclass, jobject l) {
  InvokeSpecificMethod(e, l, "sayHiTwice");
}

extern "C" JNIEXPORT void JNICALL Java_Main_testInvokeLambdaMethod(JNIEnv* e, jclass, jobject l) {
  InvokeSpecificMethod(e, l, "sayHi");
}

// Register on-demand because many tests share this JNI library and
// we can't unconditionally register them.
extern "C" JNIEXPORT jboolean JNICALL Java_Main_registerNativesJniTest(JNIEnv* e, jclass kls) {
  const size_t numMethods = sizeof(sMainMethods)/sizeof(JNINativeMethod);

  if (e->RegisterNatives(kls, sMainMethods, numMethods) < 0) {
      std::cerr << "RegisterNatives failed for 'Main'" << std::endl;
      return JNI_FALSE;
  }

  return JNI_TRUE;
}

// Annotated with @FastNative in Java code. Doesn't need to be explicitly registered with "!".
// NOTE: Has to be registered explicitly to avoid mutator lock check failures.
static jint Java_Main_intFastNativeMethod(JNIEnv*, jclass, jint a, jint b, jint c) {
  return a + b + c;
}

// Annotated with @CriticalNative in Java code. Doesn't need to be explicitly registered with "!".
// NOTE: Has to be registered explicitly to avoid mutator lock check failures.
static jint Java_Main_intCriticalNativeMethod(jint a, jint b, jint c) {
  // Note that unlike a "Fast Native" method this excludes JNIEnv and the jclass parameters.
  return a + b + c;
}

}  // namespace art

