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, ...@@ -1468,7 +1468,9 @@ Handle<WasmStruct> Factory::NewWasmStruct(const wasm::StructType* type,
for (uint32_t i = 0; i < type->field_count(); i++) { for (uint32_t i = 0; i < type->field_count(); i++) {
Address address = result.RawFieldAddress(type->field_offset(i)); Address address = result.RawFieldAddress(type->field_offset(i));
if (type->field(i).is_numeric()) { 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 { } else {
base::WriteUnalignedValue<Object>(address, *args[i].to_ref()); base::WriteUnalignedValue<Object>(address, *args[i].to_ref());
} }
......
...@@ -1830,7 +1830,8 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1830,7 +1830,8 @@ class ModuleDecoderImpl : public Decoder {
WasmInitExpr* stack_args = &stack.back() - type->field_count(); WasmInitExpr* stack_args = &stack.back() - type->field_count();
for (uint32_t i = 0; i < type->field_count(); i++) { for (uint32_t i = 0; i < type->field_count(); i++) {
WasmInitExpr& argument = stack_args[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", errorf(pc(), "struct.new[%u]: expected %s, found %s instead",
i, type->field(i).name().c_str(), i, type->field(i).name().c_str(),
TypeOf(argument).name().c_str()); TypeOf(argument).name().c_str());
......
...@@ -519,12 +519,12 @@ void WriteInitializerExpression(ZoneBuffer* buffer, const WasmInitExpr& init, ...@@ -519,12 +519,12 @@ void WriteInitializerExpression(ZoneBuffer* buffer, const WasmInitExpr& init,
} }
case WasmInitExpr::kStructNewWithRtt: case WasmInitExpr::kStructNewWithRtt:
STATIC_ASSERT((kExprStructNewWithRtt >> 8) == kGCPrefix); 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()) { for (const WasmInitExpr& operand : init.operands()) {
WriteInitializerExpression(buffer, operand, kWasmBottom); WriteInitializerExpression(buffer, operand, kWasmBottom);
} }
buffer->write_u8(kGCPrefix);
buffer->write_u8(static_cast<uint8_t>(kExprStructNewWithRtt));
buffer->write_u32v(init.immediate().index);
break; break;
case WasmInitExpr::kRttCanon: case WasmInitExpr::kRttCanon:
STATIC_ASSERT((kExprRttCanon >> 8) == kGCPrefix); STATIC_ASSERT((kExprRttCanon >> 8) == kGCPrefix);
......
...@@ -150,6 +150,16 @@ class WasmValue { ...@@ -150,6 +150,16 @@ class WasmValue {
void CopyToWithSystemEndianness(byte* to) { void CopyToWithSystemEndianness(byte* to) {
DCHECK(type_.is_numeric()); DCHECK(type_.is_numeric());
switch (type_.kind()) { 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: { case kI32: {
int32_t value = to_i32(); int32_t value = to_i32();
base::Memcpy(static_cast<void*>(to), &value, sizeof(value)); base::Memcpy(static_cast<void*>(to), &value, sizeof(value));
...@@ -179,12 +189,24 @@ class WasmValue { ...@@ -179,12 +189,24 @@ class WasmValue {
case kOptRef: case kOptRef:
case kBottom: case kBottom:
case kVoid: case kVoid:
case kI8:
case kI16:
UNREACHABLE(); 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> template <typename T>
inline T to() const; inline T to() const;
......
...@@ -109,10 +109,12 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -109,10 +109,12 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
var struct_index = builder.addStruct([{type: kWasmI32, mutability: false}]); var struct_index = builder.addStruct([{type: kWasmI32, mutability: false}]);
var composite_struct_index = builder.addStruct( var composite_struct_index = builder.addStruct(
[{type: kWasmI32, mutability: false}, [{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 field1_value = 432;
let field2_value = -123; let field2_value = -123;
let field3_value = -555;
var global0 = builder.addGlobal( var global0 = builder.addGlobal(
wasmRefType(struct_index), false, wasmRefType(struct_index), false,
...@@ -127,6 +129,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -127,6 +129,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
composite_struct_index, composite_struct_index,
[WasmInitExpr.I32Const(field1_value), [WasmInitExpr.I32Const(field1_value),
WasmInitExpr.GlobalGet(global0.index), WasmInitExpr.GlobalGet(global0.index),
WasmInitExpr.I32Const(field3_value),
WasmInitExpr.RttCanon(composite_struct_index)])); WasmInitExpr.RttCanon(composite_struct_index)]));
builder.addFunction("field_1", kSig_i_v) builder.addFunction("field_1", kSig_i_v)
...@@ -144,8 +147,14 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); ...@@ -144,8 +147,14 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
]) ])
.exportFunc(); .exportFunc();
builder.addFunction("field_3", kSig_i_v)
.addBody([
kExprGlobalGet, global.index,
kGCPrefix, kExprStructGetS, composite_struct_index, 2])
.exportFunc();
var instance = builder.instantiate({}); var instance = builder.instantiate({});
assertEquals(field1_value, instance.exports.field_1()); assertEquals(field1_value, instance.exports.field_1());
assertEquals(field2_value, instance.exports.field_2()); 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