Index: runtime/vm/stub_code_arm.cc |
=================================================================== |
--- runtime/vm/stub_code_arm.cc (revision 25822) |
+++ runtime/vm/stub_code_arm.cc (working copy) |
@@ -173,7 +173,93 @@ |
// For now, space is reserved on the stack and we pass a pointer to it. |
__ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); |
__ mov(R0, ShifterOperand(SP)); // Pass the pointer to the NativeArguments. |
+ __ mov(R1, ShifterOperand(R5)); // Pass the function entrypoint to call. |
+ // Call native function invocation wrapper or redirection via simulator. |
+#if defined(USING_SIMULATOR) |
+ uword entry = reinterpret_cast<uword>(NativeEntry::NativeCallWrapper); |
+ entry = Simulator::RedirectExternalReference( |
+ entry, Simulator::kNativeCall, NativeEntry::kNumCallWrapperArguments); |
+ __ LoadImmediate(R2, entry); |
+ __ blx(R2); |
+#else |
+ __ BranchLink(&NativeEntry::NativeCallWrapperLabel()); |
+#endif |
+ |
+ // Reset exit frame information in Isolate structure. |
+ __ LoadImmediate(R2, 0); |
+ __ StoreToOffset(kWord, R2, CTX, Isolate::top_exit_frame_info_offset()); |
+ |
+ // Load Context pointer from Isolate structure into R2. |
+ __ LoadFromOffset(kWord, R2, CTX, Isolate::top_context_offset()); |
+ |
+ // Reset Context pointer in Isolate structure. |
+ __ LoadImmediate(R3, reinterpret_cast<intptr_t>(Object::null())); |
+ __ StoreToOffset(kWord, R3, CTX, Isolate::top_context_offset()); |
+ |
+ // Cache Context pointer into CTX while executing Dart code. |
+ __ mov(CTX, ShifterOperand(R2)); |
+ |
+ __ LeaveFrame((1 << FP) | (1 << LR)); |
+ __ Ret(); |
+} |
+ |
+ |
+// Input parameters: |
+// LR : return address. |
+// SP : address of return value. |
+// R5 : address of the native function to call. |
+// R2 : address of first argument in argument array. |
+// R1 : argc_tag including number of arguments and function kind. |
+void StubCode::GenerateCallBootstrapCFunctionStub(Assembler* assembler) { |
+ const intptr_t isolate_offset = NativeArguments::isolate_offset(); |
+ const intptr_t argc_tag_offset = NativeArguments::argc_tag_offset(); |
+ const intptr_t argv_offset = NativeArguments::argv_offset(); |
+ const intptr_t retval_offset = NativeArguments::retval_offset(); |
+ |
+ __ EnterFrame((1 << FP) | (1 << LR), 0); |
+ |
+ // Load current Isolate pointer from Context structure into R0. |
+ __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); |
+ |
+ // Save exit frame information to enable stack walking as we are about |
+ // to transition to native code. |
+ __ StoreToOffset(kWord, SP, R0, Isolate::top_exit_frame_info_offset()); |
+ |
+ // Save current Context pointer into Isolate structure. |
+ __ StoreToOffset(kWord, CTX, R0, Isolate::top_context_offset()); |
+ |
+ // Cache Isolate pointer into CTX while executing native code. |
+ __ mov(CTX, ShifterOperand(R0)); |
+ |
+ // Reserve space for the native arguments structure passed on the stack (the |
+ // outgoing pointer parameter to the native arguments structure is passed in |
+ // R0) and align frame before entering the C++ world. |
+ __ ReserveAlignedFrameSpace(sizeof(NativeArguments)); |
+ |
+ // Initialize NativeArguments structure and call native function. |
+ // Registers R0, R1, R2, and R3 are used. |
+ |
+ ASSERT(isolate_offset == 0 * kWordSize); |
+ // Set isolate in NativeArgs: R0 already contains CTX. |
+ |
+ // There are no native calls to closures, so we do not need to set the tag |
+ // bits kClosureFunctionBit and kInstanceFunctionBit in argc_tag_. |
+ ASSERT(argc_tag_offset == 1 * kWordSize); |
+ // Set argc in NativeArguments: R1 already contains argc. |
+ |
+ ASSERT(argv_offset == 2 * kWordSize); |
+ // Set argv in NativeArguments: R2 already contains argv. |
+ |
+ ASSERT(retval_offset == 3 * kWordSize); |
+ __ add(R3, FP, ShifterOperand(2 * kWordSize)); // Set retval in NativeArgs. |
+ |
+ // TODO(regis): Should we pass the structure by value as in runtime calls? |
+ // It would require changing Dart API for native functions. |
+ // For now, space is reserved on the stack and we pass a pointer to it. |
+ __ stm(IA, SP, (1 << R0) | (1 << R1) | (1 << R2) | (1 << R3)); |
+ __ mov(R0, ShifterOperand(SP)); // Pass the pointer to the NativeArguments. |
+ |
// Call native function or redirection via simulator. |
__ blx(R5); |