[wasm-gc] Add struct.new_default* to constant expressions
Bug: v8:7748 Change-Id: I5b6d8bf0b6dbf88c4762f4d61fb468c3e2898201 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3168621 Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Commit-Queue: Manos Koukoutos <manoskouk@chromium.org> Cr-Commit-Position: refs/heads/main@{#76927}
This commit is contained in:
parent
6ec7e0a76c
commit
eee722cbf4
@ -945,6 +945,8 @@ struct ControlBase : public PcForErrors<validate> {
|
||||
F(GlobalGet, Value* result, const GlobalIndexImmediate<validate>& imm) \
|
||||
F(StructNewWithRtt, const StructIndexImmediate<validate>& imm, \
|
||||
const Value& rtt, const Value args[], Value* result) \
|
||||
F(StructNewDefault, const StructIndexImmediate<validate>& imm, \
|
||||
const Value& rtt, Value* result) \
|
||||
F(ArrayInit, const ArrayIndexImmediate<validate>& imm, \
|
||||
const base::Vector<Value>& elements, const Value& rtt, Value* result) \
|
||||
F(RttCanon, uint32_t type_index, Value* result) \
|
||||
@ -1047,8 +1049,6 @@ struct ControlBase : public PcForErrors<validate> {
|
||||
F(TableSize, const IndexImmediate<validate>& imm, Value* result) \
|
||||
F(TableFill, const IndexImmediate<validate>& imm, const Value& start, \
|
||||
const Value& value, const Value& count) \
|
||||
F(StructNewDefault, const StructIndexImmediate<validate>& imm, \
|
||||
const Value& rtt, Value* result) \
|
||||
F(StructGet, const Value& struct_object, \
|
||||
const FieldImmediate<validate>& field, bool is_signed, Value* result) \
|
||||
F(StructSet, const Value& struct_object, \
|
||||
@ -4074,7 +4074,6 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
|
||||
}
|
||||
case kExprStructNewDefault:
|
||||
case kExprStructNewDefaultWithRtt: {
|
||||
NON_CONST_ONLY
|
||||
StructIndexImmediate<validate> imm(this, this->pc_ + opcode_length);
|
||||
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
|
||||
if (validate) {
|
||||
|
@ -89,6 +89,48 @@ void InitExprInterface::StructNewWithRtt(
|
||||
ValueType::Ref(HeapType(imm.index), kNonNullable));
|
||||
}
|
||||
|
||||
namespace {
|
||||
WasmValue DefaultValueForType(ValueType type, Isolate* isolate) {
|
||||
switch (type.kind()) {
|
||||
case kI32:
|
||||
case kI8:
|
||||
case kI16:
|
||||
return WasmValue(0);
|
||||
case kI64:
|
||||
return WasmValue(int64_t{0});
|
||||
case kF32:
|
||||
return WasmValue(0.0f);
|
||||
case kF64:
|
||||
return WasmValue(0.0);
|
||||
case kS128:
|
||||
return WasmValue(Simd128());
|
||||
case kOptRef:
|
||||
return WasmValue(isolate->factory()->null_value(), type);
|
||||
case kVoid:
|
||||
case kRtt:
|
||||
case kRttWithDepth:
|
||||
case kRef:
|
||||
case kBottom:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void InitExprInterface::StructNewDefault(
|
||||
FullDecoder* decoder, const StructIndexImmediate<validate>& imm,
|
||||
const Value& rtt, Value* result) {
|
||||
if (isolate_ == nullptr) return;
|
||||
std::vector<WasmValue> field_values(imm.struct_type->field_count());
|
||||
for (uint32_t i = 0; i < field_values.size(); i++) {
|
||||
field_values[i] = DefaultValueForType(imm.struct_type->field(i), isolate_);
|
||||
}
|
||||
result->runtime_value =
|
||||
WasmValue(isolate_->factory()->NewWasmStruct(
|
||||
imm.struct_type, field_values.data(),
|
||||
Handle<Map>::cast(rtt.runtime_value.to_ref())),
|
||||
ValueType::Ref(HeapType(imm.index), kNonNullable));
|
||||
}
|
||||
|
||||
void InitExprInterface::ArrayInit(FullDecoder* decoder,
|
||||
const ArrayIndexImmediate<validate>& imm,
|
||||
const base::Vector<Value>& elements,
|
||||
|
@ -40,6 +40,8 @@ ValueType WasmInitExpr::type(const WasmModule* module,
|
||||
return ValueType::Ref(immediate().heap_type, kNullable);
|
||||
case kStructNewWithRtt:
|
||||
case kStructNew:
|
||||
case kStructNewDefaultWithRtt:
|
||||
case kStructNewDefault:
|
||||
case kArrayInit:
|
||||
case kArrayInitStatic:
|
||||
return ValueType::Ref(immediate().index, kNonNullable);
|
||||
|
@ -35,6 +35,8 @@ class WasmInitExpr {
|
||||
kRefFuncConst,
|
||||
kStructNewWithRtt,
|
||||
kStructNew,
|
||||
kStructNewDefaultWithRtt,
|
||||
kStructNewDefault,
|
||||
kArrayInit,
|
||||
kArrayInitStatic,
|
||||
kRttCanon,
|
||||
@ -110,6 +112,22 @@ class WasmInitExpr {
|
||||
return expr;
|
||||
}
|
||||
|
||||
static WasmInitExpr StructNewDefaultWithRtt(uint32_t index,
|
||||
WasmInitExpr rtt) {
|
||||
WasmInitExpr expr;
|
||||
expr.kind_ = kStructNewDefaultWithRtt;
|
||||
expr.immediate_.index = index;
|
||||
expr.operands_.push_back(std::move(rtt));
|
||||
return expr;
|
||||
}
|
||||
|
||||
static WasmInitExpr StructNewDefault(uint32_t index) {
|
||||
WasmInitExpr expr;
|
||||
expr.kind_ = kStructNewDefault;
|
||||
expr.immediate_.index = index;
|
||||
return expr;
|
||||
}
|
||||
|
||||
static WasmInitExpr ArrayInit(uint32_t index,
|
||||
std::vector<WasmInitExpr> elements) {
|
||||
WasmInitExpr expr;
|
||||
@ -178,6 +196,8 @@ class WasmInitExpr {
|
||||
return immediate().heap_type == other.immediate().heap_type;
|
||||
case kStructNewWithRtt:
|
||||
case kStructNew:
|
||||
case kStructNewDefaultWithRtt:
|
||||
case kStructNewDefault:
|
||||
if (immediate().index != other.immediate().index) return false;
|
||||
DCHECK_EQ(operands().size(), other.operands().size());
|
||||
for (uint32_t i = 0; i < operands().size(); i++) {
|
||||
|
@ -512,15 +512,34 @@ void WriteInitializerExpressionWithEnd(ZoneBuffer* buffer,
|
||||
}
|
||||
case WasmInitExpr::kStructNew:
|
||||
case WasmInitExpr::kStructNewWithRtt:
|
||||
case WasmInitExpr::kStructNewDefault:
|
||||
case WasmInitExpr::kStructNewDefaultWithRtt:
|
||||
STATIC_ASSERT((kExprStructNew >> 8) == kGCPrefix);
|
||||
STATIC_ASSERT((kExprStructNewWithRtt >> 8) == kGCPrefix);
|
||||
STATIC_ASSERT((kExprStructNewDefault >> 8) == kGCPrefix);
|
||||
STATIC_ASSERT((kExprStructNewDefaultWithRtt >> 8) == kGCPrefix);
|
||||
for (const WasmInitExpr& operand : init.operands()) {
|
||||
WriteInitializerExpressionWithEnd(buffer, operand, kWasmBottom);
|
||||
}
|
||||
buffer->write_u8(kGCPrefix);
|
||||
buffer->write_u8(static_cast<uint8_t>(
|
||||
init.kind() == WasmInitExpr::kStructNew ? kExprStructNew
|
||||
: kExprStructNewWithRtt));
|
||||
WasmOpcode opcode;
|
||||
switch (init.kind()) {
|
||||
case WasmInitExpr::kStructNewWithRtt:
|
||||
opcode = kExprStructNewWithRtt;
|
||||
break;
|
||||
case WasmInitExpr::kStructNew:
|
||||
opcode = kExprStructNew;
|
||||
break;
|
||||
case WasmInitExpr::kStructNewDefaultWithRtt:
|
||||
opcode = kExprStructNewDefaultWithRtt;
|
||||
break;
|
||||
case WasmInitExpr::kStructNewDefault:
|
||||
opcode = kExprStructNewDefault;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
buffer->write_u8(static_cast<uint8_t>(opcode));
|
||||
buffer->write_u32v(init.immediate().index);
|
||||
break;
|
||||
case WasmInitExpr::kArrayInit:
|
||||
|
@ -113,7 +113,7 @@ 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: wasmOptRefType(struct_index), mutability: false},
|
||||
{type: kWasmI8, mutability: true}]);
|
||||
|
||||
let field1_value = 432;
|
||||
@ -136,6 +136,12 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
WasmInitExpr.I32Const(field3_value),
|
||||
WasmInitExpr.RttCanon(composite_struct_index)]));
|
||||
|
||||
var global_default = builder.addGlobal(
|
||||
wasmRefType(composite_struct_index), false,
|
||||
WasmInitExpr.StructNewDefaultWithRtt(
|
||||
composite_struct_index,
|
||||
WasmInitExpr.RttCanon(composite_struct_index)));
|
||||
|
||||
builder.addFunction("field_1", kSig_i_v)
|
||||
.addBody([
|
||||
kExprGlobalGet, global.index,
|
||||
@ -156,11 +162,33 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
kExprGlobalGet, global.index,
|
||||
kGCPrefix, kExprStructGetS, composite_struct_index, 2])
|
||||
.exportFunc();
|
||||
|
||||
builder.addFunction("field_1_default", kSig_i_v)
|
||||
.addBody([
|
||||
kExprGlobalGet, global_default.index,
|
||||
kGCPrefix, kExprStructGet, composite_struct_index, 0])
|
||||
.exportFunc();
|
||||
|
||||
builder.addFunction("field_2_default", makeSig([], [kWasmAnyRef]))
|
||||
.addBody([
|
||||
kExprGlobalGet, global_default.index,
|
||||
kGCPrefix, kExprStructGet, composite_struct_index, 1])
|
||||
.exportFunc();
|
||||
|
||||
builder.addFunction("field_3_default", kSig_i_v)
|
||||
.addBody([
|
||||
kExprGlobalGet, global_default.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());
|
||||
assertEquals(0, instance.exports.field_1_default());
|
||||
assertEquals(null, instance.exports.field_2_default());
|
||||
assertEquals(0, instance.exports.field_3_default());
|
||||
})();
|
||||
|
||||
(function TestArrayInitExprNumeric() {
|
||||
|
@ -983,7 +983,6 @@ class Binary {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
emit_init_expr_recursive(expr) {
|
||||
switch (expr.kind) {
|
||||
case kExprGlobalGet:
|
||||
@ -1015,6 +1014,8 @@ class Binary {
|
||||
break;
|
||||
case kExprStructNew:
|
||||
case kExprStructNewWithRtt:
|
||||
case kExprStructNewDefault:
|
||||
case kExprStructNewDefaultWithRtt:
|
||||
for (let operand of expr.operands) {
|
||||
this.emit_init_expr_recursive(operand);
|
||||
}
|
||||
@ -1184,6 +1185,12 @@ class WasmInitExpr {
|
||||
static StructNew(type, args) {
|
||||
return {kind: kExprStructNew, value: type, operands: args};
|
||||
}
|
||||
static StructNewDefaultWithRtt(type, rtt) {
|
||||
return {kind: kExprStructNewDefaultWithRtt, value: type, operands: [rtt]};
|
||||
}
|
||||
static StructNewDefault(type) {
|
||||
return {kind: kExprStructNewDefault, value: type, operands: []};
|
||||
}
|
||||
static ArrayInit(type, args) {
|
||||
return {kind: kExprArrayInit, value: type, operands: args};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user