Commit 3f695391 authored by Thibaud Michaud's avatar Thibaud Michaud Committed by V8 LUCI CQ

[wasm] Fix stack-switching import wrapper return

The JS import returns a tagged value, not a value of the machine
representation that corresponds to the signature's return type, since it
hasn't been converted yet.

R=ahaas@chromium.org

Bug: v8:12191
Change-Id: I0783af85eed9c5d25347200540e3e4eee48edfd4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3464036Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80213}
parent 4ac65c1b
...@@ -7065,11 +7065,10 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -7065,11 +7065,10 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
global_proxy); global_proxy);
} }
Node* BuildSuspend(Node* value, Node* api_function_ref, Node* BuildSuspend(Node* value, Node* api_function_ref) {
MachineRepresentation rep) {
// If value is a promise, suspend to the js-to-wasm prompt, and resume later // If value is a promise, suspend to the js-to-wasm prompt, and resume later
// with the promise's resolved value. // with the promise's resolved value.
auto resume = gasm_->MakeLabel(rep); auto resume = gasm_->MakeLabel(MachineRepresentation::kTagged);
gasm_->GotoIf(IsSmi(value), &resume, value); gasm_->GotoIf(IsSmi(value), &resume, value);
gasm_->GotoIfNot(gasm_->HasInstanceType(value, JS_PROMISE_TYPE), &resume, gasm_->GotoIfNot(gasm_->HasInstanceType(value, JS_PROMISE_TYPE), &resume,
BranchHint::kTrue, value); BranchHint::kTrue, value);
...@@ -7158,11 +7157,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { ...@@ -7158,11 +7157,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
DCHECK_EQ(pos, args.size()); DCHECK_EQ(pos, args.size());
call = gasm_->Call(call_descriptor, pos, args.begin()); call = gasm_->Call(call_descriptor, pos, args.begin());
if (suspend == wasm::kSuspend) { if (suspend == wasm::kSuspend) {
MachineRepresentation rep = call = BuildSuspend(call, Param(0));
sig_->return_count() >= 1
? sig_->GetReturn(0).machine_representation()
: MachineRepresentation::kNone;
call = BuildSuspend(call, Param(0), rep);
} }
break; break;
} }
......
...@@ -226,3 +226,26 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -226,3 +226,26 @@ load("test/mjsunit/wasm/wasm-module-builder.js");
wrapped_export.apply(null, args); wrapped_export.apply(null, args);
combined_promise.then(v => assertEquals(reduce(args), v)); combined_promise.then(v => assertEquals(reduce(args), v));
})(); })();
(function TestStackSwitchReturnFloat() {
print(arguments.callee.name);
let builder = new WasmModuleBuilder();
import_index = builder.addImport('m', 'import', kSig_f_v);
builder.addFunction("test", kSig_f_v)
.addBody([
kExprCallFunction, import_index, // suspend
]).exportFunc();
let suspender = new WebAssembly.Suspender();
function js_import() {
return Promise.resolve(0.5);
};
let wasm_js_import = new WebAssembly.Function(
{parameters: [], results: ['externref']}, js_import);
let suspending_wasm_js_import =
suspender.suspendOnReturnedPromise(wasm_js_import);
let instance = builder.instantiate({m: {import: suspending_wasm_js_import}});
let wrapped_export = suspender.returnPromiseOnSuspend(instance.exports.test);
let combined_promise = wrapped_export();
combined_promise.then(v => assertEquals(0.5, v));
})();
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