Generating stub code for registering a jni function at runtime.

On ARM and x86. Added a unit test.

Change-Id: I6b1ee09ad18295108f406ce21d73555796ecbba6
diff --git a/src/jni_compiler_test.cc b/src/jni_compiler_test.cc
index 343ea1d..216350b 100644
--- a/src/jni_compiler_test.cc
+++ b/src/jni_compiler_test.cc
@@ -52,8 +52,10 @@
     }
     ASSERT_TRUE(jmethod_ != NULL);
 
-    JNINativeMethod methods[] = {{method_name, method_sig, native_fnptr}};
-    ASSERT_EQ(JNI_OK, env_->RegisterNatives(jklass_, methods, 1));
+    if (native_fnptr) {
+      JNINativeMethod methods[] = {{method_name, method_sig, native_fnptr}};
+      ASSERT_EQ(JNI_OK, env_->RegisterNatives(jklass_, methods, 1));
+    }
 
     jmethodID constructor = env_->GetMethodID(jklass_, "<init>", "()V");
     jobj_ = env_->NewObject(jklass_, constructor);
@@ -92,6 +94,22 @@
   EXPECT_EQ(2, gJava_MyClass_foo_calls);
 }
 
+TEST_F(JniCompilerTest, CompileAndRunIntMethodThroughStub) {
+  SetupForTest(false,
+               "bar",
+               "(I)I",
+               NULL /* dlsym will find &Java_MyClass_bar later */);
+
+  std::string path("libarttest.so");
+  std::string reason;
+  ASSERT_TRUE(Runtime::Current()->GetJavaVM()->LoadNativeLibrary(
+      path, const_cast<ClassLoader*>(class_loader_), reason))
+      << path << ": " << reason;
+
+  jint result = env_->CallNonvirtualIntMethod(jobj_, jklass_, jmethod_, 24);
+  EXPECT_EQ(25, result);
+}
+
 int gJava_MyClass_fooI_calls = 0;
 jint Java_MyClass_fooI(JNIEnv* env, jobject thisObj, jint x) {
   EXPECT_EQ(1u, Thread::Current()->NumSirtReferences());