Chromium Code Reviews| Index: src/compiler/wasm-compiler.cc |
| diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc |
| index 4285f58f7e49640dd59024adf14c154884bfddfd..faafe36e69a725212d7287d85fc85367fb4211a7 100644 |
| --- a/src/compiler/wasm-compiler.cc |
| +++ b/src/compiler/wasm-compiler.cc |
| @@ -2184,7 +2184,7 @@ Node* WasmGraphBuilder::BuildChangeFloat64ToTagged(Node* value) { |
| return value; |
| } |
| -Node* WasmGraphBuilder::ToJS(Node* node, Node* context, wasm::LocalType type) { |
| +Node* WasmGraphBuilder::ToJS(Node* node, wasm::LocalType type) { |
| switch (type) { |
| case wasm::kAstI32: |
| return BuildChangeInt32ToTagged(node); |
| @@ -2523,18 +2523,18 @@ void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Code> wasm_code, |
| retval = graph()->NewNode(jsgraph()->common()->Projection(0), retval, |
| graph()->start()); |
| } |
| - Node* jsval = |
| - ToJS(retval, context, |
| - sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); |
| + Node* jsval = ToJS( |
| + retval, sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); |
| Node* ret = |
| graph()->NewNode(jsgraph()->common()->Return(), jsval, call, start); |
| MergeControlToEnd(jsgraph(), ret); |
| } |
| -void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSFunction> function, |
| +void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target, |
| wasm::FunctionSig* sig) { |
| - int js_count = function->shared()->internal_formal_parameter_count(); |
| + DCHECK(target->IsCallable()); |
| + |
| int wasm_count = static_cast<int>(sig->parameter_count()); |
| int param_count; |
| if (jsgraph()->machine()->Is64()) { |
| @@ -2549,21 +2549,24 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSFunction> function, |
| Node* start = Start(param_count + 3); |
| *effect_ = start; |
| *control_ = start; |
| - // JS context is the last parameter. |
| - Node* context = HeapConstant(Handle<Context>(function->context(), isolate)); |
| Node** args = Buffer(wasm_count + 7); |
| bool arg_count_before_args = false; |
| bool add_new_target_undefined = false; |
| - |
| + bool call_direct = false; |
| int pos = 0; |
| - if (js_count == wasm_count) { |
| - // exact arity match, just call the function directly. |
| - desc = Linkage::GetJSCallDescriptor(graph()->zone(), false, wasm_count + 1, |
| - CallDescriptor::kNoFlags); |
| - arg_count_before_args = false; |
| - add_new_target_undefined = true; |
| - } else { |
| + Handle<JSFunction> function; |
|
Mircea Trofin
2016/08/09 14:54:07
For readability/maintainability, could you perhaps
ahaas
2016/08/09 18:00:09
I refactored the code now and think that it's more
|
| + if (target->IsJSFunction()) { |
| + function = Handle<JSFunction>::cast(target); |
| + if (function->shared()->internal_formal_parameter_count() == wasm_count) { |
| + desc = Linkage::GetJSCallDescriptor( |
| + graph()->zone(), false, wasm_count + 1, CallDescriptor::kNoFlags); |
| + arg_count_before_args = false; |
| + add_new_target_undefined = true; |
| + call_direct = true; |
| + } |
| + } |
| + if (!call_direct) { |
| // Use the Call builtin. |
| Callable callable = CodeFactory::Call(isolate); |
| args[pos++] = jsgraph()->HeapConstant(callable.code()); |
| @@ -2573,23 +2576,22 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSFunction> function, |
| arg_count_before_args = true; |
| } |
| - args[pos++] = jsgraph()->Constant(function); // JS function. |
| + args[pos++] = jsgraph()->Constant(target); // target callable. |
| if (arg_count_before_args) { |
| args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count |
| } |
| // Create the receiver constant (either undefined or the global proxy). |
| Handle<Object> receiver(isolate->heap()->undefined_value(), isolate); |
| - if (is_sloppy(function->shared()->language_mode())) { |
| - receiver = Handle<Object>(function->context()->global_proxy(), isolate); |
| + if (call_direct && is_sloppy(function->shared()->language_mode())) { |
| + receiver = handle(function->context()->global_proxy(), isolate); |
| } |
| args[pos++] = jsgraph()->Constant(receiver); |
| - |
| // Convert WASM numbers to JS values. |
| int param_index = 0; |
| for (int i = 0; i < wasm_count; ++i) { |
| Node* param = |
| graph()->NewNode(jsgraph()->common()->Parameter(param_index++), start); |
| - args[pos++] = ToJS(param, context, sig->GetParam(i)); |
| + args[pos++] = ToJS(param, sig->GetParam(i)); |
| if (jsgraph()->machine()->Is32() && sig->GetParam(i) == wasm::kAstI64) { |
| // On 32 bit platforms we have to skip the high word of int64 parameters. |
| param_index++; |
| @@ -2603,7 +2605,13 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSFunction> function, |
| if (!arg_count_before_args) { |
| args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count |
| } |
| - args[pos++] = context; |
| + if (call_direct) { |
| + // We do a direct call to JS, we need the context of the function. |
| + args[pos++] = HeapConstant(handle(function->context())); |
| + } else { |
| + args[pos++] = HeapConstant(isolate->native_context()); |
| + } |
| + |
| args[pos++] = *effect_; |
| args[pos++] = *control_; |
| @@ -2612,7 +2620,7 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSFunction> function, |
| // Convert the return value back. |
| Node* ret; |
| Node* val = |
| - FromJS(call, context, |
| + FromJS(call, HeapConstant(isolate->native_context()), |
| sig->return_count() == 0 ? wasm::kAstStmt : sig->GetReturn()); |
| if (jsgraph()->machine()->Is32() && sig->return_count() > 0 && |
| sig->GetReturn() == wasm::kAstI64) { |
| @@ -3052,8 +3060,7 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::ModuleEnv* module, |
| return code; |
| } |
| -Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, |
| - Handle<JSFunction> function, |
| +Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target, |
| wasm::FunctionSig* sig, uint32_t index, |
| Handle<String> import_module, |
| MaybeHandle<String> import_function) { |
| @@ -3072,7 +3079,7 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, |
| WasmGraphBuilder builder(&zone, &jsgraph, sig); |
| builder.set_control_ptr(&control); |
| builder.set_effect_ptr(&effect); |
| - builder.BuildWasmToJSWrapper(function, sig); |
| + builder.BuildWasmToJSWrapper(target, sig); |
| Handle<Code> code = Handle<Code>::null(); |
| { |