[wasm][multi-return] Fix reftypes in stack slots

Stack slots are uncompressed, so we must always write the full
64-bit pointer.

Fixed: v8:13363
Change-Id: Iac5375388dd877dff2ddb3d6ef23ed56943da704
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3938230
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Auto-Submit: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83574}
This commit is contained in:
Jakob Kummerow 2022-10-07 18:55:12 +02:00 committed by V8 LUCI CQ
parent 98e46e7bef
commit 0cfd038a7f
2 changed files with 22 additions and 17 deletions

View File

@ -95,8 +95,8 @@ inline Operand GetMemOp(LiftoffAssembler* assm, Register addr,
return Operand(addr, scratch, scale_factor, 0);
}
inline void Load(LiftoffAssembler* assm, LiftoffRegister dst, Operand src,
ValueKind kind) {
inline void LoadFromStack(LiftoffAssembler* assm, LiftoffRegister dst,
Operand src, ValueKind kind) {
switch (kind) {
case kI32:
assm->movl(dst.gp(), src);
@ -105,6 +105,7 @@ inline void Load(LiftoffAssembler* assm, LiftoffRegister dst, Operand src,
case kRefNull:
case kRef:
case kRtt:
// Stack slots are uncompressed even when heap pointers are compressed.
assm->movq(dst.gp(), src);
break;
case kF32:
@ -121,19 +122,18 @@ inline void Load(LiftoffAssembler* assm, LiftoffRegister dst, Operand src,
}
}
inline void Store(LiftoffAssembler* assm, Operand dst, LiftoffRegister src,
ValueKind kind) {
inline void StoreToStack(LiftoffAssembler* assm, Operand dst,
LiftoffRegister src, ValueKind kind) {
switch (kind) {
case kI32:
assm->movl(dst, src.gp());
break;
case kI64:
assm->movq(dst, src.gp());
break;
case kRefNull:
case kRef:
case kRtt:
assm->StoreTaggedField(dst, src.gp());
// Stack slots are uncompressed even when heap pointers are compressed.
assm->movq(dst, src.gp());
break;
case kF32:
assm->Movss(dst, src.fp());
@ -860,20 +860,20 @@ void LiftoffAssembler::LoadCallerFrameSlot(LiftoffRegister dst,
uint32_t caller_slot_idx,
ValueKind kind) {
Operand src(rbp, kSystemPointerSize * (caller_slot_idx + 1));
liftoff::Load(this, dst, src, kind);
liftoff::LoadFromStack(this, dst, src, kind);
}
void LiftoffAssembler::StoreCallerFrameSlot(LiftoffRegister src,
uint32_t caller_slot_idx,
ValueKind kind) {
Operand dst(rbp, kSystemPointerSize * (caller_slot_idx + 1));
liftoff::Store(this, dst, src, kind);
liftoff::StoreToStack(this, dst, src, kind);
}
void LiftoffAssembler::LoadReturnStackSlot(LiftoffRegister reg, int offset,
ValueKind kind) {
Operand src(rsp, offset);
liftoff::Load(this, reg, src, kind);
liftoff::LoadFromStack(this, reg, src, kind);
}
void LiftoffAssembler::MoveStackValue(uint32_t dst_offset, uint32_t src_offset,
@ -977,7 +977,7 @@ void LiftoffAssembler::Spill(int offset, WasmValue value) {
}
void LiftoffAssembler::Fill(LiftoffRegister reg, int offset, ValueKind kind) {
liftoff::Load(this, reg, liftoff::GetStackSlot(offset), kind);
liftoff::LoadFromStack(this, reg, liftoff::GetStackSlot(offset), kind);
}
void LiftoffAssembler::FillI64Half(Register, int offset, RegPairHalf) {
@ -4224,7 +4224,7 @@ void LiftoffAssembler::CallC(const ValueKindSig* sig,
int arg_bytes = 0;
for (ValueKind param_kind : sig->parameters()) {
liftoff::Store(this, Operand(rsp, arg_bytes), *args++, param_kind);
liftoff::StoreToStack(this, Operand(rsp, arg_bytes), *args++, param_kind);
arg_bytes += value_kind_size(param_kind);
}
DCHECK_LE(arg_bytes, stack_bytes);
@ -4251,7 +4251,8 @@ void LiftoffAssembler::CallC(const ValueKindSig* sig,
// Load potential output value from the buffer on the stack.
if (out_argument_kind != kVoid) {
liftoff::Load(this, *next_result_reg, Operand(rsp, 0), out_argument_kind);
liftoff::LoadFromStack(this, *next_result_reg, Operand(rsp, 0),
out_argument_kind);
}
addq(rsp, Immediate(stack_bytes));

View File

@ -336,10 +336,12 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
(function MultiReturnRefTest() {
print("MultiReturnTest");
let builder = new WasmModuleBuilder();
let gc_sig = builder.addType(kSig_v_v);
let sig = makeSig([kWasmExternRef],
[kWasmExternRef, kWasmExternRef, kWasmExternRef, kWasmExternRef]);
builder.addFunction("callee", sig)
let gc_index = builder.addImport('q', 'gc', gc_sig);
let callee = builder.addFunction("callee", sig)
.addBody([
kExprLocalGet, 0,
kExprLocalGet, 0,
@ -349,11 +351,13 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
builder.addFunction("main", sig)
.addBody([
kExprLocalGet, 0,
kExprCallFunction, 0
kExprCallFunction, callee.index,
kExprCallFunction, gc_index,
])
.exportAs("main");
let module = new WebAssembly.Module(builder.toBuffer());
let instance = new WebAssembly.Instance(module);
let instance = builder.instantiate({
q: { gc: () => gc() }
});
assertEquals(instance.exports.main(null), [null, null, null, null]);
})();