[wasm] Refactor BuildWasmToJSWrapper to clearly separate direct calls from Call-codestub calls
Looking at the code with Toon showed me that the code is not really readable at the moment. This refactoring should make the different kinds of calls and their parameters more apparent. R=titzer@chromium.org Review-Url: https://codereview.chromium.org/2295743002 Cr-Commit-Position: refs/heads/master@{#39126}
This commit is contained in:
parent
9521a5d609
commit
e809937eb3
@ -2541,6 +2541,23 @@ void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Code> wasm_code,
|
||||
MergeControlToEnd(jsgraph(), ret);
|
||||
}
|
||||
|
||||
int WasmGraphBuilder::AddParameterNodes(Node** args, int pos, int param_count,
|
||||
wasm::FunctionSig* sig) {
|
||||
// Convert WASM numbers to JS values.
|
||||
int param_index = 0;
|
||||
for (int i = 0; i < param_count; ++i) {
|
||||
Node* param = graph()->NewNode(
|
||||
jsgraph()->common()->Parameter(param_index++), graph()->start());
|
||||
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++;
|
||||
}
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target,
|
||||
wasm::FunctionSig* sig) {
|
||||
DCHECK(target->IsCallable());
|
||||
@ -2561,18 +2578,14 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target,
|
||||
*control_ = start;
|
||||
Node** args = Buffer(wasm_count + 7);
|
||||
|
||||
// The default context of the target.
|
||||
Handle<Context> target_context = isolate->native_context();
|
||||
Node* call;
|
||||
bool direct_call = false;
|
||||
|
||||
// Optimization: check if the target is a JSFunction with the right arity so
|
||||
// that we can call it directly.
|
||||
bool call_direct = false;
|
||||
int pos = 0;
|
||||
if (target->IsJSFunction()) {
|
||||
Handle<JSFunction> function = Handle<JSFunction>::cast(target);
|
||||
if (function->shared()->internal_formal_parameter_count() == wasm_count) {
|
||||
call_direct = true;
|
||||
|
||||
direct_call = true;
|
||||
int pos = 0;
|
||||
args[pos++] = jsgraph()->Constant(target); // target callable.
|
||||
// Receiver.
|
||||
if (is_sloppy(function->shared()->language_mode()) &&
|
||||
@ -2587,13 +2600,22 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target,
|
||||
desc = Linkage::GetJSCallDescriptor(
|
||||
graph()->zone(), false, wasm_count + 1, CallDescriptor::kNoFlags);
|
||||
|
||||
// For a direct call we have to use the context of the JSFunction.
|
||||
target_context = handle(function->context());
|
||||
// Convert WASM numbers to JS values.
|
||||
pos = AddParameterNodes(args, pos, wasm_count, sig);
|
||||
|
||||
args[pos++] = jsgraph()->UndefinedConstant(); // new target
|
||||
args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count
|
||||
args[pos++] = HeapConstant(handle(function->context()));
|
||||
args[pos++] = *effect_;
|
||||
args[pos++] = *control_;
|
||||
|
||||
call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args);
|
||||
}
|
||||
}
|
||||
|
||||
// We cannot call the target directly, we have to use the Call builtin.
|
||||
if (!call_direct) {
|
||||
if (!direct_call) {
|
||||
int pos = 0;
|
||||
Callable callable = CodeFactory::Call(isolate);
|
||||
args[pos++] = jsgraph()->HeapConstant(callable.code());
|
||||
args[pos++] = jsgraph()->Constant(target); // target callable
|
||||
@ -2604,31 +2626,22 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target,
|
||||
desc = Linkage::GetStubCallDescriptor(isolate, graph()->zone(),
|
||||
callable.descriptor(), wasm_count + 1,
|
||||
CallDescriptor::kNoFlags);
|
||||
|
||||
// Convert WASM numbers to JS values.
|
||||
pos = AddParameterNodes(args, pos, wasm_count, sig);
|
||||
|
||||
// The native_context is sufficient here, because all kind of callables
|
||||
// which depend on the context provide their own context. The context here
|
||||
// is only needed if the target is a constructor to throw a TypeError, if
|
||||
// the target is a native function, or if the target is a callable JSObject,
|
||||
// which can only be constructed by the runtime.
|
||||
args[pos++] = HeapConstant(isolate->native_context());
|
||||
args[pos++] = *effect_;
|
||||
args[pos++] = *control_;
|
||||
|
||||
call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args);
|
||||
}
|
||||
|
||||
// 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, 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++;
|
||||
}
|
||||
}
|
||||
|
||||
if (call_direct) {
|
||||
args[pos++] = jsgraph()->UndefinedConstant(); // new target
|
||||
args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count
|
||||
}
|
||||
|
||||
args[pos++] = HeapConstant(target_context);
|
||||
args[pos++] = *effect_;
|
||||
args[pos++] = *control_;
|
||||
|
||||
Node* call = graph()->NewNode(jsgraph()->common()->Call(desc), pos, args);
|
||||
|
||||
// Convert the return value back.
|
||||
Node* ret;
|
||||
Node* val =
|
||||
|
@ -337,6 +337,9 @@ class WasmGraphBuilder {
|
||||
if (buf != buffer) memcpy(buf, buffer, old_count * sizeof(Node*));
|
||||
return buf;
|
||||
}
|
||||
|
||||
int AddParameterNodes(Node** args, int pos, int param_count,
|
||||
wasm::FunctionSig* sig);
|
||||
};
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
|
Loading…
Reference in New Issue
Block a user