/*
 * 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 <pthread.h>

#include <cstdio>
#include <iostream>
#include <vector>

#include <android-base/logging.h>

#include "art_method-inl.h"
#include "base/runtime_debug.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);

  using Fn = void(*)(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());
}

extern "C" JNIEXPORT void JNICALL Java_Main_testUTFRegion(JNIEnv* env, jclass, jstring null_str) {
  jstring foo_str = env->NewStringUTF("FOOBAR");
  jstring emoji_str = env->NewStringUTF("SKI ⛷ SKI");
  char buf[1024];
  memset(buf, 'Y', sizeof(buf));
  buf[1023] = '\0';

  env->GetStringUTFRegion(foo_str, 3, 1, buf);
  buf[1023] = '\0';
  CHECK_EQ(strcmp("B", buf), 0) << buf;

  // Null char on 0 len region
  env->GetStringUTFRegion(foo_str, 3, 0, buf);
  buf[1023] = '\0';
  CHECK_EQ(strcmp("", buf), 0) << buf;

  // No SEGV
  env->GetStringUTFRegion(foo_str, 3, 0, nullptr);

  env->GetStringUTFRegion(null_str, 1, 1, buf);
  buf[1023] = '\0';
  std::array<uint8_t, 3> nullbuf{ 0xc0, 0x80, 0x00 };
  CHECK_EQ(memcmp(nullbuf.data(), buf, 3), 0);

  env->GetStringUTFRegion(emoji_str, 1, 6, buf);
  buf[1023] = '\0';
  CHECK_EQ(strcmp("KI ⛷ S", buf), 0);
}

extern "C" JNIEXPORT jint JNICALL Java_Main_getFieldSubclass(JNIEnv* env,
                                                             jclass,
                                                             jobject f_obj,
                                                             jclass sub) {
  jfieldID f = env->FromReflectedField(f_obj);
  return env->GetStaticIntField(sub, f);
}

// 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, const 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;
}

extern "C" JNIEXPORT jobject JNICALL Java_Main_lookupClinit(JNIEnv* env, jclass, jclass kls) {
  jmethodID clinit_id = env->GetStaticMethodID(kls, "<clinit>", "()V");

  if (clinit_id != nullptr) {
    jobject obj = env->ToReflectedMethod(kls, clinit_id, /*isStatic*/ true);
    CHECK(obj != nullptr);
    return obj;
  } else {
    return nullptr;
  }
}

extern "C" JNIEXPORT jboolean JNICALL Java_Main_isSlowDebug(JNIEnv*, jclass) {
  // Return whether slow-debug is on. Only relevant for debug builds.
  if (kIsDebugBuild) {
    // Register a fake flag and get the default value it should be initialized with.
    static bool fake_flag = false;
    fake_flag = RegisterRuntimeDebugFlag(&fake_flag);

    return fake_flag ? JNI_TRUE : JNI_FALSE;
  }
  // To pass the Java-side test, just so "on" for release builds.
  return JNI_TRUE;
}

}  // namespace art

