Commit 89f52f8a authored by Ben L. Titzer's avatar Ben L. Titzer Committed by Commit Bot

[wasm] Load formal_param_count for mismatched import calls

For WASM import calls to JSFunctions where the arity is mismatched,
we currently generate code that inlines the formal parameter count
of the target function as a constant in a call to the arguments
adapter. This CL changes this to generate code that loads the formal
parameter count from the function at runtime in order to permit
more sharing later.

R=mstarzinger@chromium.org
CC=clemensh@chromium.org

Change-Id: I5cce97fc338f6468f9d42d48f5bc860b25fb7d73
Reviewed-on: https://chromium-review.googlesource.com/1243108
Commit-Queue: Ben Titzer <titzer@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56220}
parent 274aecdd
...@@ -4387,8 +4387,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4387,8 +4387,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
Node* BuildLoadFunctionDataFromExportedFunction(Node* closure) { Node* BuildLoadFunctionDataFromExportedFunction(Node* closure) {
Node* shared = SetEffect(graph()->NewNode( Node* shared = SetEffect(graph()->NewNode(
jsgraph()->machine()->Load(MachineType::AnyTagged()), closure, jsgraph()->machine()->Load(MachineType::AnyTagged()), closure,
jsgraph()->Int32Constant(JSFunction::kSharedFunctionInfoOffset - jsgraph()->Int32Constant(
kHeapObjectTag), wasm::ObjectAccess::SharedFunctionInfoOffsetInTaggedJSFunction()),
Effect(), Control())); Effect(), Control()));
return SetEffect(graph()->NewNode( return SetEffect(graph()->NewNode(
jsgraph()->machine()->Load(MachineType::AnyTagged()), shared, jsgraph()->machine()->Load(MachineType::AnyTagged()), shared,
...@@ -4502,8 +4502,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4502,8 +4502,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
Return(jsval); Return(jsval);
} }
bool BuildWasmImportCallWrapper(WasmImportCallKind kind, int func_index, bool BuildWasmImportCallWrapper(WasmImportCallKind kind, int func_index) {
int formal_param_count) {
int wasm_count = static_cast<int>(sig_->parameter_count()); int wasm_count = static_cast<int>(sig_->parameter_count());
// Build the start and the parameter nodes. // Build the start and the parameter nodes.
...@@ -4600,7 +4599,24 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -4600,7 +4599,24 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
args[pos++] = callable_node; // target callable args[pos++] = callable_node; // target callable
args[pos++] = undefined_node; // new target args[pos++] = undefined_node; // new target
args[pos++] = mcgraph()->Int32Constant(wasm_count); // argument count args[pos++] = mcgraph()->Int32Constant(wasm_count); // argument count
args[pos++] = mcgraph()->Int32Constant(formal_param_count);
// Load shared function info, and then the formal parameter count.
Node* shared_function_info = SetEffect(graph()->NewNode(
mcgraph()->machine()->Load(MachineType::TaggedPointer()),
callable_node,
mcgraph()->Int32Constant(
wasm::ObjectAccess::
SharedFunctionInfoOffsetInTaggedJSFunction()),
Effect(), Control()));
Node* formal_param_count = SetEffect(graph()->NewNode(
mcgraph()->machine()->Load(MachineType::Uint16()),
shared_function_info,
mcgraph()->Int32Constant(
wasm::ObjectAccess::
FormalParameterCountOffsetInSharedFunctionInfo()),
Effect(), Control()));
args[pos++] = formal_param_count;
// Receiver. // Receiver.
if (sloppy_receiver) { if (sloppy_receiver) {
Node* global_proxy = LOAD_FIXED_ARRAY_SLOT( Node* global_proxy = LOAD_FIXED_ARRAY_SLOT(
...@@ -4936,8 +4952,8 @@ WasmImportCallKind GetWasmImportCallKind(Handle<JSReceiver> target, ...@@ -4936,8 +4952,8 @@ WasmImportCallKind GetWasmImportCallKind(Handle<JSReceiver> target,
} }
MaybeHandle<Code> CompileWasmImportCallWrapper( MaybeHandle<Code> CompileWasmImportCallWrapper(
Isolate* isolate, WasmImportCallKind kind, Handle<JSReceiver> js_receiver, Isolate* isolate, WasmImportCallKind kind, wasm::FunctionSig* sig,
wasm::FunctionSig* sig, uint32_t index, wasm::ModuleOrigin origin, uint32_t index, wasm::ModuleOrigin origin,
wasm::UseTrapHandler use_trap_handler) { wasm::UseTrapHandler use_trap_handler) {
DCHECK_NE(WasmImportCallKind::kLinkError, kind); DCHECK_NE(WasmImportCallKind::kLinkError, kind);
DCHECK_NE(WasmImportCallKind::kWasmToWasm, kind); DCHECK_NE(WasmImportCallKind::kWasmToWasm, kind);
...@@ -4971,13 +4987,7 @@ MaybeHandle<Code> CompileWasmImportCallWrapper( ...@@ -4971,13 +4987,7 @@ MaybeHandle<Code> CompileWasmImportCallWrapper(
StubCallMode::kCallWasmRuntimeStub); StubCallMode::kCallWasmRuntimeStub);
builder.set_control_ptr(&control); builder.set_control_ptr(&control);
builder.set_effect_ptr(&effect); builder.set_effect_ptr(&effect);
// TODO(titzer): gen code to load the formal param count from the callable. builder.BuildWasmImportCallWrapper(kind, index);
int formal_param_count = js_receiver->IsJSFunction()
? JSFunction::cast(*js_receiver)
->shared()
->internal_formal_parameter_count()
: static_cast<int>(sig->parameter_count());
builder.BuildWasmImportCallWrapper(kind, index, formal_param_count);
EmbeddedVector<char, 32> func_name; EmbeddedVector<char, 32> func_name;
func_name.Truncate(SNPrintF(func_name, "wasm-to-js#%d", index)); func_name.Truncate(SNPrintF(func_name, "wasm-to-js#%d", index));
......
...@@ -86,9 +86,11 @@ WasmImportCallKind GetWasmImportCallKind(Handle<JSReceiver> callable, ...@@ -86,9 +86,11 @@ WasmImportCallKind GetWasmImportCallKind(Handle<JSReceiver> callable,
wasm::FunctionSig* sig); wasm::FunctionSig* sig);
// Compiles an import call wrapper, which allows WASM to call imports. // Compiles an import call wrapper, which allows WASM to call imports.
MaybeHandle<Code> CompileWasmImportCallWrapper( MaybeHandle<Code> CompileWasmImportCallWrapper(Isolate*, WasmImportCallKind,
Isolate*, WasmImportCallKind, Handle<JSReceiver>, wasm::FunctionSig*, wasm::FunctionSig*,
uint32_t index, wasm::ModuleOrigin, wasm::UseTrapHandler); uint32_t index,
wasm::ModuleOrigin,
wasm::UseTrapHandler);
// Creates a code object calling a wasm function with the given signature, // Creates a code object calling a wasm function with the given signature,
// callable from JS. // callable from JS.
......
...@@ -1518,8 +1518,8 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) { ...@@ -1518,8 +1518,8 @@ int InstanceBuilder::ProcessImports(Handle<WasmInstanceObject> instance) {
// The imported function is a callable. // The imported function is a callable.
Handle<Code> wrapper_code = Handle<Code> wrapper_code =
compiler::CompileWasmImportCallWrapper( compiler::CompileWasmImportCallWrapper(
isolate_, kind, js_receiver, expected_sig, func_index, isolate_, kind, expected_sig, func_index, module_->origin,
module_->origin, use_trap_handler()) use_trap_handler())
.ToHandleChecked(); .ToHandleChecked();
RecordStats(*wrapper_code, isolate_->counters()); RecordStats(*wrapper_code, isolate_->counters());
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "src/globals.h" #include "src/globals.h"
#include "src/objects/fixed-array.h" #include "src/objects/fixed-array.h"
#include "src/objects/js-objects.h" #include "src/objects/js-objects.h"
#include "src/objects/shared-function-info.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -27,6 +28,17 @@ class ObjectAccess : public AllStatic { ...@@ -27,6 +28,17 @@ class ObjectAccess : public AllStatic {
static constexpr int ContextOffsetInTaggedJSFunction() { static constexpr int ContextOffsetInTaggedJSFunction() {
return ToTagged(JSFunction::kContextOffset); return ToTagged(JSFunction::kContextOffset);
} }
// Get the offset of the shared function info in a {JSFunction} object.
static constexpr int SharedFunctionInfoOffsetInTaggedJSFunction() {
return ToTagged(JSFunction::kSharedFunctionInfoOffset);
}
// Get the offset of the formal parameter count in a {SharedFunctionInfo}
// object.
static constexpr int FormalParameterCountOffsetInSharedFunctionInfo() {
return ToTagged(SharedFunctionInfo::kFormalParameterCountOffset);
}
}; };
} // namespace wasm } // namespace wasm
......
...@@ -44,8 +44,8 @@ TestingModuleBuilder::TestingModuleBuilder( ...@@ -44,8 +44,8 @@ TestingModuleBuilder::TestingModuleBuilder(
auto kind = compiler::GetWasmImportCallKind(maybe_import->js_function, auto kind = compiler::GetWasmImportCallKind(maybe_import->js_function,
maybe_import->sig); maybe_import->sig);
MaybeHandle<Code> code = compiler::CompileWasmImportCallWrapper( MaybeHandle<Code> code = compiler::CompileWasmImportCallWrapper(
isolate_, kind, maybe_import->js_function, maybe_import->sig, isolate_, kind, maybe_import->sig, maybe_import_index,
maybe_import_index, test_module_->origin, test_module_->origin,
trap_handler::IsTrapHandlerEnabled() ? kUseTrapHandler trap_handler::IsTrapHandlerEnabled() ? kUseTrapHandler
: kNoTrapHandler); : kNoTrapHandler);
auto wasm_to_js_wrapper = native_module_->AddImportWrapper( auto wasm_to_js_wrapper = native_module_->AddImportWrapper(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment