[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:
parent
98e46e7bef
commit
0cfd038a7f
@ -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));
|
||||
|
@ -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]);
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user