Commit ca0cde89 authored by Manos Koukoutos's avatar Manos Koukoutos Committed by V8 LUCI CQ

[wasm-gc] Fix issues with struct.new init. expressions

- Add support for packed types.
- Emit arguments first in wasm-module-builder.cc.

Bug: v8:7748
Change-Id: I358ca13db4332e026ee5850de6f629822bc92b04
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2948887Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75061}
parent dda3f509
......@@ -1468,7 +1468,9 @@ Handle<WasmStruct> Factory::NewWasmStruct(const wasm::StructType* type,
for (uint32_t i = 0; i < type->field_count(); i++) {
Address address = result.RawFieldAddress(type->field_offset(i));
if (type->field(i).is_numeric()) {
args[i].CopyToWithSystemEndianness(reinterpret_cast<byte*>(address));
args[i]
.Packed(type->field(i))
.CopyToWithSystemEndianness(reinterpret_cast<byte*>(address));
} else {
base::WriteUnalignedValue<Object>(address, *args[i].to_ref());
}
......
......@@ -1830,7 +1830,8 @@ class ModuleDecoderImpl : public Decoder {
WasmInitExpr* stack_args = &stack.back() - type->field_count();
for (uint32_t i = 0; i < type->field_count(); i++) {
WasmInitExpr& argument = stack_args[i];
if (!IsSubtypeOf(TypeOf(argument), type->field(i), module)) {
if (!IsSubtypeOf(TypeOf(argument), type->field(i).Unpacked(),
module)) {
errorf(pc(), "struct.new[%u]: expected %s, found %s instead",
i, type->field(i).name().c_str(),
TypeOf(argument).name().c_str());
......
......@@ -519,12 +519,12 @@ void WriteInitializerExpression(ZoneBuffer* buffer, const WasmInitExpr& init,
}
case WasmInitExpr::kStructNewWithRtt:
STATIC_ASSERT((kExprStructNewWithRtt >> 8) == kGCPrefix);
buffer->write_u8(kGCPrefix);
buffer->write_u8(static_cast<uint8_t>(kExprStructNewWithRtt));
buffer->write_u32v(init.immediate().index);
for (const WasmInitExpr& operand : init.operands()) {
WriteInitializerExpression(buffer, operand, kWasmBottom);
}
buffer->write_u8(kGCPrefix);
buffer->write_u8(static_cast<uint8_t>(kExprStructNewWithRtt));
buffer->write_u32v(init.immediate().index);
break;
case WasmInitExpr::kRttCanon:
STATIC_ASSERT((kExprRttCanon >> 8) == kGCPrefix);
......
......@@ -150,6 +150,16 @@ class WasmValue {
void CopyToWithSystemEndianness(byte* to) {
DCHECK(type_.is_numeric());
switch (type_.kind()) {
case kI8: {
int8_t value = to_i8();
base::Memcpy(static_cast<void*>(to), &value, sizeof(value));
break;
}
case kI16: {
int16_t value = to_i16();
base::Memcpy(static_cast<void*>(to), &value, sizeof(value));
break;
}
case kI32: {
int32_t value = to_i32();
base::Memcpy(static_cast<void*>(to), &value, sizeof(value));
......@@ -179,12 +189,24 @@ class WasmValue {
case kOptRef:
case kBottom:
case kVoid:
case kI8:
case kI16:
UNREACHABLE();
}
}
// If {packed_type.is_packed()}, create a new value of {packed_type()}.
// Otherwise, return this object.
WasmValue Packed(ValueType packed_type) const {
if (packed_type == kWasmI8) {
DCHECK_EQ(type_, kWasmI32);
return WasmValue(static_cast<int8_t>(to_i32()));
}
if (packed_type == kWasmI16) {
DCHECK_EQ(type_, kWasmI32);
return WasmValue(static_cast<int16_t>(to_i32()));
}
return *this;
}
template <typename T>
inline T to() const;
......
......@@ -109,10 +109,12 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
var struct_index = builder.addStruct([{type: kWasmI32, mutability: false}]);
var composite_struct_index = builder.addStruct(
[{type: kWasmI32, mutability: false},
{type: wasmRefType(struct_index), mutability: false}]);
{type: wasmRefType(struct_index), mutability: false},
{type: kWasmI8, mutability: true}]);
let field1_value = 432;
let field2_value = -123;
let field3_value = -555;
var global0 = builder.addGlobal(
wasmRefType(struct_index), false,
......@@ -127,6 +129,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
composite_struct_index,
[WasmInitExpr.I32Const(field1_value),
WasmInitExpr.GlobalGet(global0.index),
WasmInitExpr.I32Const(field3_value),
WasmInitExpr.RttCanon(composite_struct_index)]));
builder.addFunction("field_1", kSig_i_v)
......@@ -144,8 +147,14 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
])
.exportFunc();
builder.addFunction("field_3", kSig_i_v)
.addBody([
kExprGlobalGet, global.index,
kGCPrefix, kExprStructGetS, composite_struct_index, 2])
.exportFunc();
var instance = builder.instantiate({});
assertEquals(field1_value, instance.exports.field_1());
assertEquals(field2_value, instance.exports.field_2());
assertEquals((field3_value << 24) >> 24, instance.exports.field_3());
})();
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