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" |
11 #include "vm/dart_api_impl.h" | 11 #include "vm/dart_api_impl.h" |
12 #include "vm/dart_api_state.h" | 12 #include "vm/dart_api_state.h" |
13 #include "vm/native_symbol.h" | 13 #include "vm/native_symbol.h" |
14 #include "vm/object_store.h" | 14 #include "vm/object_store.h" |
15 #include "vm/reusable_handles.h" | 15 #include "vm/reusable_handles.h" |
16 #include "vm/safepoint.h" | 16 #include "vm/safepoint.h" |
17 #include "vm/stack_frame.h" | 17 #include "vm/stack_frame.h" |
18 #include "vm/symbols.h" | 18 #include "vm/symbols.h" |
19 #include "vm/tags.h" | 19 #include "vm/tags.h" |
20 | 20 |
21 | 21 |
22 namespace dart { | 22 namespace dart { |
23 | 23 |
24 DEFINE_FLAG(bool, trace_natives, false, | 24 DEFINE_FLAG(bool, |
| 25 trace_natives, |
| 26 false, |
25 "Trace invocation of natives (debug mode only)"); | 27 "Trace invocation of natives (debug mode only)"); |
26 | 28 |
27 | 29 |
28 void DartNativeThrowArgumentException(const Instance& instance) { | 30 void DartNativeThrowArgumentException(const Instance& instance) { |
29 const Array& __args__ = Array::Handle(Array::New(1)); | 31 const Array& __args__ = Array::Handle(Array::New(1)); |
30 __args__.SetAt(0, instance); | 32 __args__.SetAt(0, instance); |
31 Exceptions::ThrowByType(Exceptions::kArgument, __args__); | 33 Exceptions::ThrowByType(Exceptions::kArgument, __args__); |
32 } | 34 } |
33 | 35 |
34 | 36 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 } | 144 } |
143 } else { | 145 } else { |
144 Isolate* isolate = thread->isolate(); | 146 Isolate* isolate = thread->isolate(); |
145 ApiState* state = isolate->api_state(); | 147 ApiState* state = isolate->api_state(); |
146 ASSERT(state != NULL); | 148 ASSERT(state != NULL); |
147 ApiLocalScope* current_top_scope = thread->api_top_scope(); | 149 ApiLocalScope* current_top_scope = thread->api_top_scope(); |
148 ApiLocalScope* scope = thread->api_reusable_scope(); | 150 ApiLocalScope* scope = thread->api_reusable_scope(); |
149 TRACE_NATIVE_CALL("0x%" Px "", reinterpret_cast<uintptr_t>(func)); | 151 TRACE_NATIVE_CALL("0x%" Px "", reinterpret_cast<uintptr_t>(func)); |
150 TransitionGeneratedToNative transition(thread); | 152 TransitionGeneratedToNative transition(thread); |
151 if (scope == NULL) { | 153 if (scope == NULL) { |
152 scope = new ApiLocalScope(current_top_scope, | 154 scope = |
153 thread->top_exit_frame_info()); | 155 new ApiLocalScope(current_top_scope, thread->top_exit_frame_info()); |
154 ASSERT(scope != NULL); | 156 ASSERT(scope != NULL); |
155 } else { | 157 } else { |
156 scope->Reinit(thread, | 158 scope->Reinit(thread, current_top_scope, thread->top_exit_frame_info()); |
157 current_top_scope, | |
158 thread->top_exit_frame_info()); | |
159 thread->set_api_reusable_scope(NULL); | 159 thread->set_api_reusable_scope(NULL); |
160 } | 160 } |
161 thread->set_api_top_scope(scope); // New scope is now the top scope. | 161 thread->set_api_top_scope(scope); // New scope is now the top scope. |
162 | 162 |
163 func(args); | 163 func(args); |
164 if (ReturnValueIsError(arguments)) { | 164 if (ReturnValueIsError(arguments)) { |
165 PropagateErrors(arguments); | 165 PropagateErrors(arguments); |
166 } | 166 } |
167 | 167 |
168 ASSERT(current_top_scope == scope->previous()); | 168 ASSERT(current_top_scope == scope->previous()); |
(...skipping 21 matching lines...) Expand all Loading... |
190 const Library& library = Library::Handle(zone, cls.library()); | 190 const Library& library = Library::Handle(zone, cls.library()); |
191 | 191 |
192 *is_bootstrap_native = | 192 *is_bootstrap_native = |
193 Bootstrap::IsBootstapResolver(library.native_entry_resolver()); | 193 Bootstrap::IsBootstapResolver(library.native_entry_resolver()); |
194 | 194 |
195 const String& native_name = String::Handle(zone, func.native_name()); | 195 const String& native_name = String::Handle(zone, func.native_name()); |
196 ASSERT(!native_name.IsNull()); | 196 ASSERT(!native_name.IsNull()); |
197 | 197 |
198 const int num_params = NativeArguments::ParameterCountForResolution(func); | 198 const int num_params = NativeArguments::ParameterCountForResolution(func); |
199 bool auto_setup_scope = true; | 199 bool auto_setup_scope = true; |
200 return NativeEntry::ResolveNative( | 200 return NativeEntry::ResolveNative(library, native_name, num_params, |
201 library, native_name, num_params, &auto_setup_scope); | 201 &auto_setup_scope); |
202 } | 202 } |
203 | 203 |
204 | 204 |
205 uword NativeEntry::LinkNativeCallEntry() { | 205 uword NativeEntry::LinkNativeCallEntry() { |
206 uword entry = reinterpret_cast<uword>(NativeEntry::LinkNativeCall); | 206 uword entry = reinterpret_cast<uword>(NativeEntry::LinkNativeCall); |
207 #if defined(USING_SIMULATOR) | 207 #if defined(USING_SIMULATOR) |
208 entry = Simulator::RedirectExternalReference( | 208 entry = Simulator::RedirectExternalReference( |
209 entry, Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments); | 209 entry, Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments); |
210 #endif | 210 #endif |
211 return entry; | 211 return entry; |
(...skipping 19 matching lines...) Expand all Loading... |
231 StackFrame* caller_frame = iterator.NextFrame(); | 231 StackFrame* caller_frame = iterator.NextFrame(); |
232 | 232 |
233 const Code& code = Code::Handle(caller_frame->LookupDartCode()); | 233 const Code& code = Code::Handle(caller_frame->LookupDartCode()); |
234 const Function& func = Function::Handle(code.function()); | 234 const Function& func = Function::Handle(code.function()); |
235 | 235 |
236 if (FLAG_trace_natives) { | 236 if (FLAG_trace_natives) { |
237 OS::Print("Resolving native target for %s\n", func.ToCString()); | 237 OS::Print("Resolving native target for %s\n", func.ToCString()); |
238 } | 238 } |
239 | 239 |
240 bool is_bootstrap_native = false; | 240 bool is_bootstrap_native = false; |
241 target_function = ResolveNativeFunction( | 241 target_function = ResolveNativeFunction(arguments->thread()->zone(), func, |
242 arguments->thread()->zone(), func, &is_bootstrap_native); | 242 &is_bootstrap_native); |
243 ASSERT(target_function != NULL); | 243 ASSERT(target_function != NULL); |
244 | 244 |
245 #if defined(DEBUG) | 245 #if defined(DEBUG) |
246 { | 246 { |
247 NativeFunction current_function = NULL; | 247 NativeFunction current_function = NULL; |
248 const Code& current_trampoline = Code::Handle( | 248 const Code& current_trampoline = |
249 CodePatcher::GetNativeCallAt(caller_frame->pc(), | 249 Code::Handle(CodePatcher::GetNativeCallAt(caller_frame->pc(), code, |
250 code, | 250 ¤t_function)); |
251 ¤t_function)); | |
252 #if !defined(USING_SIMULATOR) | 251 #if !defined(USING_SIMULATOR) |
253 ASSERT(current_function == | 252 ASSERT(current_function == |
254 reinterpret_cast<NativeFunction>(LinkNativeCall)); | 253 reinterpret_cast<NativeFunction>(LinkNativeCall)); |
255 #else | 254 #else |
256 ASSERT(current_function == | 255 ASSERT( |
257 reinterpret_cast<NativeFunction>( | 256 current_function == |
258 Simulator::RedirectExternalReference( | 257 reinterpret_cast<NativeFunction>(Simulator::RedirectExternalReference( |
259 reinterpret_cast<uword>(LinkNativeCall), | 258 reinterpret_cast<uword>(LinkNativeCall), |
260 Simulator::kBootstrapNativeCall, | 259 Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments))); |
261 NativeEntry::kNumArguments))); | |
262 #endif | 260 #endif |
263 ASSERT(current_trampoline.raw() == | 261 ASSERT(current_trampoline.raw() == |
264 StubCode::CallBootstrapCFunction_entry()->code()); | 262 StubCode::CallBootstrapCFunction_entry()->code()); |
265 } | 263 } |
266 #endif | 264 #endif |
267 | 265 |
268 call_through_wrapper = !is_bootstrap_native; | 266 call_through_wrapper = !is_bootstrap_native; |
269 const Code& trampoline = | 267 const Code& trampoline = |
270 Code::Handle(call_through_wrapper ? | 268 Code::Handle(call_through_wrapper |
271 StubCode::CallNativeCFunction_entry()->code() : | 269 ? StubCode::CallNativeCFunction_entry()->code() |
272 StubCode::CallBootstrapCFunction_entry()->code()); | 270 : StubCode::CallBootstrapCFunction_entry()->code()); |
273 | 271 |
274 NativeFunction patch_target_function = target_function; | 272 NativeFunction patch_target_function = target_function; |
275 #if defined(USING_SIMULATOR) | 273 #if defined(USING_SIMULATOR) |
276 if (!call_through_wrapper) { | 274 if (!call_through_wrapper) { |
277 patch_target_function = reinterpret_cast<NativeFunction>( | 275 patch_target_function = |
278 Simulator::RedirectExternalReference( | 276 reinterpret_cast<NativeFunction>(Simulator::RedirectExternalReference( |
279 reinterpret_cast<uword>(patch_target_function), | 277 reinterpret_cast<uword>(patch_target_function), |
280 Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments)); | 278 Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments)); |
281 } | 279 } |
282 #endif | 280 #endif |
283 | 281 |
284 CodePatcher::PatchNativeCallAt( | 282 CodePatcher::PatchNativeCallAt(caller_frame->pc(), code, |
285 caller_frame->pc(), code, patch_target_function, trampoline); | 283 patch_target_function, trampoline); |
286 | 284 |
287 if (FLAG_trace_natives) { | 285 if (FLAG_trace_natives) { |
288 OS::Print(" -> %p (%s)\n", | 286 OS::Print(" -> %p (%s)\n", target_function, |
289 target_function, | |
290 is_bootstrap_native ? "bootstrap" : "non-bootstrap"); | 287 is_bootstrap_native ? "bootstrap" : "non-bootstrap"); |
291 } | 288 } |
292 } | 289 } |
293 VERIFY_ON_TRANSITION; | 290 VERIFY_ON_TRANSITION; |
294 | 291 |
295 // Tail-call resolved target. | 292 // Tail-call resolved target. |
296 if (call_through_wrapper) { | 293 if (call_through_wrapper) { |
297 // Because this call is within a compilation unit, Clang doesn't respect | 294 // Because this call is within a compilation unit, Clang doesn't respect |
298 // the ABI alignment here. | 295 // the ABI alignment here. |
299 NativeEntry::NativeCallWrapperNoStackCheck( | 296 NativeEntry::NativeCallWrapperNoStackCheck( |
300 args, reinterpret_cast<Dart_NativeFunction>(target_function)); | 297 args, reinterpret_cast<Dart_NativeFunction>(target_function)); |
301 } else { | 298 } else { |
302 target_function(arguments); | 299 target_function(arguments); |
303 } | 300 } |
304 } | 301 } |
305 #endif // !defined(TARGET_ARCH_DBC) | 302 #endif // !defined(TARGET_ARCH_DBC) |
306 | 303 |
307 | 304 |
308 } // namespace dart | 305 } // namespace dart |
OLD | NEW |