// Copyright 2011 Google Inc. All Rights Reserved.
// Author: irogers@google.com (Ian Rogers)

#include <sys/mman.h>

#include "assembler.h"
#include "class_linker.h"
#include "common_test.h"
#include "dex_file.h"
#include "jni_compiler.h"
#include "runtime.h"
#include "thread.h"
#include "gtest/gtest.h"

namespace art {

class JniCompilerTest : public RuntimeTest {
 protected:
  virtual void SetUp() {
    RuntimeTest::SetUp();
    // Create thunk code that performs the native to managed transition
    thunk_code_size_ = kPageSize;
    thunk_ = mmap(NULL, thunk_code_size_, PROT_READ | PROT_WRITE | PROT_EXEC,
                  MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
    CHECK_NE(MAP_FAILED, thunk_);
    Assembler thk_asm;
    // TODO: shouldn't have machine specific code in a general purpose file
#if defined(__i386__)
    thk_asm.pushl(EDI);                   // preserve EDI
    thk_asm.movl(EAX, Address(ESP, 8));   // EAX = method->GetCode()
    thk_asm.movl(EDI, Address(ESP, 12));  // EDI = method
    thk_asm.pushl(Immediate(0));          // push pad
    thk_asm.pushl(Immediate(0));          // push pad
    thk_asm.pushl(Address(ESP, 44));      // push pad  or jlong high
    thk_asm.pushl(Address(ESP, 44));      // push jint or jlong low
    thk_asm.pushl(Address(ESP, 44));      // push jint or jlong high
    thk_asm.pushl(Address(ESP, 44));      // push jint or jlong low
    thk_asm.pushl(Address(ESP, 44));      // push jobject
    thk_asm.call(EAX);                    // Continue in method->GetCode()
    thk_asm.addl(ESP, Immediate(28));     // pop arguments
    thk_asm.popl(EDI);                    // restore EDI
    thk_asm.ret();
#elif defined(__arm__)
    thk_asm.AddConstant(SP, -32);         // Build frame
    thk_asm.StoreToOffset(kStoreWord, LR, SP, 28);  // Spill link register
    thk_asm.StoreToOffset(kStoreWord, R9, SP, 24);  // Spill R9
    thk_asm.mov(R12, ShifterOperand(R0));  // R12 = method->GetCode()
    thk_asm.mov(R0,  ShifterOperand(R1));  // R0  = method
    thk_asm.mov(R9,  ShifterOperand(R2));  // R9  = Thread::Current()
    thk_asm.mov(R1,  ShifterOperand(R3));  // R1  = arg1 (jint/jlong low)
    thk_asm.LoadFromOffset(kLoadWord, R3, SP, 44);  // R3 = arg5 (pad/jlong high)
    thk_asm.StoreToOffset(kStoreWord, R3, SP, 4);
    thk_asm.LoadFromOffset(kLoadWord, R3, SP, 40);  // R3 = arg4 (jint/jlong low)
    thk_asm.StoreToOffset(kStoreWord, R3, SP, 0);
    thk_asm.LoadFromOffset(kLoadWord, R3, SP, 36);  // R3 = arg3 (jint/jlong high)
    thk_asm.LoadFromOffset(kLoadWord, R2, SP, 32);  // R2 = arg2 (jint/jlong high)
    thk_asm.blx(R12);                     // Branch and link R12
    thk_asm.LoadFromOffset(kLoadWord, LR, SP, 28);  // Fill link register
    thk_asm.LoadFromOffset(kLoadWord, R9, SP, 24);  // Fill R9
    thk_asm.AddConstant(SP, 32);          // Remove frame
    thk_asm.mov(PC, ShifterOperand(LR));  // Return
#else
#error Unimplemented
#endif
    size_t cs = thk_asm.CodeSize();
    MemoryRegion code(thunk_, cs);
    thk_asm.FinalizeInstructions(code);
    thunk_entry1_ = reinterpret_cast<jint (*)(const void*, art::Method*,
                                              Thread*, jobject, jint, jint,
                                              jint)
                                    >(code.pointer());
    thunk_entry2_ = reinterpret_cast<jdouble (*)(const void*, art::Method*,
                                                 Thread*, jobject, jdouble,
                                                 jdouble)
                                    >(code.pointer());
  }

  virtual void TearDown() {
    // Release thunk code
    CHECK(runtime_->DetachCurrentThread());
    CHECK_EQ(0, munmap(thunk_, thunk_code_size_));
  }

  // Run generated code associated with method passing and returning int size
  // arguments
  jvalue RunMethod(Method* method, jvalue a, jvalue b, jvalue c, jvalue d) {
    jvalue result;
    // sanity checks
    EXPECT_NE(static_cast<void*>(NULL), method->GetCode());
    EXPECT_EQ(0u, Thread::Current()->NumShbHandles());
    EXPECT_EQ(Thread::kRunnable, Thread::Current()->GetState());
    // perform call
    result.i = (*thunk_entry1_)(method->GetCode(), method, Thread::Current(),
                                a.l, b.i, c.i, d.i);
    // sanity check post-call
    EXPECT_EQ(0u, Thread::Current()->NumShbHandles());
    EXPECT_EQ(Thread::kRunnable, Thread::Current()->GetState());
    return result;
  }

  // Run generated code associated with method passing and returning double size
  // arguments
  jvalue RunMethodD(Method* method, jvalue a, jvalue b, jvalue c) {
    jvalue result;
    // sanity checks
    EXPECT_NE(static_cast<void*>(NULL), method->GetCode());
    EXPECT_EQ(0u, Thread::Current()->NumShbHandles());
    EXPECT_EQ(Thread::kRunnable, Thread::Current()->GetState());
    // perform call
    result.d = (*thunk_entry2_)(method->GetCode(), method, Thread::Current(),
                                a.l, b.d, c.d);
    // sanity check post-call
    EXPECT_EQ(0u, Thread::Current()->NumShbHandles());
    EXPECT_EQ(Thread::kRunnable, Thread::Current()->GetState());
    return result;
  }

  void* thunk_;
  size_t thunk_code_size_;
  jint (*thunk_entry1_)(const void*, Method*, Thread*, jobject, jint, jint,
                        jint);
  jdouble (*thunk_entry2_)(const void*, Method*, Thread*, jobject, jdouble,
                           jdouble);
};

int gJava_MyClass_foo_calls = 0;
void Java_MyClass_foo(JNIEnv*, jobject) {
  EXPECT_EQ(1u, Thread::Current()->NumShbHandles());
  EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
  gJava_MyClass_foo_calls++;
}

int gJava_MyClass_fooI_calls = 0;
jint Java_MyClass_fooI(JNIEnv*, jobject, jint x) {
  EXPECT_EQ(1u, Thread::Current()->NumShbHandles());
  EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
  gJava_MyClass_fooI_calls++;
  return x;
}

int gJava_MyClass_fooII_calls = 0;
jint Java_MyClass_fooII(JNIEnv*, jobject, jint x, jint y) {
  EXPECT_EQ(1u, Thread::Current()->NumShbHandles());
  EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
  gJava_MyClass_fooII_calls++;
  return x - y;  // non-commutative operator
}

int gJava_MyClass_fooDD_calls = 0;
jdouble Java_MyClass_fooDD(JNIEnv*, jobject, jdouble x, jdouble y) {
  EXPECT_EQ(1u, Thread::Current()->NumShbHandles());
  EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
  gJava_MyClass_fooDD_calls++;
  return x - y;  // non-commutative operator
}

int gJava_MyClass_fooIOO_calls = 0;
jobject Java_MyClass_fooIOO(JNIEnv*, jobject thisObject, jint x, jobject y,
                            jobject z) {
  EXPECT_EQ(3u, Thread::Current()->NumShbHandles());
  EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
  gJava_MyClass_fooIOO_calls++;
  switch (x) {
    case 1:
      return y;
    case 2:
      return z;
    default:
      return thisObject;
  }
}

int gJava_MyClass_fooSIOO_calls = 0;
jobject Java_MyClass_fooSIOO(JNIEnv*, jclass klass, jint x, jobject y,
                             jobject z) {
  EXPECT_EQ(3u, Thread::Current()->NumShbHandles());
  EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
  gJava_MyClass_fooSIOO_calls++;
  switch (x) {
    case 1:
      return y;
    case 2:
      return z;
    default:
      return klass;
  }
}

int gJava_MyClass_fooSSIOO_calls = 0;
jobject Java_MyClass_fooSSIOO(JNIEnv*, jclass klass, jint x, jobject y,
                             jobject z) {
  EXPECT_EQ(3u, Thread::Current()->NumShbHandles());
  EXPECT_EQ(Thread::kNative, Thread::Current()->GetState());
  gJava_MyClass_fooSSIOO_calls++;
  switch (x) {
    case 1:
      return y;
    case 2:
      return z;
    default:
      return klass;
  }
}

TEST_F(JniCompilerTest, CompileAndRunNoArgMethod) {
  scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex));
  PathClassLoader* class_loader = AllocPathClassLoader(dex.get());

