Index: src/arm/simulator-arm.cc |
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc |
index fcefdee056a961ce678a7acd0bff196f4a4b58c8..8104747f14d49d861d86f97b5550c66e512a9a70 100644 |
--- a/src/arm/simulator-arm.cc |
+++ b/src/arm/simulator-arm.cc |
@@ -744,10 +744,10 @@ Simulator::Simulator() { |
// offset from the svc instruction so the simulator knows what to call. |
class Redirection { |
public: |
- Redirection(void* external_function, bool fp_return) |
+ Redirection(void* external_function, ExternalReference::Type type) |
: external_function_(external_function), |
swi_instruction_(al | (0xf*B24) | kCallRtRedirected), |
- fp_return_(fp_return), |
+ type_(type), |
next_(list_) { |
Simulator::current()-> |
FlushICache(reinterpret_cast<void*>(&swi_instruction_), |
@@ -760,14 +760,15 @@ class Redirection { |
} |
void* external_function() { return external_function_; } |
- bool fp_return() { return fp_return_; } |
+ ExternalReference::Type type() { return type_; } |
- static Redirection* Get(void* external_function, bool fp_return) { |
+ static Redirection* Get(void* external_function, |
+ ExternalReference::Type type) { |
Redirection* current; |
for (current = list_; current != NULL; current = current->next_) { |
if (current->external_function_ == external_function) return current; |
} |
- return new Redirection(external_function, fp_return); |
+ return new Redirection(external_function, type); |
} |
static Redirection* FromSwiInstruction(Instruction* swi_instruction) { |
@@ -780,7 +781,7 @@ class Redirection { |
private: |
void* external_function_; |
uint32_t swi_instruction_; |
- bool fp_return_; |
+ ExternalReference::Type type_; |
Redirection* next_; |
static Redirection* list_; |
}; |
@@ -790,8 +791,8 @@ Redirection* Redirection::list_ = NULL; |
void* Simulator::RedirectExternalReference(void* external_function, |
- bool fp_return) { |
- Redirection* redirection = Redirection::Get(external_function, fp_return); |
+ ExternalReference::Type type) { |
+ Redirection* redirection = Redirection::Get(external_function, type); |
return redirection->address_of_swi_instruction(); |
} |
@@ -1528,6 +1529,9 @@ typedef double (*SimulatorRuntimeFPCall)(int32_t arg0, |
int32_t arg2, |
int32_t arg3); |
+// This signature supports direct call in to API function native callback |
+// (refer to InvocationCallback in v8.h). |
+typedef v8::Handle<v8::Value> (*SimulatorRuntimeApiCall)(int32_t arg0); |
// Software interrupt instructions are used by the simulator to call into the |
// C-based V8 runtime. |
@@ -1550,9 +1554,9 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { |
// This is dodgy but it works because the C entry stubs are never moved. |
// See comment in codegen-arm.cc and bug 1242173. |
int32_t saved_lr = get_register(lr); |
- if (redirection->fp_return()) { |
- intptr_t external = |
- reinterpret_cast<intptr_t>(redirection->external_function()); |
+ intptr_t external = |
+ reinterpret_cast<intptr_t>(redirection->external_function()); |
+ if (redirection->type() == ExternalReference::FP_RETURN_CALL) { |
SimulatorRuntimeFPCall target = |
reinterpret_cast<SimulatorRuntimeFPCall>(external); |
if (::v8::internal::FLAG_trace_sim || !stack_aligned) { |
@@ -1568,9 +1572,28 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { |
CHECK(stack_aligned); |
double result = target(arg0, arg1, arg2, arg3); |
SetFpResult(result); |
+ } else if (redirection->type() == ExternalReference::DIRECT_CALL) { |
+ SimulatorRuntimeApiCall target = |
+ reinterpret_cast<SimulatorRuntimeApiCall>(external); |
+ if (::v8::internal::FLAG_trace_sim || !stack_aligned) { |
+ PrintF( |
+ "Call to host function at %p args %08x", |
+ FUNCTION_ADDR(target), |
+ arg0); |
+ if (!stack_aligned) { |
+ PrintF(" with unaligned stack %08x\n", get_register(sp)); |
+ } |
+ PrintF("\n"); |
+ } |
+ CHECK(stack_aligned); |
+ v8::Handle<v8::Value> result = target(arg0); |
+ if (::v8::internal::FLAG_trace_sim) { |
+ PrintF("Returned %p\n", reinterpret_cast<void *>(*result)); |
+ } |
+ set_register(r0, (int32_t) *result); |
} else { |
- intptr_t external = |
- reinterpret_cast<int32_t>(redirection->external_function()); |
+ // builtin call. |
+ ASSERT(redirection->type() == ExternalReference::BUILTIN_CALL); |
SimulatorRuntimeCall target = |
reinterpret_cast<SimulatorRuntimeCall>(external); |
if (::v8::internal::FLAG_trace_sim || !stack_aligned) { |