Support for currently untested exceptions/errors.
Replace place holder implementations of exception/error code with code
that is likely mostly correct. Testing and creating detail messages are
TODO items for each of these exceptions/errors and warning are created
to reflect this need.
As we don't currently generate code to throw these exceptions, they are
untested.
Change-Id: I75876a9cca37892fa065eccdf34f9868b4142ec9
diff --git a/src/runtime_support.S b/src/runtime_support.S
index 4a50344..1b2c39b 100644
--- a/src/runtime_support.S
+++ b/src/runtime_support.S
@@ -67,6 +67,51 @@
mov r2, sp @ pass SP
b artThrowStackOverflowFromCode @ artThrowStackOverflowFromCode(method, Thread*, SP)
+ .global art_throw_neg_array_size_from_code
+ .extern artThrowNegArraySizeFromCode
+art_throw_neg_array_size_from_code:
+ stmdb sp!, {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
+ sub sp, #16 @ 4 words of space, bottom word will hold Method*
+ mov r1, r9 @ pass Thread::Current
+ mov r2, sp @ pass SP
+ b artThrowNegArraySizeFromCode @ artThrowNegArraySizeFromCode(size, Thread*, SP)
+
+ .global art_throw_internal_error_from_code
+ .extern artThrowInternalErrorFromCode
+art_throw_internal_error_from_code:
+ stmdb sp!, {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
+ sub sp, #16 @ 4 words of space, bottom word will hold Method*
+ mov r1, r9 @ pass Thread::Current
+ mov r2, sp @ pass SP
+ b artThrowInternalErrorFromCode @ artThrowInternalErrorFromCode(errnum, Thread*, SP)
+
+ .global art_throw_no_such_method_from_code
+ .extern artThrowNoSuchMethodFromCode
+art_throw_no_such_method_from_code:
+ stmdb sp!, {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
+ sub sp, #16 @ 4 words of space, bottom word will hold Method*
+ mov r1, r9 @ pass Thread::Current
+ mov r2, sp @ pass SP
+ b artThrowNoSuchMethodFromCode @ artThrowNoSuchMethodFromCode(method_idx, Thread*, SP)
+
+ .global art_throw_runtime_exception_from_code
+ .extern artThrowRuntimeExceptionFromCode
+art_throw_runtime_exception_from_code:
+ stmdb sp!, {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
+ sub sp, #16 @ 4 words of space, bottom word will hold Method*
+ mov r1, r9 @ pass Thread::Current
+ mov r2, sp @ pass SP
+ b artThrowRuntimeExceptionFromCode @ artThrowRuntimeExceptionFromCode(errnum, Thread*, SP)
+
+ .global art_throw_verification_error_from_code
+ .extern artThrowVerificationErrorFromCode
+art_throw_verification_error_from_code:
+ stmdb sp!, {r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
+ sub sp, #16 @ 4 words of space, bottom word will hold Method*
+ mov r2, r9 @ pass Thread::Current
+ mov r3, sp @ pass SP
+ b artThrowVerificationErrorFromCode @ artThrowVerificationErrorFromCode(src1, ref, Thread*, SP)
+
.global art_invoke_interface_trampoline
.extern artFindInterfaceMethodInCacheFromCode
/*
diff --git a/src/runtime_support.h b/src/runtime_support.h
index d9cc364..202142a 100644
--- a/src/runtime_support.h
+++ b/src/runtime_support.h
@@ -19,8 +19,13 @@
extern "C" void art_test_suspend();
extern "C" void art_throw_array_bounds_from_code(int32_t index, int32_t limit);
extern "C" void art_throw_div_zero_from_code();
+ extern "C" void art_throw_internal_error_from_code(int32_t errnum);
+ extern "C" void art_throw_neg_array_size_from_code(int32_t size);
+ extern "C" void art_throw_no_such_method_from_code(int32_t method_idx);
extern "C" void art_throw_null_pointer_exception_from_code();
+ extern "C" void art_throw_runtime_exception_from_code(int32_t errnum);
extern "C" void art_throw_stack_overflow_from_code(void*);
+ extern "C" void art_throw_verification_error_from_code(int32_t src1, int32_t ref);
extern "C" void art_unlock_object_from_code(void*, void*);
/* Conversions */
diff --git a/src/thread.cc b/src/thread.cc
index 004eaae..39be3d5 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -133,38 +133,63 @@
Runtime* runtime = Runtime::Current();
*sp = runtime->GetCalleeSaveMethod();
thread->SetTopOfStack(sp, 0);
- thread->SetStackEndForStackOverflow();
+ thread->SetStackEndForStackOverflow(); // Allow space on the stack for constructor to execute
thread->ThrowNewException("Ljava/lang/StackOverflowError;",
"stack size %zdkb; default stack size: %zdkb",
thread->GetStackSize() / KB, runtime->GetDefaultStackSize() / KB);
- thread->ResetDefaultStackEnd();
+ thread->ResetDefaultStackEnd(); // Return to default stack size
thread->DeliverException();
}
-// TODO: placeholder
-void ThrowVerificationErrorFromCode(int32_t src1, int32_t ref) {
- UNIMPLEMENTED(FATAL) << "Verification error, src1: " << src1 <<
- " ref: " << ref;
+extern "C" void artThrowVerificationErrorFromCode(int32_t src1, int32_t ref, Thread* thread, Method** sp) {
+ // Place a special frame at the TOS that will save all callee saves
+ Runtime* runtime = Runtime::Current();
+ *sp = runtime->GetCalleeSaveMethod();
+ thread->SetTopOfStack(sp, 0);
+ LOG(WARNING) << "TODO: verifcation error detail message. src1=" << src1 << " ref=" << ref;
+ thread->ThrowNewException("Ljava/lang/VerifyError;",
+ "TODO: verifcation error detail message. src1=%d; ref=%d", src1, ref);
+ thread->DeliverException();
}
-// TODO: placeholder
-void ThrowNegArraySizeFromCode(int32_t index) {
- UNIMPLEMENTED(FATAL) << "Negative array size: " << index;
+extern "C" void artThrowInternalErrorFromCode(int32_t errnum, Thread* thread, Method** sp) {
+ // Place a special frame at the TOS that will save all callee saves
+ Runtime* runtime = Runtime::Current();
+ *sp = runtime->GetCalleeSaveMethod();
+ thread->SetTopOfStack(sp, 0);
+ LOG(WARNING) << "TODO: internal error detail message. errnum=" << errnum;
+ thread->ThrowNewException("Ljava/lang/InternalError;", "errnum=%d", errnum);
+ thread->DeliverException();
}
-// TODO: placeholder
-void ThrowInternalErrorFromCode(int32_t errnum) {
- UNIMPLEMENTED(FATAL) << "Internal error: " << errnum;
+extern "C" void artThrowRuntimeExceptionFromCode(int32_t errnum, Thread* thread, Method** sp) {
+ // Place a special frame at the TOS that will save all callee saves
+ Runtime* runtime = Runtime::Current();
+ *sp = runtime->GetCalleeSaveMethod();
+ thread->SetTopOfStack(sp, 0);
+ LOG(WARNING) << "TODO: runtime exception detail message. errnum=" << errnum;
+ thread->ThrowNewException("Ljava/lang/RuntimeException;", "errnum=%d", errnum);
+ thread->DeliverException();
}
-// TODO: placeholder
-void ThrowRuntimeExceptionFromCode(int32_t errnum) {
- UNIMPLEMENTED(FATAL) << "Internal error: " << errnum;
+extern "C" void artThrowNoSuchMethodFromCode(int32_t method_idx, Thread* thread, Method** sp) {
+ // Place a special frame at the TOS that will save all callee saves
+ Runtime* runtime = Runtime::Current();
+ *sp = runtime->GetCalleeSaveMethod();
+ thread->SetTopOfStack(sp, 0);
+ LOG(WARNING) << "TODO: no such method exception detail message. method_idx=" << method_idx;
+ thread->ThrowNewException("Ljava/lang/NoSuchMethodError;", "method_idx=%d", method_idx);
+ thread->DeliverException();
}
-// TODO: placeholder
-void ThrowNoSuchMethodFromCode(int32_t method_idx) {
- UNIMPLEMENTED(FATAL) << "No such method, idx: " << method_idx;
+extern "C" void artThrowNegArraySizeFromCode(int32_t size, Thread* thread, Method** sp) {
+ LOG(WARNING) << "UNTESTED artThrowNegArraySizeFromCode";
+ // Place a special frame at the TOS that will save all callee saves
+ Runtime* runtime = Runtime::Current();
+ *sp = runtime->GetCalleeSaveMethod();
+ thread->SetTopOfStack(sp, 0);
+ thread->ThrowNewException("Ljava/lang/NegativeArraySizeException;", "%d", size);
+ thread->DeliverException();
}
// TODO: placeholder. Helper function to type
@@ -447,11 +472,17 @@
pTestSuspendFromCode = art_test_suspend;
pThrowArrayBoundsFromCode = art_throw_array_bounds_from_code;
pThrowDivZeroFromCode = art_throw_div_zero_from_code;
+ pThrowInternalErrorFromCode = art_throw_internal_error_from_code;
+ pThrowNegArraySizeFromCode = art_throw_neg_array_size_from_code;
+ pThrowNoSuchMethodFromCode = art_throw_no_such_method_from_code;
pThrowNullPointerFromCode = art_throw_null_pointer_exception_from_code;
+ pThrowRuntimeExceptionFromCode = art_throw_runtime_exception_from_code;
pThrowStackOverflowFromCode = art_throw_stack_overflow_from_code;
+ pThrowVerificationErrorFromCode = art_throw_verification_error_from_code;
pUnlockObjectFromCode = art_unlock_object_from_code;
#endif
pDeliverException = art_deliver_exception_from_code;
+ pThrowAbstractMethodErrorFromCode = ThrowAbstractMethodErrorFromCode;
pF2l = F2L;
pD2l = D2L;
pMemcpy = memcpy;
@@ -467,12 +498,6 @@
pLockObjectFromCode = LockObjectFromCode;
pFindInstanceFieldFromCode = Field::FindInstanceFieldFromCode;
pCheckSuspendFromCode = artCheckSuspendFromCode;
- pThrowVerificationErrorFromCode = ThrowVerificationErrorFromCode;
- pThrowNegArraySizeFromCode = ThrowNegArraySizeFromCode;
- pThrowRuntimeExceptionFromCode = ThrowRuntimeExceptionFromCode;
- pThrowInternalErrorFromCode = ThrowInternalErrorFromCode;
- pThrowNoSuchMethodFromCode = ThrowNoSuchMethodFromCode;
- pThrowAbstractMethodErrorFromCode = ThrowAbstractMethodErrorFromCode;
pFindNativeMethod = FindNativeMethod;
pDecodeJObjectInThread = DecodeJObjectInThread;
pDebugMe = DebugMe;