  Class* klass = class_linker_->FindClass("LMyClass;", class_loader);
  ASSERT_TRUE(klass != NULL);

  Method* method = klass->FindVirtualMethod("foo", "()V");
  ASSERT_TRUE(method != NULL);

  Assembler jni_asm;
  JniCompiler jni_compiler;
  jni_compiler.Compile(&jni_asm, method);

  // TODO: should really use JNIEnv to RegisterNative, but missing a
  // complete story on this, so hack the RegisterNative below
  // JNIEnv* env = Thread::Current()->GetJniEnv();
  // JNINativeMethod methods[] = {{"foo", "()V", (void*)&Java_MyClass_foo}};
  method->RegisterNative(reinterpret_cast<void*>(&Java_MyClass_foo));

  jvalue a;
  a.l = (jobject)NULL;
  gJava_MyClass_foo_calls = 0;
  RunMethod(method, a, a, a, a);
  EXPECT_EQ(1, gJava_MyClass_foo_calls);
  RunMethod(method, a, a, a, a);
  EXPECT_EQ(2, gJava_MyClass_foo_calls);
}

TEST_F(JniCompilerTest, CompileAndRunIntMethod) {
  scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex));
  PathClassLoader* class_loader = AllocPathClassLoader(dex.get());

  Class* klass = class_linker_->FindClass("LMyClass;", class_loader);
  ASSERT_TRUE(klass != NULL);

  Method* method = klass->FindVirtualMethod("fooI", "(I)I");
  ASSERT_TRUE(method != NULL);

  Assembler jni_asm;
  JniCompiler jni_compiler;
  jni_compiler.Compile(&jni_asm, method);

  // TODO: should really use JNIEnv to RegisterNative, but missing a
  // complete story on this, so hack the RegisterNative below
  method->RegisterNative(reinterpret_cast<void*>(&Java_MyClass_fooI));

  jvalue a, b, c;
  a.l = (jobject)NULL;
  b.i = 42;
  EXPECT_EQ(0, gJava_MyClass_fooI_calls);
  c = RunMethod(method, a, b, a, a);
  ASSERT_EQ(42, c.i);
  EXPECT_EQ(1, gJava_MyClass_fooI_calls);
  b.i = 0xCAFED00D;
  c = RunMethod(method, a, b, a, a);
  ASSERT_EQ((jint)0xCAFED00D, c.i);
  EXPECT_EQ(2, gJava_MyClass_fooI_calls);
}

