[wasm-gc][cleanup] Remove array.new, struct.new
They have been replaced with {array,struct}.new_with_rtt. Also, rework tests that used those instructions. Bug: v8:7748 Change-Id: I2aaccb1958bf2b8d6cad4969abc612216856393d Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2307318 Commit-Queue: Manos Koukoutos <manoskouk@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Cr-Commit-Position: refs/heads/master@{#68961}
This commit is contained in:
parent
cfebd19a3a
commit
0747681e41
@ -819,7 +819,6 @@ namespace internal {
|
||||
ASM(WasmDebugBreak, Dummy) \
|
||||
TFC(WasmFloat32ToNumber, WasmFloat32ToNumber) \
|
||||
TFC(WasmFloat64ToNumber, WasmFloat64ToNumber) \
|
||||
TFS(WasmAllocateArray, kMapIndex, kLength, kElementSize) \
|
||||
TFS(WasmAllocateArrayWithRtt, kMap, kLength, kElementSize) \
|
||||
TFC(WasmI32AtomicWait32, WasmI32AtomicWait32) \
|
||||
TFC(WasmI64AtomicWait32, WasmI64AtomicWait32) \
|
||||
|
@ -114,30 +114,6 @@ TF_BUILTIN(WasmI64AtomicWait32, WasmBuiltinsAssembler) {
|
||||
Return(Unsigned(SmiToInt32(result_smi)));
|
||||
}
|
||||
|
||||
TF_BUILTIN(WasmAllocateArray, WasmBuiltinsAssembler) {
|
||||
TNode<WasmInstanceObject> instance = LoadInstanceFromFrame();
|
||||
TNode<Smi> map_index = CAST(Parameter(Descriptor::kMapIndex));
|
||||
TNode<Smi> length = CAST(Parameter(Descriptor::kLength));
|
||||
TNode<Smi> element_size = CAST(Parameter(Descriptor::kElementSize));
|
||||
TNode<FixedArray> maps_list = LoadObjectField<FixedArray>(
|
||||
instance, WasmInstanceObject::kManagedObjectMapsOffset);
|
||||
TNode<Map> map = CAST(LoadFixedArrayElement(maps_list, map_index));
|
||||
TNode<IntPtrT> untagged_length = SmiUntag(length);
|
||||
// instance_size = WasmArray::kHeaderSize
|
||||
// + RoundUp(element_size * length, kObjectAlignment)
|
||||
TNode<IntPtrT> raw_size = IntPtrMul(SmiUntag(element_size), untagged_length);
|
||||
TNode<IntPtrT> rounded_size =
|
||||
WordAnd(IntPtrAdd(raw_size, IntPtrConstant(kObjectAlignmentMask)),
|
||||
IntPtrConstant(~kObjectAlignmentMask));
|
||||
TNode<IntPtrT> instance_size =
|
||||
IntPtrAdd(IntPtrConstant(WasmArray::kHeaderSize), rounded_size);
|
||||
TNode<WasmArray> result = UncheckedCast<WasmArray>(Allocate(instance_size));
|
||||
StoreMap(result, map);
|
||||
StoreObjectFieldNoWriteBarrier(result, WasmArray::kLengthOffset,
|
||||
TruncateIntPtrToInt32(untagged_length));
|
||||
Return(result);
|
||||
}
|
||||
|
||||
TF_BUILTIN(WasmAllocateArrayWithRtt, WasmBuiltinsAssembler) {
|
||||
TNode<Map> map = CAST(Parameter(Descriptor::kMap));
|
||||
TNode<Smi> length = CAST(Parameter(Descriptor::kLength));
|
||||
|
@ -225,18 +225,6 @@ builtin WasmAllocateJSArray(implicit context: Context)(size: Smi): JSArray {
|
||||
return AllocateJSArray(ElementsKind::PACKED_ELEMENTS, map, size, size);
|
||||
}
|
||||
|
||||
builtin WasmAllocateStruct(implicit context: Context)(mapIndex: Smi):
|
||||
HeapObject {
|
||||
const instance: WasmInstanceObject = LoadInstanceFromFrame();
|
||||
const maps: FixedArray = LoadManagedObjectMapsFromInstance(instance);
|
||||
const map: Map = %RawDownCast<Map>(LoadFixedArrayElement(maps, mapIndex));
|
||||
const instanceSize: intptr =
|
||||
unsafe::TimesTaggedSize(Convert<intptr>(map.instance_size_in_words));
|
||||
const result: HeapObject = unsafe::Allocate(instanceSize);
|
||||
*UnsafeConstCast(&result.map) = map;
|
||||
return result;
|
||||
}
|
||||
|
||||
builtin WasmAllocateRtt(implicit context: Context)(
|
||||
typeIndex: Smi, parent: Map): Map {
|
||||
tail runtime::WasmAllocateRtt(context, typeIndex, parent);
|
||||
|
@ -5243,7 +5243,7 @@ Node* StoreWithTaggedAlignment(WasmGraphAssembler* gasm, Node* base,
|
||||
}
|
||||
|
||||
// Set a field of a struct, without checking if the struct is null.
|
||||
// Helper method for StructNew and StructSet.
|
||||
// Helper method for StructNewWithRtt and StructSet.
|
||||
Node* StoreStructFieldUnchecked(MachineGraph* graph, WasmGraphAssembler* gasm,
|
||||
Node* struct_object,
|
||||
const wasm::StructType* type,
|
||||
@ -5269,20 +5269,6 @@ Node* ArrayLength(GraphAssembler* gasm, Node* array) {
|
||||
|
||||
} // namespace
|
||||
|
||||
Node* WasmGraphBuilder::StructNew(uint32_t struct_index,
|
||||
const wasm::StructType* type,
|
||||
Vector<Node*> fields) {
|
||||
int map_index = wasm::GetCanonicalRttIndex(env_->module, struct_index);
|
||||
Node* s = CALL_BUILTIN(
|
||||
WasmAllocateStruct,
|
||||
graph()->NewNode(mcgraph()->common()->NumberConstant(map_index)),
|
||||
LOAD_INSTANCE_FIELD(NativeContext, MachineType::TaggedPointer()));
|
||||
for (uint32_t i = 0; i < type->field_count(); i++) {
|
||||
StoreStructFieldUnchecked(mcgraph(), gasm_.get(), s, type, i, fields[i]);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::StructNewWithRtt(uint32_t struct_index,
|
||||
const wasm::StructType* type,
|
||||
Node* rtt, Vector<Node*> fields) {
|
||||
@ -5295,46 +5281,6 @@ Node* WasmGraphBuilder::StructNewWithRtt(uint32_t struct_index,
|
||||
return s;
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::ArrayNew(uint32_t array_index,
|
||||
const wasm::ArrayType* type, Node* length,
|
||||
Node* initial_value) {
|
||||
int map_index = GetCanonicalRttIndex(env_->module, array_index);
|
||||
wasm::ValueType element_type = type->element_type();
|
||||
Node* a = CALL_BUILTIN(
|
||||
WasmAllocateArray,
|
||||
graph()->NewNode(mcgraph()->common()->NumberConstant(map_index)),
|
||||
BuildChangeUint31ToSmi(length),
|
||||
graph()->NewNode(mcgraph()->common()->NumberConstant(
|
||||
element_type.element_size_bytes())),
|
||||
LOAD_INSTANCE_FIELD(NativeContext, MachineType::TaggedPointer()));
|
||||
auto loop = gasm_->MakeLoopLabel(MachineRepresentation::kWord32);
|
||||
auto done = gasm_->MakeLabel();
|
||||
Node* start_offset =
|
||||
gasm_->Int32Constant(WasmArray::kHeaderSize - kHeapObjectTag);
|
||||
Node* element_size = gasm_->Int32Constant(element_type.element_size_bytes());
|
||||
Node* end_offset =
|
||||
gasm_->Int32Add(start_offset, gasm_->Int32Mul(element_size, length));
|
||||
// "Goto" requires the graph's end to have been set up.
|
||||
// TODO(jkummerow): Figure out if there's a more elegant solution.
|
||||
Graph* g = mcgraph()->graph();
|
||||
if (!g->end()) {
|
||||
g->SetEnd(g->NewNode(mcgraph()->common()->End(0)));
|
||||
}
|
||||
gasm_->Goto(&loop, start_offset);
|
||||
gasm_->Bind(&loop);
|
||||
{
|
||||
Node* offset = loop.PhiAt(0);
|
||||
Node* check = gasm_->Uint32LessThan(offset, end_offset);
|
||||
gasm_->GotoIfNot(check, &done);
|
||||
StoreWithTaggedAlignment(gasm_.get(), a, offset, initial_value,
|
||||
type->element_type());
|
||||
offset = gasm_->Int32Add(offset, element_size);
|
||||
gasm_->Goto(&loop, offset);
|
||||
}
|
||||
gasm_->Bind(&done);
|
||||
return a;
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::ArrayNewWithRtt(uint32_t array_index,
|
||||
const wasm::ArrayType* type,
|
||||
Node* length, Node* initial_value,
|
||||
|
@ -390,8 +390,6 @@ class WasmGraphBuilder {
|
||||
Node* TableSize(uint32_t table_index);
|
||||
Node* TableFill(uint32_t table_index, Node* start, Node* value, Node* count);
|
||||
|
||||
Node* StructNew(uint32_t struct_index, const wasm::StructType* type,
|
||||
Vector<Node*> fields);
|
||||
Node* StructNewWithRtt(uint32_t struct_index, const wasm::StructType* type,
|
||||
Node* rtt, Vector<Node*> fields);
|
||||
Node* StructGet(Node* struct_object, const wasm::StructType* struct_type,
|
||||
@ -400,8 +398,6 @@ class WasmGraphBuilder {
|
||||
Node* StructSet(Node* struct_object, const wasm::StructType* struct_type,
|
||||
uint32_t field_index, Node* value, CheckForNull null_check,
|
||||
wasm::WasmCodePosition position);
|
||||
Node* ArrayNew(uint32_t array_index, const wasm::ArrayType* type,
|
||||
Node* length, Node* initial_value);
|
||||
Node* ArrayNewWithRtt(uint32_t array_index, const wasm::ArrayType* type,
|
||||
Node* length, Node* initial_value, Node* rtt);
|
||||
void BoundsCheck(Node* array, Node* index, wasm::WasmCodePosition position);
|
||||
|
@ -3587,12 +3587,6 @@ class LiftoffCompiler {
|
||||
unsupported(decoder, kRefTypes, "table.fill");
|
||||
}
|
||||
|
||||
void StructNew(FullDecoder* decoder,
|
||||
const StructIndexImmediate<validate>& imm, const Value args[],
|
||||
Value* result) {
|
||||
// TODO(7748): Implement.
|
||||
unsupported(decoder, kGC, "struct.new");
|
||||
}
|
||||
void StructNewWithRtt(FullDecoder* decoder,
|
||||
const StructIndexImmediate<validate>& imm,
|
||||
const Value& rtt, const Value args[], Value* result) {
|
||||
@ -3612,12 +3606,6 @@ class LiftoffCompiler {
|
||||
unsupported(decoder, kGC, "struct.set");
|
||||
}
|
||||
|
||||
void ArrayNew(FullDecoder* decoder, const ArrayIndexImmediate<validate>& imm,
|
||||
const Value& length, const Value& initial_value,
|
||||
Value* result) {
|
||||
// TODO(7748): Implement.
|
||||
unsupported(decoder, kGC, "array.new");
|
||||
}
|
||||
void ArrayNewWithRtt(FullDecoder* decoder,
|
||||
const ArrayIndexImmediate<validate>& imm,
|
||||
const Value& length, const Value& initial_value,
|
||||
|
@ -944,16 +944,12 @@ struct ControlBase {
|
||||
F(TableSize, const TableIndexImmediate<validate>& imm, Value* result) \
|
||||
F(TableFill, const TableIndexImmediate<validate>& imm, const Value& start, \
|
||||
const Value& value, const Value& count) \
|
||||
F(StructNew, const StructIndexImmediate<validate>& imm, const Value args[], \
|
||||
Value* result) \
|
||||
F(StructNewWithRtt, const StructIndexImmediate<validate>& imm, \
|
||||
const Value& rtt, const Value args[], Value* result) \
|
||||
F(StructGet, const Value& struct_object, \
|
||||
const FieldIndexImmediate<validate>& field, bool is_signed, Value* result) \
|
||||
F(StructSet, const Value& struct_object, \
|
||||
const FieldIndexImmediate<validate>& field, const Value& field_value) \
|
||||
F(ArrayNew, const ArrayIndexImmediate<validate>& imm, const Value& length, \
|
||||
const Value& initial_value, Value* result) \
|
||||
F(ArrayNewWithRtt, const ArrayIndexImmediate<validate>& imm, \
|
||||
const Value& length, const Value& initial_value, const Value& rtt, \
|
||||
Value* result) \
|
||||
@ -1670,7 +1666,6 @@ class WasmDecoder : public Decoder {
|
||||
byte gc_index = decoder->read_u8<validate>(pc + 1, "gc_index");
|
||||
WasmOpcode opcode = static_cast<WasmOpcode>(kGCPrefix << 8 | gc_index);
|
||||
switch (opcode) {
|
||||
case kExprStructNew:
|
||||
case kExprStructNewWithRtt:
|
||||
case kExprStructNewDefault: {
|
||||
StructIndexImmediate<validate> imm(decoder, pc + 2);
|
||||
@ -1683,7 +1678,6 @@ class WasmDecoder : public Decoder {
|
||||
FieldIndexImmediate<validate> imm(decoder, pc + 2);
|
||||
return 2 + imm.length;
|
||||
}
|
||||
case kExprArrayNew:
|
||||
case kExprArrayNewWithRtt:
|
||||
case kExprArrayNewDefault:
|
||||
case kExprArrayGet:
|
||||
@ -1845,7 +1839,6 @@ class WasmDecoder : public Decoder {
|
||||
return {1, 1};
|
||||
case kExprStructSet:
|
||||
return {2, 0};
|
||||
case kExprArrayNew:
|
||||
case kExprArrayGet:
|
||||
case kExprArrayGetS:
|
||||
case kExprArrayGetU:
|
||||
@ -1859,11 +1852,6 @@ class WasmDecoder : public Decoder {
|
||||
return {0, 1};
|
||||
case kExprArrayNewWithRtt:
|
||||
return {3, 1};
|
||||
case kExprStructNew: {
|
||||
StructIndexImmediate<validate> imm(this, this->pc_ + 2);
|
||||
this->Complete(imm);
|
||||
return {imm.struct_type->field_count(), 1};
|
||||
}
|
||||
case kExprStructNewWithRtt: {
|
||||
StructIndexImmediate<validate> imm(this, this->pc_ + 2);
|
||||
this->Complete(imm);
|
||||
@ -3381,14 +3369,6 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
|
||||
int DecodeGCOpcode(WasmOpcode opcode) {
|
||||
switch (opcode) {
|
||||
case kExprStructNew: {
|
||||
StructIndexImmediate<validate> imm(this, this->pc_ + 2);
|
||||
if (!this->Validate(this->pc_ + 2, imm)) return 0;
|
||||
ArgVector args = PopArgs(imm.struct_type);
|
||||
Value* value = Push(ValueType::Ref(imm.index, kNonNullable));
|
||||
CALL_INTERFACE_IF_REACHABLE(StructNew, imm, args.begin(), value);
|
||||
return 2 + imm.length;
|
||||
}
|
||||
case kExprStructNewWithRtt: {
|
||||
StructIndexImmediate<validate> imm(this, this->pc_ + 2);
|
||||
if (!this->Validate(this->pc_, imm)) return 0;
|
||||
@ -3466,16 +3446,6 @@ class WasmFullDecoder : public WasmDecoder<validate> {
|
||||
CALL_INTERFACE_IF_REACHABLE(StructSet, struct_obj, field, field_value);
|
||||
return 2 + field.length;
|
||||
}
|
||||
case kExprArrayNew: {
|
||||
ArrayIndexImmediate<validate> imm(this, this->pc_ + 2);
|
||||
if (!this->Validate(this->pc_ + 2, imm)) return 0;
|
||||
Value length = Pop(1, kWasmI32);
|
||||
Value initial_value = Pop(0, imm.array_type->element_type().Unpacked());
|
||||
Value* value = Push(ValueType::Ref(imm.index, kNonNullable));
|
||||
CALL_INTERFACE_IF_REACHABLE(ArrayNew, imm, length, initial_value,
|
||||
value);
|
||||
return 2 + imm.length;
|
||||
}
|
||||
case kExprArrayNewWithRtt: {
|
||||
ArrayIndexImmediate<validate> imm(this, this->pc_ + 2);
|
||||
if (!this->Validate(this->pc_ + 2, imm)) return 0;
|
||||
|
@ -646,18 +646,6 @@ class WasmGraphBuildingInterface {
|
||||
BUILD(TableFill, imm.index, start.node, value.node, count.node);
|
||||
}
|
||||
|
||||
void StructNew(FullDecoder* decoder,
|
||||
const StructIndexImmediate<validate>& imm, const Value args[],
|
||||
Value* result) {
|
||||
uint32_t field_count = imm.struct_type->field_count();
|
||||
base::SmallVector<TFNode*, 16> arg_nodes(field_count);
|
||||
for (uint32_t i = 0; i < field_count; i++) {
|
||||
arg_nodes[i] = args[i].node;
|
||||
}
|
||||
result->node =
|
||||
BUILD(StructNew, imm.index, imm.struct_type, VectorOf(arg_nodes));
|
||||
}
|
||||
|
||||
void StructNewWithRtt(FullDecoder* decoder,
|
||||
const StructIndexImmediate<validate>& imm,
|
||||
const Value& rtt, const Value args[], Value* result) {
|
||||
@ -693,13 +681,6 @@ class WasmGraphBuildingInterface {
|
||||
field.index, field_value.node, null_check, decoder->position());
|
||||
}
|
||||
|
||||
void ArrayNew(FullDecoder* decoder, const ArrayIndexImmediate<validate>& imm,
|
||||
const Value& length, const Value& initial_value,
|
||||
Value* result) {
|
||||
result->node = BUILD(ArrayNew, imm.index, imm.array_type, length.node,
|
||||
initial_value.node);
|
||||
}
|
||||
|
||||
void ArrayNewWithRtt(FullDecoder* decoder,
|
||||
const ArrayIndexImmediate<validate>& imm,
|
||||
const Value& length, const Value& initial_value,
|
||||
|
@ -355,14 +355,12 @@ constexpr const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
|
||||
CASE_UNSIGNED_ALL_OP(AtomicCompareExchange, "atomic.cmpxchng")
|
||||
|
||||
// GC operations.
|
||||
CASE_OP(StructNew, "struct.new")
|
||||
CASE_OP(StructNewWithRtt, "struct.new_with_rtt")
|
||||
CASE_OP(StructNewDefault, "struct.new_default")
|
||||
CASE_OP(StructGet, "struct.get")
|
||||
CASE_OP(StructGetS, "struct.get_s")
|
||||
CASE_OP(StructGetU, "struct.get_u")
|
||||
CASE_OP(StructSet, "struct.set")
|
||||
CASE_OP(ArrayNew, "array.new")
|
||||
CASE_OP(ArrayNewWithRtt, "array.new_with_rtt")
|
||||
CASE_OP(ArrayNewDefault, "array.new_default")
|
||||
CASE_OP(ArrayGet, "array.get")
|
||||
|
@ -601,14 +601,12 @@ bool IsJSCompatibleSignature(const FunctionSig* sig, const WasmFeatures&);
|
||||
V(I64AtomicCompareExchange32U, 0xfe4e, l_ill)
|
||||
|
||||
#define FOREACH_GC_OPCODE(V) \
|
||||
V(StructNew, 0xfb00, _) \
|
||||
V(StructNewWithRtt, 0xfb01, _) \
|
||||
V(StructNewDefault, 0xfb02, _) \
|
||||
V(StructGet, 0xfb03, _) \
|
||||
V(StructGetS, 0xfb04, _) \
|
||||
V(StructGetU, 0xfb05, _) \
|
||||
V(StructSet, 0xfb06, _) \
|
||||
V(ArrayNew, 0xfb10, _) \
|
||||
V(ArrayNewWithRtt, 0xfb11, _) \
|
||||
V(ArrayNewDefault, 0xfb12, _) \
|
||||
V(ArrayGet, 0xfb13, _) \
|
||||
|
@ -172,7 +172,8 @@ TEST(WasmBasicStruct) {
|
||||
tester.sigs.i_v(), {},
|
||||
{WASM_STRUCT_GET(
|
||||
type_index, 0,
|
||||
WASM_STRUCT_NEW(type_index, WASM_I32V(42), WASM_I32V(64))),
|
||||
WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(42), WASM_I32V(64),
|
||||
WASM_RTT_CANON(type_index))),
|
||||
kExprEnd});
|
||||
|
||||
// Test struct.new and struct.get.
|
||||
@ -180,21 +181,26 @@ TEST(WasmBasicStruct) {
|
||||
tester.sigs.i_v(), {},
|
||||
{WASM_STRUCT_GET(
|
||||
type_index, 1,
|
||||
WASM_STRUCT_NEW(type_index, WASM_I32V(42), WASM_I32V(64))),
|
||||
WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(42), WASM_I32V(64),
|
||||
WASM_RTT_CANON(type_index))),
|
||||
kExprEnd});
|
||||
|
||||
// Test struct.new, returning struct reference.
|
||||
const uint32_t kGetStruct = tester.DefineFunction(
|
||||
&sig_q_v, {},
|
||||
{WASM_STRUCT_NEW(type_index, WASM_I32V(42), WASM_I32V(64)), kExprEnd});
|
||||
{WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(42), WASM_I32V(64),
|
||||
WASM_RTT_CANON(type_index)),
|
||||
kExprEnd});
|
||||
|
||||
// Test struct.set, struct refs types in locals.
|
||||
uint32_t j_local_index = 0;
|
||||
uint32_t j_field_index = 0;
|
||||
const uint32_t kSet = tester.DefineFunction(
|
||||
tester.sigs.i_v(), {kOptRefType},
|
||||
{WASM_SET_LOCAL(j_local_index, WASM_STRUCT_NEW(type_index, WASM_I32V(42),
|
||||
WASM_I32V(64))),
|
||||
{WASM_SET_LOCAL(
|
||||
j_local_index,
|
||||
WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(42), WASM_I32V(64),
|
||||
WASM_RTT_CANON(type_index))),
|
||||
WASM_STRUCT_SET(type_index, j_field_index, WASM_GET_LOCAL(j_local_index),
|
||||
WASM_I32V(-99)),
|
||||
WASM_STRUCT_GET(type_index, j_field_index,
|
||||
@ -226,8 +232,10 @@ TEST(WasmRefAsNonNull) {
|
||||
uint32_t field_index = 0;
|
||||
const uint32_t kFunc = tester.DefineFunction(
|
||||
tester.sigs.i_v(), {},
|
||||
{WASM_SET_GLOBAL(global_index, WASM_STRUCT_NEW(type_index, WASM_I32V(55),
|
||||
WASM_I32V(66))),
|
||||
{WASM_SET_GLOBAL(
|
||||
global_index,
|
||||
WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(55), WASM_I32V(66),
|
||||
WASM_RTT_CANON(type_index))),
|
||||
WASM_STRUCT_GET(
|
||||
type_index, field_index,
|
||||
WASM_REF_AS_NON_NULL(WASM_IF_ELSE_R(
|
||||
@ -265,8 +273,9 @@ TEST(WasmBrOnNull) {
|
||||
type_index, m_field_index,
|
||||
// Branch will not be taken.
|
||||
// 52 left on stack outside the block (not 42).
|
||||
WASM_BR_ON_NULL(0, WASM_STRUCT_NEW(type_index, WASM_I32V(52),
|
||||
WASM_I32V(62)))),
|
||||
WASM_BR_ON_NULL(0, WASM_STRUCT_NEW_WITH_RTT(
|
||||
type_index, WASM_I32V(52), WASM_I32V(62),
|
||||
WASM_RTT_CANON(type_index)))),
|
||||
WASM_BR(0)),
|
||||
kExprEnd});
|
||||
|
||||
@ -286,8 +295,9 @@ TEST(WasmRefEq) {
|
||||
byte local_index = 0;
|
||||
const uint32_t kFunc = tester.DefineFunction(
|
||||
tester.sigs.i_v(), {kOptRefType},
|
||||
{WASM_SET_LOCAL(local_index, WASM_STRUCT_NEW(type_index, WASM_I32V(55),
|
||||
WASM_I32V(66))),
|
||||
{WASM_SET_LOCAL(local_index, WASM_STRUCT_NEW_WITH_RTT(
|
||||
type_index, WASM_I32V(55), WASM_I32V(66),
|
||||
WASM_RTT_CANON(type_index))),
|
||||
WASM_I32_ADD(
|
||||
WASM_I32_SHL(
|
||||
WASM_REF_EQ( // true
|
||||
@ -296,8 +306,9 @@ TEST(WasmRefEq) {
|
||||
WASM_I32_ADD(
|
||||
WASM_I32_SHL(WASM_REF_EQ( // false
|
||||
WASM_GET_LOCAL(local_index),
|
||||
WASM_STRUCT_NEW(type_index, WASM_I32V(55),
|
||||
WASM_I32V(66))),
|
||||
WASM_STRUCT_NEW_WITH_RTT(
|
||||
type_index, WASM_I32V(55), WASM_I32V(66),
|
||||
WASM_RTT_CANON(type_index))),
|
||||
WASM_I32V(1)),
|
||||
WASM_I32_ADD(WASM_I32_SHL( // false
|
||||
WASM_REF_EQ(WASM_GET_LOCAL(local_index),
|
||||
@ -328,18 +339,20 @@ TEST(WasmPackedStructU) {
|
||||
const uint32_t kF0 = tester.DefineFunction(
|
||||
tester.sigs.i_v(), {struct_type},
|
||||
{WASM_SET_LOCAL(local_index,
|
||||
WASM_STRUCT_NEW(type_index, WASM_I32V(expected_output_0),
|
||||
WASM_I32V(expected_output_1),
|
||||
WASM_I32V(0x12345678))),
|
||||
WASM_STRUCT_NEW_WITH_RTT(
|
||||
type_index, WASM_I32V(expected_output_0),
|
||||
WASM_I32V(expected_output_1), WASM_I32V(0x12345678),
|
||||
WASM_RTT_CANON(type_index))),
|
||||
WASM_STRUCT_GET_U(type_index, 0, WASM_GET_LOCAL(local_index)),
|
||||
kExprEnd});
|
||||
|
||||
const uint32_t kF1 = tester.DefineFunction(
|
||||
tester.sigs.i_v(), {struct_type},
|
||||
{WASM_SET_LOCAL(local_index,
|
||||
WASM_STRUCT_NEW(type_index, WASM_I32V(expected_output_0),
|
||||
WASM_I32V(expected_output_1),
|
||||
WASM_I32V(0x12345678))),
|
||||
WASM_STRUCT_NEW_WITH_RTT(
|
||||
type_index, WASM_I32V(expected_output_0),
|
||||
WASM_I32V(expected_output_1), WASM_I32V(0x12345678),
|
||||
WASM_RTT_CANON(type_index))),
|
||||
WASM_STRUCT_GET_U(type_index, 1, WASM_GET_LOCAL(local_index)),
|
||||
kExprEnd});
|
||||
tester.CompileModule();
|
||||
@ -364,16 +377,19 @@ TEST(WasmPackedStructS) {
|
||||
tester.sigs.i_v(), {struct_type},
|
||||
{WASM_SET_LOCAL(
|
||||
local_index,
|
||||
WASM_STRUCT_NEW(type_index, WASM_I32V(expected_output_0),
|
||||
WASM_I32V(expected_output_1), WASM_I32V(0))),
|
||||
WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(expected_output_0),
|
||||
WASM_I32V(expected_output_1), WASM_I32V(0),
|
||||
WASM_RTT_CANON(type_index))),
|
||||
WASM_STRUCT_GET_S(type_index, 0, WASM_GET_LOCAL(local_index)),
|
||||
kExprEnd});
|
||||
|
||||
const uint32_t kF1 = tester.DefineFunction(
|
||||
tester.sigs.i_v(), {struct_type},
|
||||
{WASM_SET_LOCAL(local_index, WASM_STRUCT_NEW(type_index, WASM_I32V(0x80),
|
||||
WASM_I32V(expected_output_1),
|
||||
WASM_I32V(0))),
|
||||
{WASM_SET_LOCAL(
|
||||
local_index,
|
||||
WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(0x80),
|
||||
WASM_I32V(expected_output_1), WASM_I32V(0),
|
||||
WASM_RTT_CANON(type_index))),
|
||||
WASM_STRUCT_GET_S(type_index, 1, WASM_GET_LOCAL(local_index)),
|
||||
kExprEnd});
|
||||
|
||||
@ -392,21 +408,25 @@ TEST(WasmLetInstruction) {
|
||||
uint32_t let_field_index = 0;
|
||||
const uint32_t kLetTest1 = tester.DefineFunction(
|
||||
tester.sigs.i_v(), {},
|
||||
{WASM_LET_1_I(WASM_SEQ(kLocalRef, static_cast<byte>(type_index)),
|
||||
WASM_STRUCT_NEW(type_index, WASM_I32V(42), WASM_I32V(52)),
|
||||
WASM_STRUCT_GET(type_index, let_field_index,
|
||||
WASM_GET_LOCAL(let_local_index))),
|
||||
{WASM_LET_1_I(
|
||||
WASM_SEQ(kLocalRef, static_cast<byte>(type_index)),
|
||||
WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(42), WASM_I32V(52),
|
||||
WASM_RTT_CANON(type_index)),
|
||||
WASM_STRUCT_GET(type_index, let_field_index,
|
||||
WASM_GET_LOCAL(let_local_index))),
|
||||
kExprEnd});
|
||||
|
||||
uint32_t let_2_field_index = 0;
|
||||
const uint32_t kLetTest2 = tester.DefineFunction(
|
||||
tester.sigs.i_v(), {},
|
||||
{WASM_LET_2_I(kLocalI32, WASM_I32_ADD(WASM_I32V(42), WASM_I32V(-32)),
|
||||
WASM_SEQ(kLocalRef, static_cast<byte>(type_index)),
|
||||
WASM_STRUCT_NEW(type_index, WASM_I32V(42), WASM_I32V(52)),
|
||||
WASM_I32_MUL(WASM_STRUCT_GET(type_index, let_2_field_index,
|
||||
WASM_GET_LOCAL(1)),
|
||||
WASM_GET_LOCAL(0))),
|
||||
{WASM_LET_2_I(
|
||||
kLocalI32, WASM_I32_ADD(WASM_I32V(42), WASM_I32V(-32)),
|
||||
WASM_SEQ(kLocalRef, static_cast<byte>(type_index)),
|
||||
WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(42), WASM_I32V(52),
|
||||
WASM_RTT_CANON(type_index)),
|
||||
WASM_I32_MUL(WASM_STRUCT_GET(type_index, let_2_field_index,
|
||||
WASM_GET_LOCAL(1)),
|
||||
WASM_GET_LOCAL(0))),
|
||||
kExprEnd});
|
||||
|
||||
const uint32_t kLetTestLocals = tester.DefineFunction(
|
||||
@ -449,8 +469,9 @@ TEST(WasmBasicArray) {
|
||||
uint32_t local_index = 1;
|
||||
const uint32_t kGetElem = tester.DefineFunction(
|
||||
tester.sigs.i_i(), {kOptRefType},
|
||||
{WASM_SET_LOCAL(local_index,
|
||||
WASM_ARRAY_NEW(type_index, WASM_I32V(12), WASM_I32V(3))),
|
||||
{WASM_SET_LOCAL(local_index, WASM_ARRAY_NEW_WITH_RTT(
|
||||
type_index, WASM_I32V(12), WASM_I32V(3),
|
||||
WASM_RTT_CANON(type_index))),
|
||||
WASM_ARRAY_SET(type_index, WASM_GET_LOCAL(local_index), WASM_I32V(1),
|
||||
WASM_I32V(42)),
|
||||
WASM_ARRAY_GET(type_index, WASM_GET_LOCAL(local_index),
|
||||
@ -460,14 +481,17 @@ TEST(WasmBasicArray) {
|
||||
// Reads and returns an array's length.
|
||||
const uint32_t kGetLength = tester.DefineFunction(
|
||||
tester.sigs.i_v(), {},
|
||||
{WASM_ARRAY_LEN(type_index,
|
||||
WASM_ARRAY_NEW(type_index, WASM_I32V(0), WASM_I32V(42))),
|
||||
{WASM_ARRAY_LEN(type_index, WASM_ARRAY_NEW_WITH_RTT(
|
||||
type_index, WASM_I32V(0), WASM_I32V(42),
|
||||
WASM_RTT_CANON(type_index))),
|
||||
kExprEnd});
|
||||
|
||||
// Create an array of length 2, initialized to [42, 42].
|
||||
const uint32_t kAllocate = tester.DefineFunction(
|
||||
&sig_q_v, {},
|
||||
{WASM_ARRAY_NEW(type_index, WASM_I32V(42), WASM_I32V(2)), kExprEnd});
|
||||
{WASM_ARRAY_NEW_WITH_RTT(type_index, WASM_I32V(42), WASM_I32V(2),
|
||||
WASM_RTT_CANON(type_index)),
|
||||
kExprEnd});
|
||||
|
||||
tester.CompileModule();
|
||||
|
||||
@ -497,8 +521,9 @@ TEST(WasmPackedArrayU) {
|
||||
|
||||
const uint32_t kF = tester.DefineFunction(
|
||||
tester.sigs.i_i(), {array_type},
|
||||
{WASM_SET_LOCAL(local_index,
|
||||
WASM_ARRAY_NEW(array_index, WASM_I32V(0), WASM_I32V(4))),
|
||||
{WASM_SET_LOCAL(local_index, WASM_ARRAY_NEW_WITH_RTT(
|
||||
array_index, WASM_I32V(0), WASM_I32V(4),
|
||||
WASM_RTT_CANON(array_index))),
|
||||
WASM_ARRAY_SET(array_index, WASM_GET_LOCAL(local_index), WASM_I32V(0),
|
||||
WASM_I32V(1)),
|
||||
WASM_ARRAY_SET(array_index, WASM_GET_LOCAL(local_index), WASM_I32V(1),
|
||||
@ -532,7 +557,8 @@ TEST(WasmPackedArrayS) {
|
||||
tester.sigs.i_i(), {array_type},
|
||||
{WASM_SET_LOCAL(
|
||||
local_index,
|
||||
WASM_ARRAY_NEW(array_index, WASM_I32V(0x12345678), WASM_I32V(4))),
|
||||
WASM_ARRAY_NEW_WITH_RTT(array_index, WASM_I32V(0x12345678),
|
||||
WASM_I32V(4), WASM_RTT_CANON(array_index))),
|
||||
WASM_ARRAY_SET(array_index, WASM_GET_LOCAL(local_index), WASM_I32V(1),
|
||||
WASM_I32V(10)),
|
||||
WASM_ARRAY_SET(array_index, WASM_GET_LOCAL(local_index), WASM_I32V(2),
|
||||
@ -649,7 +675,7 @@ TEST(BasicRTT) {
|
||||
tester.CheckResult(kRefCast, 43);
|
||||
}
|
||||
|
||||
TEST(ArrayNewWithRtt) {
|
||||
TEST(ArrayNewMap) {
|
||||
WasmGCTester tester;
|
||||
uint32_t type_index = tester.DefineArray(kWasmI32, true);
|
||||
|
||||
@ -784,7 +810,9 @@ TEST(JsAccessDisallowed) {
|
||||
FunctionSig sig_q_v(1, 0, kRefTypes);
|
||||
|
||||
WasmFunctionBuilder* fun = tester.builder()->AddFunction(&sig_q_v);
|
||||
byte code[] = {WASM_STRUCT_NEW(type_index, WASM_I32V(42)), kExprEnd};
|
||||
byte code[] = {WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(42),
|
||||
WASM_RTT_CANON(type_index)),
|
||||
kExprEnd};
|
||||
fun->EmitCode(code, sizeof(code));
|
||||
tester.builder()->AddExport(CStrVector("f"), fun);
|
||||
tester.CompileModule();
|
||||
|
@ -428,8 +428,6 @@ inline WasmOpcode LoadStoreOpcodeOf(MachineType type, bool store) {
|
||||
// Heap-allocated object operations.
|
||||
//------------------------------------------------------------------------------
|
||||
#define WASM_GC_OP(op) kGCPrefix, static_cast<byte>(op)
|
||||
#define WASM_STRUCT_NEW(index, ...) \
|
||||
__VA_ARGS__, WASM_GC_OP(kExprStructNew), static_cast<byte>(index)
|
||||
#define WASM_STRUCT_NEW_WITH_RTT(index, ...) \
|
||||
__VA_ARGS__, WASM_GC_OP(kExprStructNewWithRtt), static_cast<byte>(index)
|
||||
#define WASM_STRUCT_GET(typeidx, fieldidx, struct_obj) \
|
||||
@ -456,8 +454,6 @@ inline WasmOpcode LoadStoreOpcodeOf(MachineType type, bool store) {
|
||||
ref, rtt, WASM_GC_OP(kExprRefCast), static_cast<byte>(obj_type), \
|
||||
static_cast<byte>(rtt_type)
|
||||
|
||||
#define WASM_ARRAY_NEW(index, default_value, length) \
|
||||
default_value, length, WASM_GC_OP(kExprArrayNew), static_cast<byte>(index)
|
||||
#define WASM_ARRAY_NEW_WITH_RTT(index, default_value, length, rtt) \
|
||||
default_value, length, rtt, WASM_GC_OP(kExprArrayNewWithRtt), \
|
||||
static_cast<byte>(index)
|
||||
|
@ -3363,26 +3363,30 @@ TEST_F(FunctionBodyDecoderTest, TableInitMultiTable) {
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, UnpackPackedTypes) {
|
||||
WASM_FEATURE_SCOPE(reftypes);
|
||||
WASM_FEATURE_SCOPE(typed_funcref);
|
||||
WASM_FEATURE_SCOPE(gc);
|
||||
{
|
||||
TestModuleBuilder builder;
|
||||
byte type_index = builder.AddStruct({F(kWasmI8, true), F(kWasmI16, false)});
|
||||
module = builder.module();
|
||||
ExpectValidates(sigs.v_v(),
|
||||
{WASM_STRUCT_SET(type_index, 0,
|
||||
WASM_STRUCT_NEW(type_index, WASM_I32V(1),
|
||||
WASM_I32V(42)),
|
||||
WASM_I32V(-1))});
|
||||
ExpectValidates(
|
||||
sigs.v_v(),
|
||||
{WASM_STRUCT_SET(
|
||||
type_index, 0,
|
||||
WASM_STRUCT_NEW_WITH_RTT(type_index, WASM_I32V(1), WASM_I32V(42),
|
||||
WASM_RTT_CANON(type_index)),
|
||||
WASM_I32V(-1))});
|
||||
}
|
||||
{
|
||||
TestModuleBuilder builder;
|
||||
byte type_index = builder.AddArray(kWasmI8, true);
|
||||
module = builder.module();
|
||||
ExpectValidates(
|
||||
sigs.v_v(),
|
||||
{WASM_ARRAY_SET(type_index,
|
||||
WASM_ARRAY_NEW(type_index, WASM_I32V(10), WASM_I32V(5)),
|
||||
WASM_I32V(3), WASM_I32V(12345678))});
|
||||
ExpectValidates(sigs.v_v(),
|
||||
{WASM_ARRAY_SET(type_index,
|
||||
WASM_ARRAY_NEW_WITH_RTT(
|
||||
type_index, WASM_I32V(10), WASM_I32V(5),
|
||||
WASM_RTT_CANON(type_index)),
|
||||
WASM_I32V(3), WASM_I32V(12345678))});
|
||||
}
|
||||
}
|
||||
|
||||
@ -3610,29 +3614,50 @@ TEST_F(FunctionBodyDecoderTest, GCStruct) {
|
||||
const FunctionSig sig_r_v(1, 0, &struct_type);
|
||||
const FunctionSig sig_f_r(1, 1, reps_f_r);
|
||||
|
||||
/** struct.new **/
|
||||
ExpectValidates(&sig_r_v, {WASM_STRUCT_NEW(struct_type_index, WASM_I32V(0))});
|
||||
/** struct.new_with_rtt **/
|
||||
ExpectValidates(
|
||||
&sig_r_v, {WASM_STRUCT_NEW_WITH_RTT(struct_type_index, WASM_I32V(0),
|
||||
WASM_RTT_CANON(struct_type_index))});
|
||||
// Too few arguments.
|
||||
ExpectFailure(
|
||||
&sig_r_v, {WASM_GC_OP(kExprStructNew), struct_type_index}, kAppendEnd,
|
||||
"not enough arguments on the stack for struct.new, expected 1 more");
|
||||
ExpectFailure(&sig_r_v,
|
||||
{WASM_STRUCT_NEW_WITH_RTT(struct_type_index,
|
||||
WASM_RTT_CANON(struct_type_index))},
|
||||
kAppendEnd,
|
||||
"not enough arguments on the stack for struct.new_with_rtt, "
|
||||
"expected 1 more");
|
||||
// Too many arguments.
|
||||
ExpectFailure(
|
||||
&sig_r_v,
|
||||
{WASM_STRUCT_NEW(struct_type_index, WASM_I32V(0), WASM_I32V(1))},
|
||||
{WASM_STRUCT_NEW_WITH_RTT(struct_type_index, WASM_I32V(0), WASM_I32V(1),
|
||||
WASM_RTT_CANON(struct_type_index))},
|
||||
kAppendEnd,
|
||||
"expected 1 elements on the stack for fallthru to @1, found 2");
|
||||
// Mistyped arguments.
|
||||
ExpectFailure(
|
||||
&sig_v_r, {WASM_STRUCT_NEW(struct_type_index, WASM_GET_LOCAL(0))},
|
||||
kAppendEnd,
|
||||
"struct.new[0] expected type i32, found local.get of type (ref 0)");
|
||||
ExpectFailure(&sig_v_r,
|
||||
{WASM_STRUCT_NEW_WITH_RTT(struct_type_index, WASM_GET_LOCAL(0),
|
||||
WASM_RTT_CANON(struct_type_index))},
|
||||
kAppendEnd,
|
||||
"struct.new_with_rtt[0] expected type i32, found local.get of "
|
||||
"type (ref 0)");
|
||||
// Wrongly typed index.
|
||||
ExpectFailure(sigs.v_v(),
|
||||
{WASM_STRUCT_NEW(array_type_index, WASM_I32V(0)), kExprDrop},
|
||||
{WASM_STRUCT_NEW_WITH_RTT(array_type_index, WASM_I32V(0),
|
||||
WASM_RTT_CANON(struct_type_index)),
|
||||
kExprDrop},
|
||||
kAppendEnd, "invalid struct index: 1");
|
||||
// Wrongly typed rtt.
|
||||
ExpectFailure(
|
||||
sigs.v_v(),
|
||||
{WASM_STRUCT_NEW_WITH_RTT(struct_type_index, WASM_I32V(0),
|
||||
WASM_RTT_CANON(array_type_index)),
|
||||
kExprDrop},
|
||||
kAppendEnd,
|
||||
"struct.new_with_rtt expected rtt for type 0, found rtt for type 1");
|
||||
// Out-of-bounds index.
|
||||
ExpectFailure(sigs.v_v(), {WASM_STRUCT_NEW(42, WASM_I32V(0)), kExprDrop},
|
||||
ExpectFailure(sigs.v_v(),
|
||||
{WASM_STRUCT_NEW_WITH_RTT(42, WASM_I32V(0),
|
||||
WASM_RTT_CANON(struct_type_index)),
|
||||
kExprDrop},
|
||||
kAppendEnd, "invalid struct index: 42");
|
||||
|
||||
/** struct.get **/
|
||||
@ -3680,12 +3705,14 @@ TEST_F(FunctionBodyDecoderTest, GCStruct) {
|
||||
kAppendEnd,
|
||||
"expected 1 elements on the stack for fallthru to @1, found 0");
|
||||
// Setting immutable field.
|
||||
ExpectFailure(sigs.v_v(),
|
||||
{WASM_STRUCT_SET(
|
||||
immutable_struct_type_index, field_index,
|
||||
WASM_STRUCT_NEW(immutable_struct_type_index, WASM_I32V(42)),
|
||||
WASM_I32V(0))},
|
||||
kAppendEnd, "setting immutable struct field");
|
||||
ExpectFailure(
|
||||
sigs.v_v(),
|
||||
{WASM_STRUCT_SET(
|
||||
immutable_struct_type_index, field_index,
|
||||
WASM_STRUCT_NEW_WITH_RTT(immutable_struct_type_index, WASM_I32V(42),
|
||||
WASM_RTT_CANON(immutable_struct_type_index)),
|
||||
WASM_I32V(0))},
|
||||
kAppendEnd, "setting immutable struct field");
|
||||
|
||||
// struct.get_s/u fail
|
||||
ExpectFailure(
|
||||
@ -3702,7 +3729,7 @@ TEST_F(FunctionBodyDecoderTest, GCStruct) {
|
||||
"instead.");
|
||||
}
|
||||
|
||||
TEST_F(FunctionBodyDecoderTest, GCArray1) {
|
||||
TEST_F(FunctionBodyDecoderTest, GCArray) {
|
||||
WASM_FEATURE_SCOPE(reftypes);
|
||||
WASM_FEATURE_SCOPE(typed_funcref);
|
||||
WASM_FEATURE_SCOPE(gc);
|
||||
@ -3723,34 +3750,48 @@ TEST_F(FunctionBodyDecoderTest, GCArray1) {
|
||||
const FunctionSig sig_v_cr(0, 2, reps_c_r);
|
||||
const FunctionSig sig_i_r(1, 1, reps_i_r);
|
||||
|
||||
/** array.new **/
|
||||
ExpectValidates(
|
||||
&sig_r_v, {WASM_ARRAY_NEW(array_type_index, WASM_REF_NULL(kLocalFuncRef),
|
||||
WASM_I32V(10))});
|
||||
/** array.new_with_rtt **/
|
||||
ExpectValidates(&sig_r_v,
|
||||
{WASM_ARRAY_NEW_WITH_RTT(
|
||||
array_type_index, WASM_REF_NULL(kLocalFuncRef),
|
||||
WASM_I32V(10), WASM_RTT_CANON(array_type_index))});
|
||||
// Too few arguments.
|
||||
ExpectFailure(
|
||||
&sig_r_v, {WASM_I32V(10), WASM_GC_OP(kExprArrayNew), array_type_index},
|
||||
kAppendEnd,
|
||||
"not enough arguments on the stack for array.new, expected 1 more");
|
||||
ExpectFailure(&sig_r_v,
|
||||
{WASM_I32V(10), WASM_RTT_CANON(array_type_index),
|
||||
WASM_GC_OP(kExprArrayNewWithRtt), array_type_index},
|
||||
kAppendEnd,
|
||||
"not enough arguments on the stack for array.new_with_rtt, "
|
||||
"expected 1 more");
|
||||
// Mistyped initializer.
|
||||
ExpectFailure(&sig_r_v,
|
||||
{WASM_ARRAY_NEW_WITH_RTT(
|
||||
array_type_index, WASM_REF_NULL(kLocalExternRef),
|
||||
WASM_I32V(10), WASM_RTT_CANON(array_type_index))},
|
||||
kAppendEnd,
|
||||
"array.new_with_rtt[0] expected type funcref, found ref.null "
|
||||
"of type externref");
|
||||
// Mistyped length.
|
||||
ExpectFailure(
|
||||
&sig_r_v,
|
||||
{WASM_ARRAY_NEW(array_type_index, WASM_REF_NULL(kLocalExternRef),
|
||||
WASM_I32V(10))},
|
||||
{WASM_ARRAY_NEW_WITH_RTT(array_type_index, WASM_REF_NULL(kLocalFuncRef),
|
||||
WASM_I64V(5), WASM_RTT_CANON(array_type_index))},
|
||||
kAppendEnd,
|
||||
"array.new[0] expected type funcref, found ref.null of type externref");
|
||||
// Mistyped length.
|
||||
ExpectFailure(&sig_r_v,
|
||||
{WASM_ARRAY_NEW(array_type_index, WASM_REF_NULL(kLocalFuncRef),
|
||||
WASM_I64V(5))},
|
||||
kAppendEnd,
|
||||
"array.new[1] expected type i32, found i64.const of type i64");
|
||||
"array.new_with_rtt[1] expected type i32, found i64.const of type i64");
|
||||
// Mistyped rtt.
|
||||
ExpectFailure(
|
||||
&sig_r_v,
|
||||
{WASM_ARRAY_NEW_WITH_RTT(array_type_index, WASM_REF_NULL(kLocalFuncRef),
|
||||
WASM_I32V(5),
|
||||
WASM_RTT_CANON(struct_type_index))},
|
||||
kAppendEnd,
|
||||
"array.new_with_rtt expected rtt for type 0, found rtt for type 1");
|
||||
// Wrong type index.
|
||||
ExpectFailure(sigs.v_v(),
|
||||
{WASM_ARRAY_NEW(struct_type_index, WASM_REF_NULL(kLocalFuncRef),
|
||||
WASM_I32V(10)),
|
||||
kExprDrop},
|
||||
kAppendEnd, "invalid array index: 1");
|
||||
ExpectFailure(
|
||||
sigs.v_v(),
|
||||
{WASM_ARRAY_NEW_WITH_RTT(struct_type_index, WASM_REF_NULL(kLocalFuncRef),
|
||||
WASM_I32V(10), WASM_RTT_CANON(array_type_index)),
|
||||
kExprDrop},
|
||||
kAppendEnd, "invalid array index: 1");
|
||||
|
||||
/** array.get **/
|
||||
ExpectValidates(&sig_c_r, {WASM_ARRAY_GET(array_type_index, WASM_GET_LOCAL(0),
|
||||
@ -3837,22 +3878,29 @@ TEST_F(FunctionBodyDecoderTest, PackedFields) {
|
||||
byte field_index = 0;
|
||||
|
||||
// *.new with packed fields works.
|
||||
ExpectValidates(sigs.v_v(), {WASM_ARRAY_NEW_WITH_RTT(
|
||||
array_type_index, WASM_I32V(0), WASM_I32V(5),
|
||||
WASM_RTT_CANON(array_type_index)),
|
||||
kExprDrop});
|
||||
ExpectValidates(sigs.v_v(),
|
||||
{WASM_ARRAY_NEW(array_type_index, WASM_I32V(0), WASM_I32V(5)),
|
||||
{WASM_STRUCT_NEW_WITH_RTT(struct_type_index, WASM_I32V(42),
|
||||
WASM_RTT_CANON(struct_type_index)),
|
||||
kExprDrop});
|
||||
ExpectValidates(
|
||||
sigs.v_v(),
|
||||
{WASM_STRUCT_NEW(struct_type_index, WASM_I32V(42)), kExprDrop});
|
||||
// It can't unpack types other that i32.
|
||||
ExpectFailure(
|
||||
sigs.v_v(),
|
||||
{WASM_ARRAY_NEW(array_type_index, WASM_I64V(0), WASM_I32V(5)), kExprDrop},
|
||||
{WASM_ARRAY_NEW_WITH_RTT(array_type_index, WASM_I64V(0), WASM_I32V(5),
|
||||
WASM_RTT_CANON(array_type_index)),
|
||||
kExprDrop},
|
||||
kAppendEnd,
|
||||
"array.new[0] expected type i32, found i64.const of type i64");
|
||||
ExpectFailure(sigs.v_v(),
|
||||
{WASM_STRUCT_NEW(struct_type_index, WASM_I64V(42)), kExprDrop},
|
||||
kAppendEnd,
|
||||
"struct.new[0] expected type i32, found i64.const of type i64");
|
||||
"array.new_with_rtt[0] expected type i32, found i64.const of type i64");
|
||||
ExpectFailure(
|
||||
sigs.v_v(),
|
||||
{WASM_STRUCT_NEW_WITH_RTT(struct_type_index, WASM_I64V(42),
|
||||
WASM_RTT_CANON(struct_type_index)),
|
||||
kExprDrop},
|
||||
kAppendEnd,
|
||||
"struct.new_with_rtt[0] expected type i32, found i64.const of type i64");
|
||||
|
||||
// *.set with packed fields works.
|
||||
ExpectValidates(sigs.v_v(), {WASM_ARRAY_SET(array_type_index,
|
||||
@ -3870,10 +3918,11 @@ TEST_F(FunctionBodyDecoderTest, PackedFields) {
|
||||
"array.set[2] expected type i32, found i64.const of type i64");
|
||||
ExpectFailure(
|
||||
sigs.v_v(),
|
||||
{WASM_STRUCT_NEW(struct_type_index, field_index,
|
||||
WASM_REF_NULL(struct_type_index), WASM_I64V(42))},
|
||||
{WASM_STRUCT_NEW_WITH_RTT(struct_type_index, field_index,
|
||||
WASM_REF_NULL(struct_type_index), WASM_I64V(42),
|
||||
WASM_RTT_CANON(struct_type_index))},
|
||||
kAppendEnd,
|
||||
"struct.new[0] expected type i32, found i64.const of type i64");
|
||||
"struct.new_with_rtt[0] expected type i32, found i64.const of type i64");
|
||||
|
||||
// *.get_s/u works.
|
||||
ExpectValidates(sigs.i_v(), {WASM_ARRAY_GET_S(array_type_index,
|
||||
|
Loading…
Reference in New Issue
Block a user