Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Unified Diff: src/compiler/wasm-compiler.cc

Issue 2208703002: [wasm] Allow import function to be any kind of callables. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/runtime/runtime.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/wasm-compiler.cc
diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc
index 324d3bea003c73145a5eae7150bb739c21f1a31c..b457efec4ec3e0e34ddd7305b16f1539a29fc631 100644
--- a/src/compiler/wasm-compiler.cc
+++ b/src/compiler/wasm-compiler.cc
@@ -2182,7 +2182,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);
@@ -2515,18 +2515,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()) {
@@ -2541,61 +2541,71 @@ 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;
+ // The default context of the target.
+ Handle<Context> target_context = isolate->native_context();
+ // 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 (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 {
- // Use the Call builtin.
+ if (target->IsJSFunction()) {
+ Handle<JSFunction> function = Handle<JSFunction>::cast(target);
+ if (function->shared()->internal_formal_parameter_count() == wasm_count) {
+ call_direct = true;
+
+ args[pos++] = jsgraph()->Constant(target); // target callable.
+ // Receiver.
+ if (is_sloppy(function->shared()->language_mode()) &&
+ !function->shared()->native()) {
+ args[pos++] =
+ HeapConstant(handle(function->context()->global_proxy(), isolate));
+ } else {
+ args[pos++] = jsgraph()->Constant(
+ handle(isolate->heap()->undefined_value(), isolate));
+ }
+
+ 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());
+ }
+ }
+
+ // We cannot call the target directly, we have to use the Call builtin.
+ if (!call_direct) {
Callable callable = CodeFactory::Call(isolate);
args[pos++] = jsgraph()->HeapConstant(callable.code());
+ args[pos++] = jsgraph()->Constant(target); // target callable
+ args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count
+ args[pos++] = jsgraph()->Constant(
+ handle(isolate->heap()->undefined_value(), isolate)); // receiver
+
desc = Linkage::GetStubCallDescriptor(isolate, graph()->zone(),
callable.descriptor(), wasm_count + 1,
CallDescriptor::kNoFlags);
- arg_count_before_args = true;
}
- args[pos++] = jsgraph()->Constant(function); // JS function.
- 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);
- }
- 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++;
}
}
- if (add_new_target_undefined) {
+ if (call_direct) {
args[pos++] = jsgraph()->UndefinedConstant(); // new target
- }
-
- if (!arg_count_before_args) {
args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count
}
- args[pos++] = context;
+
+ args[pos++] = HeapConstant(target_context);
args[pos++] = *effect_;
args[pos++] = *control_;
@@ -2604,7 +2614,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) {
@@ -2960,8 +2970,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) {
@@ -2980,7 +2989,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();
{
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/runtime/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698