TEST_F(JniCompilerTest, CompileAndRunIntIntMethod) {
  scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex));
  PathClassLoader* class_loader = AllocPathClassLoader(dex.get());

  Class* klass = class_linker_->FindClass("LMyClass;", class_loader);
  ASSERT_TRUE(klass != NULL);

  Method* method = klass->FindVirtualMethod("fooII", "(II)I");
  ASSERT_TRUE(method != NULL);

  Assembler jni_asm;
  JniCompiler jni_compiler;
  jni_compiler.Compile(&jni_asm, method);

  // TODO: should really use JNIEnv to RegisterNative, but missing a
  // complete story on this, so hack the RegisterNative below
  method->RegisterNative(reinterpret_cast<void*>(&Java_MyClass_fooII));

  jvalue a, b, c, d;
  a.l = (jobject)NULL;
  b.i = 99;
  c.i = 10;
  EXPECT_EQ(0, gJava_MyClass_fooII_calls);
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ(99 - 10, d.i);
  EXPECT_EQ(1, gJava_MyClass_fooII_calls);
  b.i = 0xCAFEBABE;
  c.i = 0xCAFED00D;
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ((jint)(0xCAFEBABE - 0xCAFED00D), d.i);
  EXPECT_EQ(2, gJava_MyClass_fooII_calls);
}


