Chromium Code Reviews| Index: runtime/vm/native_entry.cc |
| diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc |
| index 2277319bb4d0e994804e5ccc14bfa656340a35a6..8523a272077b07b8a1fa57200fffa707d1dc1224 100644 |
| --- a/runtime/vm/native_entry.cc |
| +++ b/runtime/vm/native_entry.cc |
| @@ -91,6 +91,26 @@ uword NativeEntry::NativeCallWrapperEntry() { |
| } |
| +void NativeEntry::PropagateErrors(NativeArguments* arguments) { |
| + RawObject* raw_retval = arguments->ReturnValue(); |
| + if (raw_retval->IsHeapObject() && |
| + RawObject::IsErrorClassId(raw_retval->GetClassId())) { |
| + Thread* thread = arguments->thread(); |
| + const Object* error; |
| + { |
| + // We use a NoSafepointScope to make sure that the raw_retval |
| + // is preserved while we are unwinding scopes. |
| + NoSafepointScope no_safepoint; |
| + thread->UnwindScopes(thread->top_exit_frame_info()); |
| + // The thread->zone() now is different here than before we unwound. |
| + error = &Object::Handle(thread->zone(), raw_retval); |
| + } |
|
siva
2016/02/03 16:50:00
Why do you declare it as:
const Object* error;
w
turnidge
2016/02/03 19:13:46
Done.
|
| + Exceptions::PropagateError(Error::Cast(*error)); |
| + UNREACHABLE(); |
| + } |
| +} |
| + |
| + |
| void NativeEntry::NativeCallWrapper(Dart_NativeArguments args, |
| Dart_NativeFunction func) { |
| CHECK_STACK_ALIGNMENT; |
| @@ -102,6 +122,7 @@ void NativeEntry::NativeCallWrapper(Dart_NativeArguments args, |
| if (!arguments->IsNativeAutoSetupScope()) { |
| TransitionGeneratedToNative transition(thread); |
| func(args); |
| + PropagateErrors(arguments); |
|
siva
2016/02/03 16:50:00
Might be more efficient to have an inlinable funct
turnidge
2016/02/03 19:13:46
Done.
|
| } else { |
| Isolate* isolate = thread->isolate(); |
| ApiState* state = isolate->api_state(); |
| @@ -123,6 +144,7 @@ void NativeEntry::NativeCallWrapper(Dart_NativeArguments args, |
| thread->set_api_top_scope(scope); // New scope is now the top scope. |
| func(args); |
| + PropagateErrors(arguments); |
| ASSERT(current_top_scope == scope->previous()); |
| thread->set_api_top_scope(current_top_scope); // Reset top scope to prev. |