[wasm] Drop suspender param in wasm-to-JS wrapper
The suspender is only needed by the wrapper, do not forward it to the JS import. R=ahaas@chromium.org Bug: v8:12191 Change-Id: Id8e9a820491588b40fffb5dfd8706e85a16b8b23 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3768410 Reviewed-by: Andreas Haas <ahaas@chromium.org> Commit-Queue: Thibaud Michaud <thibaudm@chromium.org> Cr-Commit-Position: refs/heads/main@{#81818}
This commit is contained in:
parent
f7a73d8ba8
commit
5c02c29097
@ -6275,12 +6275,14 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
}
|
||||
|
||||
int AddArgumentNodes(base::Vector<Node*> args, int pos, int param_count,
|
||||
const wasm::FunctionSig* sig, Node* context) {
|
||||
const wasm::FunctionSig* sig, Node* context,
|
||||
wasm::Suspend suspend) {
|
||||
// Convert wasm numbers to JS values.
|
||||
for (int i = 0; i < param_count; ++i) {
|
||||
Node* param =
|
||||
Param(i + 1); // Start from index 1 to drop the instance_node.
|
||||
args[pos++] = ToJS(param, sig->GetParam(i), context);
|
||||
// Drop the instance node, and possibly the suspender node.
|
||||
int param_offset = 1 + suspend;
|
||||
for (int i = 0; i < param_count - suspend; ++i) {
|
||||
Node* param = Param(i + param_offset);
|
||||
args[pos++] = ToJS(param, sig->GetParam(i + suspend), context);
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
@ -7060,7 +7062,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
// === JS Functions with matching arity ==================================
|
||||
// =======================================================================
|
||||
case WasmImportCallKind::kJSFunctionArityMatch: {
|
||||
base::SmallVector<Node*, 16> args(wasm_count + 7);
|
||||
base::SmallVector<Node*, 16> args(wasm_count + 7 - suspend);
|
||||
int pos = 0;
|
||||
Node* function_context =
|
||||
gasm_->LoadContextFromJSFunction(callable_node);
|
||||
@ -7071,15 +7073,16 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
BuildReceiverNode(callable_node, native_context, undefined_node);
|
||||
|
||||
auto call_descriptor = Linkage::GetJSCallDescriptor(
|
||||
graph()->zone(), false, wasm_count + 1, CallDescriptor::kNoFlags);
|
||||
graph()->zone(), false, wasm_count + 1 - suspend,
|
||||
CallDescriptor::kNoFlags);
|
||||
|
||||
// Convert wasm numbers to JS values.
|
||||
pos = AddArgumentNodes(base::VectorOf(args), pos, wasm_count, sig_,
|
||||
native_context);
|
||||
native_context, suspend);
|
||||
|
||||
args[pos++] = undefined_node; // new target
|
||||
args[pos++] =
|
||||
Int32Constant(JSParameterCount(wasm_count)); // argument count
|
||||
args[pos++] = Int32Constant(
|
||||
JSParameterCount(wasm_count - suspend)); // argument count
|
||||
args[pos++] = function_context;
|
||||
args[pos++] = effect();
|
||||
args[pos++] = control();
|
||||
@ -7095,7 +7098,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
// === JS Functions with mismatching arity ===============================
|
||||
// =======================================================================
|
||||
case WasmImportCallKind::kJSFunctionArityMismatch: {
|
||||
int pushed_count = std::max(expected_arity, wasm_count);
|
||||
int pushed_count = std::max(expected_arity, wasm_count - suspend);
|
||||
base::SmallVector<Node*, 16> args(pushed_count + 7);
|
||||
int pos = 0;
|
||||
|
||||
@ -7106,13 +7109,13 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
|
||||
// Convert wasm numbers to JS values.
|
||||
pos = AddArgumentNodes(base::VectorOf(args), pos, wasm_count, sig_,
|
||||
native_context);
|
||||
for (int i = wasm_count; i < expected_arity; ++i) {
|
||||
native_context, suspend);
|
||||
for (int i = wasm_count - suspend; i < expected_arity; ++i) {
|
||||
args[pos++] = undefined_node;
|
||||
}
|
||||
args[pos++] = undefined_node; // new target
|
||||
args[pos++] =
|
||||
Int32Constant(JSParameterCount(wasm_count)); // argument count
|
||||
args[pos++] = Int32Constant(
|
||||
JSParameterCount(wasm_count - suspend)); // argument count
|
||||
|
||||
Node* function_context =
|
||||
gasm_->LoadContextFromJSFunction(callable_node);
|
||||
@ -7133,23 +7136,23 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
// === General case of unknown callable ==================================
|
||||
// =======================================================================
|
||||
case WasmImportCallKind::kUseCallBuiltin: {
|
||||
base::SmallVector<Node*, 16> args(wasm_count + 7);
|
||||
base::SmallVector<Node*, 16> args(wasm_count + 7 - suspend);
|
||||
int pos = 0;
|
||||
args[pos++] =
|
||||
gasm_->GetBuiltinPointerTarget(Builtin::kCall_ReceiverIsAny);
|
||||
args[pos++] = callable_node;
|
||||
args[pos++] =
|
||||
Int32Constant(JSParameterCount(wasm_count)); // argument count
|
||||
args[pos++] = Int32Constant(
|
||||
JSParameterCount(wasm_count - suspend)); // argument count
|
||||
args[pos++] = undefined_node; // receiver
|
||||
|
||||
auto call_descriptor = Linkage::GetStubCallDescriptor(
|
||||
graph()->zone(), CallTrampolineDescriptor{}, wasm_count + 1,
|
||||
CallDescriptor::kNoFlags, Operator::kNoProperties,
|
||||
StubCallMode::kCallBuiltinPointer);
|
||||
graph()->zone(), CallTrampolineDescriptor{},
|
||||
wasm_count + 1 - suspend, CallDescriptor::kNoFlags,
|
||||
Operator::kNoProperties, StubCallMode::kCallBuiltinPointer);
|
||||
|
||||
// Convert wasm numbers to JS values.
|
||||
pos = AddArgumentNodes(base::VectorOf(args), pos, wasm_count, sig_,
|
||||
native_context);
|
||||
native_context, suspend);
|
||||
|
||||
// The native_context is sufficient here, because all kind of callables
|
||||
// which depend on the context provide their own context. The context
|
||||
@ -7450,7 +7453,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
|
||||
|
||||
// Convert wasm numbers to JS values.
|
||||
pos = AddArgumentNodes(base::VectorOf(args), pos, wasm_count, sig_,
|
||||
native_context);
|
||||
native_context, wasm::kNoSuspend);
|
||||
|
||||
// The native_context is sufficient here, because all kind of
|
||||
// callables which depend on the context provide their own context.
|
||||
@ -7934,7 +7937,7 @@ WasmImportData ResolveWasmImportCall(
|
||||
}
|
||||
|
||||
if (shared->internal_formal_parameter_count_without_receiver() ==
|
||||
expected_sig->parameter_count()) {
|
||||
expected_sig->parameter_count() - suspend) {
|
||||
return {WasmImportCallKind::kJSFunctionArityMatch, callable, suspend};
|
||||
}
|
||||
|
||||
|
@ -1692,6 +1692,7 @@ Handle<WasmJSFunctionData> Factory::NewWasmJSFunctionData(
|
||||
result.set_serialized_return_count(return_count);
|
||||
result.set_serialized_parameter_count(parameter_count);
|
||||
result.set_serialized_signature(*serialized_sig);
|
||||
result.set_suspend(suspend);
|
||||
return handle(result, isolate());
|
||||
}
|
||||
|
||||
|
@ -2036,6 +2036,22 @@ void WebAssemblyFunctionType(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
}
|
||||
} else if (i::WasmJSFunction::IsWasmJSFunction(*arg0)) {
|
||||
sig = i::Handle<i::WasmJSFunction>::cast(arg0)->GetSignature(&zone);
|
||||
auto wasm_js_function = i::Handle<i::WasmJSFunction>::cast(arg0);
|
||||
if (wasm_js_function->shared().wasm_js_function_data().suspend()) {
|
||||
// If this function is the result of calling
|
||||
// WebAssembly.suspendOnReturnedPromise(), it takes an extra suspender
|
||||
// parameter which will be consumed by the wasm-to-JS wrapper.
|
||||
size_t param_count = sig->parameter_count();
|
||||
i::wasm::FunctionSig::Builder builder(&zone, 1, param_count + 1);
|
||||
builder.AddParam(internal::wasm::kWasmAnyRef);
|
||||
for (size_t i = 0; i < param_count; ++i) {
|
||||
builder.AddParam(sig->GetParam(i));
|
||||
}
|
||||
DCHECK_EQ(1, sig->return_count());
|
||||
DCHECK_EQ(i::wasm::kWasmAnyRef, sig->GetReturn(0));
|
||||
builder.AddReturn(i::wasm::kWasmAnyRef);
|
||||
sig = builder.Build();
|
||||
}
|
||||
} else {
|
||||
thrower.TypeError("Argument 0 must be a WebAssembly.Function");
|
||||
return;
|
||||
@ -2781,11 +2797,6 @@ void WebAssemblySuspendOnReturnedPromise(
|
||||
return;
|
||||
}
|
||||
sig = i::Handle<i::WasmJSFunction>::cast(arg0)->GetSignature(&zone);
|
||||
if (sig->parameter_count() == 0 || sig->GetParam(0) != i::wasm::kWasmAnyRef) {
|
||||
thrower.TypeError("Expected at least one parameter of type %s",
|
||||
i::wasm::kWasmAnyRef.name().c_str());
|
||||
return;
|
||||
}
|
||||
if (sig->return_count() != 1 || sig->GetReturn(0) != i::wasm::kWasmAnyRef) {
|
||||
thrower.TypeError("Expected a WebAssembly.Function with return type %s",
|
||||
i::wasm::kWasmAnyRef.name().c_str());
|
||||
|
@ -2165,22 +2165,22 @@ bool WasmJSFunction::MatchesSignatureForSuspend(const wasm::FunctionSig* sig) {
|
||||
DCHECK_LE(sig->all().size(), kMaxInt);
|
||||
int sig_size = static_cast<int>(sig->all().size());
|
||||
int parameter_count = static_cast<int>(sig->parameter_count());
|
||||
int return_count = static_cast<int>(sig->return_count());
|
||||
DisallowHeapAllocation no_alloc;
|
||||
WasmJSFunctionData function_data = shared().wasm_js_function_data();
|
||||
if (parameter_count != function_data.serialized_parameter_count()) {
|
||||
// The suspender parameter is not forwarded to the JS function so the
|
||||
// parameter count should differ by one.
|
||||
if (parameter_count != function_data.serialized_parameter_count() + 1) {
|
||||
return false;
|
||||
}
|
||||
if (sig_size == 0) return true; // Prevent undefined behavior.
|
||||
// This function is only called for functions wrapped by a
|
||||
// WebAssembly.Suspender object, so the return type has to be externref.
|
||||
// This function is only called for functions wrapped by
|
||||
// WebAssembly.suspendOnReturnedPromise, so the return type has to be
|
||||
// externref.
|
||||
CHECK_EQ(function_data.serialized_return_count(), 1);
|
||||
CHECK_EQ(function_data.serialized_signature().get(0), wasm::kWasmAnyRef);
|
||||
CHECK_GE(sig->parameter_count(), 1);
|
||||
CHECK_EQ(sig->GetParam(0), wasm::kWasmAnyRef);
|
||||
const wasm::ValueType* expected = sig->all().begin();
|
||||
return function_data.serialized_signature().matches(
|
||||
1, expected + return_count, parameter_count);
|
||||
const wasm::ValueType* expected = sig->parameters().begin() + 1;
|
||||
return function_data.serialized_signature().matches(1, expected,
|
||||
parameter_count - 1);
|
||||
}
|
||||
|
||||
// TODO(9495): Update this if function type variance is introduced.
|
||||
|
@ -76,6 +76,9 @@ extern class WasmJSFunctionData extends WasmFunctionData {
|
||||
serialized_return_count: Smi;
|
||||
serialized_parameter_count: Smi;
|
||||
serialized_signature: PodArrayOfWasmValueType;
|
||||
// Whether this function is the result of wrapping another function with
|
||||
// WebAssembly.suspendOnReturnedPromise.
|
||||
suspend: Smi;
|
||||
}
|
||||
|
||||
extern class WasmCapiFunctionData extends WasmFunctionData {
|
||||
|
@ -20,7 +20,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
let builder = new WasmModuleBuilder();
|
||||
let sig_i_ri = makeSig([kWasmExternRef, kWasmI32], [kWasmI32]);
|
||||
let sig_ii_r = makeSig([kWasmExternRef], [kWasmI32, kWasmI32]);
|
||||
let sig_v_ri = makeSig([kWasmExternRef, kWasmI32], [kWasmI32]);
|
||||
let sig_v_ri = makeSig([kWasmExternRef, kWasmI32], []);
|
||||
builder.addImport('m', 'import', sig_v_ri);
|
||||
builder.addFunction("export", sig_i_ri)
|
||||
.addBody([kExprLocalGet, 1]).exportFunc();
|
||||
@ -31,13 +31,13 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
builder.addFunction("wrong3", kSig_i_v)
|
||||
.addBody([kExprI32Const, 0]).exportFunc();
|
||||
let suspender = new WebAssembly.Suspender();
|
||||
function js_import(suspender, i) {
|
||||
function js_import(i) {
|
||||
return Promise.resolve(42);
|
||||
}
|
||||
|
||||
// Wrap the import, instantiate the module, and wrap the export.
|
||||
let wasm_js_import = new WebAssembly.Function(
|
||||
{parameters: ['externref', 'i32'], results: ['externref']}, js_import);
|
||||
{parameters: ['i32'], results: ['externref']}, js_import);
|
||||
let import_wrapper = WebAssembly.suspendOnReturnedPromise(wasm_js_import);
|
||||
let instance = builder.instantiate({'m': {'import': import_wrapper}});
|
||||
let export_wrapper =
|
||||
@ -48,12 +48,6 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
{parameters: ['externref'], results: ['i32']}, js_import);
|
||||
assertThrows(() => WebAssembly.suspendOnReturnedPromise(wasm_js_import),
|
||||
TypeError, /Expected a WebAssembly.Function with return type externref/);
|
||||
assertThrows(() => WebAssembly.suspendOnReturnedPromise(
|
||||
new WebAssembly.Function(
|
||||
{parameters: ['i32'], results: ['externref']},
|
||||
() => {})),
|
||||
TypeError,
|
||||
/Expected at least one parameter of type externref/);
|
||||
assertThrows(() => WebAssembly.returnPromiseOnSuspend(instance.exports.wrong1),
|
||||
TypeError,
|
||||
/Expected a WebAssembly.Function with exactly one return type/);
|
||||
@ -122,7 +116,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
]).exportFunc();
|
||||
let js_import = WebAssembly.suspendOnReturnedPromise(
|
||||
new WebAssembly.Function(
|
||||
{parameters: ['externref'], results: ['externref']},
|
||||
{parameters: [], results: ['externref']},
|
||||
() => Promise.resolve(42)));
|
||||
let instance = builder.instantiate({m: {import: js_import}});
|
||||
let wrapped_export = WebAssembly.returnPromiseOnSuspend(instance.exports.test);
|
||||
@ -133,7 +127,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
// Also try with a JS function with a mismatching arity.
|
||||
js_import = WebAssembly.suspendOnReturnedPromise(
|
||||
new WebAssembly.Function(
|
||||
{parameters: ['externref'], results: ['externref']},
|
||||
{parameters: [], results: ['externref']},
|
||||
(unused) => Promise.resolve(42)));
|
||||
instance = builder.instantiate({m: {import: js_import}});
|
||||
wrapped_export = WebAssembly.returnPromiseOnSuspend(instance.exports.test);
|
||||
@ -144,7 +138,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
// Also try with a proxy.
|
||||
js_import = WebAssembly.suspendOnReturnedPromise(
|
||||
new WebAssembly.Function(
|
||||
{parameters: ['externref'], results: ['externref']},
|
||||
{parameters: [], results: ['externref']},
|
||||
new Proxy(() => Promise.resolve(42), {})));
|
||||
instance = builder.instantiate({m: {import: js_import}});
|
||||
wrapped_export = WebAssembly.returnPromiseOnSuspend(instance.exports.test);
|
||||
@ -189,7 +183,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
return Promise.resolve(++i);
|
||||
};
|
||||
let wasm_js_import = new WebAssembly.Function(
|
||||
{parameters: ['externref'], results: ['externref']}, js_import);
|
||||
{parameters: [], results: ['externref']}, js_import);
|
||||
let suspending_wasm_js_import =
|
||||
WebAssembly.suspendOnReturnedPromise(wasm_js_import);
|
||||
let instance = builder.instantiate({m: {import: suspending_wasm_js_import}});
|
||||
@ -212,8 +206,8 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
let suspender = new WebAssembly.Suspender();
|
||||
let js_import = WebAssembly.suspendOnReturnedPromise(
|
||||
new WebAssembly.Function(
|
||||
{parameters: ['externref'], results: ['externref']},
|
||||
suspender => gc()));
|
||||
{parameters: [], results: ['externref']},
|
||||
gc));
|
||||
let instance = builder.instantiate({'m': {'gc': js_import}});
|
||||
let wrapper = WebAssembly.returnPromiseOnSuspend(instance.exports.test);
|
||||
wrapper(suspender);
|
||||
@ -237,7 +231,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
function js_import(suspender) {
|
||||
return 42
|
||||
};
|
||||
let wasm_js_import = new WebAssembly.Function({parameters: ['externref'], results: ['externref']}, js_import);
|
||||
let wasm_js_import = new WebAssembly.Function({parameters: [], results: ['externref']}, js_import);
|
||||
let suspending_wasm_js_import = WebAssembly.suspendOnReturnedPromise(wasm_js_import);
|
||||
let instance = builder.instantiate({m: {import: suspending_wasm_js_import}});
|
||||
let wrapped_export = WebAssembly.returnPromiseOnSuspend(instance.exports.test);
|
||||
@ -265,11 +259,11 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
kExprCallFunction, import_index, // suspend
|
||||
]).exportFunc();
|
||||
let suspender = new WebAssembly.Suspender();
|
||||
function js_import(suspender, i1, i2, i3, i4, i5, i6, f1, f2, f3, f4, f5, f6, f7) {
|
||||
return Promise.resolve(reduce(Array.from(arguments).slice(1)));
|
||||
function js_import(i1, i2, i3, i4, i5, i6, f1, f2, f3, f4, f5, f6, f7) {
|
||||
return Promise.resolve(reduce(Array.from(arguments)));
|
||||
};
|
||||
let wasm_js_import = new WebAssembly.Function(
|
||||
{parameters: ['externref', 'i32', 'i32', 'i32', 'i32', 'i32', 'i32', 'f32', 'f32',
|
||||
{parameters: ['i32', 'i32', 'i32', 'i32', 'i32', 'i32', 'f32', 'f32',
|
||||
'f32', 'f32', 'f32', 'f32', 'f32'], results: ['externref']}, js_import);
|
||||
let suspending_wasm_js_import =
|
||||
WebAssembly.suspendOnReturnedPromise(wasm_js_import);
|
||||
@ -297,7 +291,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
return Promise.resolve(0.5);
|
||||
};
|
||||
let wasm_js_import = new WebAssembly.Function(
|
||||
{parameters: ['externref'], results: ['externref']}, js_import);
|
||||
{parameters: [], results: ['externref']}, js_import);
|
||||
let suspending_wasm_js_import =
|
||||
WebAssembly.suspendOnReturnedPromise(wasm_js_import);
|
||||
|
||||
@ -344,7 +338,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
return Promise.resolve(42);
|
||||
};
|
||||
let wasm_js_import = new WebAssembly.Function(
|
||||
{parameters: ['externref'], results: ['externref']}, js_import);
|
||||
{parameters: [], results: ['externref']}, js_import);
|
||||
let suspending_wasm_js_import =
|
||||
WebAssembly.suspendOnReturnedPromise(wasm_js_import);
|
||||
|
||||
@ -373,7 +367,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
return Promise.reject(new WebAssembly.Exception(tag, [42]));
|
||||
};
|
||||
let wasm_js_import = new WebAssembly.Function(
|
||||
{parameters: ['externref'], results: ['externref']}, js_import);
|
||||
{parameters: [], results: ['externref']}, js_import);
|
||||
let suspending_wasm_js_import =
|
||||
WebAssembly.suspendOnReturnedPromise(wasm_js_import);
|
||||
|
||||
@ -394,11 +388,12 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
kExprI32Const, 0
|
||||
]).exportFunc();
|
||||
let wrapped_export;
|
||||
function js_import(suspender) {
|
||||
let suspender;
|
||||
function js_import() {
|
||||
wrapped_export(suspender); // Re-enter the same wrapped export.
|
||||
}
|
||||
let instance = builder.instantiate({m: {i: js_import}});
|
||||
let suspender = new WebAssembly.Suspender();
|
||||
suspender = new WebAssembly.Suspender();
|
||||
wrapped_export = WebAssembly.returnPromiseOnSuspend(instance.exports.test);
|
||||
assertThrows(() => wrapped_export(suspender), WebAssembly.RuntimeError,
|
||||
/re-entering an active\/suspended suspender/);
|
||||
@ -417,7 +412,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
let suspender = new WebAssembly.Suspender();
|
||||
let i = WebAssembly.suspendOnReturnedPromise(
|
||||
new WebAssembly.Function(
|
||||
{parameters: ['externref'], results: ['externref']},
|
||||
{parameters: [], results: ['externref']},
|
||||
() => Promise.resolve(0)));
|
||||
let instance = builder.instantiate({m: {i}});
|
||||
let wrapped_export = WebAssembly.returnPromiseOnSuspend(instance.exports.test);
|
||||
@ -437,7 +432,6 @@ function TestNestedSuspenders(suspend) {
|
||||
// promise resolves which resumes the outer continuation.
|
||||
// If 'suspend' is false, the inner JS function returns a regular value and
|
||||
// no computation is suspended.
|
||||
print(arguments.callee.name);
|
||||
let builder = new WasmModuleBuilder();
|
||||
inner_index = builder.addImport('m', 'inner', kSig_i_r);
|
||||
outer_index = builder.addImport('m', 'outer', kSig_i_r);
|
||||
@ -456,14 +450,14 @@ function TestNestedSuspenders(suspend) {
|
||||
|
||||
let inner = WebAssembly.suspendOnReturnedPromise(
|
||||
new WebAssembly.Function(
|
||||
{parameters: ['externref'], results: ['externref']},
|
||||
{parameters: [], results: ['externref']},
|
||||
() => suspend ? Promise.resolve(42) : 42));
|
||||
|
||||
let export_inner;
|
||||
let outer = WebAssembly.suspendOnReturnedPromise(
|
||||
new WebAssembly.Function(
|
||||
{parameters: ['externref'], results: ['externref']},
|
||||
(suspender) => export_inner(inner_suspender)));
|
||||
{parameters: [], results: ['externref']},
|
||||
() => export_inner(inner_suspender)));
|
||||
|
||||
let instance = builder.instantiate({m: {inner, outer}});
|
||||
export_inner = WebAssembly.returnPromiseOnSuspend(instance.exports.inner);
|
||||
@ -476,10 +470,12 @@ function TestNestedSuspenders(suspend) {
|
||||
}
|
||||
|
||||
(function TestNestedSuspendersSuspend() {
|
||||
print(arguments.callee.name);
|
||||
TestNestedSuspenders(true);
|
||||
})();
|
||||
|
||||
(function TestNestedSuspendersNoSuspend() {
|
||||
print(arguments.callee.name);
|
||||
TestNestedSuspenders(false);
|
||||
})();
|
||||
|
||||
@ -495,7 +491,7 @@ function TestNestedSuspenders(suspend) {
|
||||
let suspender = new WebAssembly.Suspender();
|
||||
let i = WebAssembly.suspendOnReturnedPromise(
|
||||
new WebAssembly.Function(
|
||||
{parameters: ['externref'], results: ['externref']},
|
||||
{parameters: [], results: ['externref']},
|
||||
() => Promise.resolve(0)));
|
||||
let instance = builder.instantiate({m: {i}});
|
||||
let wrapped_export = WebAssembly.returnPromiseOnSuspend(instance.exports.test);
|
||||
|
Loading…
Reference in New Issue
Block a user