TEST_F(JniCompilerTest, CompileAndRunDoubleDoubleMethod) {
  scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex));
  PathClassLoader* class_loader = AllocPathClassLoader(dex.get());

  Class* klass = class_linker_->FindClass("LMyClass;", class_loader);
  ASSERT_TRUE(klass != NULL);

  Method* method = klass->FindVirtualMethod("fooDD", "(DD)D");
  ASSERT_TRUE(method != NULL);

  Assembler jni_asm;
  JniCompiler jni_compiler;
  jni_compiler.Compile(&jni_asm, method);

  // TODO: should really use JNIEnv to RegisterNative, but missing a
  // complete story on this, so hack the RegisterNative below
  method->RegisterNative(reinterpret_cast<void*>(&Java_MyClass_fooDD));

  jvalue a, b, c, d;
  a.l = (jobject)NULL;
  b.d = 99;
  c.d = 10;
  EXPECT_EQ(0, gJava_MyClass_fooDD_calls);
  d = RunMethodD(method, a, b, c);
  ASSERT_EQ(b.d - c.d, d.d);
  EXPECT_EQ(1, gJava_MyClass_fooDD_calls);
  b.d = 3.14159265358979323846;
  c.d = 0.69314718055994530942;
  d = RunMethodD(method, a, b, c);
  ASSERT_EQ(b.d - c.d, d.d);
  EXPECT_EQ(2, gJava_MyClass_fooDD_calls);
}

TEST_F(JniCompilerTest, CompileAndRunIntObjectObjectMethod) {
  scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex));
  PathClassLoader* class_loader = AllocPathClassLoader(dex.get());

  Class* klass = class_linker_->FindClass("LMyClass;", class_loader);
  ASSERT_TRUE(klass != NULL);

  Method* method = klass->FindVirtualMethod(
      "fooIOO",
      "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
  ASSERT_TRUE(method != NULL);

  Assembler jni_asm;
  JniCompiler jni_compiler;
  jni_compiler.Compile(&jni_asm, method);

  // TODO: should really use JNIEnv to RegisterNative, but missing a
  // complete story on this, so hack the RegisterNative below
  method->RegisterNative(reinterpret_cast<void*>(&Java_MyClass_fooIOO));

  jvalue a, b, c, d, e;
  a.l = (jobject)NULL;
  b.i = 0;
  c.l = (jobject)NULL;
  d.l = (jobject)NULL;
  EXPECT_EQ(0, gJava_MyClass_fooIOO_calls);
  e = RunMethod(method, a, b, c, d);
  ASSERT_EQ((jobject)NULL, e.l);
  EXPECT_EQ(1, gJava_MyClass_fooIOO_calls);
  a.l = (jobject)8;
  b.i = 0;
  c.l = (jobject)NULL;
  d.l = (jobject)16;
  e = RunMethod(method, a, b, c, d);
  ASSERT_EQ((jobject)8, e.l);
  EXPECT_EQ(2, gJava_MyClass_fooIOO_calls);
  b.i = 1;
  e = RunMethod(method, a, b, c, d);
  ASSERT_EQ((jobject)NULL, e.l);
  EXPECT_EQ(3, gJava_MyClass_fooIOO_calls);
  b.i = 2;
  e = RunMethod(method, a, b, c, d);
  ASSERT_EQ((jobject)16, e.l);
  EXPECT_EQ(4, gJava_MyClass_fooIOO_calls);
  a.l = (jobject)8;
  b.i = 0;
  c.l = (jobject)16;
  d.l = (jobject)NULL;
  e = RunMethod(method, a, b, c, d);
  ASSERT_EQ((jobject)8, e.l);
  EXPECT_EQ(5, gJava_MyClass_fooIOO_calls);
  b.i = 1;
  e = RunMethod(method, a, b, c, d);
  ASSERT_EQ((jobject)16, e.l);
  EXPECT_EQ(6, gJava_MyClass_fooIOO_calls);
  b.i = 2;
  e = RunMethod(method, a, b, c, d);
  ASSERT_EQ((jobject)NULL, e.l);
  EXPECT_EQ(7, gJava_MyClass_fooIOO_calls);
}

