diff options
Diffstat (limited to 'runtime/interpreter/interpreter_goto_table_impl.cc')
-rw-r--r-- | runtime/interpreter/interpreter_goto_table_impl.cc | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/runtime/interpreter/interpreter_goto_table_impl.cc b/runtime/interpreter/interpreter_goto_table_impl.cc index d70b80eb93..018add3007 100644 --- a/runtime/interpreter/interpreter_goto_table_impl.cc +++ b/runtime/interpreter/interpreter_goto_table_impl.cc @@ -74,6 +74,7 @@ namespace interpreter { template<bool do_access_check> JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame, JValue result_register) { + bool do_assignability_check = do_access_check; if (UNLIKELY(!shadow_frame.HasReferenceArray())) { LOG(FATAL) << "Invalid shadow frame for interpreter use"; return JValue(); @@ -264,11 +265,28 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* HANDLE_INSTRUCTION_START(RETURN_OBJECT) { JValue result; + Object* obj_result = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data)); result.SetJ(0); - result.SetL(shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data))); + result.SetL(obj_result); if (UNLIKELY(self->TestAllFlags())) { CheckSuspend(self); } + if (do_assignability_check && obj_result != NULL) { + Class* return_type = MethodHelper(shadow_frame.GetMethod()).GetReturnType(); + if (return_type == NULL) { + // Return the pending exception. + HANDLE_PENDING_EXCEPTION(); + } + if (!obj_result->VerifierInstanceOf(return_type)) { + // This should never happen. + self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(), + "Ljava/lang/VirtualMachineError;", + "Returning '%s' that is not instance of return type '%s'", + ClassHelper(obj_result->GetClass()).GetDescriptor(), + ClassHelper(return_type).GetDescriptor()); + HANDLE_PENDING_EXCEPTION(); + } + } if (UNLIKELY(instrumentation->HasMethodExitListeners())) { instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), shadow_frame.GetMethod(), dex_pc, @@ -512,6 +530,12 @@ JValue ExecuteGotoImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data)); if (UNLIKELY(exception == NULL)) { ThrowNullPointerException(NULL, "throw with null exception"); + } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) { + // This should never happen. + self->ThrowNewExceptionF(self->GetCurrentLocationForThrow(), + "Ljava/lang/VirtualMachineError;", + "Throwing '%s' that is not instance of Throwable", + ClassHelper(exception->GetClass()).GetDescriptor()); } else { self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable()); } |