Commit eb65f35e authored by Aseem Garg's avatar Aseem Garg Committed by Commit Bot

[wasm] redirect wasm calls to js functions through a GCed table

With this patch, rather than embedding the JSReceiver address directly
in the WasmToJS wrappers, we put that in a fixed array with global handle
scope and instead embed the location of the handle and the index in the
wrapper. This ensures that the wrapper doesn't need to be patched if the
GC kicks in. This is needed to get the WASM code off the GCed heap.

R=mtrofin@chromium.org

Bug: 
Change-Id: Ie5a77a78cdecec51b04f702c63b8e4285e6a2d8d
Reviewed-on: https://chromium-review.googlesource.com/581682
Commit-Queue: Aseem Garg <aseemgarg@chromium.org>
Reviewed-by: 's avatarMircea Trofin <mtrofin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46884}
parent 4fe1d715
...@@ -2754,8 +2754,9 @@ int WasmGraphBuilder::AddParameterNodes(Node** args, int pos, int param_count, ...@@ -2754,8 +2754,9 @@ int WasmGraphBuilder::AddParameterNodes(Node** args, int pos, int param_count,
return pos; return pos;
} }
void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target, bool WasmGraphBuilder::BuildWasmToJSWrapper(
wasm::FunctionSig* sig) { Handle<JSReceiver> target, wasm::FunctionSig* sig,
Handle<FixedArray> global_js_imports_table, int index) {
DCHECK(target->IsCallable()); DCHECK(target->IsCallable());
int wasm_count = static_cast<int>(sig->parameter_count()); int wasm_count = static_cast<int>(sig->parameter_count());
...@@ -2777,7 +2778,7 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target, ...@@ -2777,7 +2778,7 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target,
// We don't need to return a value here, as the runtime call will not return // We don't need to return a value here, as the runtime call will not return
// anyway (the c entry stub will trigger stack unwinding). // anyway (the c entry stub will trigger stack unwinding).
ReturnVoid(); ReturnVoid();
return; return false;
} }
Node** args = Buffer(wasm_count + 7); Node** args = Buffer(wasm_count + 7);
...@@ -2786,11 +2787,31 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target, ...@@ -2786,11 +2787,31 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target,
BuildModifyThreadInWasmFlag(false); BuildModifyThreadInWasmFlag(false);
// We add the target function to a table and look it up during runtime. This
// ensures that if the GC kicks in, it doesn't need to patch the code for the
// JS function.
// js_imports_table is fixed array with global handle scope whose lifetime is
// tied to the instance.
// TODO(aseemgarg): explore using per-import global handle instead of a table
Node* js_table = jsgraph()->IntPtrConstant(
reinterpret_cast<intptr_t>(global_js_imports_table.location()));
Node* load_table = graph()->NewNode(
jsgraph()->machine()->Load(LoadRepresentation::TaggedPointer()), js_table,
jsgraph()->IntPtrConstant(0), *effect_, *control_);
*effect_ = load_table;
int offset =
global_js_imports_table->OffsetOfElementAt(index) - kHeapObjectTag;
Node* offset_node = jsgraph()->Int32Constant(offset);
Node* target_address = graph()->NewNode(
jsgraph()->machine()->Load(LoadRepresentation::TaggedPointer()),
load_table, offset_node, *effect_, *control_);
*effect_ = target_address;
if (target->IsJSFunction()) { if (target->IsJSFunction()) {
Handle<JSFunction> function = Handle<JSFunction>::cast(target); Handle<JSFunction> function = Handle<JSFunction>::cast(target);
if (function->shared()->internal_formal_parameter_count() == wasm_count) { if (function->shared()->internal_formal_parameter_count() == wasm_count) {
int pos = 0; int pos = 0;
args[pos++] = jsgraph()->Constant(target); // target callable. args[pos++] = target_address; // target callable.
// Receiver. // Receiver.
if (is_sloppy(function->shared()->language_mode()) && if (is_sloppy(function->shared()->language_mode()) &&
!function->shared()->native()) { !function->shared()->native()) {
...@@ -2822,7 +2843,7 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target, ...@@ -2822,7 +2843,7 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target,
int pos = 0; int pos = 0;
Callable callable = CodeFactory::Call(isolate); Callable callable = CodeFactory::Call(isolate);
args[pos++] = jsgraph()->HeapConstant(callable.code()); args[pos++] = jsgraph()->HeapConstant(callable.code());
args[pos++] = jsgraph()->Constant(target); // target callable args[pos++] = target_address; // target callable
args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count args[pos++] = jsgraph()->Int32Constant(wasm_count); // argument count
args[pos++] = jsgraph()->Constant( args[pos++] = jsgraph()->Constant(
handle(isolate->heap()->undefined_value(), isolate)); // receiver handle(isolate->heap()->undefined_value(), isolate)); // receiver
...@@ -2857,6 +2878,7 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target, ...@@ -2857,6 +2878,7 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target,
: FromJS(call, HeapConstant(isolate->native_context()), : FromJS(call, HeapConstant(isolate->native_context()),
sig->GetReturn()); sig->GetReturn());
Return(val); Return(val);
return true;
} }
void WasmGraphBuilder::BuildWasmInterpreterEntry( void WasmGraphBuilder::BuildWasmInterpreterEntry(
...@@ -3846,11 +3868,10 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, ...@@ -3846,11 +3868,10 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate,
return code; return code;
} }
Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target, Handle<Code> CompileWasmToJSWrapper(
wasm::FunctionSig* sig, uint32_t index, Isolate* isolate, Handle<JSReceiver> target, wasm::FunctionSig* sig,
Handle<String> module_name, uint32_t index, Handle<String> module_name, MaybeHandle<String> import_name,
MaybeHandle<String> import_name, wasm::ModuleOrigin origin, Handle<FixedArray> global_js_imports_table) {
wasm::ModuleOrigin origin) {
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Create the Graph // Create the Graph
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -3872,7 +3893,10 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target, ...@@ -3872,7 +3893,10 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target,
source_position_table); source_position_table);
builder.set_control_ptr(&control); builder.set_control_ptr(&control);
builder.set_effect_ptr(&effect); builder.set_effect_ptr(&effect);
builder.BuildWasmToJSWrapper(target, sig); if (builder.BuildWasmToJSWrapper(target, sig, global_js_imports_table,
index)) {
global_js_imports_table->set(index, *target);
}
Handle<Code> code = Handle<Code>::null(); Handle<Code> code = Handle<Code>::null();
{ {
...@@ -3906,6 +3930,18 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target, ...@@ -3906,6 +3930,18 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target,
CompilationInfo info(func_name, isolate, &zone, flags); CompilationInfo info(func_name, isolate, &zone, flags);
code = Pipeline::GenerateCodeForTesting(&info, incoming, &graph, nullptr, code = Pipeline::GenerateCodeForTesting(&info, incoming, &graph, nullptr,
source_position_table); source_position_table);
if (FLAG_wasm_interpret_all) {
Handle<FixedArray> deopt_data =
isolate->factory()->NewFixedArray(2, TENURED);
intptr_t loc =
reinterpret_cast<intptr_t>(global_js_imports_table.location());
Handle<Object> loc_handle =
isolate->factory()->NewHeapNumberFromBits(loc);
deopt_data->set(0, *loc_handle);
Handle<Object> index_handle = isolate->factory()->NewNumberFromInt(index);
deopt_data->set(1, *index_handle);
code->set_deoptimization_data(*deopt_data);
}
#ifdef ENABLE_DISASSEMBLER #ifdef ENABLE_DISASSEMBLER
if (FLAG_print_opt_code && !code.is_null()) { if (FLAG_print_opt_code && !code.is_null()) {
OFStream os(stdout); OFStream os(stdout);
......
...@@ -107,11 +107,15 @@ class WasmCompilationUnit final { ...@@ -107,11 +107,15 @@ class WasmCompilationUnit final {
}; };
// Wraps a JS function, producing a code object that can be called from wasm. // Wraps a JS function, producing a code object that can be called from wasm.
// The global_js_imports_table is a global handle to a fixed array of target
// JSReceiver with the lifetime tied to the module. We store it's location (non
// GCable) in the generated code so that it can reside outside of GCed heap.
Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target, Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target,
wasm::FunctionSig* sig, uint32_t index, wasm::FunctionSig* sig, uint32_t index,
Handle<String> module_name, Handle<String> module_name,
MaybeHandle<String> import_name, MaybeHandle<String> import_name,
wasm::ModuleOrigin origin); wasm::ModuleOrigin origin,
Handle<FixedArray> global_js_imports_table);
// Wraps a given wasm code object, producing a code object. // Wraps a given wasm code object, producing a code object.
Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, Handle<Code> CompileJSToWasmWrapper(Isolate* isolate,
...@@ -218,7 +222,9 @@ class WasmGraphBuilder { ...@@ -218,7 +222,9 @@ class WasmGraphBuilder {
wasm::WasmCodePosition position); wasm::WasmCodePosition position);
void BuildJSToWasmWrapper(Handle<Code> wasm_code, wasm::FunctionSig* sig); void BuildJSToWasmWrapper(Handle<Code> wasm_code, wasm::FunctionSig* sig);
void BuildWasmToJSWrapper(Handle<JSReceiver> target, wasm::FunctionSig* sig); bool BuildWasmToJSWrapper(Handle<JSReceiver> target, wasm::FunctionSig* sig,
Handle<FixedArray> global_js_imports_table,
int index);
void BuildWasmInterpreterEntry(uint32_t func_index, wasm::FunctionSig* sig, void BuildWasmInterpreterEntry(uint32_t func_index, wasm::FunctionSig* sig,
Handle<WasmInstanceObject> instance); Handle<WasmInstanceObject> instance);
......
...@@ -514,7 +514,8 @@ using WasmInstanceMap = ...@@ -514,7 +514,8 @@ using WasmInstanceMap =
Handle<Code> UnwrapOrCompileImportWrapper( Handle<Code> UnwrapOrCompileImportWrapper(
Isolate* isolate, int index, FunctionSig* sig, Handle<JSReceiver> target, Isolate* isolate, int index, FunctionSig* sig, Handle<JSReceiver> target,
Handle<String> module_name, MaybeHandle<String> import_name, Handle<String> module_name, MaybeHandle<String> import_name,
ModuleOrigin origin, WasmInstanceMap* imported_instances) { ModuleOrigin origin, WasmInstanceMap* imported_instances,
Handle<FixedArray> js_imports_table) {
WasmFunction* other_func = GetWasmFunctionForImportWrapper(isolate, target); WasmFunction* other_func = GetWasmFunctionForImportWrapper(isolate, target);
if (other_func) { if (other_func) {
if (!sig->Equals(other_func->sig)) return Handle<Code>::null(); if (!sig->Equals(other_func->sig)) return Handle<Code>::null();
...@@ -529,7 +530,8 @@ Handle<Code> UnwrapOrCompileImportWrapper( ...@@ -529,7 +530,8 @@ Handle<Code> UnwrapOrCompileImportWrapper(
// No wasm function or being debugged. Compile a new wrapper for the new // No wasm function or being debugged. Compile a new wrapper for the new
// signature. // signature.
return compiler::CompileWasmToJSWrapper(isolate, target, sig, index, return compiler::CompileWasmToJSWrapper(isolate, target, sig, index,
module_name, import_name, origin); module_name, import_name, origin,
js_imports_table);
} }
double MonotonicallyIncreasingTimeInMs() { double MonotonicallyIncreasingTimeInMs() {
...@@ -1265,6 +1267,13 @@ int InstanceBuilder::ProcessImports(Handle<FixedArray> code_table, ...@@ -1265,6 +1267,13 @@ int InstanceBuilder::ProcessImports(Handle<FixedArray> code_table,
Handle<WasmInstanceObject> instance) { Handle<WasmInstanceObject> instance) {
int num_imported_functions = 0; int num_imported_functions = 0;
int num_imported_tables = 0; int num_imported_tables = 0;
Handle<FixedArray> func_table = isolate_->factory()->NewFixedArray(
static_cast<int>(module_->import_table.size()), TENURED);
Handle<FixedArray> js_imports_table =
isolate_->global_handles()->Create(*func_table);
Handle<Foreign> js_imports_foreign = isolate_->factory()->NewForeign(
reinterpret_cast<Address>(js_imports_table.location()), TENURED);
instance->set_js_imports_table(*js_imports_foreign);
WasmInstanceMap imported_wasm_instances(isolate_->heap()); WasmInstanceMap imported_wasm_instances(isolate_->heap());
for (int index = 0; index < static_cast<int>(module_->import_table.size()); for (int index = 0; index < static_cast<int>(module_->import_table.size());
++index) { ++index) {
...@@ -1300,7 +1309,7 @@ int InstanceBuilder::ProcessImports(Handle<FixedArray> code_table, ...@@ -1300,7 +1309,7 @@ int InstanceBuilder::ProcessImports(Handle<FixedArray> code_table,
Handle<Code> import_wrapper = UnwrapOrCompileImportWrapper( Handle<Code> import_wrapper = UnwrapOrCompileImportWrapper(
isolate_, index, module_->functions[import.index].sig, isolate_, index, module_->functions[import.index].sig,
Handle<JSReceiver>::cast(value), module_name, import_name, Handle<JSReceiver>::cast(value), module_name, import_name,
module_->origin(), &imported_wasm_instances); module_->origin(), &imported_wasm_instances, js_imports_table);
if (import_wrapper.is_null()) { if (import_wrapper.is_null()) {
ReportLinkError("imported function does not match the expected type", ReportLinkError("imported function does not match the expected type",
index, module_name, import_name); index, module_name, import_name);
......
...@@ -634,23 +634,24 @@ const char* OpcodeName(uint32_t val) { ...@@ -634,23 +634,24 @@ const char* OpcodeName(uint32_t val) {
Handle<HeapObject> UnwrapWasmToJSWrapper(Isolate* isolate, Handle<HeapObject> UnwrapWasmToJSWrapper(Isolate* isolate,
Handle<Code> js_wrapper) { Handle<Code> js_wrapper) {
DCHECK_EQ(Code::WASM_TO_JS_FUNCTION, js_wrapper->kind()); DCHECK_EQ(Code::WASM_TO_JS_FUNCTION, js_wrapper->kind());
int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); Handle<FixedArray> deopt_data(js_wrapper->deoptimization_data(), isolate);
for (RelocIterator it(*js_wrapper, mask); !it.done(); it.next()) { DCHECK_EQ(2, deopt_data->length());
HeapObject* obj = it.rinfo()->target_object(); intptr_t js_imports_table_loc = static_cast<intptr_t>(
if (!obj->IsCallable()) continue; HeapNumber::cast(deopt_data->get(0))->value_as_bits());
#ifdef DEBUG Handle<FixedArray> js_imports_table(
// There should only be this one reference to a callable object. reinterpret_cast<FixedArray**>(js_imports_table_loc));
for (it.next(); !it.done(); it.next()) { int index = 0;
HeapObject* other = it.rinfo()->target_object(); CHECK(deopt_data->get(1)->ToInt32(&index));
DCHECK(!other->IsCallable()); DCHECK_GT(js_imports_table->length(), index);
} Handle<Object> obj(js_imports_table->get(index), isolate);
#endif if (obj->IsCallable()) {
return handle(obj, isolate); return Handle<HeapObject>::cast(obj);
} } else {
// If we did not find a callable object, then there must be a reference to // If we did not find a callable object, this is not from wasm and obj must
// the WasmThrowTypeError runtime function. // be undefined.
// TODO(clemensh): Check that this is the case. DCHECK(obj->IsUndefined(isolate));
return Handle<HeapObject>::null(); return Handle<HeapObject>::null();
}
} }
class SideTable; class SideTable;
......
...@@ -179,6 +179,9 @@ static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) { ...@@ -179,6 +179,9 @@ static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) {
TRACE_CHAIN(wasm_module->compiled_module()); TRACE_CHAIN(wasm_module->compiled_module());
TRACE("}\n"); TRACE("}\n");
} }
Foreign* js_imports_foreign = owner->js_imports_table();
GlobalHandles::Destroy(
reinterpret_cast<Object**>(js_imports_foreign->foreign_address()));
compiled_module->reset_weak_owning_instance(); compiled_module->reset_weak_owning_instance();
GlobalHandles::Destroy(reinterpret_cast<Object**>(p)); GlobalHandles::Destroy(reinterpret_cast<Object**>(p));
TRACE("}\n"); TRACE("}\n");
...@@ -399,7 +402,6 @@ void wasm::UpdateDispatchTables(Isolate* isolate, ...@@ -399,7 +402,6 @@ void wasm::UpdateDispatchTables(Isolate* isolate,
} }
} }
void wasm::TableSet(ErrorThrower* thrower, Isolate* isolate, void wasm::TableSet(ErrorThrower* thrower, Isolate* isolate,
Handle<WasmTableObject> table, int32_t index, Handle<WasmTableObject> table, int32_t index,
Handle<JSFunction> function) { Handle<JSFunction> function) {
......
...@@ -155,6 +155,7 @@ class WasmInstanceObject : public JSObject { ...@@ -155,6 +155,7 @@ class WasmInstanceObject : public JSObject {
DECL_OPTIONAL_ACCESSORS(debug_info, WasmDebugInfo) DECL_OPTIONAL_ACCESSORS(debug_info, WasmDebugInfo)
// FixedArray of all instances whose code was imported // FixedArray of all instances whose code was imported
DECL_OPTIONAL_ACCESSORS(directly_called_instances, FixedArray) DECL_OPTIONAL_ACCESSORS(directly_called_instances, FixedArray)
DECL_ACCESSORS(js_imports_table, Foreign)
enum { // -- enum { // --
kCompiledModuleIndex, kCompiledModuleIndex,
...@@ -163,6 +164,7 @@ class WasmInstanceObject : public JSObject { ...@@ -163,6 +164,7 @@ class WasmInstanceObject : public JSObject {
kGlobalsBufferIndex, kGlobalsBufferIndex,
kDebugInfoIndex, kDebugInfoIndex,
kDirectlyCalledInstancesIndex, kDirectlyCalledInstancesIndex,
kJsImportsTableIndex,
kFieldCount kFieldCount
}; };
...@@ -173,6 +175,7 @@ class WasmInstanceObject : public JSObject { ...@@ -173,6 +175,7 @@ class WasmInstanceObject : public JSObject {
DEF_OFFSET(GlobalsBuffer) DEF_OFFSET(GlobalsBuffer)
DEF_OFFSET(DebugInfo) DEF_OFFSET(DebugInfo)
DEF_OFFSET(DirectlyCalledInstances) DEF_OFFSET(DirectlyCalledInstances)
DEF_OFFSET(JsImportsTable)
WasmModuleObject* module_object(); WasmModuleObject* module_object();
V8_EXPORT_PRIVATE wasm::WasmModule* module(); V8_EXPORT_PRIVATE wasm::WasmModule* module();
...@@ -688,6 +691,7 @@ ACCESSORS(WasmInstanceObject, globals_buffer, JSArrayBuffer, ...@@ -688,6 +691,7 @@ ACCESSORS(WasmInstanceObject, globals_buffer, JSArrayBuffer,
ACCESSORS(WasmInstanceObject, debug_info, WasmDebugInfo, kDebugInfoOffset) ACCESSORS(WasmInstanceObject, debug_info, WasmDebugInfo, kDebugInfoOffset)
ACCESSORS(WasmInstanceObject, directly_called_instances, FixedArray, ACCESSORS(WasmInstanceObject, directly_called_instances, FixedArray,
kDirectlyCalledInstancesOffset) kDirectlyCalledInstancesOffset)
ACCESSORS(WasmInstanceObject, js_imports_table, Foreign, kJsImportsTableOffset)
// WasmSharedModuleData // WasmSharedModuleData
ACCESSORS(WasmSharedModuleData, module_bytes, SeqOneByteString, ACCESSORS(WasmSharedModuleData, module_bytes, SeqOneByteString,
......
...@@ -46,7 +46,8 @@ class PredictableInputValues { ...@@ -46,7 +46,8 @@ class PredictableInputValues {
} }
}; };
uint32_t AddJSSelector(TestingModule* module, FunctionSig* sig, int which) { uint32_t AddJSSelector(TestingModule* module, FunctionSig* sig, int which,
Handle<FixedArray> js_imports_table) {
const int kMaxParams = 11; const int kMaxParams = 11;
static const char* formals[kMaxParams] = {"", static const char* formals[kMaxParams] = {"",
"a", "a",
...@@ -67,7 +68,7 @@ uint32_t AddJSSelector(TestingModule* module, FunctionSig* sig, int which) { ...@@ -67,7 +68,7 @@ uint32_t AddJSSelector(TestingModule* module, FunctionSig* sig, int which) {
SNPrintF(source, "(function(%s) { return %c; })", SNPrintF(source, "(function(%s) { return %c; })",
formals[sig->parameter_count()], param); formals[sig->parameter_count()], param);
return module->AddJsFunction(sig, source.start()); return module->AddJsFunction(sig, source.start(), js_imports_table);
} }
void EXPECT_CALL(double expected, Handle<JSFunction> jsfunc, void EXPECT_CALL(double expected, Handle<JSFunction> jsfunc,
...@@ -136,8 +137,10 @@ TEST(Run_I32Popcount_jswrapped) { ...@@ -136,8 +137,10 @@ TEST(Run_I32Popcount_jswrapped) {
TEST(Run_CallJS_Add_jswrapped) { TEST(Run_CallJS_Add_jswrapped) {
WasmRunner<int, int> r(kExecuteCompiled); WasmRunner<int, int> r(kExecuteCompiled);
TestSignatures sigs; TestSignatures sigs;
uint32_t js_index = Handle<FixedArray> js_imports_table =
r.module().AddJsFunction(sigs.i_i(), "(function(a) { return a + 99; })"); r.main_isolate()->factory()->NewFixedArray(2, TENURED);
uint32_t js_index = r.module().AddJsFunction(
sigs.i_i(), "(function(a) { return a + 99; })", js_imports_table);
BUILD(r, WASM_CALL_FUNCTION(js_index, WASM_GET_LOCAL(0))); BUILD(r, WASM_CALL_FUNCTION(js_index, WASM_GET_LOCAL(0)));
Handle<JSFunction> jsfunc = r.module().WrapCode(r.function()->func_index); Handle<JSFunction> jsfunc = r.module().WrapCode(r.function()->func_index);
...@@ -158,7 +161,10 @@ void RunJSSelectTest(int which) { ...@@ -158,7 +161,10 @@ void RunJSSelectTest(int which) {
FunctionSig sig(1, num_params, types); FunctionSig sig(1, num_params, types);
WasmRunner<void> r(kExecuteCompiled); WasmRunner<void> r(kExecuteCompiled);
uint32_t js_index = AddJSSelector(&r.module(), &sig, which); Handle<FixedArray> js_imports_table =
scope.isolate()->factory()->NewFixedArray(2, TENURED);
uint32_t js_index =
AddJSSelector(&r.module(), &sig, which, js_imports_table);
WasmFunctionCompiler& t = r.NewFunction(&sig); WasmFunctionCompiler& t = r.NewFunction(&sig);
{ {
...@@ -416,7 +422,9 @@ void RunJSSelectAlignTest(int num_args, int num_params) { ...@@ -416,7 +422,9 @@ void RunJSSelectAlignTest(int num_args, int num_params) {
// Call different select JS functions. // Call different select JS functions.
for (int which = 0; which < num_params; which++) { for (int which = 0; which < num_params; which++) {
WasmRunner<void> r(kExecuteCompiled); WasmRunner<void> r(kExecuteCompiled);
uint32_t js_index = AddJSSelector(&r.module(), &sig, which); Handle<FixedArray> js_imports_table = factory->NewFixedArray(2, TENURED);
uint32_t js_index =
AddJSSelector(&r.module(), &sig, which, js_imports_table);
CHECK_EQ(predicted_js_index, js_index); CHECK_EQ(predicted_js_index, js_index);
WasmFunctionCompiler& t = r.NewFunction(&sig); WasmFunctionCompiler& t = r.NewFunction(&sig);
t.Build(&code[0], &code[end]); t.Build(&code[0], &code[end]);
......
...@@ -79,9 +79,12 @@ TEST(CollectDetailedWasmStack_ExplicitThrowFromJs) { ...@@ -79,9 +79,12 @@ TEST(CollectDetailedWasmStack_ExplicitThrowFromJs) {
WasmRunner<void> r(kExecuteCompiled); WasmRunner<void> r(kExecuteCompiled);
TestSignatures sigs; TestSignatures sigs;
Handle<FixedArray> js_imports_table =
r.main_isolate()->factory()->NewFixedArray(2, TENURED);
uint32_t js_throwing_index = r.module().AddJsFunction( uint32_t js_throwing_index = r.module().AddJsFunction(
sigs.v_v(), sigs.v_v(),
"(function js() {\n function a() {\n throw new Error(); };\n a(); })"); "(function js() {\n function a() {\n throw new Error(); };\n a(); })",
js_imports_table);
// Add a nop such that we don't always get position 1. // Add a nop such that we don't always get position 1.
BUILD(r, WASM_NOP, WASM_CALL_FUNCTION0(js_throwing_index)); BUILD(r, WASM_NOP, WASM_CALL_FUNCTION0(js_throwing_index));
......
...@@ -209,13 +209,14 @@ class TestingModule : public ModuleEnv { ...@@ -209,13 +209,14 @@ class TestingModule : public ModuleEnv {
return index; return index;
} }
uint32_t AddJsFunction(FunctionSig* sig, const char* source) { uint32_t AddJsFunction(FunctionSig* sig, const char* source,
Handle<FixedArray> js_imports_table) {
Handle<JSFunction> jsfunc = Handle<JSFunction>::cast(v8::Utils::OpenHandle( Handle<JSFunction> jsfunc = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
*v8::Local<v8::Function>::Cast(CompileRun(source)))); *v8::Local<v8::Function>::Cast(CompileRun(source))));
uint32_t index = AddFunction(sig, Handle<Code>::null(), nullptr); uint32_t index = AddFunction(sig, Handle<Code>::null(), nullptr);
Handle<Code> code = CompileWasmToJSWrapper( Handle<Code> code = CompileWasmToJSWrapper(
isolate_, jsfunc, sig, index, Handle<String>::null(), isolate_, jsfunc, sig, index, Handle<String>::null(),
Handle<String>::null(), module->origin()); Handle<String>::null(), module->origin(), js_imports_table);
instance->function_code[index] = code; instance->function_code[index] = code;
return index; return index;
} }
......
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