OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/native_entry.h" | 5 #include "vm/native_entry.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 | 8 |
9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
10 #include "vm/code_patcher.h" | 10 #include "vm/code_patcher.h" |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 uword NativeEntry::NativeCallWrapperEntry() { | 84 uword NativeEntry::NativeCallWrapperEntry() { |
85 uword entry = reinterpret_cast<uword>(NativeEntry::NativeCallWrapper); | 85 uword entry = reinterpret_cast<uword>(NativeEntry::NativeCallWrapper); |
86 #if defined(USING_SIMULATOR) | 86 #if defined(USING_SIMULATOR) |
87 entry = Simulator::RedirectExternalReference( | 87 entry = Simulator::RedirectExternalReference( |
88 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments); | 88 entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments); |
89 #endif | 89 #endif |
90 return entry; | 90 return entry; |
91 } | 91 } |
92 | 92 |
93 | 93 |
| 94 bool NativeEntry::ReturnValueIsError(NativeArguments* arguments) { |
| 95 RawObject* retval = arguments->ReturnValue(); |
| 96 return (retval->IsHeapObject() && |
| 97 RawObject::IsErrorClassId(retval->GetClassId())); |
| 98 } |
| 99 |
| 100 |
| 101 void NativeEntry::PropagateErrors(NativeArguments* arguments) { |
| 102 Thread* thread = arguments->thread(); |
| 103 thread->UnwindScopes(thread->top_exit_frame_info()); |
| 104 |
| 105 // The thread->zone() is different here than before we unwound. |
| 106 const Object& error = |
| 107 Object::Handle(thread->zone(), arguments->ReturnValue()); |
| 108 Exceptions::PropagateError(Error::Cast(error)); |
| 109 UNREACHABLE(); |
| 110 } |
| 111 |
| 112 |
94 void NativeEntry::NativeCallWrapper(Dart_NativeArguments args, | 113 void NativeEntry::NativeCallWrapper(Dart_NativeArguments args, |
95 Dart_NativeFunction func) { | 114 Dart_NativeFunction func) { |
96 CHECK_STACK_ALIGNMENT; | 115 CHECK_STACK_ALIGNMENT; |
97 VERIFY_ON_TRANSITION; | 116 VERIFY_ON_TRANSITION; |
98 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); | 117 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); |
99 /* Tell MemorySanitizer 'arguments' is initialized by generated code. */ | 118 /* Tell MemorySanitizer 'arguments' is initialized by generated code. */ |
100 MSAN_UNPOISON(arguments, sizeof(*arguments)); | 119 MSAN_UNPOISON(arguments, sizeof(*arguments)); |
101 Thread* thread = arguments->thread(); | 120 Thread* thread = arguments->thread(); |
102 if (!arguments->IsNativeAutoSetupScope()) { | 121 if (!arguments->IsNativeAutoSetupScope()) { |
103 TransitionGeneratedToNative transition(thread); | 122 TransitionGeneratedToNative transition(thread); |
104 func(args); | 123 func(args); |
| 124 if (ReturnValueIsError(arguments)) { |
| 125 PropagateErrors(arguments); |
| 126 } |
105 } else { | 127 } else { |
106 Isolate* isolate = thread->isolate(); | 128 Isolate* isolate = thread->isolate(); |
107 ApiState* state = isolate->api_state(); | 129 ApiState* state = isolate->api_state(); |
108 ASSERT(state != NULL); | 130 ASSERT(state != NULL); |
109 ApiLocalScope* current_top_scope = thread->api_top_scope(); | 131 ApiLocalScope* current_top_scope = thread->api_top_scope(); |
110 ApiLocalScope* scope = thread->api_reusable_scope(); | 132 ApiLocalScope* scope = thread->api_reusable_scope(); |
111 TRACE_NATIVE_CALL("0x%" Px "", reinterpret_cast<uintptr_t>(func)); | 133 TRACE_NATIVE_CALL("0x%" Px "", reinterpret_cast<uintptr_t>(func)); |
112 TransitionGeneratedToNative transition(thread); | 134 TransitionGeneratedToNative transition(thread); |
113 if (scope == NULL) { | 135 if (scope == NULL) { |
114 scope = new ApiLocalScope(current_top_scope, | 136 scope = new ApiLocalScope(current_top_scope, |
115 thread->top_exit_frame_info()); | 137 thread->top_exit_frame_info()); |
116 ASSERT(scope != NULL); | 138 ASSERT(scope != NULL); |
117 } else { | 139 } else { |
118 scope->Reinit(thread, | 140 scope->Reinit(thread, |
119 current_top_scope, | 141 current_top_scope, |
120 thread->top_exit_frame_info()); | 142 thread->top_exit_frame_info()); |
121 thread->set_api_reusable_scope(NULL); | 143 thread->set_api_reusable_scope(NULL); |
122 } | 144 } |
123 thread->set_api_top_scope(scope); // New scope is now the top scope. | 145 thread->set_api_top_scope(scope); // New scope is now the top scope. |
124 | 146 |
125 func(args); | 147 func(args); |
| 148 if (ReturnValueIsError(arguments)) { |
| 149 PropagateErrors(arguments); |
| 150 } |
126 | 151 |
127 ASSERT(current_top_scope == scope->previous()); | 152 ASSERT(current_top_scope == scope->previous()); |
128 thread->set_api_top_scope(current_top_scope); // Reset top scope to prev. | 153 thread->set_api_top_scope(current_top_scope); // Reset top scope to prev. |
129 if (thread->api_reusable_scope() == NULL) { | 154 if (thread->api_reusable_scope() == NULL) { |
130 scope->Reset(thread); // Reset the old scope which we just exited. | 155 scope->Reset(thread); // Reset the old scope which we just exited. |
131 thread->set_api_reusable_scope(scope); | 156 thread->set_api_reusable_scope(scope); |
132 } else { | 157 } else { |
133 ASSERT(thread->api_reusable_scope() != scope); | 158 ASSERT(thread->api_reusable_scope() != scope); |
134 delete scope; | 159 delete scope; |
135 } | 160 } |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 if (call_through_wrapper) { | 276 if (call_through_wrapper) { |
252 NativeEntry::NativeCallWrapper( | 277 NativeEntry::NativeCallWrapper( |
253 args, reinterpret_cast<Dart_NativeFunction>(target_function)); | 278 args, reinterpret_cast<Dart_NativeFunction>(target_function)); |
254 } else { | 279 } else { |
255 target_function(arguments); | 280 target_function(arguments); |
256 } | 281 } |
257 } | 282 } |
258 | 283 |
259 | 284 |
260 } // namespace dart | 285 } // namespace dart |
OLD | NEW |