@@ -46,6 +46,8 @@ class Type {
4646 FuncRef = -0x10 , // 0x70
4747 ExternRef = -0x11 , // 0x6f
4848 Reference = -0x15 , // 0x6b
49+ Ref = -0x1c , // 0x64
50+ RefNull = -0x1d , // 0x63
4951 Func = -0x20 , // 0x60
5052 Struct = -0x21 , // 0x5f
5153 Array = -0x22 , // 0x5e
@@ -58,25 +60,52 @@ class Type {
5860 I32U = 7 , // Not actually specified, but used internally with load/store
5961 };
6062
63+ // Used by FuncRef / ExternRef
64+ enum GenericReferenceType : uint32_t {
65+ ReferenceOrNull = kInvalidIndex ,
66+ ReferenceNonNull = kInvalidIndex - 1 ,
67+ };
68+
6169 Type () = default ; // Provided so Type can be member of a union.
6270 Type (int32_t code)
6371 : enum_(static_cast <Enum>(code)), type_index_(kInvalidIndex ) {}
6472 Type (Enum e) : enum_(e), type_index_(kInvalidIndex ) {}
6573 Type (Enum e, Index type_index) : enum_(e), type_index_(type_index) {
66- assert (e == Enum::Reference);
74+ assert (e == Enum::FuncRef || e == Enum::ExternRef ||
75+ e == Enum::Reference || e == Enum::Ref ||
76+ e == Enum::RefNull || type_index == kInvalidIndex );
6777 }
6878 constexpr operator Enum () const { return enum_; }
6979
80+ bool IsNullableRef () const {
81+ return enum_ == Type::Reference || enum_ == Type::ExnRef ||
82+ enum_ == Type::RefNull ||
83+ ((enum_ == Type::ExternRef || enum_ == Type::FuncRef) && type_index_ == ReferenceOrNull);
84+ }
85+
7086 bool IsRef () const {
7187 return enum_ == Type::ExternRef || enum_ == Type::FuncRef ||
72- enum_ == Type::Reference || enum_ == Type::ExnRef;
88+ enum_ == Type::Reference || enum_ == Type::ExnRef ||
89+ enum_ == Type::RefNull || enum_ == Type::Ref;
7390 }
7491
75- bool IsReferenceWithIndex () const { return enum_ == Type::Reference; }
92+ bool IsReferenceWithIndex () const {
93+ return enum_ == Type::Reference || enum_ == Type::Ref ||
94+ enum_ == Type::RefNull;
95+ }
7696
77- bool IsNullableRef () const {
78- // Currently all reftypes are nullable
79- return IsRef ();
97+ bool IsGenericRef () const {
98+ return enum_ == Type::ExternRef || enum_ == Type::FuncRef;
99+ }
100+
101+ bool IsNullableGenericRef () const {
102+ assert (enum_ == Type::ExternRef || enum_ == Type::FuncRef);
103+ return type_index_ == ReferenceOrNull;
104+ }
105+
106+ // The == comparison only compares the enum_ member.
107+ bool IsSame (const Type& rhs) const {
108+ return enum_ == rhs.enum_ && type_index_ == rhs.type_index_ ;
80109 }
81110
82111 std::string GetName () const {
@@ -89,13 +118,18 @@ class Type {
89118 case Type::I8: return " i8" ;
90119 case Type::I16: return " i16" ;
91120 case Type::ExnRef: return " exnref" ;
92- case Type::FuncRef: return " funcref" ;
93121 case Type::Func: return " func" ;
94122 case Type::Void: return " void" ;
95123 case Type::Any: return " any" ;
96- case Type::ExternRef: return " externref" ;
124+ case Type::FuncRef:
125+ return type_index_ == ReferenceOrNull ? " funcref" : " (ref func)" ;
126+ case Type::ExternRef:
127+ return type_index_ == ReferenceOrNull ? " externref" : " (ref extern)" ;
97128 case Type::Reference:
129+ case Type::Ref:
98130 return StringPrintf (" (ref %d)" , type_index_);
131+ case Type::RefNull:
132+ return StringPrintf (" (ref null %d)" , type_index_);
99133 default :
100134 return StringPrintf (" <type_index[%d]>" , enum_);
101135 }
@@ -132,7 +166,7 @@ class Type {
132166 }
133167
134168 Index GetReferenceIndex () const {
135- assert (enum_ == Enum::Reference );
169+ assert (IsReferenceWithIndex () );
136170 return type_index_;
137171 }
138172
@@ -151,6 +185,8 @@ class Type {
151185 case Type::ExnRef:
152186 case Type::ExternRef:
153187 case Type::Reference:
188+ case Type::Ref:
189+ case Type::RefNull:
154190 return TypeVector (this , this + 1 );
155191
156192 default :
0 commit comments