From d4a3ebeb2bd8483e3031b8d761ef917ec304ece1 Mon Sep 17 00:00:00 2001 From: Matthias Liedtke Date: Fri, 14 Oct 2022 10:46:34 +0200 Subject: [PATCH] Reland "Reland "[wasm-gc] Ref types: Convert dataref to structref"" This is a reland of commit 3b883e787df53fc8ec829ead16a2ed4ff268ce2e Fixed a test case that was merged in the meantime still using the old kExprRefAsData which is now called kExprRefAsStruct. Original change's description: > Reland "[wasm-gc] Ref types: Convert dataref to structref" > > This is a reland of commit 20327d1599425947e264029461bc0ea03751a4a7 > > Changed in reland: > - Added new flag wasm-gc-structref-as-dataref which defaults to true > and preserves the existing behavior. > - Passing --no-wasm-gc-structref-as-dataref enables the new behavior. > - The flag affects static subtyping information between structref and > arrays and the corresponding cast, test and br_on instructions. > - Even with the old behavior the name still changed to "structref". > > Original change's description: > > [wasm-gc] Ref types: Convert dataref to structref > > > > This change changes the type hierarchy in a non-backwards compatible > > way: dataref is replaced with structref meaning that arrayref is > > no longer a subtype of it. > > > > Bug: v8:7748 > > Change-Id: I965267d9ed11ea7c7d7df133cc39ee63e6b5abc3 > > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3929041 > > Reviewed-by: Jakob Kummerow > > Commit-Queue: Matthias Liedtke > > Cr-Commit-Position: refs/heads/main@{#83515} > > Bug: v8:7748 > Change-Id: I2d8dd49dbc56246c087ac93452a87f860ead2195 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3945109 > Reviewed-by: Jakob Kummerow > Commit-Queue: Matthias Liedtke > Cr-Commit-Position: refs/heads/main@{#83697} Bug: v8:7748 Change-Id: I54f7b141ffc5b7597420fa0c838412be825a260b Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3952936 Auto-Submit: Matthias Liedtke Reviewed-by: Jakob Kummerow Commit-Queue: Matthias Liedtke Commit-Queue: Jakob Kummerow Cr-Commit-Position: refs/heads/main@{#83706} --- src/compiler/wasm-compiler.cc | 56 +++++++---- src/compiler/wasm-compiler.h | 12 +-- src/flags/flag-definitions.h | 2 + src/wasm/baseline/liftoff-compiler.cc | 49 +++++----- src/wasm/function-body-decoder-impl.h | 77 +++++++++------ src/wasm/graph-builder-interface.cc | 22 ++--- src/wasm/value-type.h | 20 ++-- src/wasm/wasm-constants.h | 2 +- src/wasm/wasm-js.cc | 16 +-- src/wasm/wasm-objects.cc | 13 +-- src/wasm/wasm-opcodes.h | 8 +- src/wasm/wasm-subtyping.cc | 70 +++++++++---- test/cctest/wasm/test-gc.cc | 97 ++++++++++--------- test/common/wasm/wasm-macro-gen.h | 12 +-- test/fuzzer/wasm-compile.cc | 20 ++-- test/fuzzer/wasm-fuzzer-common.cc | 10 +- test/mjsunit/regress/wasm/regress-12874.js | 4 +- test/mjsunit/regress/wasm/regress-13061.js | 2 +- .../regress/wasm/typecheck-null-undefined.js | 2 +- test/mjsunit/wasm/array-init-from-segment.js | 2 +- test/mjsunit/wasm/gc-casts-from-any.js | 20 ++-- test/mjsunit/wasm/gc-casts-subtypes.js | 20 ++-- .../gc-experimental-string-conversions.js | 2 +- test/mjsunit/wasm/gc-experiments.js | 2 +- test/mjsunit/wasm/gc-js-interop-import.mjs | 2 +- test/mjsunit/wasm/gc-js-interop-wasm.js | 2 +- test/mjsunit/wasm/gc-optimizations.js | 2 +- test/mjsunit/wasm/reference-globals-import.js | 47 ++++----- test/mjsunit/wasm/reference-globals.js | 4 +- .../wasm/reference-table-js-interop.js | 45 ++++----- test/mjsunit/wasm/reference-tables.js | 4 +- .../wasm/runtime-type-canonicalization.js | 6 +- test/mjsunit/wasm/test-wasm-module-builder.js | 2 +- .../wasm/wasm-gc-externalize-internalize.js | 4 +- test/mjsunit/wasm/wasm-gc-js-roundtrip.js | 32 +++--- test/mjsunit/wasm/wasm-module-builder.js | 10 +- .../wasm/function-body-decoder-unittest.cc | 64 ++++++------ .../unittests/wasm/module-decoder-unittest.cc | 2 +- test/unittests/wasm/subtyping-unittest.cc | 65 ++++++------- 39 files changed, 446 insertions(+), 385 deletions(-) diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc index d30177f961..eff3b93c9f 100644 --- a/src/compiler/wasm-compiler.cc +++ b/src/compiler/wasm-compiler.cc @@ -5431,12 +5431,12 @@ WasmGraphBuilder::Callbacks WasmGraphBuilder::BranchCallbacks( void WasmGraphBuilder::DataCheck(Node* object, bool object_can_be_null, Callbacks callbacks, bool null_succeeds) { + // TODO(7748): Only used for backwards compatibility in combination with + // v8_flags.wasm_gc_structref_as_dataref. Remove. if (object_can_be_null) { if (null_succeeds) { callbacks.succeed_if(IsNull(object), BranchHint::kFalse); } else { - // TODO(7748): Is the extra null check actually beneficial for - // performance? callbacks.fail_if(IsNull(object), BranchHint::kFalse); } } @@ -5530,8 +5530,8 @@ Node* WasmGraphBuilder::RefTestAbstract(Node* object, wasm::HeapType type, return RefIsEq(object, is_nullable, null_succeeds); case wasm::HeapType::kI31: return RefIsI31(object, null_succeeds); - case wasm::HeapType::kData: - return RefIsData(object, is_nullable, null_succeeds); + case wasm::HeapType::kStruct: + return RefIsStruct(object, is_nullable, null_succeeds); case wasm::HeapType::kArray: return RefIsArray(object, is_nullable, null_succeeds); case wasm::HeapType::kAny: @@ -5572,36 +5572,52 @@ Node* WasmGraphBuilder::RefIsEq(Node* object, bool object_can_be_null, return done.PhiAt(0); } -Node* WasmGraphBuilder::RefIsData(Node* object, bool object_can_be_null, - bool null_succeeds) { +Node* WasmGraphBuilder::RefIsStruct(Node* object, bool object_can_be_null, + bool null_succeeds) { auto done = gasm_->MakeLabel(MachineRepresentation::kWord32); - DataCheck(object, object_can_be_null, TestCallbacks(&done), null_succeeds); + if (!v8_flags.wasm_gc_structref_as_dataref) { + ManagedObjectInstanceCheck(object, object_can_be_null, WASM_STRUCT_TYPE, + TestCallbacks(&done), null_succeeds); + } else { + DataCheck(object, object_can_be_null, TestCallbacks(&done), null_succeeds); + } gasm_->Goto(&done, Int32Constant(1)); gasm_->Bind(&done); return done.PhiAt(0); } -Node* WasmGraphBuilder::RefAsData(Node* object, bool object_can_be_null, - wasm::WasmCodePosition position) { +Node* WasmGraphBuilder::RefAsStruct(Node* object, bool object_can_be_null, + wasm::WasmCodePosition position) { bool null_succeeds = false; auto done = gasm_->MakeLabel(); - DataCheck(object, object_can_be_null, CastCallbacks(&done, position), - null_succeeds); + if (!v8_flags.wasm_gc_structref_as_dataref) { + ManagedObjectInstanceCheck(object, object_can_be_null, WASM_STRUCT_TYPE, + CastCallbacks(&done, position), null_succeeds); + } else { + DataCheck(object, object_can_be_null, CastCallbacks(&done, position), + null_succeeds); + } gasm_->Goto(&done); gasm_->Bind(&done); return object; } -void WasmGraphBuilder::BrOnData(Node* object, Node* /*rtt*/, - WasmTypeCheckConfig config, - Node** match_control, Node** match_effect, - Node** no_match_control, - Node** no_match_effect) { +void WasmGraphBuilder::BrOnStruct(Node* object, Node* /*rtt*/, + WasmTypeCheckConfig config, + Node** match_control, Node** match_effect, + Node** no_match_control, + Node** no_match_effect) { bool null_succeeds = false; BrOnCastAbs(match_control, match_effect, no_match_control, no_match_effect, [=](Callbacks callbacks) -> void { - return DataCheck(object, config.object_can_be_null, callbacks, - null_succeeds); + if (!v8_flags.wasm_gc_structref_as_dataref) { + return ManagedObjectInstanceCheck( + object, config.object_can_be_null, WASM_STRUCT_TYPE, + callbacks, null_succeeds); + } else { + return DataCheck(object, config.object_can_be_null, callbacks, + null_succeeds); + } }); } @@ -6407,7 +6423,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { gasm_->Bind(&done); return done.PhiAt(0); } - case wasm::HeapType::kData: + case wasm::HeapType::kStruct: case wasm::HeapType::kArray: // TODO(7748): Update this when JS interop is settled. if (type.kind() == wasm::kRefNull) { @@ -6548,7 +6564,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder { case wasm::HeapType::kI31: UNREACHABLE(); case wasm::HeapType::kFunc: - case wasm::HeapType::kData: + case wasm::HeapType::kStruct: case wasm::HeapType::kArray: case wasm::HeapType::kEq: default: { diff --git a/src/compiler/wasm-compiler.h b/src/compiler/wasm-compiler.h index 6ff58e8ed4..e00d9ee006 100644 --- a/src/compiler/wasm-compiler.h +++ b/src/compiler/wasm-compiler.h @@ -501,12 +501,12 @@ class WasmGraphBuilder { Node** match_control, Node** match_effect, Node** no_match_control, Node** no_match_effect); Node* RefIsEq(Node* object, bool object_can_be_null, bool null_succeeds); - Node* RefIsData(Node* object, bool object_can_be_null, bool null_succeeds); - Node* RefAsData(Node* object, bool object_can_be_null, - wasm::WasmCodePosition position); - void BrOnData(Node* object, Node* rtt, WasmTypeCheckConfig config, - Node** match_control, Node** match_effect, - Node** no_match_control, Node** no_match_effect); + Node* RefIsStruct(Node* object, bool object_can_be_null, bool null_succeeds); + Node* RefAsStruct(Node* object, bool object_can_be_null, + wasm::WasmCodePosition position); + void BrOnStruct(Node* object, Node* rtt, WasmTypeCheckConfig config, + Node** match_control, Node** match_effect, + Node** no_match_control, Node** no_match_effect); Node* RefIsArray(Node* object, bool object_can_be_null, bool null_succeeds); Node* RefAsArray(Node* object, bool object_can_be_null, wasm::WasmCodePosition position); diff --git a/src/flags/flag-definitions.h b/src/flags/flag-definitions.h index 586d512eb8..a3e3bda9af 100644 --- a/src/flags/flag-definitions.h +++ b/src/flags/flag-definitions.h @@ -1116,6 +1116,8 @@ DEFINE_IMPLICATION(experimental_wasm_stack_switching, experimental_wasm_type_reflection) DEFINE_BOOL(wasm_gc_js_interop, true, "experimental WasmGC-JS interop") +DEFINE_BOOL(wasm_gc_structref_as_dataref, true, + "compatibility mode: Treat structref as dataref") DEFINE_BOOL(wasm_staging, false, "enable staged wasm features") diff --git a/src/wasm/baseline/liftoff-compiler.cc b/src/wasm/baseline/liftoff-compiler.cc index d58950c4ad..b7802ebdf8 100644 --- a/src/wasm/baseline/liftoff-compiler.cc +++ b/src/wasm/baseline/liftoff-compiler.cc @@ -5997,8 +5997,8 @@ class LiftoffCompiler { return RefIsEq(decoder, obj, result_val, null_succeeds); case HeapType::kI31: return RefIsI31(decoder, obj, result_val, null_succeeds); - case HeapType::kData: - return RefIsData(decoder, obj, result_val, null_succeeds); + case HeapType::kStruct: + return RefIsStruct(decoder, obj, result_val, null_succeeds); case HeapType::kArray: return RefIsArray(decoder, obj, result_val, null_succeeds); case HeapType::kAny: @@ -6139,15 +6139,19 @@ class LiftoffCompiler { } // Abstract type checkers. They all fall through on match. - void DataCheck(TypeCheck& check, const FreezeCacheState& frozen) { + void StructCheck(TypeCheck& check, const FreezeCacheState& frozen) { LoadInstanceType(check, frozen, check.no_match); - // We're going to test a range of WasmObject instance types with a single - // unsigned comparison. - Register tmp = check.instance_type(); - __ emit_i32_subi(tmp, tmp, FIRST_WASM_OBJECT_TYPE); - __ emit_i32_cond_jumpi(kUnsignedGreaterThan, check.no_match, tmp, - LAST_WASM_OBJECT_TYPE - FIRST_WASM_OBJECT_TYPE, - frozen); + LiftoffRegister instance_type(check.instance_type()); + if (!v8_flags.wasm_gc_structref_as_dataref) { + __ emit_i32_cond_jumpi(kUnequal, check.no_match, check.instance_type(), + WASM_STRUCT_TYPE, frozen); + } else { + Register tmp = check.instance_type(); + __ emit_i32_subi(tmp, tmp, FIRST_WASM_OBJECT_TYPE); + __ emit_i32_cond_jumpi(kUnsignedGreaterThan, check.no_match, tmp, + LAST_WASM_OBJECT_TYPE - FIRST_WASM_OBJECT_TYPE, + frozen); + } } void ArrayCheck(TypeCheck& check, const FreezeCacheState& frozen) { @@ -6206,9 +6210,9 @@ class LiftoffCompiler { __ PushRegister(kI32, result); } - void RefIsData(FullDecoder* /* decoder */, const Value& object, - Value* /* result_val */, bool null_succeeds = false) { - AbstractTypeCheck<&LiftoffCompiler::DataCheck>(object, null_succeeds); + void RefIsStruct(FullDecoder* /* decoder */, const Value& object, + Value* /* result_val */, bool null_succeeds = false) { + AbstractTypeCheck<&LiftoffCompiler::StructCheck>(object, null_succeeds); } void RefIsEq(FullDecoder* /* decoder */, const Value& object, @@ -6238,9 +6242,9 @@ class LiftoffCompiler { (this->*type_checker)(check, frozen); } - void RefAsData(FullDecoder* decoder, const Value& object, - Value* /* result */) { - AbstractTypeCast<&LiftoffCompiler::DataCheck>(object, decoder, kRef); + void RefAsStruct(FullDecoder* decoder, const Value& object, + Value* /* result */) { + AbstractTypeCast<&LiftoffCompiler::StructCheck>(object, decoder, kRef); } void RefAsI31(FullDecoder* decoder, const Value& object, Value* result) { @@ -6294,9 +6298,9 @@ class LiftoffCompiler { __ bind(&end); } - void BrOnData(FullDecoder* decoder, const Value& object, - Value* /* value_on_branch */, uint32_t br_depth) { - BrOnAbstractType<&LiftoffCompiler::DataCheck>(object, decoder, br_depth); + void BrOnStruct(FullDecoder* decoder, const Value& object, + Value* /* value_on_branch */, uint32_t br_depth) { + BrOnAbstractType<&LiftoffCompiler::StructCheck>(object, decoder, br_depth); } void BrOnI31(FullDecoder* decoder, const Value& object, @@ -6309,9 +6313,10 @@ class LiftoffCompiler { BrOnAbstractType<&LiftoffCompiler::ArrayCheck>(object, decoder, br_depth); } - void BrOnNonData(FullDecoder* decoder, const Value& object, - Value* /* value_on_branch */, uint32_t br_depth) { - BrOnNonAbstractType<&LiftoffCompiler::DataCheck>(object, decoder, br_depth); + void BrOnNonStruct(FullDecoder* decoder, const Value& object, + Value* /* value_on_branch */, uint32_t br_depth) { + BrOnNonAbstractType<&LiftoffCompiler::StructCheck>(object, decoder, + br_depth); } void BrOnNonI31(FullDecoder* decoder, const Value& object, diff --git a/src/wasm/function-body-decoder-impl.h b/src/wasm/function-body-decoder-impl.h index 8aaff23750..7685fbdd06 100644 --- a/src/wasm/function-body-decoder-impl.h +++ b/src/wasm/function-body-decoder-impl.h @@ -238,7 +238,7 @@ HeapType read_heap_type(Decoder* decoder, const byte* pc, switch (code) { case kEqRefCode: case kI31RefCode: - case kDataRefCode: + case kStructRefCode: case kArrayRefCode: case kAnyRefCode: case kNoneCode: @@ -313,7 +313,7 @@ ValueType read_value_type(Decoder* decoder, const byte* pc, switch (code) { case kEqRefCode: case kI31RefCode: - case kDataRefCode: + case kStructRefCode: case kArrayRefCode: case kAnyRefCode: case kNoneCode: @@ -1076,17 +1076,18 @@ struct ControlBase : public PcForErrors { uint32_t depth) \ F(BrOnCastFail, const Value& obj, const Value& rtt, \ Value* result_on_fallthrough, uint32_t depth) \ - F(RefIsData, const Value& object, Value* result) \ + F(RefIsStruct, const Value& object, Value* result) \ F(RefIsEq, const Value& object, Value* result) \ F(RefIsI31, const Value& object, Value* result) \ F(RefIsArray, const Value& object, Value* result) \ - F(RefAsData, const Value& object, Value* result) \ + F(RefAsStruct, const Value& object, Value* result) \ F(RefAsI31, const Value& object, Value* result) \ F(RefAsArray, const Value& object, Value* result) \ - F(BrOnData, const Value& object, Value* value_on_branch, uint32_t br_depth) \ + F(BrOnStruct, const Value& object, Value* value_on_branch, \ + uint32_t br_depth) \ F(BrOnI31, const Value& object, Value* value_on_branch, uint32_t br_depth) \ F(BrOnArray, const Value& object, Value* value_on_branch, uint32_t br_depth) \ - F(BrOnNonData, const Value& object, Value* value_on_fallthrough, \ + F(BrOnNonStruct, const Value& object, Value* value_on_fallthrough, \ uint32_t br_depth) \ F(BrOnNonI31, const Value& object, Value* value_on_fallthrough, \ uint32_t br_depth) \ @@ -2045,10 +2046,10 @@ class WasmDecoder : public Decoder { return length + array_imm.length + data_imm.length; } case kExprBrOnArray: - case kExprBrOnData: + case kExprBrOnStruct: case kExprBrOnI31: case kExprBrOnNonArray: - case kExprBrOnNonData: + case kExprBrOnNonStruct: case kExprBrOnNonI31: { BranchDepthImmediate imm(decoder, pc + length); if (io) io->BranchDepth(imm); @@ -2081,10 +2082,10 @@ class WasmDecoder : public Decoder { case kExprI31GetS: case kExprI31GetU: case kExprRefAsArray: - case kExprRefAsData: + case kExprRefAsStruct: case kExprRefAsI31: case kExprRefIsArray: - case kExprRefIsData: + case kExprRefIsStruct: case kExprRefIsI31: case kExprExternInternalize: case kExprExternExternalize: @@ -4816,9 +4817,12 @@ class WasmFullDecoder : public WasmDecoder { Value obj = Peek(1); Value value = CreateValue(kWasmI32); if (!VALIDATE(IsSubtypeOf(obj.type, kWasmFuncRef, this->module_) || - IsSubtypeOf(obj.type, kWasmDataRef, this->module_) || + IsSubtypeOf(obj.type, kWasmStructRef, this->module_) || + IsSubtypeOf(obj.type, kWasmArrayRef, this->module_) || obj.type.is_bottom())) { - PopTypeError(0, obj, "subtype of (ref null func) or (ref null data)"); + PopTypeError(0, obj, + "subtype of (ref null func), (ref null struct) or (ref " + "null array)"); return 0; } if (current_code_reachable_and_ok_) { @@ -4862,9 +4866,12 @@ class WasmFullDecoder : public WasmDecoder { opcode_length += imm.length; Value obj = Peek(0); if (!VALIDATE(IsSubtypeOf(obj.type, kWasmFuncRef, this->module_) || - IsSubtypeOf(obj.type, kWasmDataRef, this->module_) || + IsSubtypeOf(obj.type, kWasmStructRef, this->module_) || + IsSubtypeOf(obj.type, kWasmArrayRef, this->module_) || obj.type.is_bottom())) { - PopTypeError(0, obj, "subtype of (ref null func) or (ref null data)"); + PopTypeError(0, obj, + "subtype of (ref null func), (ref null struct) or (ref " + "null array)"); return 0; } Value value = CreateValue(ValueType::RefMaybeNull( @@ -4886,9 +4893,12 @@ class WasmFullDecoder : public WasmDecoder { Push(rtt); Value obj = Peek(1); if (!VALIDATE(IsSubtypeOf(obj.type, kWasmFuncRef, this->module_) || - IsSubtypeOf(obj.type, kWasmDataRef, this->module_) || + IsSubtypeOf(obj.type, kWasmStructRef, this->module_) || + IsSubtypeOf(obj.type, kWasmArrayRef, this->module_) || obj.type.is_bottom())) { - PopTypeError(0, obj, "subtype of (ref null func) or (ref null data)"); + PopTypeError(0, obj, + "subtype of (ref null func), (ref null struct) or (ref " + "null array)"); return 0; } // If either value is bottom, we emit the most specific type possible. @@ -4943,9 +4953,12 @@ class WasmFullDecoder : public WasmDecoder { // anyway. Value obj = Peek(0); if (!VALIDATE(IsSubtypeOf(obj.type, kWasmFuncRef, this->module_) || - IsSubtypeOf(obj.type, kWasmDataRef, this->module_) || + IsSubtypeOf(obj.type, kWasmStructRef, this->module_) || + IsSubtypeOf(obj.type, kWasmArrayRef, this->module_) || obj.type.is_bottom())) { - PopTypeError(0, obj, "subtype of (ref null func) or (ref null data)"); + PopTypeError(0, obj, + "subtype of (ref null func), (ref null struct) or (ref " + "null array)"); return 0; } Control* c = control_at(branch_depth.depth); @@ -5010,9 +5023,12 @@ class WasmFullDecoder : public WasmDecoder { CALL_INTERFACE_IF_OK_AND_REACHABLE(RttCanon, imm.index, &rtt); Value obj = Peek(0); if (!VALIDATE(IsSubtypeOf(obj.type, kWasmFuncRef, this->module_) || - IsSubtypeOf(obj.type, kWasmDataRef, this->module_) || + IsSubtypeOf(obj.type, kWasmStructRef, this->module_) || + IsSubtypeOf(obj.type, kWasmArrayRef, this->module_) || obj.type.is_bottom())) { - PopTypeError(0, obj, "subtype of (ref null func) or (ref null data)"); + PopTypeError(0, obj, + "subtype of (ref null func), (ref null struct) or (ref " + "null array)"); return 0; } Control* c = control_at(branch_depth.depth); @@ -5092,7 +5108,7 @@ class WasmFullDecoder : public WasmDecoder { Push(result); \ return opcode_length; \ } - ABSTRACT_TYPE_CHECK(Data) + ABSTRACT_TYPE_CHECK(Struct) ABSTRACT_TYPE_CHECK(I31) ABSTRACT_TYPE_CHECK(Array) #undef ABSTRACT_TYPE_CHECK @@ -5126,12 +5142,12 @@ class WasmFullDecoder : public WasmDecoder { Push(result); \ return opcode_length; \ } - ABSTRACT_TYPE_CAST(Data) + ABSTRACT_TYPE_CAST(Struct) ABSTRACT_TYPE_CAST(I31) ABSTRACT_TYPE_CAST(Array) #undef ABSTRACT_TYPE_CAST - case kExprBrOnData: + case kExprBrOnStruct: case kExprBrOnArray: case kExprBrOnI31: { NON_CONST_ONLY @@ -5157,7 +5173,7 @@ class WasmFullDecoder : public WasmDecoder { Value obj = Peek(0, 0, kWasmAnyRef); Drop(obj); HeapType::Representation heap_type = - opcode == kExprBrOnData ? HeapType::kData + opcode == kExprBrOnStruct ? HeapType::kStruct : opcode == kExprBrOnArray ? HeapType::kArray : HeapType::kI31; Value result_on_branch = CreateValue(ValueType::Ref(heap_type)); @@ -5168,8 +5184,9 @@ class WasmFullDecoder : public WasmDecoder { // {result_on_branch} which was passed-by-value to {Push}. Value* value_on_branch = stack_value(1); if (V8_LIKELY(current_code_reachable_and_ok_)) { - if (opcode == kExprBrOnData) { - CALL_INTERFACE(BrOnData, obj, value_on_branch, branch_depth.depth); + if (opcode == kExprBrOnStruct) { + CALL_INTERFACE(BrOnStruct, obj, value_on_branch, + branch_depth.depth); } else if (opcode == kExprBrOnArray) { CALL_INTERFACE(BrOnArray, obj, value_on_branch, branch_depth.depth); } else { @@ -5181,7 +5198,7 @@ class WasmFullDecoder : public WasmDecoder { Push(obj); // Restore stack state on fallthrough. return opcode_length + branch_depth.length; } - case kExprBrOnNonData: + case kExprBrOnNonStruct: case kExprBrOnNonArray: case kExprBrOnNonI31: { NON_CONST_ONLY @@ -5202,14 +5219,14 @@ class WasmFullDecoder : public WasmDecoder { Value obj = Peek(0, 0, kWasmAnyRef); HeapType::Representation heap_type = - opcode == kExprBrOnNonData ? HeapType::kData + opcode == kExprBrOnNonStruct ? HeapType::kStruct : opcode == kExprBrOnNonArray ? HeapType::kArray : HeapType::kI31; Value value_on_fallthrough = CreateValue(ValueType::Ref(heap_type)); if (V8_LIKELY(current_code_reachable_and_ok_)) { - if (opcode == kExprBrOnNonData) { - CALL_INTERFACE(BrOnNonData, obj, &value_on_fallthrough, + if (opcode == kExprBrOnNonStruct) { + CALL_INTERFACE(BrOnNonStruct, obj, &value_on_fallthrough, branch_depth.depth); } else if (opcode == kExprBrOnNonArray) { CALL_INTERFACE(BrOnNonArray, obj, &value_on_fallthrough, diff --git a/src/wasm/graph-builder-interface.cc b/src/wasm/graph-builder-interface.cc index 8df643bc4c..e73cef442e 100644 --- a/src/wasm/graph-builder-interface.cc +++ b/src/wasm/graph-builder-interface.cc @@ -1314,30 +1314,30 @@ class WasmGraphBuildingInterface { null_succeeds)); } - void RefIsData(FullDecoder* decoder, const Value& object, Value* result) { + void RefIsStruct(FullDecoder* decoder, const Value& object, Value* result) { bool null_succeeds = false; SetAndTypeNode(result, - builder_->RefIsData(object.node, object.type.is_nullable(), - null_succeeds)); + builder_->RefIsStruct(object.node, object.type.is_nullable(), + null_succeeds)); } - void RefAsData(FullDecoder* decoder, const Value& object, Value* result) { - TFNode* cast_object = builder_->RefAsData( + void RefAsStruct(FullDecoder* decoder, const Value& object, Value* result) { + TFNode* cast_object = builder_->RefAsStruct( object.node, object.type.is_nullable(), decoder->position()); TFNode* rename = builder_->TypeGuard(cast_object, result->type); SetAndTypeNode(result, rename); } - void BrOnData(FullDecoder* decoder, const Value& object, - Value* value_on_branch, uint32_t br_depth) { - BrOnCastAbs<&compiler::WasmGraphBuilder::BrOnData>( + void BrOnStruct(FullDecoder* decoder, const Value& object, + Value* value_on_branch, uint32_t br_depth) { + BrOnCastAbs<&compiler::WasmGraphBuilder::BrOnStruct>( decoder, object, Value{nullptr, kWasmBottom}, value_on_branch, br_depth, true); } - void BrOnNonData(FullDecoder* decoder, const Value& object, - Value* value_on_fallthrough, uint32_t br_depth) { - BrOnCastAbs<&compiler::WasmGraphBuilder::BrOnData>( + void BrOnNonStruct(FullDecoder* decoder, const Value& object, + Value* value_on_fallthrough, uint32_t br_depth) { + BrOnCastAbs<&compiler::WasmGraphBuilder::BrOnStruct>( decoder, object, Value{nullptr, kWasmBottom}, value_on_fallthrough, br_depth, false); } diff --git a/src/wasm/value-type.h b/src/wasm/value-type.h index da001f037a..12f1bdd777 100644 --- a/src/wasm/value-type.h +++ b/src/wasm/value-type.h @@ -62,7 +62,7 @@ class HeapType { kFunc = kV8MaxWasmTypes, // shorthand: c kEq, // shorthand: q kI31, // shorthand: j - kData, // shorthand: o + kStruct, // shorthand: o kArray, // shorthand: g kAny, // kExtern, // shorthand: a. @@ -90,8 +90,8 @@ class HeapType { return HeapType(kAny); case ValueTypeCode::kExternRefCode: return HeapType(kExtern); - case ValueTypeCode::kDataRefCode: - return HeapType(kData); + case ValueTypeCode::kStructRefCode: + return HeapType(kStruct); case ValueTypeCode::kArrayRefCode: return HeapType(kArray); case ValueTypeCode::kStringRefCode: @@ -156,8 +156,8 @@ class HeapType { return std::string("eq"); case kI31: return std::string("i31"); - case kData: - return std::string("data"); + case kStruct: + return std::string("struct"); case kArray: return std::string("array"); case kExtern: @@ -195,8 +195,8 @@ class HeapType { return mask | kEqRefCode; case kI31: return mask | kI31RefCode; - case kData: - return mask | kDataRefCode; + case kStruct: + return mask | kStructRefCode; case kArray: return mask | kArrayRefCode; case kExtern: @@ -550,8 +550,8 @@ class ValueType { return kAnyRefCode; case HeapType::kI31: return kI31RefCode; - case HeapType::kData: - return kDataRefCode; + case HeapType::kStruct: + return kStructRefCode; case HeapType::kArray: return kArrayRefCode; case HeapType::kString: @@ -702,7 +702,7 @@ constexpr ValueType kWasmAnyRef = ValueType::RefNull(HeapType::kAny); constexpr ValueType kWasmExternRef = ValueType::RefNull(HeapType::kExtern); constexpr ValueType kWasmEqRef = ValueType::RefNull(HeapType::kEq); constexpr ValueType kWasmI31Ref = ValueType::RefNull(HeapType::kI31); -constexpr ValueType kWasmDataRef = ValueType::RefNull(HeapType::kData); +constexpr ValueType kWasmStructRef = ValueType::RefNull(HeapType::kStruct); constexpr ValueType kWasmArrayRef = ValueType::RefNull(HeapType::kArray); constexpr ValueType kWasmStringRef = ValueType::RefNull(HeapType::kString); constexpr ValueType kWasmStringViewWtf8 = diff --git a/src/wasm/wasm-constants.h b/src/wasm/wasm-constants.h index 316694ec59..0f64a2aa7a 100644 --- a/src/wasm/wasm-constants.h +++ b/src/wasm/wasm-constants.h @@ -48,7 +48,7 @@ enum ValueTypeCode : uint8_t { kRefNullCode = 0x6c, kRefCode = 0x6b, kI31RefCode = 0x6a, - kDataRefCode = 0x67, + kStructRefCode = 0x67, kArrayRefCode = 0x66, kNoneCode = 0x65, kStringRefCode = 0x64, diff --git a/src/wasm/wasm-js.cc b/src/wasm/wasm-js.cc index 7806d88567..99c3f32b1f 100644 --- a/src/wasm/wasm-js.cc +++ b/src/wasm/wasm-js.cc @@ -1174,8 +1174,8 @@ void WebAssemblyTable(const v8::FunctionCallbackInfo& args) { string->StringEquals(v8_str(isolate, "eqref"))) { type = i::wasm::kWasmEqRef; } else if (enabled_features.has_gc() && - string->StringEquals(v8_str(isolate, "dataref"))) { - type = i::wasm::kWasmDataRef; + string->StringEquals(v8_str(isolate, "structref"))) { + type = i::wasm::kWasmStructRef; } else if (enabled_features.has_gc() && string->StringEquals(v8_str(isolate, "arrayref"))) { type = i::wasm::kWasmArrayRef; @@ -1390,8 +1390,8 @@ bool GetValueType(Isolate* isolate, MaybeLocal maybe, string->StringEquals(v8_str(isolate, "anyref"))) { *type = i::wasm::kWasmAnyRef; } else if (enabled_features.has_gc() && - string->StringEquals(v8_str(isolate, "dataref"))) { - *type = i::wasm::kWasmDataRef; + string->StringEquals(v8_str(isolate, "structref"))) { + *type = i::wasm::kWasmStructRef; } else if (enabled_features.has_gc() && string->StringEquals(v8_str(isolate, "arrayref"))) { *type = i::wasm::kWasmArrayRef; @@ -1747,7 +1747,7 @@ void EncodeExceptionValues(v8::Isolate* isolate, case i::wasm::HeapType::kAny: case i::wasm::HeapType::kEq: case i::wasm::HeapType::kI31: - case i::wasm::HeapType::kData: + case i::wasm::HeapType::kStruct: case i::wasm::HeapType::kArray: case i::wasm::HeapType::kString: case i::wasm::HeapType::kStringViewWtf8: @@ -2263,7 +2263,7 @@ void WasmObjectToJSReturnValue(v8::ReturnValue& return_value, return; case i::wasm::HeapType::kBottom: UNREACHABLE(); - case i::wasm::HeapType::kData: + case i::wasm::HeapType::kStruct: case i::wasm::HeapType::kArray: case i::wasm::HeapType::kEq: case i::wasm::HeapType::kAny: { @@ -2572,7 +2572,7 @@ void WebAssemblyExceptionGetArg( case i::wasm::HeapType::kAny: case i::wasm::HeapType::kEq: case i::wasm::HeapType::kI31: - case i::wasm::HeapType::kData: + case i::wasm::HeapType::kStruct: case i::wasm::HeapType::kArray: case i::wasm::HeapType::kString: case i::wasm::HeapType::kStringViewWtf8: @@ -2636,7 +2636,7 @@ void WebAssemblyExceptionGetArg( case i::wasm::HeapType::kEq: case i::wasm::HeapType::kI31: case i::wasm::HeapType::kArray: - case i::wasm::HeapType::kData: + case i::wasm::HeapType::kStruct: case i::wasm::HeapType::kString: case i::wasm::HeapType::kStringViewWtf8: case i::wasm::HeapType::kStringViewWtf16: diff --git a/src/wasm/wasm-objects.cc b/src/wasm/wasm-objects.cc index caa2440104..19430719f4 100644 --- a/src/wasm/wasm-objects.cc +++ b/src/wasm/wasm-objects.cc @@ -325,7 +325,7 @@ void WasmTableObject::Set(Isolate* isolate, Handle table, case wasm::HeapType::kStringViewWtf16: case wasm::HeapType::kStringViewIter: case wasm::HeapType::kEq: - case wasm::HeapType::kData: + case wasm::HeapType::kStruct: case wasm::HeapType::kArray: case wasm::HeapType::kAny: case wasm::HeapType::kI31: @@ -373,7 +373,7 @@ Handle WasmTableObject::Get(Isolate* isolate, case wasm::HeapType::kString: case wasm::HeapType::kEq: case wasm::HeapType::kI31: - case wasm::HeapType::kData: + case wasm::HeapType::kStruct: case wasm::HeapType::kArray: case wasm::HeapType::kAny: return entry; @@ -2291,15 +2291,16 @@ MaybeHandle JSToWasmObject(Isolate* isolate, const WasmModule* module, *error_message = "null is not allowed for (ref any)"; return {}; } - case HeapType::kData: { + case HeapType::kStruct: { if (v8_flags.wasm_gc_js_interop - ? value->IsWasmStruct() || value->IsWasmArray() + ? value->IsWasmStruct() || + (value->IsWasmArray() && + v8_flags.wasm_gc_structref_as_dataref) : TryUnpackObjectWrapper(isolate, value)) { return value; } *error_message = - "dataref object must be null (if nullable) or a wasm " - "struct/array"; + "structref object must be null (if nullable) or a wasm struct"; return {}; } case HeapType::kArray: { diff --git a/src/wasm/wasm-opcodes.h b/src/wasm/wasm-opcodes.h index 7d4c80d0b8..7f2dd5a48e 100644 --- a/src/wasm/wasm-opcodes.h +++ b/src/wasm/wasm-opcodes.h @@ -714,16 +714,16 @@ bool V8_EXPORT_PRIVATE IsJSCompatibleSignature(const FunctionSig* sig, V(BrOnCast, 0xfb46, _, "br_on_cast") \ V(BrOnCastFail, 0xfb47, _, "br_on_cast_fail") \ V(RefCastNop, 0xfb4c, _, "ref.cast_nop") \ - V(RefIsData, 0xfb51, _, "ref.is_data") \ + V(RefIsStruct, 0xfb51, _, "ref.is_struct") \ V(RefIsI31, 0xfb52, _, "ref.is_i31") \ V(RefIsArray, 0xfb53, _, "ref.is_array") \ - V(RefAsData, 0xfb59, _, "ref.as_data") \ + V(RefAsStruct, 0xfb59, _, "ref.as_struct") \ V(RefAsI31, 0xfb5a, _, "ref.as_i31") \ V(RefAsArray, 0xfb5b, _, "ref.as_array") \ - V(BrOnData, 0xfb61, _, "br_on_data") \ + V(BrOnStruct, 0xfb61, _, "br_on_struct") \ V(BrOnI31, 0xfb62, _, "br_on_i31") \ V(BrOnArray, 0xfb66, _, "br_on_array") \ - V(BrOnNonData, 0xfb64, _, "br_on_non_data") \ + V(BrOnNonStruct, 0xfb64, _, "br_on_non_struct") \ V(BrOnNonI31, 0xfb65, _, "br_on_non_i31") \ V(BrOnNonArray, 0xfb67, _, "br_on_non_array") \ V(ExternInternalize, 0xfb70, _, "extern.internalize") \ diff --git a/src/wasm/wasm-subtyping.cc b/src/wasm/wasm-subtyping.cc index 8cc6ba872f..2a78123521 100644 --- a/src/wasm/wasm-subtyping.cc +++ b/src/wasm/wasm-subtyping.cc @@ -4,6 +4,7 @@ #include "src/wasm/wasm-subtyping.h" +#include "src/base/v8-fallthrough.h" #include "src/wasm/canonical-types.h" #include "src/wasm/wasm-module.h" @@ -104,7 +105,7 @@ HeapType::Representation NullSentinelImpl(HeapType type, case HeapType::kI31: case HeapType::kNone: case HeapType::kEq: - case HeapType::kData: + case HeapType::kStruct: case HeapType::kArray: case HeapType::kAny: case HeapType::kString: @@ -211,12 +212,17 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsHeapSubtypeOfImpl( case HeapType::kExtern: return super_heap == HeapType::kExtern; case HeapType::kI31: - case HeapType::kData: + case HeapType::kStruct: + case HeapType::kArray: + if (v8_flags.wasm_gc_structref_as_dataref && + sub_heap.representation() == HeapType::kArray) { + // TODO(7748): Remove temporary workaround for backwards compatibility. + return super_heap == HeapType::kArray || + super_heap == HeapType::kStruct || super_heap == HeapType::kEq || + super_heap == HeapType::kAny; + } return super_heap == sub_heap || super_heap == HeapType::kEq || super_heap == HeapType::kAny; - case HeapType::kArray: - return super_heap == HeapType::kArray || super_heap == HeapType::kData || - super_heap == HeapType::kEq || super_heap == HeapType::kAny; case HeapType::kString: // stringref is a subtype of anyref under wasm-gc. return sub_heap == super_heap || @@ -256,8 +262,12 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsHeapSubtypeOfImpl( switch (super_heap.representation()) { case HeapType::kFunc: return sub_module->has_signature(sub_index); + case HeapType::kStruct: + if (!v8_flags.wasm_gc_structref_as_dataref) { + return sub_module->has_struct(sub_index); + } + V8_FALLTHROUGH; case HeapType::kEq: - case HeapType::kData: case HeapType::kAny: return !sub_module->has_signature(sub_index); case HeapType::kArray: @@ -345,14 +355,25 @@ HeapType::Representation CommonAncestor(uint32_t type_index1, DCHECK_EQ(kind2, kind1); return HeapType::kFunc; case TypeDefinition::kStruct: - DCHECK_NE(kind2, TypeDefinition::kFunction); - return HeapType::kData; + if (v8_flags.wasm_gc_structref_as_dataref) { + DCHECK_NE(kind2, TypeDefinition::kFunction); + return HeapType::kStruct; + } + switch (kind2) { + case TypeDefinition::kFunction: + UNREACHABLE(); + case TypeDefinition::kStruct: + return HeapType::kStruct; + case TypeDefinition::kArray: + return HeapType::kEq; + } case TypeDefinition::kArray: switch (kind2) { case TypeDefinition::kFunction: UNREACHABLE(); case TypeDefinition::kStruct: - return HeapType::kData; + return v8_flags.wasm_gc_structref_as_dataref ? HeapType::kStruct + : HeapType::kEq; case TypeDefinition::kArray: return HeapType::kArray; } @@ -380,7 +401,7 @@ HeapType::Representation CommonAncestorWithGeneric(HeapType heap1, case HeapType::kNone: return HeapType::kI31; case HeapType::kEq: - case HeapType::kData: + case HeapType::kStruct: case HeapType::kArray: return HeapType::kEq; case HeapType::kAny: @@ -394,12 +415,14 @@ HeapType::Representation CommonAncestorWithGeneric(HeapType heap1, return module2->has_signature(heap2.ref_index()) ? HeapType::kBottom : HeapType::kEq; } - case HeapType::kData: + case HeapType::kStruct: switch (heap2.representation()) { - case HeapType::kData: - case HeapType::kArray: + case HeapType::kStruct: case HeapType::kNone: - return HeapType::kData; + return HeapType::kStruct; + case HeapType::kArray: + return v8_flags.wasm_gc_structref_as_dataref ? HeapType::kStruct + : HeapType::kEq; case HeapType::kI31: case HeapType::kEq: return HeapType::kEq; @@ -412,15 +435,17 @@ HeapType::Representation CommonAncestorWithGeneric(HeapType heap1, UNREACHABLE(); default: return module2->has_signature(heap2.ref_index()) ? HeapType::kBottom - : HeapType::kData; + : module2->has_struct(heap2.ref_index()) ? HeapType::kStruct + : v8_flags.wasm_gc_structref_as_dataref ? HeapType::kStruct + : HeapType::kEq; } case HeapType::kArray: switch (heap2.representation()) { case HeapType::kArray: case HeapType::kNone: return HeapType::kArray; - case HeapType::kData: - return HeapType::kData; + case HeapType::kStruct: + return HeapType::kEq; case HeapType::kI31: case HeapType::kEq: return HeapType::kEq; @@ -432,9 +457,12 @@ HeapType::Representation CommonAncestorWithGeneric(HeapType heap1, case HeapType::kNoFunc: UNREACHABLE(); default: - return module2->has_array(heap2.ref_index()) ? HeapType::kArray - : module2->has_struct(heap2.ref_index()) ? HeapType::kData - : HeapType::kBottom; + return module2->has_array(heap2.ref_index()) ? HeapType::kArray + : module2->has_struct(heap2.ref_index()) + ? (v8_flags.wasm_gc_structref_as_dataref + ? HeapType::kStruct + : HeapType::kEq) + : HeapType::kBottom; } case HeapType::kAny: return HeapType::kAny; @@ -446,7 +474,7 @@ HeapType::Representation CommonAncestorWithGeneric(HeapType heap1, switch (heap2.representation()) { case HeapType::kArray: case HeapType::kNone: - case HeapType::kData: + case HeapType::kStruct: case HeapType::kI31: case HeapType::kEq: case HeapType::kAny: diff --git a/test/cctest/wasm/test-gc.cc b/test/cctest/wasm/test-gc.cc index 945f100dab..8c269e9bc0 100644 --- a/test/cctest/wasm/test-gc.cc +++ b/test/cctest/wasm/test-gc.cc @@ -571,7 +571,7 @@ WASM_COMPILED_EXEC_TEST(BrOnCast) { const byte other_type_index = tester.DefineStruct({F(kWasmF32, true)}); const byte kTestStructStatic = tester.DefineFunction( - tester.sigs.i_v(), {kWasmI32, kWasmDataRef}, + tester.sigs.i_v(), {kWasmI32, kWasmStructRef}, {WASM_BLOCK_R( ValueType::RefNull(type_index), WASM_LOCAL_SET(0, WASM_I32V(111)), // Pipe a struct through a local so it's statically typed @@ -593,7 +593,7 @@ WASM_COMPILED_EXEC_TEST(BrOnCast) { kExprI32Add, kExprEnd}); const byte kTestNull = tester.DefineFunction( - tester.sigs.i_v(), {kWasmI32, kWasmDataRef}, + tester.sigs.i_v(), {kWasmI32, kWasmStructRef}, {WASM_BLOCK_R( ValueType::RefNull(type_index), WASM_LOCAL_SET(0, WASM_I32V(111)), WASM_LOCAL_GET(1), // Put a nullref onto the value stack. @@ -604,7 +604,7 @@ WASM_COMPILED_EXEC_TEST(BrOnCast) { WASM_DROP, WASM_LOCAL_GET(0), kExprEnd}); const byte kTypedAfterBranch = tester.DefineFunction( - tester.sigs.i_v(), {kWasmI32, kWasmDataRef}, + tester.sigs.i_v(), {kWasmI32, kWasmStructRef}, {WASM_LOCAL_SET(1, WASM_STRUCT_NEW(type_index, WASM_I32V(42))), WASM_BLOCK_I( // The inner block should take the early branch with a struct @@ -645,7 +645,7 @@ WASM_COMPILED_EXEC_TEST(BrOnCastFail) { #define FUNCTION_BODY(value) \ WASM_LOCAL_SET(0, WASM_SEQ(value)), \ WASM_BLOCK( \ - WASM_BLOCK_R(kWasmDataRef, WASM_LOCAL_GET(0), \ + WASM_BLOCK_R(kWasmStructRef, WASM_LOCAL_GET(0), \ WASM_BR_ON_CAST_FAIL(0, type0), \ WASM_GC_OP(kExprStructGet), type0, 0, kExprReturn), \ kExprBrOnNull, 0, WASM_GC_OP(kExprRefCast), type1, \ @@ -653,16 +653,17 @@ WASM_COMPILED_EXEC_TEST(BrOnCastFail) { WASM_I32V(null_value), kExprEnd const byte kBranchTaken = tester.DefineFunction( - tester.sigs.i_v(), {kWasmDataRef}, + tester.sigs.i_v(), {kWasmStructRef}, {FUNCTION_BODY( WASM_STRUCT_NEW(type1, WASM_I64V(10), WASM_I32V(field1_value)))}); const byte kBranchNotTaken = tester.DefineFunction( - tester.sigs.i_v(), {kWasmDataRef}, + tester.sigs.i_v(), {kWasmStructRef}, {FUNCTION_BODY(WASM_STRUCT_NEW(type0, WASM_I32V(field0_value)))}); - const byte kNull = tester.DefineFunction( - tester.sigs.i_v(), {kWasmDataRef}, {FUNCTION_BODY(WASM_REF_NULL(type0))}); + const byte kNull = + tester.DefineFunction(tester.sigs.i_v(), {kWasmStructRef}, + {FUNCTION_BODY(WASM_REF_NULL(type0))}); const byte kUnrelatedTypes = tester.DefineFunction( tester.sigs.i_v(), {ValueType::RefNull(type1)}, @@ -671,11 +672,11 @@ WASM_COMPILED_EXEC_TEST(BrOnCastFail) { #undef FUNCTION_BODY const byte kBranchTakenStatic = tester.DefineFunction( - tester.sigs.i_v(), {kWasmDataRef}, + tester.sigs.i_v(), {kWasmStructRef}, {WASM_LOCAL_SET( 0, WASM_STRUCT_NEW(type1, WASM_I64V(10), WASM_I32V(field1_value))), WASM_BLOCK( - WASM_BLOCK_R(kWasmDataRef, WASM_LOCAL_GET(0), + WASM_BLOCK_R(kWasmStructRef, WASM_LOCAL_GET(0), WASM_BR_ON_CAST_FAIL(0, type0), WASM_GC_OP(kExprStructGet), type0, 0, kExprReturn), kExprBrOnNull, 0, WASM_GC_OP(kExprRefCast), type1, @@ -1559,7 +1560,7 @@ WASM_COMPILED_EXEC_TEST(CallAbstractNullTypeImplicitConversion) { {kWasmFuncRef, kNoFuncCode}, {kWasmEqRef, kNoneCode}, {kWasmI31Ref.AsNullable(), kNoneCode}, - {kWasmDataRef.AsNullable(), kNoneCode}, + {kWasmStructRef.AsNullable(), kNoneCode}, {kWasmArrayRef.AsNullable(), kNoneCode}, {kWasmAnyRef, kNoneCode}, {kWasmExternRef, kNoExternCode}, @@ -1602,14 +1603,15 @@ WASM_COMPILED_EXEC_TEST(CastNullRef) { tester.sigs.i_v(), {}, {WASM_REF_IS_NULL(WASM_REF_AS_ARRAY(WASM_REF_NULL(kNoneCode))), kExprEnd}); - byte to_data = tester.DefineFunction( + byte to_struct = tester.DefineFunction( tester.sigs.i_v(), {}, - {WASM_REF_IS_NULL(WASM_REF_AS_DATA(WASM_REF_NULL(kNoneCode))), kExprEnd}); + {WASM_REF_IS_NULL(WASM_REF_AS_STRUCT(WASM_REF_NULL(kNoneCode))), + kExprEnd}); byte to_i31 = tester.DefineFunction( tester.sigs.i_v(), {}, {WASM_REF_IS_NULL(WASM_REF_AS_I31(WASM_REF_NULL(kNoneCode))), kExprEnd}); byte struct_idx = tester.DefineStruct({F(wasm::kWasmI32, true)}); - byte to_struct = tester.DefineFunction( + byte to_struct_idx = tester.DefineFunction( tester.sigs.i_v(), {}, {WASM_REF_IS_NULL(WASM_REF_CAST(WASM_REF_NULL(kNoneCode), struct_idx)), kExprEnd}); @@ -1617,10 +1619,10 @@ WASM_COMPILED_EXEC_TEST(CastNullRef) { // Generic casts trap on null. tester.CheckHasThrown(to_non_null); tester.CheckHasThrown(to_array); - tester.CheckHasThrown(to_data); + tester.CheckHasThrown(to_struct); tester.CheckHasThrown(to_i31); // Static ref.cast succeeds. - tester.CheckResult(to_struct, 1); + tester.CheckResult(to_struct_idx, 1); } WASM_COMPILED_EXEC_TEST(CallReftypeParameters) { @@ -1673,9 +1675,9 @@ WASM_COMPILED_EXEC_TEST(AbstractTypeChecks) { tester.AddGlobal(ValueType::RefNull(sig_index), false, WasmInitExpr::RefFuncConst(function_index)); - byte kDataCheckNull = tester.DefineFunction( + byte kStructCheckNull = tester.DefineFunction( tester.sigs.i_v(), {}, - {WASM_REF_IS_DATA(WASM_REF_NULL(kAnyRefCode)), kExprEnd}); + {WASM_REF_IS_STRUCT(WASM_REF_NULL(kAnyRefCode)), kExprEnd}); byte kArrayCheckNull = tester.DefineFunction( tester.sigs.i_v(), {}, {WASM_REF_IS_ARRAY(WASM_REF_NULL(kAnyRefCode)), kExprEnd}); @@ -1683,9 +1685,9 @@ WASM_COMPILED_EXEC_TEST(AbstractTypeChecks) { tester.sigs.i_v(), {}, {WASM_REF_IS_I31(WASM_REF_NULL(kAnyRefCode)), kExprEnd}); - byte kDataCastNull = + byte kStructCastNull = tester.DefineFunction(tester.sigs.i_v(), {}, - {WASM_REF_AS_DATA(WASM_REF_NULL(kAnyRefCode)), + {WASM_REF_AS_STRUCT(WASM_REF_NULL(kAnyRefCode)), WASM_DROP, WASM_I32V(1), kExprEnd}); byte kArrayCastNull = tester.DefineFunction(tester.sigs.i_v(), {}, @@ -1701,9 +1703,9 @@ WASM_COMPILED_EXEC_TEST(AbstractTypeChecks) { {WASM_LOCAL_SET(0, WASM_SEQ(value)), \ WASM_REF_IS_##type(WASM_LOCAL_GET(0)), kExprEnd}) - byte kDataCheckSuccess = - TYPE_CHECK(DATA, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10))); - byte kDataCheckFailure = TYPE_CHECK(DATA, WASM_I31_NEW(WASM_I32V(42))); + byte kStructCheckSuccess = + TYPE_CHECK(STRUCT, WASM_STRUCT_NEW_DEFAULT(struct_index)); + byte kStructCheckFailure = TYPE_CHECK(STRUCT, WASM_I31_NEW(WASM_I32V(42))); byte kArrayCheckSuccess = TYPE_CHECK(ARRAY, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10))); byte kArrayCheckFailure = @@ -1719,12 +1721,12 @@ WASM_COMPILED_EXEC_TEST(AbstractTypeChecks) { WASM_REF_AS_##type(WASM_LOCAL_GET(0)), WASM_DROP, \ WASM_I32V(1), kExprEnd}) - byte kDataCastSuccess = - TYPE_CAST(DATA, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10))); - byte kDataCastFailure = TYPE_CAST(DATA, WASM_I31_NEW(WASM_I32V(42))); + byte kStructCastSuccess = + TYPE_CAST(STRUCT, WASM_STRUCT_NEW_DEFAULT(struct_index)); + byte kStructCastFailure = TYPE_CAST(STRUCT, WASM_I31_NEW(WASM_I32V(42))); byte kArrayCastSuccess = - TYPE_CAST(DATA, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10))); - byte kArrayCastFailure = TYPE_CAST(DATA, WASM_I31_NEW(WASM_I32V(42))); + TYPE_CAST(ARRAY, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10))); + byte kArrayCastFailure = TYPE_CAST(ARRAY, WASM_I31_NEW(WASM_I32V(42))); byte kI31CastSuccess = TYPE_CAST(I31, WASM_I31_NEW(WASM_I32V(42))); byte kI31CastFailure = TYPE_CAST(I31, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10))); @@ -1741,9 +1743,9 @@ WASM_COMPILED_EXEC_TEST(AbstractTypeChecks) { WASM_RETURN(WASM_I32V(0)))), \ kExprEnd}) - byte kBrOnDataTaken = - BR_ON(DATA, Data, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10))); - byte kBrOnDataNotTaken = BR_ON(DATA, Data, WASM_REF_NULL(kNoneCode)); + byte kBrOnStructTaken = + BR_ON(STRUCT, Struct, WASM_STRUCT_NEW_DEFAULT(struct_index)); + byte kBrOnStructNotTaken = BR_ON(STRUCT, Struct, WASM_REF_NULL(kNoneCode)); byte kBrOnArrayTaken = BR_ON(ARRAY, Array, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10))); byte kBrOnArrayNotTaken = BR_ON(ARRAY, Array, WASM_I31_NEW(WASM_I32V(42))); @@ -1763,9 +1765,10 @@ WASM_COMPILED_EXEC_TEST(AbstractTypeChecks) { WASM_RETURN(WASM_I32V(1)))), \ kExprEnd}) - byte kBrOnNonDataNotTaken = - BR_ON_NON(DATA, Data, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10))); - byte kBrOnNonDataTaken = BR_ON_NON(DATA, Data, WASM_REF_NULL(kNoneCode)); + byte kBrOnNonStructNotTaken = + BR_ON_NON(STRUCT, Struct, WASM_STRUCT_NEW_DEFAULT(struct_index)); + byte kBrOnNonStructTaken = + BR_ON_NON(STRUCT, Struct, WASM_REF_NULL(kNoneCode)); byte kBrOnNonArrayNotTaken = BR_ON_NON( ARRAY, Array, WASM_ARRAY_NEW_DEFAULT(array_index, WASM_I32V(10))); byte kBrOnNonArrayTaken = @@ -1777,39 +1780,39 @@ WASM_COMPILED_EXEC_TEST(AbstractTypeChecks) { tester.CompileModule(); - tester.CheckResult(kDataCheckNull, 0); + tester.CheckResult(kStructCheckNull, 0); tester.CheckResult(kArrayCheckNull, 0); tester.CheckResult(kI31CheckNull, 0); - tester.CheckHasThrown(kDataCastNull); + tester.CheckHasThrown(kStructCastNull); tester.CheckHasThrown(kArrayCastNull); tester.CheckHasThrown(kI31CastNull); - tester.CheckResult(kDataCheckSuccess, 1); + tester.CheckResult(kStructCheckSuccess, 1); tester.CheckResult(kArrayCheckSuccess, 1); tester.CheckResult(kI31CheckSuccess, 1); - tester.CheckResult(kDataCheckFailure, 0); + tester.CheckResult(kStructCheckFailure, 0); tester.CheckResult(kArrayCheckFailure, 0); tester.CheckResult(kI31CheckFailure, 0); - tester.CheckResult(kDataCastSuccess, 1); + tester.CheckResult(kStructCastSuccess, 1); tester.CheckResult(kArrayCastSuccess, 1); tester.CheckResult(kI31CastSuccess, 1); - tester.CheckHasThrown(kDataCastFailure); + tester.CheckHasThrown(kStructCastFailure); tester.CheckHasThrown(kArrayCastFailure); tester.CheckHasThrown(kI31CastFailure); - tester.CheckResult(kBrOnDataTaken, 1); - tester.CheckResult(kBrOnDataNotTaken, 0); + tester.CheckResult(kBrOnStructTaken, 1); + tester.CheckResult(kBrOnStructNotTaken, 0); tester.CheckResult(kBrOnArrayTaken, 1); tester.CheckResult(kBrOnArrayNotTaken, 0); tester.CheckResult(kBrOnI31Taken, 1); tester.CheckResult(kBrOnI31NotTaken, 0); - tester.CheckResult(kBrOnNonDataTaken, 0); - tester.CheckResult(kBrOnNonDataNotTaken, 1); + tester.CheckResult(kBrOnNonStructTaken, 0); + tester.CheckResult(kBrOnNonStructNotTaken, 1); tester.CheckResult(kBrOnNonArrayTaken, 0); tester.CheckResult(kBrOnNonArrayNotTaken, 1); tester.CheckResult(kBrOnNonI31Taken, 0); @@ -1824,7 +1827,7 @@ WASM_COMPILED_EXEC_TEST(CastsBenchmark) { const byte SubType = tester.DefineStruct( {F(wasm::kWasmI32, true), F(wasm::kWasmI32, true)}, SuperType); - const byte ListType = tester.DefineArray(kWasmDataRef, true); + const byte ListType = tester.DefineArray(kWasmStructRef, true); const byte List = tester.AddGlobal(ValueType::RefNull(ListType), true, @@ -2014,9 +2017,9 @@ WASM_COMPILED_EXEC_TEST(JsAccess) { WasmGCTester tester(execution_tier); const byte type_index = tester.DefineStruct({F(wasm::kWasmI32, true)}); ValueType kRefType = ref(type_index); - ValueType kSupertypeToI[] = {kWasmI32, kWasmDataRef}; + ValueType kSupertypeToI[] = {kWasmI32, kWasmStructRef}; FunctionSig sig_t_v(1, 0, &kRefType); - FunctionSig sig_super_v(1, 0, &kWasmDataRef); + FunctionSig sig_super_v(1, 0, &kWasmStructRef); FunctionSig sig_i_super(1, 1, kSupertypeToI); tester.DefineExportedFunction( diff --git a/test/common/wasm/wasm-macro-gen.h b/test/common/wasm/wasm-macro-gen.h index d7f825d11e..66462abd5b 100644 --- a/test/common/wasm/wasm-macro-gen.h +++ b/test/common/wasm/wasm-macro-gen.h @@ -539,21 +539,21 @@ inline uint16_t ExtractPrefixedOpcodeBytes(WasmOpcode opcode) { #define WASM_GC_INTERNALIZE(extern) extern, WASM_GC_OP(kExprExternInternalize) #define WASM_GC_EXTERNALIZE(ref) ref, WASM_GC_OP(kExprExternExternalize) -#define WASM_REF_IS_DATA(ref) ref, WASM_GC_OP(kExprRefIsData) +#define WASM_REF_IS_STRUCT(ref) ref, WASM_GC_OP(kExprRefIsStruct) #define WASM_REF_IS_ARRAY(ref) ref, WASM_GC_OP(kExprRefIsArray) #define WASM_REF_IS_I31(ref) ref, WASM_GC_OP(kExprRefIsI31) -#define WASM_REF_AS_DATA(ref) ref, WASM_GC_OP(kExprRefAsData) +#define WASM_REF_AS_STRUCT(ref) ref, WASM_GC_OP(kExprRefAsStruct) #define WASM_REF_AS_ARRAY(ref) ref, WASM_GC_OP(kExprRefAsArray) #define WASM_REF_AS_I31(ref) ref, WASM_GC_OP(kExprRefAsI31) #define WASM_BR_ON_ARRAY(depth) \ WASM_GC_OP(kExprBrOnArray), static_cast(depth) -#define WASM_BR_ON_DATA(depth) \ - WASM_GC_OP(kExprBrOnData), static_cast(depth) +#define WASM_BR_ON_STRUCT(depth) \ + WASM_GC_OP(kExprBrOnStruct), static_cast(depth) #define WASM_BR_ON_I31(depth) WASM_GC_OP(kExprBrOnI31), static_cast(depth) #define WASM_BR_ON_NON_ARRAY(depth) \ WASM_GC_OP(kExprBrOnNonArray), static_cast(depth) -#define WASM_BR_ON_NON_DATA(depth) \ - WASM_GC_OP(kExprBrOnNonData), static_cast(depth) +#define WASM_BR_ON_NON_STRUCT(depth) \ + WASM_GC_OP(kExprBrOnNonStruct), static_cast(depth) #define WASM_BR_ON_NON_I31(depth) \ WASM_GC_OP(kExprBrOnNonI31), static_cast(depth) diff --git a/test/fuzzer/wasm-compile.cc b/test/fuzzer/wasm-compile.cc index 0a8adf24cf..7c402fa4de 100644 --- a/test/fuzzer/wasm-compile.cc +++ b/test/fuzzer/wasm-compile.cc @@ -131,7 +131,7 @@ ValueType GetValueTypeHelper(DataRange* data, bool liftoff_as_reference, kWasmNullExternRef, kWasmNullFuncRef}); } if (include_generics == kIncludeGenerics) { - types.insert(types.end(), {kWasmDataRef, kWasmAnyRef, kWasmEqRef}); + types.insert(types.end(), {kWasmStructRef, kWasmAnyRef, kWasmEqRef}); } // The last index of user-defined types allowed is different based on the @@ -2111,8 +2111,10 @@ void WasmGenerator::GenerateRef(HeapType type, DataRange* data, } random = data->get() % (num_data_types + emit_i31ref); } - if (random < num_data_types) { - GenerateRef(HeapType(HeapType::kData), data, nullability); + if (random < num_structs_) { + GenerateRef(HeapType(HeapType::kStruct), data, nullability); + } else if (random < num_data_types) { + GenerateRef(HeapType(HeapType::kArray), data, nullability); } else { GenerateRef(HeapType(HeapType::kI31), data, nullability); } @@ -2132,18 +2134,18 @@ void WasmGenerator::GenerateRef(HeapType type, DataRange* data, GenerateRef(HeapType(random), data, nullability); return; } - case HeapType::kData: { + case HeapType::kStruct: { DCHECK(liftoff_as_reference_); constexpr uint8_t fallback_to_dataref = 2; - uint8_t random = data->get() % - (num_arrays_ + num_structs_ + fallback_to_dataref); + uint8_t random = + data->get() % (num_structs_ + fallback_to_dataref); // Try generating one of the alternatives // and continue to the rest of the methods in case it fails. - if (random >= num_arrays_ + num_structs_) { + if (random >= num_structs_) { if (GenerateOneOf(alternatives_other, type, data, nullability)) { return; } - random = data->get() % (num_arrays_ + num_structs_); + random = data->get() % num_structs_; } GenerateRef(HeapType(random), data, nullability); return; @@ -2384,7 +2386,7 @@ WasmInitExpr GenerateInitExpr(Zone* zone, WasmModuleBuilder* builder, } case kRef: { switch (type.heap_type().representation()) { - case HeapType::kData: + case HeapType::kStruct: case HeapType::kAny: case HeapType::kEq: { // We materialize all these types with a struct because they are all diff --git a/test/fuzzer/wasm-fuzzer-common.cc b/test/fuzzer/wasm-fuzzer-common.cc index 7193ffc3ef..00a8116266 100644 --- a/test/fuzzer/wasm-fuzzer-common.cc +++ b/test/fuzzer/wasm-fuzzer-common.cc @@ -231,8 +231,8 @@ std::string HeapTypeToJSByteEncoding(HeapType heap_type) { return "kEqRefCode"; case HeapType::kI31: return "kI31RefCode"; - case HeapType::kData: - return "kDataRefCode"; + case HeapType::kStruct: + return "kStructRefCode"; case HeapType::kArray: return "kArrayRefCode"; case HeapType::kAny: @@ -260,8 +260,8 @@ std::string HeapTypeToConstantName(HeapType heap_type) { return "kWasmEqRef"; case HeapType::kI31: return "kWasmI31Ref"; - case HeapType::kData: - return "kWasmDataRef"; + case HeapType::kStruct: + return "kWasmStructRef"; case HeapType::kArray: return "kWasmArrayRef"; case HeapType::kExtern: @@ -309,7 +309,7 @@ std::string ValueTypeToConstantName(ValueType type) { return "kWasmAnyRef"; case HeapType::kBottom: UNREACHABLE(); - case HeapType::kData: + case HeapType::kStruct: case HeapType::kArray: case HeapType::kI31: default: diff --git a/test/mjsunit/regress/wasm/regress-12874.js b/test/mjsunit/regress/wasm/regress-12874.js index 2a74508708..58a9146ebb 100644 --- a/test/mjsunit/regress/wasm/regress-12874.js +++ b/test/mjsunit/regress/wasm/regress-12874.js @@ -9,12 +9,12 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); var builder = new WasmModuleBuilder(); -var sig_index = builder.addType({params: [kWasmDataRef], results: [kWasmI32]}); +var sig_index = builder.addType({params: [kWasmStructRef], results: [kWasmI32]}); var sub1 = builder.addStruct([makeField(kWasmI32, true)]); var sub2 = builder.addStruct([makeField(kWasmI32, false)]); -builder.addFunction('producer', makeSig([], [kWasmDataRef])) +builder.addFunction('producer', makeSig([], [kWasmStructRef])) .addBody([ kExprI32Const, 10, kGCPrefix, kExprStructNew, sub1]) diff --git a/test/mjsunit/regress/wasm/regress-13061.js b/test/mjsunit/regress/wasm/regress-13061.js index a75d153336..58fe99b121 100644 --- a/test/mjsunit/regress/wasm/regress-13061.js +++ b/test/mjsunit/regress/wasm/regress-13061.js @@ -10,7 +10,7 @@ let builder = new WasmModuleBuilder(); builder.addFunction('repro', kSig_v_v) .exportFunc() - .addLocals(wasmRefNullType(kWasmDataRef), 1) + .addLocals(wasmRefNullType(kWasmStructRef), 1) .addBody([ kExprI32Const, 0, kExprIf, kWasmVoid, diff --git a/test/mjsunit/regress/wasm/typecheck-null-undefined.js b/test/mjsunit/regress/wasm/typecheck-null-undefined.js index 81729d9da6..6e3f8c2c4e 100644 --- a/test/mjsunit/regress/wasm/typecheck-null-undefined.js +++ b/test/mjsunit/regress/wasm/typecheck-null-undefined.js @@ -9,7 +9,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); var builder = new WasmModuleBuilder(); var sig_index = builder.addType( - {params: [wasmRefType(kWasmDataRef)], results: []}); + {params: [wasmRefType(kWasmStructRef)], results: []}); builder.addFunction('main', sig_index).addBody([]).exportFunc(); diff --git a/test/mjsunit/wasm/array-init-from-segment.js b/test/mjsunit/wasm/array-init-from-segment.js index 411e1601ec..f98c86e8b8 100644 --- a/test/mjsunit/wasm/array-init-from-segment.js +++ b/test/mjsunit/wasm/array-init-from-segment.js @@ -123,7 +123,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); .addBody([ kExprLocalGet, 0, // offset in table kExprTableGet, table, - kGCPrefix, kExprRefAsData, + kGCPrefix, kExprRefAsArray, kGCPrefix, kExprRefCast, array_type_index, kExprLocalGet, 1, // index in the array kGCPrefix, kExprArrayGet, array_type_index, diff --git a/test/mjsunit/wasm/gc-casts-from-any.js b/test/mjsunit/wasm/gc-casts-from-any.js index 234ddb7cd1..56ca60acca 100644 --- a/test/mjsunit/wasm/gc-casts-from-any.js +++ b/test/mjsunit/wasm/gc-casts-from-any.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --experimental-wasm-gc +// Flags: --experimental-wasm-gc --no-wasm-gc-structref-as-dataref d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); @@ -43,7 +43,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); ["Array", array], ["I31", kI31RefCode], ["AnyArray", kArrayRefCode], - ["Data", kDataRefCode], + ["Struct", kStructRefCode], ["Eq", kEqRefCode], // 'ref.test any' is semantically the same as '!ref.is_null' here. ["Any", kAnyRefCode], @@ -108,14 +108,14 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); assertEquals([0, 0], wasm.refTestAnyArray(1)); assertEquals([0, 0], wasm.refTestAnyArray({'JavaScript': 'Object'})); - assertEquals([0, 1], wasm.refTestData(null)); - assertEquals([0, 0], wasm.refTestData(undefined)); - assertEquals([1, 1], wasm.refTestData(wasm.createStructSuper())); - assertEquals([1, 1], wasm.refTestData(wasm.createStructSub())); - assertEquals([1, 1], wasm.refTestData(wasm.createArray())); - assertEquals([0, 0], wasm.refTestData(wasm.createFuncRef())); - assertEquals([0, 0], wasm.refTestData(1)); - assertEquals([0, 0], wasm.refTestData({'JavaScript': 'Object'})); + assertEquals([0, 1], wasm.refTestStruct(null)); + assertEquals([0, 0], wasm.refTestStruct(undefined)); + assertEquals([1, 1], wasm.refTestStruct(wasm.createStructSuper())); + assertEquals([1, 1], wasm.refTestStruct(wasm.createStructSub())); + assertEquals([0, 0], wasm.refTestStruct(wasm.createArray())); + assertEquals([0, 0], wasm.refTestStruct(wasm.createFuncRef())); + assertEquals([0, 0], wasm.refTestStruct(1)); + assertEquals([0, 0], wasm.refTestStruct({'JavaScript': 'Object'})); assertEquals([0, 1], wasm.refTestEq(null)); assertEquals([0, 0], wasm.refTestEq(undefined)); diff --git a/test/mjsunit/wasm/gc-casts-subtypes.js b/test/mjsunit/wasm/gc-casts-subtypes.js index 249c70483e..ea94987a1e 100644 --- a/test/mjsunit/wasm/gc-casts-subtypes.js +++ b/test/mjsunit/wasm/gc-casts-subtypes.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --experimental-wasm-gc --experimental-wasm-type-reflection +// Flags: --experimental-wasm-gc --experimental-wasm-type-reflection --no-wasm-gc-structref-as-dataref d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); @@ -110,7 +110,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); let types = { any: kWasmAnyRef, eq: kWasmEqRef, - data: kWasmDataRef, + struct: kWasmStructRef, anyArray: kWasmArrayRef, array: wasmRefNullType(array), structSuper: wasmRefNullType(structSuper), @@ -137,7 +137,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); values: ['nullref', 'i31ref', 'structSuper', 'structSub', 'array'], targets: { eq: ['i31ref', 'structSuper', 'structSub', 'array'], - data: ['structSuper', 'structSub', 'array'], + struct: ['structSuper', 'structSub'], anyArray: ['array'], array: ['array'], structSuper: ['structSuper', 'structSub'], @@ -149,7 +149,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); values: ['nullref', 'i31ref', 'structSuper', 'structSub', 'array'], targets: { eq: ['i31ref', 'structSuper', 'structSub', 'array'], - data: ['structSuper', 'structSub', 'array'], + struct: ['structSuper', 'structSub'], anyArray: ['array'], array: ['array'], structSuper: ['structSuper', 'structSub'], @@ -157,11 +157,11 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); } }, { - source: 'data', - values: ['nullref', 'structSuper', 'structSub', 'array'], + source: 'struct', + values: ['nullref', 'structSuper', 'structSub'], targets: { - eq: ['structSuper', 'structSub', 'array'], - data: ['structSuper', 'structSub', 'array'], + eq: ['structSuper', 'structSub'], + struct: ['structSuper', 'structSub'], anyArray: ['array'], array: ['array'], structSuper: ['structSuper', 'structSub'], @@ -173,7 +173,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); values: ['nullref', 'array'], targets: { eq: ['array'], - data: ['array'], + struct: [], anyArray: ['array'], array: ['array'], structSuper: [], @@ -185,7 +185,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); values: ['nullref', 'structSuper', 'structSub'], targets: { eq: ['structSuper', 'structSub'], - data: ['structSuper', 'structSub'], + struct: ['structSuper', 'structSub'], anyArray: [], array: [], structSuper: ['structSuper', 'structSub'], diff --git a/test/mjsunit/wasm/gc-experimental-string-conversions.js b/test/mjsunit/wasm/gc-experimental-string-conversions.js index c1bdcb448c..51b343b176 100644 --- a/test/mjsunit/wasm/gc-experimental-string-conversions.js +++ b/test/mjsunit/wasm/gc-experimental-string-conversions.js @@ -20,7 +20,7 @@ builder.addFunction('getHelloArray', makeSig([], [kWasmArrayRef])) builder.addFunction('getChar', makeSig([kWasmArrayRef, kWasmI32], [kWasmI32])) .addBody([ - kExprLocalGet, 0, kGCPrefix, kExprRefAsData, kGCPrefix, + kExprLocalGet, 0, kGCPrefix, kExprRefAsArray, kGCPrefix, kExprRefCast, i16Array, kExprLocalGet, 1, kGCPrefix, kExprArrayGetS, i16Array ]) diff --git a/test/mjsunit/wasm/gc-experiments.js b/test/mjsunit/wasm/gc-experiments.js index 506e019373..3cf398cde1 100644 --- a/test/mjsunit/wasm/gc-experiments.js +++ b/test/mjsunit/wasm/gc-experiments.js @@ -11,7 +11,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); let struct = builder.addStruct([makeField(kWasmI32, true)]); builder.addFunction("main", kSig_i_i) - .addLocals(wasmRefNullType(kWasmDataRef), 1) + .addLocals(wasmRefNullType(kWasmStructRef), 1) .addBody([ kExprLocalGet, 0, kGCPrefix, kExprStructNew, struct, diff --git a/test/mjsunit/wasm/gc-js-interop-import.mjs b/test/mjsunit/wasm/gc-js-interop-import.mjs index ce4d5f9633..0673e2d3e7 100644 --- a/test/mjsunit/wasm/gc-js-interop-import.mjs +++ b/test/mjsunit/wasm/gc-js-interop-import.mjs @@ -16,7 +16,7 @@ builder.addFunction('readStruct', makeSig([kWasmExternRef], [kWasmI32])) .addBody([ kExprLocalGet, 0, // -- kGCPrefix, kExprExternInternalize, // -- - kGCPrefix, kExprRefAsData, // -- + kGCPrefix, kExprRefAsStruct, // -- kGCPrefix, kExprRefCast, struct_type, // -- kGCPrefix, kExprStructGet, struct_type, 0, // -- ]); diff --git a/test/mjsunit/wasm/gc-js-interop-wasm.js b/test/mjsunit/wasm/gc-js-interop-wasm.js index d97bff89cd..a680646032 100644 --- a/test/mjsunit/wasm/gc-js-interop-wasm.js +++ b/test/mjsunit/wasm/gc-js-interop-wasm.js @@ -70,7 +70,7 @@ for (const wasm_obj of [struct, array]) { testThrowsRepeated( () => new WebAssembly.Tag({parameters: [wasm_obj]}), TypeError); - let tag = new WebAssembly.Tag({parameters: ['dataref']}); + let tag = new WebAssembly.Tag({parameters: ['structref']}); testThrowsRepeated(() => new WebAssembly.Exception(wasm_obj), TypeError); testThrowsRepeated(() => new WebAssembly.Exception(tag, wasm_obj), TypeError); repeated(() => new WebAssembly.Exception(tag, [wasm_obj])); diff --git a/test/mjsunit/wasm/gc-optimizations.js b/test/mjsunit/wasm/gc-optimizations.js index 42014e1c7b..a063892956 100644 --- a/test/mjsunit/wasm/gc-optimizations.js +++ b/test/mjsunit/wasm/gc-optimizations.js @@ -551,7 +551,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("main", makeSig([kWasmExternRef], [kWasmI32])) .addBody([kExprLocalGet, 0, kGCPrefix, kExprExternInternalize, - kGCPrefix, kExprRefAsData, + kGCPrefix, kExprRefAsStruct, kGCPrefix, kExprRefCast, struct_a, kExprCallFunction, callee.index]) .exportFunc(); diff --git a/test/mjsunit/wasm/reference-globals-import.js b/test/mjsunit/wasm/reference-globals-import.js index 77092f5ee5..456bc92af0 100644 --- a/test/mjsunit/wasm/reference-globals-import.js +++ b/test/mjsunit/wasm/reference-globals-import.js @@ -3,6 +3,7 @@ // found in the LICENSE file. // Flags: --experimental-wasm-gc --experimental-wasm-stringref +// Flags: --no-wasm-gc-structref-as-dataref d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); // Test type checks when creating a global with a value imported from a global @@ -301,7 +302,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("get_struct_val", makeSig([], [kWasmI32])) .addBody([ kExprGlobalGet, 0, - kGCPrefix, kExprRefAsData, + kGCPrefix, kExprRefAsStruct, kGCPrefix, kExprRefCast, struct_type, kGCPrefix, kExprStructGet, struct_type, 0, ]) @@ -309,7 +310,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("get_array_val", makeSig([], [kWasmI32])) .addBody([ kExprGlobalGet, 0, - kGCPrefix, kExprRefAsData, + kGCPrefix, kExprRefAsArray, kGCPrefix, kExprRefCast, array_type, kExprI32Const, 0, kGCPrefix, kExprArrayGet, array_type, @@ -369,7 +370,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("get_struct_val", makeSig([], [kWasmI32])) .addBody([ kExprGlobalGet, 0, - kGCPrefix, kExprRefAsData, + kGCPrefix, kExprRefAsStruct, kGCPrefix, kExprRefCast, struct_type, kGCPrefix, kExprStructGet, struct_type, 0, ]) @@ -377,7 +378,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("get_array_val", makeSig([], [kWasmI32])) .addBody([ kExprGlobalGet, 0, - kGCPrefix, kExprRefAsData, + kGCPrefix, kExprRefAsArray, kGCPrefix, kExprRefCast, array_type, kExprI32Const, 0, kGCPrefix, kExprArrayGet, array_type, @@ -414,34 +415,25 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); assertThrows(() => eqref_global.value = "string", TypeError); })(); -(function TestDataRefGlobalFromJS() { +(function TestStructRefGlobalFromJS() { print(arguments.callee.name); - let dataref_global = new WebAssembly.Global( - { value: "dataref", mutable: true }, null); - assertNull(dataref_global.value); + let structref_global = new WebAssembly.Global( + { value: "structref", mutable: true }, null); + assertNull(structref_global.value); let builder = new WasmModuleBuilder(); - builder.addImportedGlobal("imports", "dataref_global", kWasmDataRef, true); + builder.addImportedGlobal("imports", "structref_global", kWasmStructRef, true); let struct_type = builder.addStruct([makeField(kWasmI32, false)]); let array_type = builder.addArray(kWasmI32); builder.addFunction("get_struct_val", makeSig([], [kWasmI32])) .addBody([ kExprGlobalGet, 0, - kGCPrefix, kExprRefAsData, + kGCPrefix, kExprRefAsStruct, kGCPrefix, kExprRefCast, struct_type, kGCPrefix, kExprStructGet, struct_type, 0, ]) .exportFunc(); - builder.addFunction("get_array_val", makeSig([], [kWasmI32])) - .addBody([ - kExprGlobalGet, 0, - kGCPrefix, kExprRefAsData, - kGCPrefix, kExprRefCast, array_type, - kExprI32Const, 0, - kGCPrefix, kExprArrayGet, array_type, - ]) - .exportFunc(); builder.addFunction("create_struct", makeSig([kWasmI32], [kWasmExternRef])) .addBody([ kExprLocalGet, 0, @@ -455,18 +447,17 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); kGCPrefix, kExprExternExternalize]) .exportFunc(); - let instance = builder.instantiate({imports : {dataref_global}}); + let instance = builder.instantiate({imports : {structref_global}}); let wasm = instance.exports; - dataref_global.value = wasm.create_struct(42); + structref_global.value = wasm.create_struct(42); assertEquals(42, wasm.get_struct_val()); - dataref_global.value = wasm.create_array(43); - assertEquals(43, wasm.get_array_val()); - dataref_global.value = null; - assertEquals(null, dataref_global.value); + structref_global.value = null; + assertEquals(null, structref_global.value); - assertThrows(() => dataref_global.value = undefined, TypeError); - assertThrows(() => dataref_global.value = "string", TypeError); + assertThrows(() => structref_global.value = undefined, TypeError); + assertThrows(() => structref_global.value = "string", TypeError); + assertThrows(() => structref_global.value = wasm.create_array(1), TypeError); })(); (function TestArrayRefGlobalFromJS() { @@ -483,7 +474,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); builder.addFunction("get_array_val", makeSig([], [kWasmI32])) .addBody([ kExprGlobalGet, 0, - kGCPrefix, kExprRefAsData, + kGCPrefix, kExprRefAsArray, kGCPrefix, kExprRefCast, array_type, kExprI32Const, 0, kGCPrefix, kExprArrayGet, array_type, diff --git a/test/mjsunit/wasm/reference-globals.js b/test/mjsunit/wasm/reference-globals.js index 57a37e6552..821c2b1b27 100644 --- a/test/mjsunit/wasm/reference-globals.js +++ b/test/mjsunit/wasm/reference-globals.js @@ -162,7 +162,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); kGCPrefix, kExprStructGet, composite_struct_index, 0]) .exportFunc(); - builder.addFunction("field_2_default", makeSig([], [kWasmDataRef])) + builder.addFunction("field_2_default", makeSig([], [kWasmStructRef])) .addBody([ kExprGlobalGet, global_default.index, kGCPrefix, kExprStructGet, composite_struct_index, 1]) @@ -245,7 +245,7 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js"); kGCPrefix, kExprStructGet, struct_index, 0]) .exportFunc(); - builder.addFunction("element1", makeSig([], [kWasmDataRef])) + builder.addFunction("element1", makeSig([], [kWasmStructRef])) .addBody([ kExprGlobalGet, global.index, kExprI32Const, 1, diff --git a/test/mjsunit/wasm/reference-table-js-interop.js b/test/mjsunit/wasm/reference-table-js-interop.js index 5d91b68940..5f36bae8da 100644 --- a/test/mjsunit/wasm/reference-table-js-interop.js +++ b/test/mjsunit/wasm/reference-table-js-interop.js @@ -2,14 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --experimental-wasm-gc --experimental-wasm-stringref --wasm-gc-js-interop +// Flags: --experimental-wasm-gc --experimental-wasm-stringref +// Flags: --wasm-gc-js-interop --no-wasm-gc-structref-as-dataref d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); let tableTypes = { "anyref": kWasmAnyRef, "eqref": kWasmEqRef, - "dataref": kWasmDataRef, + "structref": kWasmStructRef, "arrayref": kWasmArrayRef, }; @@ -74,7 +75,7 @@ for (let [typeName, type] of Object.entries(tableTypes)) { builder.addFunction("tableGetStructVal", getValSig) .addBody([ kExprLocalGet, 0, kExprTableGet, 0, - kGCPrefix, kExprRefAsData, + kGCPrefix, kExprRefAsStruct, kGCPrefix, kExprRefCast, struct, kGCPrefix, kExprStructGet, struct, 0, ]) @@ -82,7 +83,7 @@ for (let [typeName, type] of Object.entries(tableTypes)) { builder.addFunction("tableGetArrayVal", getValSig) .addBody([ kExprLocalGet, 0, kExprTableGet, 0, - kGCPrefix, kExprRefAsData, + kGCPrefix, kExprRefAsArray, kGCPrefix, kExprRefCast, array, kExprI32Const, 0, kGCPrefix, kExprArrayGet, array, @@ -106,21 +107,10 @@ for (let [typeName, type] of Object.entries(tableTypes)) { ]) .exportFunc(); - let blockSig = builder.addType(makeSig([kWasmAnyRef], [kWasmEqRef])); - let castExternToEqRef = [ - kGCPrefix, kExprExternInternalize, - kExprBlock, blockSig, - kGCPrefix, kExprBrOnI31, 0, - kGCPrefix, kExprBrOnData, 0, - // non-data, non-i31 - kExprUnreachable, // conversion failure - kExprEnd, - ]; - builder.addFunction("createNull", creatorSig) .addBody([kExprRefNull, kNullRefCode]) .exportFunc(); - let i31Sig = typeName != "dataref" && typeName != "arrayref" + let i31Sig = typeName != "structref" && typeName != "arrayref" ? creatorSig : creatorAnySig; builder.addFunction("createI31", i31Sig) .addBody([kExprI32Const, 12, kGCPrefix, kExprI31New]) @@ -129,7 +119,8 @@ for (let [typeName, type] of Object.entries(tableTypes)) { builder.addFunction("createStruct", structSig) .addBody([kExprI32Const, 12, kGCPrefix, kExprStructNew, struct]) .exportFunc(); - builder.addFunction("createArray", creatorSig) + let arraySig = typeName != "structref" ? creatorSig : creatorAnySig; + builder.addFunction("createArray", arraySig) .addBody([ kExprI32Const, 12, kGCPrefix, kExprArrayNewFixed, array, 1 @@ -159,7 +150,7 @@ for (let [typeName, type] of Object.entries(tableTypes)) { assertEquals(null, wasm.tableGet(1)); assertEquals(null, table.get(1)); // Set i31. - if (typeName != "dataref" && typeName != "arrayref") { + if (typeName != "structref" && typeName != "arrayref") { table.set(2, wasm.exported(wasm.createI31)); assertSame(table.get(2), wasm.tableGet(2)); wasm.tableSet(3, wasm.createI31); @@ -177,13 +168,15 @@ for (let [typeName, type] of Object.entries(tableTypes)) { assertNotSame(table.get(4), table.get(5)); } // Set array. - table.set(6, wasm.exported(wasm.createArray)); - assertSame(table.get(6), wasm.tableGet(6)); - assertEquals(12, wasm.tableGetArrayVal(6)); - wasm.tableSet(7, wasm.createArray); - assertSame(table.get(7), wasm.tableGet(7)); - assertEquals(12, wasm.tableGetArrayVal(7)); - assertNotSame(table.get(6), table.get(7)); + if (typeName != "structref") { + table.set(6, wasm.exported(wasm.createArray)); + assertSame(table.get(6), wasm.tableGet(6)); + assertEquals(12, wasm.tableGetArrayVal(6)); + wasm.tableSet(7, wasm.createArray); + assertSame(table.get(7), wasm.tableGet(7)); + assertEquals(12, wasm.tableGetArrayVal(7)); + assertNotSame(table.get(6), table.get(7)); + } // Set stringref. if (typeName == "anyref") { @@ -217,7 +210,7 @@ for (let [typeName, type] of Object.entries(tableTypes)) { let invalidValues = { "anyref": [], "eqref": [], - "dataref": ["I31"], + "structref": ["I31", "Array"], "arrayref": ["I31", "Struct"], }; for (let invalidType of invalidValues[typeName]) { diff --git a/test/mjsunit/wasm/reference-tables.js b/test/mjsunit/wasm/reference-tables.js index 2b6506bf54..c54fef5218 100644 --- a/test/mjsunit/wasm/reference-tables.js +++ b/test/mjsunit/wasm/reference-tables.js @@ -186,7 +186,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); builder.addFunction("struct_getter", kSig_i_v) .addBody([ kExprI32Const, 2, kExprTableGet, 0, - kGCPrefix, kExprRefAsData, kGCPrefix, kExprRefCast, struct_type, + kGCPrefix, kExprRefAsStruct, kGCPrefix, kExprRefCast, struct_type, kGCPrefix, kExprStructGet, struct_type, 0]) .exportFunc(); @@ -250,7 +250,7 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); builder.addFunction("struct_getter", kSig_i_i) .addBody([ kExprLocalGet, 0, kExprTableGet, 0, - kGCPrefix, kExprRefAsData, kGCPrefix, kExprRefCast, struct_type, + kGCPrefix, kExprRefAsStruct, kGCPrefix, kExprRefCast, struct_type, kGCPrefix, kExprStructGet, struct_type, 0]) .exportFunc(); diff --git a/test/mjsunit/wasm/runtime-type-canonicalization.js b/test/mjsunit/wasm/runtime-type-canonicalization.js index 1d87812cf4..72bcae09af 100644 --- a/test/mjsunit/wasm/runtime-type-canonicalization.js +++ b/test/mjsunit/wasm/runtime-type-canonicalization.js @@ -14,16 +14,16 @@ let identical_struct_index = builder.addStruct([makeField(kWasmI32, true)]); let distinct_struct_index = builder.addStruct([makeField(kWasmI64, true)]); let struct_init = builder.addFunction("struct_init", - makeSig([], [kWasmDataRef])) + makeSig([], [kWasmStructRef])) .addBody([kGCPrefix, kExprStructNewDefault, struct_index]) .exportFunc(); let test_pass = builder.addFunction("test_pass", - makeSig([kWasmDataRef], [kWasmI32])) + makeSig([kWasmStructRef], [kWasmI32])) .addBody([kExprLocalGet, 0, kGCPrefix, kExprRefTestDeprecated, identical_struct_index]) .exportFunc(); let test_fail = builder.addFunction("test_fail", - makeSig([kWasmDataRef], [kWasmI32])) + makeSig([kWasmStructRef], [kWasmI32])) .addBody([kExprLocalGet, 0, kGCPrefix, kExprRefTestDeprecated, distinct_struct_index]) .exportFunc(); diff --git a/test/mjsunit/wasm/test-wasm-module-builder.js b/test/mjsunit/wasm/test-wasm-module-builder.js index af44839eff..6b3b431c85 100644 --- a/test/mjsunit/wasm/test-wasm-module-builder.js +++ b/test/mjsunit/wasm/test-wasm-module-builder.js @@ -188,7 +188,7 @@ function instantiate(buffer, ffi) { print(arguments.callee.name); // These are all positive type indices (e.g. kI31RefCode and not kWasmI31Ref) // and should be treated as such. - let indices = [kI31RefCode, kDataRefCode, 200, 400]; + let indices = [kI31RefCode, kStructRefCode, 200, 400]; let kMaxIndex = 400; let builder = new WasmModuleBuilder(); for (let i = 0; i <= kMaxIndex; i++) { diff --git a/test/mjsunit/wasm/wasm-gc-externalize-internalize.js b/test/mjsunit/wasm/wasm-gc-externalize-internalize.js index d82fc3b9e9..4d232775dc 100644 --- a/test/mjsunit/wasm/wasm-gc-externalize-internalize.js +++ b/test/mjsunit/wasm/wasm-gc-externalize-internalize.js @@ -43,7 +43,7 @@ let instance = (() => { kExprBlock, kWasmVoid, kExprLocalGet, 0, kExprBrOnNull, 0, - kGCPrefix, kExprRefAsData, + kGCPrefix, kExprRefAsStruct, kGCPrefix, kExprRefCast, struct, kGCPrefix, kExprStructGet, struct, 0, // value kExprI32Const, 0, // isNull @@ -64,7 +64,7 @@ let instance = (() => { kExprLocalGet, 0, kGCPrefix, kExprExternInternalize, kExprBrOnNull, 0, - kGCPrefix, kExprRefAsData, + kGCPrefix, kExprRefAsStruct, kGCPrefix, kExprRefCast, struct, kGCPrefix, kExprStructGet, struct, 0, // value kExprI32Const, 0, // isNull diff --git a/test/mjsunit/wasm/wasm-gc-js-roundtrip.js b/test/mjsunit/wasm/wasm-gc-js-roundtrip.js index 6c6ad06e6e..93cf72d54c 100644 --- a/test/mjsunit/wasm/wasm-gc-js-roundtrip.js +++ b/test/mjsunit/wasm/wasm-gc-js-roundtrip.js @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Flags: --experimental-wasm-gc +// Flags: --experimental-wasm-gc --no-wasm-gc-structref-as-dataref d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js'); @@ -16,11 +16,11 @@ let instance = (() => { .addBody([kExprLocalGet, 0, kExprI32Const, 1, kExprI32Add]) .exportAs('inc'); - builder.addFunction('struct_producer', makeSig([], [kWasmDataRef])) + builder.addFunction('struct_producer', makeSig([], [kWasmStructRef])) .addBody([kGCPrefix, kExprStructNewDefault, struct]) .exportFunc(); - builder.addFunction('array_producer', makeSig([], [kWasmDataRef])) + builder.addFunction('array_producer', makeSig([], [kWasmArrayRef])) .addBody([ kExprI32Const, 10, kGCPrefix, kExprArrayNewDefault, array @@ -36,12 +36,11 @@ let instance = (() => { .exportFunc(); let test_types = { - struct: kWasmDataRef, - array: kWasmDataRef, + struct: kWasmStructRef, + array: kWasmArrayRef, raw_struct: struct, raw_array: array, typed_func: sig, - data: kWasmDataRef, eq: kWasmEqRef, func: kWasmFuncRef, any: kWasmAnyRef, @@ -67,15 +66,18 @@ let instance = (() => { // Wasm-exposed null is the same as JS null. assertEquals(instance.exports.struct_null(), null); -// We can roundtrip a struct as dataref. -instance.exports.data_id(instance.exports.struct_producer()); -// We can roundtrip an array as dataref. -instance.exports.data_id(instance.exports.array_producer()); -// We can roundtrip null as dataref. -instance.exports.data_id(instance.exports.data_null()); -// We cannot roundtrip an i31 as dataref. +// We can roundtrip a struct as structref. +instance.exports.struct_id(instance.exports.struct_producer()); +// We cannot roundtrip an array as structref. assertThrows( - () => instance.exports.data_id(instance.exports.i31_as_eq_producer()), + () => instance.exports.struct_id(instance.exports.array_producer()), + TypeError, + 'type incompatibility when transforming from/to JS'); +// We can roundtrip null as structref. +instance.exports.struct_id(instance.exports.struct_null()); +// We cannot roundtrip an i31 as structref. +assertThrows( + () => instance.exports.struct_id(instance.exports.i31_as_eq_producer()), TypeError, 'type incompatibility when transforming from/to JS'); @@ -86,7 +88,7 @@ instance.exports.eq_id(instance.exports.array_producer()); // We can roundtrip an i31 as eqref. instance.exports.eq_id(instance.exports.i31_as_eq_producer()); // We can roundtrip any null as eqref. -instance.exports.eq_id(instance.exports.data_null()); +instance.exports.eq_id(instance.exports.struct_null()); instance.exports.eq_id(instance.exports.eq_null()); instance.exports.eq_id(instance.exports.func_null()); // We cannot roundtrip a func as eqref. diff --git a/test/mjsunit/wasm/wasm-module-builder.js b/test/mjsunit/wasm/wasm-module-builder.js index 18928fe4be..0d08ca61d1 100644 --- a/test/mjsunit/wasm/wasm-module-builder.js +++ b/test/mjsunit/wasm/wasm-module-builder.js @@ -125,7 +125,7 @@ let kWasmEqRef = -0x13; let kWasmI31Ref = -0x16; let kWasmNullExternRef = -0x17; let kWasmNullFuncRef = -0x18; -let kWasmDataRef = -0x19; +let kWasmStructRef = -0x19; let kWasmArrayRef = -0x1a; let kWasmNullRef = -0x1b; let kWasmStringRef = -0x1c; @@ -143,7 +143,7 @@ let kEqRefCode = kWasmEqRef & kLeb128Mask; let kI31RefCode = kWasmI31Ref & kLeb128Mask; let kNullExternRefCode = kWasmNullExternRef & kLeb128Mask; let kNullFuncRefCode = kWasmNullFuncRef & kLeb128Mask; -let kDataRefCode = kWasmDataRef & kLeb128Mask; +let kStructRefCode = kWasmStructRef & kLeb128Mask; let kArrayRefCode = kWasmArrayRef & kLeb128Mask; let kNullRefCode = kWasmNullRef & kLeb128Mask; let kStringRefCode = kWasmStringRef & kLeb128Mask; @@ -517,13 +517,13 @@ let kExprRefCastNop = 0x4c; let kExprRefIsData = 0x51; let kExprRefIsI31 = 0x52; let kExprRefIsArray = 0x53; -let kExprRefAsData = 0x59; +let kExprRefAsStruct = 0x59; let kExprRefAsI31 = 0x5a; let kExprRefAsArray = 0x5b; -let kExprBrOnData = 0x61; +let kExprBrOnStruct = 0x61; let kExprBrOnI31 = 0x62; let kExprBrOnArray = 0x66; -let kExprBrOnNonData = 0x64; +let kExprBrOnNonStruct = 0x64; let kExprBrOnNonI31 = 0x65; let kExprBrOnNonArray = 0x67; let kExprExternInternalize = 0x70; diff --git a/test/unittests/wasm/function-body-decoder-unittest.cc b/test/unittests/wasm/function-body-decoder-unittest.cc index 1b031200b5..7aee0c68c8 100644 --- a/test/unittests/wasm/function-body-decoder-unittest.cc +++ b/test/unittests/wasm/function-body-decoder-unittest.cc @@ -1173,8 +1173,8 @@ TEST_F(FunctionBodyDecoderTest, UnreachableRefTypes) { ExpectValidates(FunctionSig::Build(zone(), {struct_type}, {}), {WASM_UNREACHABLE, WASM_GC_OP(kExprRefCast), struct_index}); - ExpectValidates(FunctionSig::Build(zone(), {kWasmDataRef}, {}), - {WASM_UNREACHABLE, WASM_GC_OP(kExprRefAsData)}); + ExpectValidates(FunctionSig::Build(zone(), {kWasmStructRef}, {}), + {WASM_UNREACHABLE, WASM_GC_OP(kExprRefAsStruct)}); ExpectValidates(FunctionSig::Build(zone(), {}, {struct_type_null}), {WASM_UNREACHABLE, WASM_LOCAL_GET(0), kExprBrOnNull, 0, @@ -4311,8 +4311,8 @@ TEST_F(FunctionBodyDecoderTest, RefTestCast) { std::tuple tests[] = { - std::make_tuple(HeapType::kData, array_heap, true, true), - std::make_tuple(HeapType::kData, super_struct_heap, true, true), + std::make_tuple(HeapType::kArray, array_heap, true, true), + std::make_tuple(HeapType::kStruct, super_struct_heap, true, true), std::make_tuple(HeapType::kFunc, func_heap_1, true, true), std::make_tuple(func_heap_1, func_heap_1, true, true), std::make_tuple(func_heap_1, func_heap_2, true, true), @@ -4350,8 +4350,8 @@ TEST_F(FunctionBodyDecoderTest, RefTestCast) { WASM_HEAP_TYPE(to_heap))}); } else { std::string error_message = - "[0] expected subtype of (ref null func) or (ref null data), found " - "local.get of type " + + "[0] expected subtype of (ref null func), (ref null struct) or (ref " + "null array), found local.get of type " + test_reps[1].name(); ExpectFailure(&test_sig, {WASM_REF_TEST_DEPRECATED(WASM_LOCAL_GET(0), @@ -4381,8 +4381,8 @@ TEST_F(FunctionBodyDecoderTest, RefTestCast) { ExpectFailure(sigs.v_v(), {WASM_REF_TEST_DEPRECATED(WASM_I32V(1), array_heap), kExprDrop}, kAppendEnd, - "ref.test[0] expected subtype of (ref null func) or " - "(ref null data), found i32.const of type i32"); + "ref.test[0] expected subtype of (ref null func), (ref null " + "struct) or (ref null array), found i32.const of type i32"); ExpectFailure(sigs.v_v(), {WASM_REF_TEST(WASM_I32V(1), array_heap), kExprDrop}, kAppendEnd, @@ -4391,8 +4391,8 @@ TEST_F(FunctionBodyDecoderTest, RefTestCast) { ExpectFailure(sigs.v_v(), {WASM_REF_CAST(WASM_I32V(1), array_heap), kExprDrop}, kAppendEnd, - "ref.cast[0] expected subtype of (ref null func) or " - "(ref null data), found i32.const of type i32"); + "ref.cast[0] expected subtype of (ref null func), (ref null " + "struct) or (ref null array), found i32.const of type i32"); } TEST_F(FunctionBodyDecoderTest, BrOnCastOrCastFail) { @@ -4437,17 +4437,18 @@ TEST_F(FunctionBodyDecoderTest, BrOnCastOrCastFail) { kAppendEnd, "type error in branch[0] (expected i32, got (ref null 0))"); // Argument type error. - ExpectFailure(FunctionSig::Build(this->zone(), {subtype}, {kWasmExternRef}), - {WASM_LOCAL_GET(0), WASM_BR_ON_CAST(0, sub_struct), - WASM_GC_OP(kExprRefCast), sub_struct}, - kAppendEnd, - "br_on_cast[0] expected subtype of (ref null func) or " - "(ref null data), found local.get of type externref"); - ExpectFailure(FunctionSig::Build(this->zone(), {supertype}, {kWasmExternRef}), - {WASM_LOCAL_GET(0), WASM_BR_ON_CAST_FAIL(0, sub_struct)}, - kAppendEnd, - "br_on_cast_fail[0] expected subtype of (ref null func) " - "or (ref null data), found local.get of type externref"); + ExpectFailure( + FunctionSig::Build(this->zone(), {subtype}, {kWasmExternRef}), + {WASM_LOCAL_GET(0), WASM_BR_ON_CAST(0, sub_struct), + WASM_GC_OP(kExprRefCast), sub_struct}, + kAppendEnd, + "br_on_cast[0] expected subtype of (ref null func), (ref null struct) or " + "(ref null array), found local.get of type externref"); + ExpectFailure( + FunctionSig::Build(this->zone(), {supertype}, {kWasmExternRef}), + {WASM_LOCAL_GET(0), WASM_BR_ON_CAST_FAIL(0, sub_struct)}, kAppendEnd, + "br_on_cast_fail[0] expected subtype of (ref null func), (ref null " + "struct) or (ref null array), found local.get of type externref"); } TEST_F(FunctionBodyDecoderTest, BrOnAbstractType) { @@ -4458,11 +4459,11 @@ TEST_F(FunctionBodyDecoderTest, BrOnAbstractType) { ValueType kNonNullableFunc = ValueType::Ref(HeapType::kFunc); ExpectValidates( - FunctionSig::Build(this->zone(), {kWasmDataRef}, {kWasmAnyRef}), - {WASM_LOCAL_GET(0), WASM_BR_ON_DATA(0), WASM_GC_OP(kExprRefAsData)}); + FunctionSig::Build(this->zone(), {kWasmStructRef}, {kWasmAnyRef}), + {WASM_LOCAL_GET(0), WASM_BR_ON_STRUCT(0), WASM_GC_OP(kExprRefAsStruct)}); ExpectValidates( FunctionSig::Build(this->zone(), {kWasmAnyRef}, {kWasmAnyRef}), - {WASM_LOCAL_GET(0), WASM_BR_ON_NON_DATA(0)}); + {WASM_LOCAL_GET(0), WASM_BR_ON_NON_STRUCT(0)}); ExpectValidates( FunctionSig::Build(this->zone(), {kWasmI31Ref}, {kWasmAnyRef}), {WASM_LOCAL_GET(0), WASM_BR_ON_I31(0), WASM_GC_OP(kExprRefAsI31)}); @@ -4472,20 +4473,21 @@ TEST_F(FunctionBodyDecoderTest, BrOnAbstractType) { // Wrong branch type. ExpectFailure(FunctionSig::Build(this->zone(), {}, {kWasmAnyRef}), - {WASM_LOCAL_GET(0), WASM_BR_ON_DATA(0), WASM_UNREACHABLE}, + {WASM_LOCAL_GET(0), WASM_BR_ON_STRUCT(0), WASM_UNREACHABLE}, kAppendEnd, - "br_on_data must target a branch of arity at least 1"); + "br_on_struct must target a branch of arity at least 1"); ExpectFailure( FunctionSig::Build(this->zone(), {kNonNullableFunc}, {kWasmAnyRef}), - {WASM_LOCAL_GET(0), WASM_BR_ON_NON_DATA(0)}, kAppendEnd, + {WASM_LOCAL_GET(0), WASM_BR_ON_NON_STRUCT(0)}, kAppendEnd, "type error in branch[0] (expected (ref func), got anyref)"); // Wrong fallthrough type. - ExpectFailure(FunctionSig::Build(this->zone(), {kWasmDataRef}, {kWasmAnyRef}), - {WASM_LOCAL_GET(0), WASM_BR_ON_DATA(0)}, kAppendEnd, - "type error in fallthru[0] (expected dataref, got anyref)"); + ExpectFailure( + FunctionSig::Build(this->zone(), {kWasmStructRef}, {kWasmAnyRef}), + {WASM_LOCAL_GET(0), WASM_BR_ON_STRUCT(0)}, kAppendEnd, + "type error in fallthru[0] (expected structref, got anyref)"); ExpectFailure(FunctionSig::Build(this->zone(), {kWasmAnyRef}, {kWasmAnyRef}), - {WASM_BLOCK_I(WASM_LOCAL_GET(0), WASM_BR_ON_NON_DATA(0))}, + {WASM_BLOCK_I(WASM_LOCAL_GET(0), WASM_BR_ON_NON_STRUCT(0))}, kAppendEnd, "type error in branch[0] (expected i32, got anyref)"); diff --git a/test/unittests/wasm/module-decoder-unittest.cc b/test/unittests/wasm/module-decoder-unittest.cc index 9b0dd9c809..bf4b6eb307 100644 --- a/test/unittests/wasm/module-decoder-unittest.cc +++ b/test/unittests/wasm/module-decoder-unittest.cc @@ -193,7 +193,7 @@ struct ValueTypePair { {kAnyRefCode, kWasmAnyRef}, // -- {kEqRefCode, kWasmEqRef}, // -- {kI31RefCode, kWasmI31Ref}, // -- - {kDataRefCode, kWasmDataRef}, // -- + {kStructRefCode, kWasmStructRef}, // -- {kArrayRefCode, kWasmArrayRef}, // -- {kNoneCode, kWasmNullRef}, // -- {kStringRefCode, kWasmStringRef}, // -- diff --git a/test/unittests/wasm/subtyping-unittest.cc b/test/unittests/wasm/subtyping-unittest.cc index 81648716ce..2602be49ba 100644 --- a/test/unittests/wasm/subtyping-unittest.cc +++ b/test/unittests/wasm/subtyping-unittest.cc @@ -64,6 +64,7 @@ void DefineSignature(WasmModule* module, TEST_F(WasmSubtypingTest, Subtyping) { FLAG_SCOPE(experimental_wasm_gc); + FLAG_VALUE_SCOPE(wasm_gc_structref_as_dataref, false); v8::internal::AccountingAllocator allocator; WasmModule module1_(std::make_unique(&allocator, ZONE_NAME)); WasmModule module2_(std::make_unique(&allocator, ZONE_NAME)); @@ -130,7 +131,7 @@ TEST_F(WasmSubtypingTest, Subtyping) { kWasmS128}; constexpr ValueType ref_types[] = { kWasmFuncRef, kWasmEqRef, // -- - kWasmDataRef, kWasmArrayRef, // -- + kWasmStructRef, kWasmArrayRef, // -- kWasmI31Ref, kWasmAnyRef, // -- kWasmExternRef, kWasmNullExternRef, // -- kWasmNullRef, kWasmNullFuncRef, // -- @@ -201,17 +202,15 @@ TEST_F(WasmSubtypingTest, Subtyping) { ref_type == kWasmStringViewWtf8 || ref_type == kWasmStringViewWtf16; SCOPED_TRACE("ref_type: " + ref_type.name()); - // Concrete reference types, i31ref and dataref are subtypes of eqref, - // externref/funcref/anyref/functions are not. + // Concrete reference types, i31ref, structref and arrayref are subtypes + // of eqref, externref/funcref/anyref/functions are not. SUBTYPE_IFF(ref_type, kWasmEqRef, ref_type != kWasmAnyRef && !is_any_func && !is_extern && !is_string_view && ref_type != kWasmStringRef); - // Struct/array types are subtypes of dataref. - SUBTYPE_IFF(ref_type, kWasmDataRef, - ref_type == kWasmDataRef || ref_type == kWasmArrayRef || - ref_type == kWasmNullRef || ref_type == ref(0) || - ref_type == ref(2) || ref_type == refNull(0) || - ref_type == refNull(2)); + // Struct types are subtypes of structref. + SUBTYPE_IFF(ref_type, kWasmStructRef, + ref_type == kWasmStructRef || ref_type == kWasmNullRef || + ref_type == ref(0) || ref_type == refNull(0)); // Array types are subtypes of arrayref. SUBTYPE_IFF(ref_type, kWasmArrayRef, ref_type == kWasmArrayRef || ref_type == ref(2) || @@ -379,33 +378,32 @@ TEST_F(WasmSubtypingTest, Subtyping) { } // Abstract types vs abstract types. - UNION(kWasmEqRef, kWasmDataRef, kWasmEqRef); + UNION(kWasmEqRef, kWasmStructRef, kWasmEqRef); UNION(kWasmEqRef, kWasmI31Ref, kWasmEqRef); UNION(kWasmEqRef, kWasmArrayRef, kWasmEqRef); UNION(kWasmEqRef, kWasmNullRef, kWasmEqRef); - UNION(kWasmDataRef, kWasmI31Ref, kWasmEqRef); - UNION(kWasmDataRef, kWasmArrayRef, kWasmDataRef); - UNION(kWasmDataRef, kWasmNullRef, kWasmDataRef.AsNullable()); + UNION(kWasmStructRef, kWasmI31Ref, kWasmEqRef); + UNION(kWasmStructRef, kWasmArrayRef, kWasmEqRef); + UNION(kWasmStructRef, kWasmNullRef, kWasmStructRef.AsNullable()); UNION(kWasmI31Ref.AsNonNull(), kWasmArrayRef.AsNonNull(), kWasmEqRef.AsNonNull()); UNION(kWasmI31Ref, kWasmNullRef, kWasmI31Ref.AsNullable()); UNION(kWasmArrayRef, kWasmNullRef, kWasmArrayRef.AsNullable()); - UNION(kWasmDataRef.AsNonNull(), kWasmI31Ref.AsNonNull(), + UNION(kWasmStructRef.AsNonNull(), kWasmI31Ref.AsNonNull(), kWasmEqRef.AsNonNull()); - UNION(kWasmDataRef, kWasmArrayRef, kWasmDataRef); UNION(kWasmI31Ref.AsNonNull(), kWasmArrayRef, kWasmEqRef); UNION(kWasmAnyRef, kWasmNullRef, kWasmAnyRef); UNION(kWasmExternRef, kWasmNullExternRef, kWasmExternRef); UNION(kWasmFuncRef, kWasmNullFuncRef, kWasmFuncRef); INTERSECTION(kWasmExternRef, kWasmEqRef, kWasmBottom); - INTERSECTION(kWasmExternRef, kWasmDataRef, kWasmBottom); + INTERSECTION(kWasmExternRef, kWasmStructRef, kWasmBottom); INTERSECTION(kWasmExternRef, kWasmI31Ref.AsNonNull(), kWasmBottom); INTERSECTION(kWasmExternRef, kWasmArrayRef, kWasmBottom); INTERSECTION(kWasmExternRef, kWasmNullRef, kWasmBottom); INTERSECTION(kWasmExternRef, kWasmFuncRef, kWasmBottom); INTERSECTION(kWasmNullExternRef, kWasmEqRef, kWasmBottom); - INTERSECTION(kWasmNullExternRef, kWasmDataRef, kWasmBottom); + INTERSECTION(kWasmNullExternRef, kWasmStructRef, kWasmBottom); INTERSECTION(kWasmNullExternRef, kWasmI31Ref, kWasmBottom); INTERSECTION(kWasmNullExternRef, kWasmArrayRef, kWasmBottom); INTERSECTION(kWasmNullExternRef, kWasmNullRef, kWasmBottom); @@ -413,13 +411,13 @@ TEST_F(WasmSubtypingTest, Subtyping) { INTERSECTION(kWasmNullExternRef, kWasmExternRef.AsNonNull(), kWasmBottom); INTERSECTION(kWasmFuncRef, kWasmEqRef, kWasmBottom); - INTERSECTION(kWasmFuncRef, kWasmDataRef, kWasmBottom); + INTERSECTION(kWasmFuncRef, kWasmStructRef, kWasmBottom); INTERSECTION(kWasmFuncRef, kWasmI31Ref.AsNonNull(), kWasmBottom); INTERSECTION(kWasmFuncRef, kWasmArrayRef, kWasmBottom); INTERSECTION(kWasmFuncRef, kWasmNullRef, kWasmBottom); INTERSECTION(kWasmFuncRef, kWasmNullExternRef, kWasmBottom); INTERSECTION(kWasmNullFuncRef, kWasmEqRef, kWasmBottom); - INTERSECTION(kWasmNullFuncRef, kWasmDataRef, kWasmBottom); + INTERSECTION(kWasmNullFuncRef, kWasmStructRef, kWasmBottom); INTERSECTION(kWasmNullFuncRef, kWasmI31Ref, kWasmBottom); INTERSECTION(kWasmNullFuncRef, kWasmArrayRef, kWasmBottom); INTERSECTION(kWasmNullFuncRef, kWasmNullRef, kWasmBottom); @@ -427,14 +425,14 @@ TEST_F(WasmSubtypingTest, Subtyping) { INTERSECTION(kWasmNullFuncRef, kWasmFuncRef.AsNonNull(), kWasmBottom); INTERSECTION(kWasmNullFuncRef, kWasmNullExternRef, kWasmBottom); - INTERSECTION(kWasmEqRef, kWasmDataRef, kWasmDataRef); + INTERSECTION(kWasmEqRef, kWasmStructRef, kWasmStructRef); INTERSECTION(kWasmEqRef, kWasmI31Ref, kWasmI31Ref); INTERSECTION(kWasmEqRef, kWasmArrayRef, kWasmArrayRef); INTERSECTION(kWasmEqRef, kWasmNullRef, kWasmNullRef); INTERSECTION(kWasmEqRef, kWasmFuncRef, kWasmBottom); - INTERSECTION(kWasmDataRef, kWasmI31Ref, kWasmNullRef); - INTERSECTION(kWasmDataRef, kWasmArrayRef, kWasmArrayRef); - INTERSECTION(kWasmDataRef, kWasmNullRef, kWasmNullRef); + INTERSECTION(kWasmStructRef, kWasmI31Ref, kWasmNullRef); + INTERSECTION(kWasmStructRef, kWasmArrayRef, kWasmNullRef); + INTERSECTION(kWasmStructRef, kWasmNullRef, kWasmNullRef); INTERSECTION(kWasmI31Ref, kWasmArrayRef, kWasmNullRef); INTERSECTION(kWasmI31Ref.AsNonNull(), kWasmNullRef, kWasmBottom); INTERSECTION(kWasmArrayRef.AsNonNull(), kWasmNullRef, kWasmBottom); @@ -464,11 +462,11 @@ TEST_F(WasmSubtypingTest, Subtyping) { INTERSECTION(kWasmEqRef, array_type, array_type); INTERSECTION(kWasmEqRef, function_type, kWasmBottom); - UNION(kWasmDataRef, struct_type, kWasmDataRef); - UNION(kWasmDataRef, array_type, kWasmDataRef); - INTERSECTION(kWasmDataRef, struct_type, struct_type); - INTERSECTION(kWasmDataRef, array_type, array_type); - INTERSECTION(kWasmDataRef, function_type, kWasmBottom); + UNION(kWasmStructRef, struct_type, kWasmStructRef); + UNION(kWasmStructRef, array_type, kWasmEqRef); + INTERSECTION(kWasmStructRef, struct_type, struct_type); + INTERSECTION(kWasmStructRef, array_type, kWasmBottom); + INTERSECTION(kWasmStructRef, function_type, kWasmBottom); UNION(kWasmI31Ref, struct_type, kWasmEqRef); UNION(kWasmI31Ref, array_type, kWasmEqRef); @@ -476,7 +474,7 @@ TEST_F(WasmSubtypingTest, Subtyping) { INTERSECTION(kWasmI31Ref, array_type, kWasmBottom); INTERSECTION(kWasmI31Ref, function_type, kWasmBottom); - UNION(kWasmArrayRef, struct_type, kWasmDataRef); + UNION(kWasmArrayRef, struct_type, kWasmEqRef); UNION(kWasmArrayRef, array_type, kWasmArrayRef); INTERSECTION(kWasmArrayRef, struct_type, kWasmBottom); INTERSECTION(kWasmArrayRef, array_type, array_type); @@ -490,7 +488,7 @@ TEST_F(WasmSubtypingTest, Subtyping) { INTERSECTION(kWasmNullRef, function_type, kWasmBottom); // Indexed types of different kinds. - UNION(struct_type, array_type, kWasmDataRef.AsNonNull()); + UNION(struct_type, array_type, kWasmEqRef.AsNonNull()); INTERSECTION(struct_type, array_type, kWasmBottom); INTERSECTION(struct_type, function_type, kWasmBottom); INTERSECTION(array_type, function_type, kWasmBottom); @@ -498,8 +496,9 @@ TEST_F(WasmSubtypingTest, Subtyping) { // Nullable vs. non-nullable. UNION(struct_type, struct_type.AsNullable(), struct_type.AsNullable()); INTERSECTION(struct_type, struct_type.AsNullable(), struct_type); - UNION(kWasmDataRef, kWasmDataRef.AsNullable(), kWasmDataRef.AsNullable()); - INTERSECTION(kWasmDataRef, kWasmDataRef.AsNullable(), kWasmDataRef); + UNION(kWasmStructRef, kWasmStructRef.AsNullable(), + kWasmStructRef.AsNullable()); + INTERSECTION(kWasmStructRef, kWasmStructRef.AsNullable(), kWasmStructRef); // Concrete types of the same kind. // Subtyping relation. @@ -512,7 +511,7 @@ TEST_F(WasmSubtypingTest, Subtyping) { // No common ancestor. UNION(ref(6), refNull(2), kWasmArrayRef.AsNullable()); INTERSECTION(ref(6), refNull(2), kWasmBottom); - UNION(ref(0), ref(17), kWasmDataRef.AsNonNull()); + UNION(ref(0), ref(17), kWasmStructRef.AsNonNull()); INTERSECTION(ref(0), ref(17), kWasmBottom); UNION(ref(10), refNull(11), kWasmFuncRef); INTERSECTION(ref(10), refNull(11), kWasmBottom);