TEST_F(JniCompilerTest, CompileAndRunStaticIntObjectObjectMethod) {
  scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex));
  PathClassLoader* class_loader = AllocPathClassLoader(dex.get());

  Class* klass = class_linker_->FindClass("LMyClass;", class_loader);
  ASSERT_TRUE(klass != NULL);

  Method* method = klass->FindDirectMethod(
      "fooSIOO",
      "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
  ASSERT_TRUE(method != NULL);

  Assembler jni_asm;
  JniCompiler jni_compiler;
  jni_compiler.Compile(&jni_asm, method);

  // TODO: should really use JNIEnv to RegisterNative, but missing a
  // complete story on this, so hack the RegisterNative below
  method->RegisterNative(reinterpret_cast<void*>(&Java_MyClass_fooSIOO));

  jvalue a, b, c, d;
  a.i = 0;
  b.l = (jobject)NULL;
  c.l = (jobject)NULL;
  EXPECT_EQ(0, gJava_MyClass_fooSIOO_calls);
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ((jobject)method->GetClass(), d.l);
  EXPECT_EQ(1, gJava_MyClass_fooSIOO_calls);
  a.i = 0;
  b.l = (jobject)NULL;
  c.l = (jobject)16;
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ((jobject)method->GetClass(), d.l);
  EXPECT_EQ(2, gJava_MyClass_fooSIOO_calls);
  a.i = 1;
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ((jobject)NULL, d.l);
  EXPECT_EQ(3, gJava_MyClass_fooSIOO_calls);
  a.i = 2;
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ((jobject)16, d.l);
  EXPECT_EQ(4, gJava_MyClass_fooSIOO_calls);
  a.i = 0;
  b.l = (jobject)16;
  c.l = (jobject)NULL;
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ((jobject)method->GetClass(), d.l);
  EXPECT_EQ(5, gJava_MyClass_fooSIOO_calls);
  a.i = 1;
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ((jobject)16, d.l);
  EXPECT_EQ(6, gJava_MyClass_fooSIOO_calls);
  a.i = 2;
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ((jobject)NULL, d.l);
  EXPECT_EQ(7, gJava_MyClass_fooSIOO_calls);
}

TEST_F(JniCompilerTest, CompileAndRunStaticSynchronizedIntObjectObjectMethod) {
  scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex));
  PathClassLoader* class_loader = AllocPathClassLoader(dex.get());

  Class* klass = class_linker_->FindClass("LMyClass;", class_loader);
  ASSERT_TRUE(klass != NULL);

  Method* method = klass->FindDirectMethod(
      "fooSSIOO",
      "(ILjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
  ASSERT_TRUE(method != NULL);

  Assembler jni_asm;
  JniCompiler jni_compiler;
  jni_compiler.Compile(&jni_asm, method);

  // TODO: should really use JNIEnv to RegisterNative, but missing a
  // complete story on this, so hack the RegisterNative below
  method->RegisterNative(reinterpret_cast<void*>(&Java_MyClass_fooSSIOO));

  jvalue a, b, c, d;
  a.i = 0;
  b.l = (jobject)NULL;
  c.l = (jobject)NULL;
  EXPECT_EQ(0, gJava_MyClass_fooSSIOO_calls);
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ((jobject)method->GetClass(), d.l);
  EXPECT_EQ(1, gJava_MyClass_fooSSIOO_calls);
  a.i = 0;
  b.l = (jobject)NULL;
  c.l = (jobject)16;
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ((jobject)method->GetClass(), d.l);
  EXPECT_EQ(2, gJava_MyClass_fooSSIOO_calls);
  a.i = 1;
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ((jobject)NULL, d.l);
  EXPECT_EQ(3, gJava_MyClass_fooSSIOO_calls);
  a.i = 2;
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ((jobject)16, d.l);
  EXPECT_EQ(4, gJava_MyClass_fooSSIOO_calls);
  a.i = 0;
  b.l = (jobject)16;
  c.l = (jobject)NULL;
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ((jobject)method->GetClass(), d.l);
  EXPECT_EQ(5, gJava_MyClass_fooSSIOO_calls);
  a.i = 1;
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ((jobject)16, d.l);
  EXPECT_EQ(6, gJava_MyClass_fooSSIOO_calls);
  a.i = 2;
  d = RunMethod(method, a, b, c, a);
  ASSERT_EQ((jobject)NULL, d.l);
  EXPECT_EQ(7, gJava_MyClass_fooSSIOO_calls);
}

