Fix JNI return type checking on portable path.

Change-Id: I83c259d0b27c06c8f258c71e1536d4bfa50bb0cc
diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc
index b481b57..2236525 100644
--- a/src/compiler_llvm/runtime_support_llvm.cc
+++ b/src/compiler_llvm/runtime_support_llvm.cc
@@ -497,11 +497,34 @@
   return 0;
 }
 
-Object* art_decode_jobject_in_thread(Thread* thread, jobject obj) {
-  if (thread->IsExceptionPending()) {
+Object* art_decode_jobject_in_thread(Thread* self, jobject java_object) {
+  if (self->IsExceptionPending()) {
     return NULL;
   }
-  return thread->DecodeJObject(obj);
+  Object* o = self->DecodeJObject(java_object);
+  if (o == NULL || !self->GetJniEnv()->check_jni) {
+    return o;
+  }
+
+  if (o == kInvalidIndirectRefObject) {
+    LOG(ERROR) << "JNI ERROR (app bug): invalid reference returned from "
+               << PrettyMethod(self->GetCurrentMethod());
+    JniAbort(NULL);
+  }
+
+  // Make sure that the result is an instance of the type this
+  // method was expected to return.
+  Method* m = self->GetCurrentMethod();
+  MethodHelper mh(m);
+  Class* return_type = mh.GetReturnType();
+
+  if (!o->InstanceOf(return_type)) {
+    LOG(ERROR) << "JNI ERROR (app bug): attempt to return an instance of " << PrettyTypeOf(o)
+               << " from " << PrettyMethod(m);
+    JniAbort(NULL);
+  }
+
+  return o;
 }
 
 void art_fill_array_data_from_code(Method* method, uint32_t dex_pc,
diff --git a/src/jni_compiler_test.cc b/src/jni_compiler_test.cc
index 59582f3..61e1867 100644
--- a/src/jni_compiler_test.cc
+++ b/src/jni_compiler_test.cc
@@ -673,7 +673,6 @@
   SetUpForTest(class_loader.get(), false, "instanceMethodThatShouldReturnClass", "()Ljava/lang/Class;",
                reinterpret_cast<void*>(&Java_MyClassNatives_instanceMethodThatShouldReturnClass));
 
-#if !defined(ART_USE_LLVM_COMPILER)
   {
     CheckJniAbortCatcher check_jni_abort_catcher;
     // TODO: check type of returns with portable JNI compiler.
@@ -681,7 +680,6 @@
     env_->CallObjectMethod(jobj_, jmethod_);
     check_jni_abort_catcher.Check("java.lang.Class MyClassNatives.instanceMethodThatShouldReturnClass");
   }
-#endif
 
   CheckJniAbortCatcher check_jni_abort_catcher;
   // Here, we just call the method wrong; we should catch that too.
@@ -694,7 +692,6 @@
   SetUpForTest(class_loader.get(), true, "staticMethodThatShouldReturnClass", "()Ljava/lang/Class;",
                reinterpret_cast<void*>(&Java_MyClassNatives_staticMethodThatShouldReturnClass));
 
-#if !defined(ART_USE_LLVM_COMPILER)
   {
     CheckJniAbortCatcher check_jni_abort_catcher;
     // TODO: check type of returns with portable JNI compiler.
@@ -702,7 +699,6 @@
     env_->CallStaticObjectMethod(jklass_, jmethod_);
     check_jni_abort_catcher.Check("java.lang.Class MyClassNatives.staticMethodThatShouldReturnClass");
   }
-#endif
 
   CheckJniAbortCatcher check_jni_abort_catcher;
   // Here, we just call the method wrong; we should catch that too.