[wasm-gc] Fix: externref is not a subtype of eqref
Bug: v8:7748 Change-Id: I30eb7b08b40159e399730eef5866e1f0fbf706e1 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2299368 Commit-Queue: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#68892}
This commit is contained in:
parent
b09ed9f32a
commit
3720f90577
@ -100,7 +100,7 @@ class HeapType {
|
||||
return !is_bottom() && representation_ >= kFirstSentinel;
|
||||
}
|
||||
|
||||
constexpr bool is_index() const { return !is_bottom() && !is_generic(); }
|
||||
constexpr bool is_index() const { return representation_ < kFirstSentinel; }
|
||||
|
||||
constexpr bool is_bottom() const { return representation_ == kBottom; }
|
||||
|
||||
|
@ -151,9 +151,9 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(ValueType subtype,
|
||||
if (sub_heap == super_heap) {
|
||||
return true;
|
||||
}
|
||||
// eqref is a supertype of all reference types except funcref.
|
||||
// eqref is a supertype of i31ref and all custom types.
|
||||
if (super_heap.representation() == HeapType::kEq) {
|
||||
return sub_heap.representation() != HeapType::kFunc;
|
||||
return (sub_heap.is_index() || sub_heap.representation() == HeapType::kI31);
|
||||
}
|
||||
// At the moment, generic heap types are not subtyping-related otherwise.
|
||||
if (sub_heap.is_generic() || super_heap.is_generic()) {
|
||||
|
@ -3417,12 +3417,8 @@ TEST_F(FunctionBodyDecoderTest, RefEq) {
|
||||
TestModuleBuilder builder;
|
||||
module = builder.module();
|
||||
byte struct_type_index = builder.AddStruct({F(kWasmI32, true)});
|
||||
ValueType eqref_subtypes[] = {kWasmExnRef,
|
||||
kWasmExternRef,
|
||||
kWasmEqRef,
|
||||
ValueType eqref_subtypes[] = {kWasmEqRef,
|
||||
kWasmI31Ref,
|
||||
ValueType::Ref(HeapType::kExn, kNonNullable),
|
||||
ValueType::Ref(HeapType::kExtern, kNonNullable),
|
||||
ValueType::Ref(HeapType::kEq, kNonNullable),
|
||||
ValueType::Ref(HeapType::kI31, kNullable),
|
||||
ref(struct_type_index),
|
||||
@ -3433,7 +3429,11 @@ TEST_F(FunctionBodyDecoderTest, RefEq) {
|
||||
kWasmF32,
|
||||
kWasmF64,
|
||||
kWasmS128,
|
||||
kWasmExnRef,
|
||||
kWasmExternRef,
|
||||
kWasmFuncRef,
|
||||
ValueType::Ref(HeapType::kExn, kNonNullable),
|
||||
ValueType::Ref(HeapType::kExtern, kNonNullable),
|
||||
ValueType::Ref(HeapType::kFunc, kNonNullable)};
|
||||
|
||||
for (ValueType type1 : eqref_subtypes) {
|
||||
|
@ -667,11 +667,11 @@ TEST_F(WasmModuleVerifyTest, GlobalRttSubOfCanon) {
|
||||
WASM_FEATURE_SCOPE(typed_funcref);
|
||||
WASM_FEATURE_SCOPE(gc);
|
||||
static const byte data[] = {SECTION(
|
||||
Global, ENTRY_COUNT(1), WASM_RTT(2, kLocalExternRef), 1,
|
||||
WASM_RTT_CANON(kLocalEqRef), WASM_RTT_SUB(kLocalExternRef), kExprEnd)};
|
||||
Global, ENTRY_COUNT(1), WASM_RTT(2, kLocalI31Ref), 1,
|
||||
WASM_RTT_CANON(kLocalEqRef), WASM_RTT_SUB(kLocalI31Ref), kExprEnd)};
|
||||
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
||||
WasmInitExpr expected = WasmInitExpr::RttSub(
|
||||
HeapType::kExtern, WasmInitExpr::RttCanon(HeapType::kEq));
|
||||
HeapType::kI31, WasmInitExpr::RttCanon(HeapType::kEq));
|
||||
EXPECT_OK(result);
|
||||
EXPECT_EQ(result.value()->globals.front().init, expected);
|
||||
}
|
||||
@ -681,14 +681,13 @@ TEST_F(WasmModuleVerifyTest, GlobalRttSubOfSubOfCanon) {
|
||||
WASM_FEATURE_SCOPE(typed_funcref);
|
||||
WASM_FEATURE_SCOPE(gc);
|
||||
static const byte data[] = {
|
||||
SECTION(Global, ENTRY_COUNT(1), WASM_RTT(3, kLocalExternRef), 1,
|
||||
WASM_RTT_CANON(kLocalEqRef), WASM_RTT_SUB(kLocalExternRef),
|
||||
WASM_RTT_SUB(kLocalExternRef), kExprEnd)};
|
||||
SECTION(Global, ENTRY_COUNT(1), WASM_RTT(3, kLocalEqRef), 1,
|
||||
WASM_RTT_CANON(kLocalEqRef), WASM_RTT_SUB(kLocalEqRef),
|
||||
WASM_RTT_SUB(kLocalEqRef), kExprEnd)};
|
||||
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
||||
WasmInitExpr expected = WasmInitExpr::RttSub(
|
||||
HeapType::kExtern,
|
||||
WasmInitExpr::RttSub(HeapType::kExtern,
|
||||
WasmInitExpr::RttCanon(HeapType::kEq)));
|
||||
HeapType::kEq, WasmInitExpr::RttSub(
|
||||
HeapType::kEq, WasmInitExpr::RttCanon(HeapType::kEq)));
|
||||
EXPECT_OK(result);
|
||||
EXPECT_EQ(result.value()->globals.front().init, expected);
|
||||
}
|
||||
@ -705,11 +704,11 @@ TEST_F(WasmModuleVerifyTest, GlobalRttSubOfGlobal) {
|
||||
kExternalGlobal, // import kind
|
||||
WASM_RTT(1, kLocalEqRef), // type
|
||||
0), // mutability
|
||||
SECTION(Global, ENTRY_COUNT(1), WASM_RTT(2, kLocalExternRef), 1,
|
||||
WASM_GET_GLOBAL(0), WASM_RTT_SUB(kLocalExternRef), kExprEnd)};
|
||||
SECTION(Global, ENTRY_COUNT(1), WASM_RTT(2, kLocalI31Ref), 1,
|
||||
WASM_GET_GLOBAL(0), WASM_RTT_SUB(kLocalI31Ref), kExprEnd)};
|
||||
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
||||
WasmInitExpr expected =
|
||||
WasmInitExpr::RttSub(HeapType::kExtern, WasmInitExpr::GlobalGet(0));
|
||||
WasmInitExpr::RttSub(HeapType::kI31, WasmInitExpr::GlobalGet(0));
|
||||
EXPECT_OK(result);
|
||||
EXPECT_EQ(result.value()->globals[1].init, expected);
|
||||
}
|
||||
@ -748,12 +747,12 @@ TEST_F(WasmModuleVerifyTest, RttSubGlobalTypeError) {
|
||||
WASM_FEATURE_SCOPE(typed_funcref);
|
||||
WASM_FEATURE_SCOPE(gc);
|
||||
static const byte data[] = {SECTION(
|
||||
Global, ENTRY_COUNT(1), WASM_RTT(1 /* Should be 2 */, kLocalExternRef), 1,
|
||||
WASM_RTT_CANON(kLocalEqRef), WASM_RTT_SUB(kLocalExternRef), kExprEnd)};
|
||||
Global, ENTRY_COUNT(1), WASM_RTT(1 /* Should be 2 */, kLocalI31Ref), 1,
|
||||
WASM_RTT_CANON(kLocalEqRef), WASM_RTT_SUB(kLocalI31Ref), kExprEnd)};
|
||||
ModuleResult result = DecodeModule(data, data + sizeof(data));
|
||||
EXPECT_NOT_OK(result,
|
||||
"type error in init expression, expected (rtt 1 extern), got "
|
||||
"(rtt 2 extern)");
|
||||
"type error in init expression, expected (rtt 1 i31), got "
|
||||
"(rtt 2 i31)");
|
||||
}
|
||||
|
||||
TEST_F(WasmModuleVerifyTest, ZeroExceptions) {
|
||||
|
@ -72,9 +72,11 @@ TEST_F(WasmSubtypingTest, Subtyping) {
|
||||
}
|
||||
|
||||
for (ValueType ref_type : ref_types) {
|
||||
// Reference types are a subtype of eqref, except funcref.
|
||||
// Concrete reference types and i31ref are subtypes of eqref,
|
||||
// exnref/externref/funcref are not.
|
||||
CHECK_EQ(IsSubtypeOf(ref_type, kWasmEqRef, module),
|
||||
ref_type != kWasmFuncRef);
|
||||
ref_type != kWasmFuncRef && ref_type != kWasmExternRef &&
|
||||
ref_type != kWasmExnRef);
|
||||
// Each reference type is a subtype of itself.
|
||||
CHECK(IsSubtypeOf(ref_type, ref_type, module));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user