int gSuspendCounterHandler_calls;
void SuspendCountHandler(Method** frame) {
  EXPECT_PRED2(String::EqualsUtf8, (*frame)->GetName(), "fooI");
  gSuspendCounterHandler_calls++;
  Thread::Current()->DecrementSuspendCount();
}
TEST_F(JniCompilerTest, SuspendCountAcknolewdgement) {
  scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex));
  PathClassLoader* class_loader = AllocPathClassLoader(dex.get());

  Class* klass = class_linker_->FindClass("LMyClass;", class_loader);
  ASSERT_TRUE(klass != NULL);

  Method* method = klass->FindVirtualMethod("fooI", "(I)I");
  ASSERT_TRUE(method != NULL);

  Assembler jni_asm;
  JniCompiler jni_compiler;
  jni_compiler.Compile(&jni_asm, method);

  // TODO: should really use JNIEnv to RegisterNative, but missing a
  // complete story on this, so hack the RegisterNative below
  method->RegisterNative(reinterpret_cast<void*>(&Java_MyClass_fooI));
  Thread::Current()->RegisterSuspendCountEntryPoint(&SuspendCountHandler);

  gSuspendCounterHandler_calls = 0;
  gJava_MyClass_fooI_calls = 0;
  jvalue a, b, c;
  a.l = (jobject)NULL;
  b.i = 42;
  c = RunMethod(method, a, b, a, a);
  ASSERT_EQ(42, c.i);
  EXPECT_EQ(1, gJava_MyClass_fooI_calls);
  EXPECT_EQ(0, gSuspendCounterHandler_calls);
  Thread::Current()->IncrementSuspendCount();
  c = RunMethod(method, a, b, a, a);
  ASSERT_EQ(42, c.i);
  EXPECT_EQ(2, gJava_MyClass_fooI_calls);
  EXPECT_EQ(1, gSuspendCounterHandler_calls);
  c = RunMethod(method, a, b, a, a);
  ASSERT_EQ(42, c.i);
  EXPECT_EQ(3, gJava_MyClass_fooI_calls);
  EXPECT_EQ(1, gSuspendCounterHandler_calls);
}

int gExceptionHandler_calls;
void ExceptionHandler(Method** frame) {
  EXPECT_PRED2(String::EqualsUtf8, (*frame)->GetName(), "foo");
  gExceptionHandler_calls++;
  Thread::Current()->ClearException();
}
TEST_F(JniCompilerTest, ExceptionHandling) {
  scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassNativesDex));
  PathClassLoader* class_loader = AllocPathClassLoader(dex.get());

  Class* klass = class_linker_->FindClass("LMyClass;", class_loader);
  ASSERT_TRUE(klass != NULL);

  Method* method = klass->FindVirtualMethod("foo", "()V");
  ASSERT_TRUE(method != NULL);

  Assembler jni_asm;
  JniCompiler jni_compiler;
  jni_compiler.Compile(&jni_asm, method);

  // TODO: should really use JNIEnv to RegisterNative, but missing a
  // complete story on this, so hack the RegisterNative below
  method->RegisterNative(reinterpret_cast<void*>(&Java_MyClass_foo));
  Thread::Current()->RegisterExceptionEntryPoint(&ExceptionHandler);

  gExceptionHandler_calls = 0;
  gJava_MyClass_foo_calls = 0;
  jvalue a;
  a.l = (jobject)NULL;
  RunMethod(method, a, a, a, a);
  EXPECT_EQ(1, gJava_MyClass_foo_calls);
  EXPECT_EQ(0, gExceptionHandler_calls);
  // TODO: create a real exception here
  Thread::Current()->SetException(reinterpret_cast<Object*>(8));
  RunMethod(method, a, a, a, a);
  EXPECT_EQ(2, gJava_MyClass_foo_calls);
  EXPECT_EQ(1, gExceptionHandler_calls);
  RunMethod(method, a, a, a, a);
  EXPECT_EQ(3, gJava_MyClass_foo_calls);
  EXPECT_EQ(1, gExceptionHandler_calls);
}

}  // namespace art
