Commit bcd8bf90 authored by Manos Koukoutos's avatar Manos Koukoutos Committed by V8 LUCI CQ

[wasm-gc] Introduce separate constructors for ref and (ref null)

Most often, the {ValueType::Ref} constructor was called with a
constant nullability. To make things more convenient, this CL renames
{Ref} to {RefMaybeNull}, and introduces {Ref} and {RefNull}
constructors with fixed nullability.

Bug: v8:7748
Change-Id: I664ff184ca936cc752e152c3c67546d79aa24390
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3732936Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81494}
parent f6bf7cdb
...@@ -128,9 +128,8 @@ Reduction WasmGCOperatorReducer::ReduceIf(Node* node, bool condition) { ...@@ -128,9 +128,8 @@ Reduction WasmGCOperatorReducer::ReduceIf(Node* node, bool condition) {
if (object_type.type.is_bottom()) return NoChange(); if (object_type.type.is_bottom()) return NoChange();
Node* rtt = NodeProperties::GetValueInput(condition_node, 1); Node* rtt = NodeProperties::GetValueInput(condition_node, 1);
wasm::ValueType rtt_type = wasm::ValueType::Ref( wasm::ValueType rtt_type = wasm::ValueType::RefNull(
NodeProperties::GetType(rtt).AsWasm().type.ref_index(), NodeProperties::GetType(rtt).AsWasm().type.ref_index());
wasm::kNullable);
// TODO(manoskouk): Think about {module_} below if we have cross-module // TODO(manoskouk): Think about {module_} below if we have cross-module
// inlining. // inlining.
...@@ -271,8 +270,7 @@ Reduction WasmGCOperatorReducer::ReduceWasmTypeCast(Node* node) { ...@@ -271,8 +270,7 @@ Reduction WasmGCOperatorReducer::ReduceWasmTypeCast(Node* node) {
TrapId::kTrapIllegalCast); TrapId::kTrapIllegalCast);
// TODO(manoskouk): Improve the type when we have nullref. // TODO(manoskouk): Improve the type when we have nullref.
Node* null_node = SetType( Node* null_node = SetType(
gasm_.Null(), gasm_.Null(), wasm::ValueType::RefNull(rtt_type.type.ref_index()));
wasm::ValueType::Ref(rtt_type.type.ref_index(), wasm::kNullable));
ReplaceWithValue(node, null_node, gasm_.effect(), gasm_.control()); ReplaceWithValue(node, null_node, gasm_.effect(), gasm_.control());
node->Kill(); node->Kill();
return Replace(null_node); return Replace(null_node);
...@@ -290,8 +288,7 @@ Reduction WasmGCOperatorReducer::ReduceWasmTypeCast(Node* node) { ...@@ -290,8 +288,7 @@ Reduction WasmGCOperatorReducer::ReduceWasmTypeCast(Node* node) {
// inlining. // inlining.
wasm::TypeInModule new_type = wasm::Intersection( wasm::TypeInModule new_type = wasm::Intersection(
object_type, object_type,
{wasm::ValueType::Ref(rtt_type.type.ref_index(), wasm::kNullable), {wasm::ValueType::RefNull(rtt_type.type.ref_index()), module_});
module_});
return UpdateNodeAndAliasesTypes(node, GetState(control), node, new_type, return UpdateNodeAndAliasesTypes(node, GetState(control), node, new_type,
false); false);
......
...@@ -91,7 +91,7 @@ Reduction WasmTyper::Reduce(Node* node) { ...@@ -91,7 +91,7 @@ Reduction WasmTyper::Reduce(Node* node) {
NodeProperties::GetType(NodeProperties::GetValueInput(node, 1)) NodeProperties::GetType(NodeProperties::GetValueInput(node, 1))
.AsWasm(); .AsWasm();
wasm::ValueType to_type = wasm::ValueType to_type =
wasm::ValueType::Ref(rtt_type.type.ref_index(), wasm::kNullable); wasm::ValueType::RefNull(rtt_type.type.ref_index());
computed_type = wasm::Intersection(object_type.type, to_type, computed_type = wasm::Intersection(object_type.type, to_type,
object_type.module, rtt_type.module); object_type.module, rtt_type.module);
if (object_type.type.is_nullable() && computed_type.type.is_bottom()) { if (object_type.type.is_nullable() && computed_type.type.is_bottom()) {
......
...@@ -3394,8 +3394,8 @@ class LiftoffCompiler { ...@@ -3394,8 +3394,8 @@ class LiftoffCompiler {
ValueType type = ValueType type =
index < static_cast<int>(__ num_locals()) index < static_cast<int>(__ num_locals())
? decoder->local_type(index) ? decoder->local_type(index)
: exception ? ValueType::Ref(HeapType::kAny, kNonNullable) : exception ? ValueType::Ref(HeapType::kAny)
: decoder->stack_value(decoder_stack_index--)->type; : decoder->stack_value(decoder_stack_index--)->type;
DCHECK(CheckCompatibleStackSlotTypes(slot.kind(), type.kind())); DCHECK(CheckCompatibleStackSlotTypes(slot.kind(), type.kind()));
value.type = type; value.type = type;
switch (slot.loc()) { switch (slot.loc()) {
......
...@@ -92,8 +92,7 @@ void ConstantExpressionInterface::RefFunc(FullDecoder* decoder, ...@@ -92,8 +92,7 @@ void ConstantExpressionInterface::RefFunc(FullDecoder* decoder,
return; return;
} }
if (!generate_value()) return; if (!generate_value()) return;
ValueType type = ValueType::Ref(module_->functions[function_index].sig_index, ValueType type = ValueType::Ref(module_->functions[function_index].sig_index);
kNonNullable);
Handle<WasmInternalFunction> internal = Handle<WasmInternalFunction> internal =
WasmInstanceObject::GetOrCreateWasmInternalFunction(isolate_, instance_, WasmInstanceObject::GetOrCreateWasmInternalFunction(isolate_, instance_,
function_index); function_index);
...@@ -131,7 +130,7 @@ void ConstantExpressionInterface::StructNewWithRtt( ...@@ -131,7 +130,7 @@ void ConstantExpressionInterface::StructNewWithRtt(
WasmValue(isolate_->factory()->NewWasmStruct( WasmValue(isolate_->factory()->NewWasmStruct(
imm.struct_type, field_values.data(), imm.struct_type, field_values.data(),
Handle<Map>::cast(rtt.runtime_value.to_ref())), Handle<Map>::cast(rtt.runtime_value.to_ref())),
ValueType::Ref(HeapType(imm.index), kNonNullable)); ValueType::Ref(HeapType(imm.index)));
} }
void ConstantExpressionInterface::StringConst( void ConstantExpressionInterface::StringConst(
...@@ -192,7 +191,7 @@ void ConstantExpressionInterface::StructNewDefault( ...@@ -192,7 +191,7 @@ void ConstantExpressionInterface::StructNewDefault(
WasmValue(isolate_->factory()->NewWasmStruct( WasmValue(isolate_->factory()->NewWasmStruct(
imm.struct_type, field_values.data(), imm.struct_type, field_values.data(),
Handle<Map>::cast(rtt.runtime_value.to_ref())), Handle<Map>::cast(rtt.runtime_value.to_ref())),
ValueType::Ref(HeapType(imm.index), kNonNullable)); ValueType::Ref(HeapType(imm.index)));
} }
void ConstantExpressionInterface::ArrayNewFixed( void ConstantExpressionInterface::ArrayNewFixed(
...@@ -205,7 +204,7 @@ void ConstantExpressionInterface::ArrayNewFixed( ...@@ -205,7 +204,7 @@ void ConstantExpressionInterface::ArrayNewFixed(
WasmValue(isolate_->factory()->NewWasmArrayFromElements( WasmValue(isolate_->factory()->NewWasmArrayFromElements(
imm.array_type, element_values, imm.array_type, element_values,
Handle<Map>::cast(rtt.runtime_value.to_ref())), Handle<Map>::cast(rtt.runtime_value.to_ref())),
ValueType::Ref(HeapType(imm.index), kNonNullable)); ValueType::Ref(HeapType(imm.index)));
} }
void ConstantExpressionInterface::ArrayNewSegment( void ConstantExpressionInterface::ArrayNewSegment(
...@@ -222,8 +221,7 @@ void ConstantExpressionInterface::ArrayNewSegment( ...@@ -222,8 +221,7 @@ void ConstantExpressionInterface::ArrayNewSegment(
return; return;
} }
ValueType element_type = array_imm.array_type->element_type(); ValueType element_type = array_imm.array_type->element_type();
ValueType result_type = ValueType result_type = ValueType::Ref(HeapType(array_imm.index));
ValueType::Ref(HeapType(array_imm.index), kNonNullable);
if (element_type.is_numeric()) { if (element_type.is_numeric()) {
const WasmDataSegment& data_segment = const WasmDataSegment& data_segment =
module_->data_segments[segment_imm.index]; module_->data_segments[segment_imm.index];
......
...@@ -36,7 +36,7 @@ ValueOrError EvaluateConstantExpression(Zone* zone, ConstantExpression expr, ...@@ -36,7 +36,7 @@ ValueOrError EvaluateConstantExpression(Zone* zone, ConstantExpression expr,
return WasmValue(expr.i32_value()); return WasmValue(expr.i32_value());
case ConstantExpression::kRefNull: case ConstantExpression::kRefNull:
return WasmValue(isolate->factory()->null_value(), return WasmValue(isolate->factory()->null_value(),
ValueType::Ref(expr.repr(), kNullable)); ValueType::RefNull(expr.repr()));
case ConstantExpression::kRefFunc: { case ConstantExpression::kRefFunc: {
uint32_t index = expr.index(); uint32_t index = expr.index();
Handle<Object> value = Handle<Object> value =
......
This diff is collapsed.
...@@ -1969,8 +1969,7 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1969,8 +1969,7 @@ class ModuleDecoderImpl : public Decoder {
} }
ValueType type = ValueType type =
enabled_features_.has_typed_funcref() enabled_features_.has_typed_funcref()
? ValueType::Ref(module_->functions[index].sig_index, ? ValueType::Ref(module_->functions[index].sig_index)
kNonNullable)
: kWasmFuncRef; : kWasmFuncRef;
TYPE_CHECK(type) TYPE_CHECK(type)
module_->functions[index].declared = true; module_->functions[index].declared = true;
...@@ -1984,7 +1983,7 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1984,7 +1983,7 @@ class ModuleDecoderImpl : public Decoder {
this, pc() + 1, &length, module_.get(), enabled_features_); this, pc() + 1, &length, module_.get(), enabled_features_);
if (V8_UNLIKELY(failed())) return {}; if (V8_UNLIKELY(failed())) return {};
if (V8_LIKELY(lookahead(1 + length, kExprEnd))) { if (V8_LIKELY(lookahead(1 + length, kExprEnd))) {
TYPE_CHECK(ValueType::Ref(type, kNullable)) TYPE_CHECK(ValueType::RefNull(type))
consume_bytes(length + 2); consume_bytes(length + 2);
return ConstantExpression::RefNull(type.representation()); return ConstantExpression::RefNull(type.representation());
} }
...@@ -2276,7 +2275,7 @@ class ModuleDecoderImpl : public Decoder { ...@@ -2276,7 +2275,7 @@ class ModuleDecoderImpl : public Decoder {
if (failed()) return index; if (failed()) return index;
DCHECK_NOT_NULL(func); DCHECK_NOT_NULL(func);
DCHECK_EQ(index, func->func_index); DCHECK_EQ(index, func->func_index);
ValueType entry_type = ValueType::Ref(func->sig_index, kNonNullable); ValueType entry_type = ValueType::Ref(func->sig_index);
if (V8_UNLIKELY(!IsSubtypeOf(entry_type, expected, module_.get()))) { if (V8_UNLIKELY(!IsSubtypeOf(entry_type, expected, module_.get()))) {
errorf(initial_pc, errorf(initial_pc,
"Invalid type in element entry: expected %s, got %s instead.", "Invalid type in element entry: expected %s, got %s instead.",
......
...@@ -330,14 +330,32 @@ class ValueType { ...@@ -330,14 +330,32 @@ class ValueType {
DCHECK(kind == kBottom || kind <= kI16); DCHECK(kind == kBottom || kind <= kI16);
return ValueType(KindField::encode(kind)); return ValueType(KindField::encode(kind));
} }
static constexpr ValueType Ref(uint32_t heap_type, Nullability nullability) { static constexpr ValueType Ref(uint32_t heap_type) {
DCHECK(HeapType(heap_type).is_valid());
return ValueType(KindField::encode(kRef) |
HeapTypeField::encode(heap_type));
}
static constexpr ValueType Ref(HeapType heap_type) {
return Ref(heap_type.representation());
}
static constexpr ValueType RefNull(uint32_t heap_type) {
DCHECK(HeapType(heap_type).is_valid());
return ValueType(KindField::encode(kRefNull) |
HeapTypeField::encode(heap_type));
}
static constexpr ValueType RefNull(HeapType heap_type) {
return RefNull(heap_type.representation());
}
static constexpr ValueType RefMaybeNull(uint32_t heap_type,
Nullability nullability) {
DCHECK(HeapType(heap_type).is_valid()); DCHECK(HeapType(heap_type).is_valid());
return ValueType( return ValueType(
KindField::encode(nullability == kNullable ? kRefNull : kRef) | KindField::encode(nullability == kNullable ? kRefNull : kRef) |
HeapTypeField::encode(heap_type)); HeapTypeField::encode(heap_type));
} }
static constexpr ValueType Ref(HeapType heap_type, Nullability nullability) { static constexpr ValueType RefMaybeNull(HeapType heap_type,
return Ref(heap_type.representation(), nullability); Nullability nullability) {
return RefMaybeNull(heap_type.representation(), nullability);
} }
static constexpr ValueType Rtt(uint32_t type_index) { static constexpr ValueType Rtt(uint32_t type_index) {
...@@ -391,12 +409,12 @@ class ValueType { ...@@ -391,12 +409,12 @@ class ValueType {
// If {this} is (ref null $t), returns (ref $t). Otherwise, returns {this}. // If {this} is (ref null $t), returns (ref $t). Otherwise, returns {this}.
constexpr ValueType AsNonNull() const { constexpr ValueType AsNonNull() const {
return is_nullable() ? Ref(heap_type(), kNonNullable) : *this; return is_nullable() ? Ref(heap_type()) : *this;
} }
// If {this} is (ref $t), returns (ref null $t). Otherwise, returns {this}. // If {this} is (ref $t), returns (ref null $t). Otherwise, returns {this}.
constexpr ValueType AsNullable() const { constexpr ValueType AsNullable() const {
return is_non_nullable() ? Ref(heap_type(), kNullable) : *this; return is_non_nullable() ? RefNull(heap_type()) : *this;
} }
/***************************** Field Accessors ******************************/ /***************************** Field Accessors ******************************/
...@@ -468,7 +486,7 @@ class ValueType { ...@@ -468,7 +486,7 @@ class ValueType {
case MachineRepresentation::kFloat64: case MachineRepresentation::kFloat64:
return Primitive(kF64); return Primitive(kF64);
case MachineRepresentation::kTaggedPointer: case MachineRepresentation::kTaggedPointer:
return Ref(HeapType::kAny, kNullable); return RefNull(HeapType::kAny);
case MachineRepresentation::kSimd128: case MachineRepresentation::kSimd128:
return Primitive(kS128); return Primitive(kS128);
default: default:
...@@ -650,29 +668,25 @@ constexpr ValueType kWasmI16 = ValueType::Primitive(kI16); ...@@ -650,29 +668,25 @@ constexpr ValueType kWasmI16 = ValueType::Primitive(kI16);
constexpr ValueType kWasmVoid = ValueType::Primitive(kVoid); constexpr ValueType kWasmVoid = ValueType::Primitive(kVoid);
constexpr ValueType kWasmBottom = ValueType::Primitive(kBottom); constexpr ValueType kWasmBottom = ValueType::Primitive(kBottom);
// Established reference-type and wasm-gc proposal shorthands. // Established reference-type and wasm-gc proposal shorthands.
constexpr ValueType kWasmFuncRef = ValueType::Ref(HeapType::kFunc, kNullable); constexpr ValueType kWasmFuncRef = ValueType::RefNull(HeapType::kFunc);
constexpr ValueType kWasmAnyRef = ValueType::Ref(HeapType::kAny, kNullable); constexpr ValueType kWasmAnyRef = ValueType::RefNull(HeapType::kAny);
constexpr ValueType kWasmEqRef = ValueType::Ref(HeapType::kEq, kNullable); constexpr ValueType kWasmEqRef = ValueType::RefNull(HeapType::kEq);
constexpr ValueType kWasmI31Ref = ValueType::Ref(HeapType::kI31, kNonNullable); constexpr ValueType kWasmI31Ref = ValueType::Ref(HeapType::kI31);
constexpr ValueType kWasmDataRef = constexpr ValueType kWasmDataRef = ValueType::Ref(HeapType::kData);
ValueType::Ref(HeapType::kData, kNonNullable); constexpr ValueType kWasmArrayRef = ValueType::Ref(HeapType::kArray);
constexpr ValueType kWasmArrayRef = constexpr ValueType kWasmStringRef = ValueType::RefNull(HeapType::kString);
ValueType::Ref(HeapType::kArray, kNonNullable);
constexpr ValueType kWasmStringRef =
ValueType::Ref(HeapType::kString, kNullable);
constexpr ValueType kWasmStringViewWtf8 = constexpr ValueType kWasmStringViewWtf8 =
ValueType::Ref(HeapType::kStringViewWtf8, kNullable); ValueType::RefNull(HeapType::kStringViewWtf8);
constexpr ValueType kWasmStringViewWtf16 = constexpr ValueType kWasmStringViewWtf16 =
ValueType::Ref(HeapType::kStringViewWtf16, kNullable); ValueType::RefNull(HeapType::kStringViewWtf16);
constexpr ValueType kWasmStringViewIter = constexpr ValueType kWasmStringViewIter =
ValueType::Ref(HeapType::kStringViewIter, kNullable); ValueType::RefNull(HeapType::kStringViewIter);
// Constants used by the generic js-to-wasm wrapper. // Constants used by the generic js-to-wasm wrapper.
constexpr int kWasmValueKindBitsMask = (1u << ValueType::kKindBits) - 1; constexpr int kWasmValueKindBitsMask = (1u << ValueType::kKindBits) - 1;
// This is used in wasm.tq. // This is used in wasm.tq.
constexpr ValueType kWasmAnyNonNullableRef = constexpr ValueType kWasmAnyNonNullableRef = ValueType::Ref(HeapType::kAny);
ValueType::Ref(HeapType::kAny, kNonNullable);
#define FOREACH_WASMVALUE_CTYPES(V) \ #define FOREACH_WASMVALUE_CTYPES(V) \
V(kI32, int32_t) \ V(kI32, int32_t) \
......
...@@ -34,23 +34,23 @@ ValueType WasmInitExpr::type(const WasmModule* module, ...@@ -34,23 +34,23 @@ ValueType WasmInitExpr::type(const WasmModule* module,
uint32_t heap_type = enabled_features.has_typed_funcref() uint32_t heap_type = enabled_features.has_typed_funcref()
? module->functions[immediate().index].sig_index ? module->functions[immediate().index].sig_index
: HeapType::kFunc; : HeapType::kFunc;
return ValueType::Ref(heap_type, kNonNullable); return ValueType::Ref(heap_type);
} }
case kRefNullConst: case kRefNullConst:
return ValueType::Ref(immediate().heap_type, kNullable); return ValueType::RefNull(immediate().heap_type);
case kStructNewWithRtt: case kStructNewWithRtt:
case kStructNew: case kStructNew:
case kStructNewDefaultWithRtt: case kStructNewDefaultWithRtt:
case kStructNewDefault: case kStructNewDefault:
case kArrayNewFixed: case kArrayNewFixed:
case kArrayNewFixedStatic: case kArrayNewFixedStatic:
return ValueType::Ref(immediate().index, kNonNullable); return ValueType::Ref(immediate().index);
case kI31New: case kI31New:
return kWasmI31Ref.AsNonNull(); return kWasmI31Ref.AsNonNull();
case kRttCanon: case kRttCanon:
return ValueType::Rtt(immediate().heap_type); return ValueType::Rtt(immediate().heap_type);
case kStringConst: case kStringConst:
return ValueType::Ref(HeapType::kString, kNonNullable); return ValueType::Ref(HeapType::kString);
} }
} }
......
...@@ -2366,8 +2366,7 @@ bool TypecheckJSObject(Isolate* isolate, const WasmModule* module, ...@@ -2366,8 +2366,7 @@ bool TypecheckJSObject(Isolate* isolate, const WasmModule* module,
const WasmModule* exporting_module = function.instance().module(); const WasmModule* exporting_module = function.instance().module();
ValueType real_type = ValueType::Ref( ValueType real_type = ValueType::Ref(
exporting_module->functions[function.function_index()] exporting_module->functions[function.function_index()]
.sig_index, .sig_index);
kNonNullable);
if (!IsSubtypeOf(real_type, expected, exporting_module, module)) { if (!IsSubtypeOf(real_type, expected, exporting_module, module)) {
*error_message = *error_message =
"assigned exported function has to be a subtype of the " "assigned exported function has to be a subtype of the "
......
...@@ -394,20 +394,21 @@ V8_EXPORT_PRIVATE TypeInModule Union(ValueType type1, ValueType type2, ...@@ -394,20 +394,21 @@ V8_EXPORT_PRIVATE TypeInModule Union(ValueType type1, ValueType type2,
HeapType heap1 = type1.heap_type(); HeapType heap1 = type1.heap_type();
HeapType heap2 = type2.heap_type(); HeapType heap2 = type2.heap_type();
if (heap1 == heap2 && module1 == module2) { if (heap1 == heap2 && module1 == module2) {
return {ValueType::Ref(heap1, nullability), module1}; return {ValueType::RefMaybeNull(heap1, nullability), module1};
} }
if (heap1.is_generic()) { if (heap1.is_generic()) {
return {ValueType::Ref(CommonAncestorWithGeneric(heap1, heap2, module2), return {ValueType::RefMaybeNull(
nullability), CommonAncestorWithGeneric(heap1, heap2, module2), nullability),
module1}; module1};
} else if (heap2.is_generic()) { } else if (heap2.is_generic()) {
return {ValueType::Ref(CommonAncestorWithGeneric(heap2, heap1, module1), return {ValueType::RefMaybeNull(
nullability), CommonAncestorWithGeneric(heap2, heap1, module1), nullability),
module1}; module1};
} else { } else {
return {ValueType::Ref(CommonAncestor(heap1.ref_index(), heap2.ref_index(), return {ValueType::RefMaybeNull(
module1, module2), CommonAncestor(heap1.ref_index(), heap2.ref_index(), module1,
nullability), module2),
nullability),
module1}; module1};
} }
} }
...@@ -423,11 +424,13 @@ TypeInModule Intersection(ValueType type1, ValueType type2, ...@@ -423,11 +424,13 @@ TypeInModule Intersection(ValueType type1, ValueType type2,
Nullability nullability = Nullability nullability =
type1.is_nullable() && type2.is_nullable() ? kNullable : kNonNullable; type1.is_nullable() && type2.is_nullable() ? kNullable : kNonNullable;
return IsHeapSubtypeOf(type1.heap_type(), type2.heap_type(), module1, module2) return IsHeapSubtypeOf(type1.heap_type(), type2.heap_type(), module1, module2)
? TypeInModule{ValueType::Ref(type1.heap_type(), nullability), ? TypeInModule{ValueType::RefMaybeNull(type1.heap_type(),
nullability),
module1} module1}
: IsHeapSubtypeOf(type2.heap_type(), type1.heap_type(), module2, : IsHeapSubtypeOf(type2.heap_type(), type1.heap_type(), module2,
module1) module1)
? TypeInModule{ValueType::Ref(type2.heap_type(), nullability), ? TypeInModule{ValueType::RefMaybeNull(type2.heap_type(),
nullability),
module2} module2}
: TypeInModule{kWasmBottom, module1}; : TypeInModule{kWasmBottom, module1};
} }
......
This diff is collapsed.
...@@ -437,7 +437,7 @@ TEST(Liftoff_debug_side_table_catch_all) { ...@@ -437,7 +437,7 @@ TEST(Liftoff_debug_side_table_catch_all) {
LiftoffCompileEnvironment env; LiftoffCompileEnvironment env;
TestSignatures sigs; TestSignatures sigs;
int ex = env.builder()->AddException(sigs.v_v()); int ex = env.builder()->AddException(sigs.v_v());
ValueType exception_type = ValueType::Ref(HeapType::kAny, kNonNullable); ValueType exception_type = ValueType::Ref(HeapType::kAny);
auto debug_side_table = env.GenerateDebugSideTable( auto debug_side_table = env.GenerateDebugSideTable(
{}, {kWasmI32}, {}, {kWasmI32},
{WASM_TRY_CATCH_ALL_T(kWasmI32, WASM_STMTS(WASM_I32V(0), WASM_THROW(ex)), {WASM_TRY_CATCH_ALL_T(kWasmI32, WASM_STMTS(WASM_I32V(0), WASM_THROW(ex)),
...@@ -462,7 +462,7 @@ TEST(Liftoff_debug_side_table_catch_all) { ...@@ -462,7 +462,7 @@ TEST(Liftoff_debug_side_table_catch_all) {
TEST(Regress1199526) { TEST(Regress1199526) {
EXPERIMENTAL_FLAG_SCOPE(eh); EXPERIMENTAL_FLAG_SCOPE(eh);
LiftoffCompileEnvironment env; LiftoffCompileEnvironment env;
ValueType exception_type = ValueType::Ref(HeapType::kAny, kNonNullable); ValueType exception_type = ValueType::Ref(HeapType::kAny);
auto debug_side_table = env.GenerateDebugSideTable( auto debug_side_table = env.GenerateDebugSideTable(
{}, {}, {}, {},
{kExprTry, kVoidCode, kExprCallFunction, 0, kExprCatchAll, kExprLoop, {kExprTry, kVoidCode, kExprCallFunction, 0, kExprCatchAll, kExprLoop,
......
...@@ -3673,7 +3673,7 @@ WASM_EXEC_TEST(IndirectNullTyped) { ...@@ -3673,7 +3673,7 @@ WASM_EXEC_TEST(IndirectNullTyped) {
FunctionSig sig(1, 0, &kWasmI32); FunctionSig sig(1, 0, &kWasmI32);
byte sig_index = r.builder().AddSignature(&sig); byte sig_index = r.builder().AddSignature(&sig);
r.builder().AddIndirectFunctionTable(nullptr, 1, r.builder().AddIndirectFunctionTable(nullptr, 1,
ValueType::Ref(sig_index, kNullable)); ValueType::RefNull(sig_index));
BUILD(r, WASM_CALL_INDIRECT(sig_index, WASM_I32V(0))); BUILD(r, WASM_CALL_INDIRECT(sig_index, WASM_I32V(0)));
......
...@@ -3520,7 +3520,7 @@ class WasmInterpreterInternals { ...@@ -3520,7 +3520,7 @@ class WasmInterpreterInternals {
WasmFeatures::All(), &decoder, code->at(pc + 1), module()); WasmFeatures::All(), &decoder, code->at(pc + 1), module());
len = 1 + imm.length; len = 1 + imm.length;
Push(WasmValue(isolate_->factory()->null_value(), Push(WasmValue(isolate_->factory()->null_value(),
ValueType::Ref(imm.type, kNullable))); ValueType::RefNull(imm.type)));
break; break;
} }
case kExprRefFunc: { case kExprRefFunc: {
......
...@@ -144,15 +144,17 @@ ValueType GetValueTypeHelper(DataRange* data, bool liftoff_as_reference, ...@@ -144,15 +144,17 @@ ValueType GetValueTypeHelper(DataRange* data, bool liftoff_as_reference,
// Conceptually, user-defined types are added to the end of the list. Pick a // Conceptually, user-defined types are added to the end of the list. Pick a
// random one among them. // random one among them.
uint32_t id = data->get<uint8_t>() % (types.size() + num_user_defined_types); uint32_t id = data->get<uint8_t>() % (types.size() + num_user_defined_types);
Nullability nullability = nullable ? kNullable : kNonNullable;
if (id >= types.size()) { if (id >= types.size()) {
// Return user-defined type. // Return user-defined type.
return ValueType::Ref(id - static_cast<uint32_t>(types.size()), return ValueType::RefMaybeNull(id - static_cast<uint32_t>(types.size()),
nullable ? kNullable : kNonNullable); nullability);
} }
// If returning a reference type, fix its nullability according to {nullable}. // If returning a reference type, fix its nullability according to {nullable}.
if (types[id].is_reference()) { if (types[id].is_reference()) {
return ValueType::Ref(types[id].heap_type(), return ValueType::RefMaybeNull(types[id].heap_type(), nullability);
nullable ? kNullable : kNonNullable);
} }
// Otherwise, just return the picked type. // Otherwise, just return the picked type.
return types[id]; return types[id];
...@@ -934,7 +936,7 @@ class WasmGenerator { ...@@ -934,7 +936,7 @@ class WasmGenerator {
} }
bool table_get(HeapType type, DataRange* data, Nullability nullable) { bool table_get(HeapType type, DataRange* data, Nullability nullable) {
ValueType needed_type = ValueType::Ref(type, nullable); ValueType needed_type = ValueType::RefMaybeNull(type, nullable);
int table_count = builder_->builder()->NumTables(); int table_count = builder_->builder()->NumTables();
ZoneVector<uint32_t> table(builder_->builder()->zone()); ZoneVector<uint32_t> table(builder_->builder()->zone());
for (int i = 0; i < table_count; i++) { for (int i = 0; i < table_count; i++) {
...@@ -1024,7 +1026,7 @@ class WasmGenerator { ...@@ -1024,7 +1026,7 @@ class WasmGenerator {
} }
} }
bool array_get_ref(HeapType type, DataRange* data, Nullability nullable) { bool array_get_ref(HeapType type, DataRange* data, Nullability nullable) {
ValueType needed_type = ValueType::Ref(type, nullable); ValueType needed_type = ValueType::RefMaybeNull(type, nullable);
return array_get_helper(needed_type, data); return array_get_helper(needed_type, data);
} }
...@@ -1120,7 +1122,7 @@ class WasmGenerator { ...@@ -1120,7 +1122,7 @@ class WasmGenerator {
} }
bool struct_get_ref(HeapType type, DataRange* data, Nullability nullable) { bool struct_get_ref(HeapType type, DataRange* data, Nullability nullable) {
ValueType needed_type = ValueType::Ref(type, nullable); ValueType needed_type = ValueType::RefMaybeNull(type, nullable);
return struct_get_helper(needed_type, data); return struct_get_helper(needed_type, data);
} }
......
...@@ -2210,7 +2210,7 @@ TEST_F(WasmModuleVerifyTest, TypedFunctionTable) { ...@@ -2210,7 +2210,7 @@ TEST_F(WasmModuleVerifyTest, TypedFunctionTable) {
ModuleResult result = DecodeModule(data, data + sizeof(data)); ModuleResult result = DecodeModule(data, data + sizeof(data));
EXPECT_OK(result); EXPECT_OK(result);
EXPECT_EQ(ValueType::Ref(0, kNullable), result.value()->tables[0].type); EXPECT_EQ(ValueType::RefNull(0), result.value()->tables[0].type);
} }
TEST_F(WasmModuleVerifyTest, NullableTableIllegalInitializer) { TEST_F(WasmModuleVerifyTest, NullableTableIllegalInitializer) {
...@@ -2277,7 +2277,7 @@ TEST_F(WasmModuleVerifyTest, NonNullableTable) { ...@@ -2277,7 +2277,7 @@ TEST_F(WasmModuleVerifyTest, NonNullableTable) {
SECTION(Code, ENTRY_COUNT(1), NOP_BODY)}; SECTION(Code, ENTRY_COUNT(1), NOP_BODY)};
ModuleResult result = DecodeModule(data, data + sizeof(data)); ModuleResult result = DecodeModule(data, data + sizeof(data));
EXPECT_OK(result); EXPECT_OK(result);
EXPECT_EQ(ValueType::Ref(0, kNonNullable), result.value()->tables[0].type); EXPECT_EQ(ValueType::Ref(0), result.value()->tables[0].type);
} }
TEST_F(WasmModuleVerifyTest, NonNullableTableNoInitializer) { TEST_F(WasmModuleVerifyTest, NonNullableTableNoInitializer) {
......
...@@ -16,11 +16,9 @@ namespace subtyping_unittest { ...@@ -16,11 +16,9 @@ namespace subtyping_unittest {
class WasmSubtypingTest : public TestWithPlatform {}; class WasmSubtypingTest : public TestWithPlatform {};
using FieldInit = std::pair<ValueType, bool>; using FieldInit = std::pair<ValueType, bool>;
constexpr ValueType ref(uint32_t index) { constexpr ValueType ref(uint32_t index) { return ValueType::Ref(index); }
return ValueType::Ref(index, kNonNullable);
}
constexpr ValueType refNull(uint32_t index) { constexpr ValueType refNull(uint32_t index) {
return ValueType::Ref(index, kNullable); return ValueType::RefNull(index);
} }
FieldInit mut(ValueType type) { return FieldInit(type, true); } FieldInit mut(ValueType type) { return FieldInit(type, true); }
...@@ -153,14 +151,12 @@ TEST_F(WasmSubtypingTest, Subtyping) { ...@@ -153,14 +151,12 @@ TEST_F(WasmSubtypingTest, Subtyping) {
#define NOT_VALID_SUBTYPE(type1, type2) \ #define NOT_VALID_SUBTYPE(type1, type2) \
EXPECT_FALSE(ValidSubtypeDefinition(type1.ref_index(), type2.ref_index(), \ EXPECT_FALSE(ValidSubtypeDefinition(type1.ref_index(), type2.ref_index(), \
module1, module)); module1, module));
#define IDENTICAL(index1, index2) \ #define IDENTICAL(index1, index2) \
EXPECT_TRUE(EquivalentTypes(ValueType::Ref(index1, kNullable), \ EXPECT_TRUE(EquivalentTypes(ValueType::RefNull(index1), \
ValueType::Ref(index2, kNullable), module1, \ ValueType::RefNull(index2), module1, module));
module)); #define DISTINCT(index1, index2) \
#define DISTINCT(index1, index2) \ EXPECT_FALSE(EquivalentTypes(ValueType::RefNull(index1), \
EXPECT_FALSE(EquivalentTypes(ValueType::Ref(index1, kNullable), \ ValueType::RefNull(index2), module1, module));
ValueType::Ref(index2, kNullable), module1, \
module));
// Union always expresses the result in terms of module1. // Union always expresses the result in terms of module1.
#define UNION(type1, type2, type_result) \ #define UNION(type1, type2, type_result) \
EXPECT_EQ(Union(type1, type2, module1, module), \ EXPECT_EQ(Union(type1, type2, module1, module), \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment