@@ -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,6 +60,12 @@ 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 = 0 ,
66+ ReferenceNonNull = 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_(0 ) {
@@ -67,7 +75,7 @@ class Type {
6775 assert (!EnumIsReferenceWithIndex (enum_));
6876 }
6977 Type (Enum e, Index type_index) : enum_(e), type_index_(type_index) {
70- assert (EnumIsReferenceWithIndex (e));
78+ assert (EnumIsReferenceWithIndex (e) || ( IsNonTypedRef () && (type_index_ == ReferenceOrNull || type_index_ == ReferenceNonNull)) );
7179 }
7280 constexpr operator Enum () const { return enum_; }
7381
@@ -90,14 +98,25 @@ class Type {
9098
9199 bool IsRef () const {
92100 return enum_ == Type::ExternRef || enum_ == Type::FuncRef ||
93- enum_ == Type::Reference || enum_ == Type::ExnRef;
101+ enum_ == Type::Reference || enum_ == Type::ExnRef ||
102+ enum_ == Type::RefNull || enum_ == Type::Ref;
103+ }
104+
105+ bool IsNullableRef () const {
106+ return enum_ == Type::Reference || enum_ == Type::ExnRef ||
107+ enum_ == Type::RefNull ||
108+ ((enum_ == Type::ExternRef || enum_ == Type::FuncRef) && type_index_ == ReferenceOrNull);
94109 }
95110
96111 bool IsReferenceWithIndex () const { return EnumIsReferenceWithIndex (enum_); }
97112
98- bool IsNullableRef () const {
99- // Currently all reftypes are nullable
100- return IsRef ();
113+ bool IsNonTypedRef () const {
114+ return EnumIsNonTypedRef (enum_);
115+ }
116+
117+ bool IsNullableNonTypedRef () const {
118+ assert (EnumIsNonTypedRef (enum_));
119+ return type_index_ == ReferenceOrNull;
101120 }
102121
103122 std::string GetName () const {
@@ -110,13 +129,18 @@ class Type {
110129 case Type::I8: return " i8" ;
111130 case Type::I16: return " i16" ;
112131 case Type::ExnRef: return " exnref" ;
113- case Type::FuncRef: return " funcref" ;
114132 case Type::Func: return " func" ;
115133 case Type::Void: return " void" ;
116134 case Type::Any: return " any" ;
117- case Type::ExternRef: return " externref" ;
135+ case Type::FuncRef:
136+ return type_index_ == ReferenceOrNull ? " funcref" : " (ref func)" ;
137+ case Type::ExternRef:
138+ return type_index_ == ReferenceOrNull ? " externref" : " (ref extern)" ;
118139 case Type::Reference:
140+ case Type::Ref:
119141 return StringPrintf (" (ref %d)" , type_index_);
142+ case Type::RefNull:
143+ return StringPrintf (" (ref null %d)" , type_index_);
120144 default :
121145 return StringPrintf (" <type_index[%d]>" , enum_);
122146 }
@@ -153,7 +177,7 @@ class Type {
153177 }
154178
155179 Index GetReferenceIndex () const {
156- assert (enum_ == Enum::Reference );
180+ assert (IsReferenceWithIndex () );
157181 return type_index_;
158182 }
159183
@@ -172,18 +196,25 @@ class Type {
172196 case Type::ExnRef:
173197 case Type::ExternRef:
174198 case Type::Reference:
199+ case Type::Ref:
200+ case Type::RefNull:
175201 return TypeVector (this , this + 1 );
176202
177203 default :
178204 WABT_UNREACHABLE;
179205 }
180206 }
181207
182- private:
183208 static bool EnumIsReferenceWithIndex (Enum value) {
184- return value == Type::Reference;
209+ return value == Type::Reference || value == Type::Ref ||
210+ value == Type::RefNull;
185211 }
186212
213+ static bool EnumIsNonTypedRef (Enum value) {
214+ return value == Type::ExternRef || value == Type::FuncRef;
215+ }
216+
217+ private:
187218 Enum enum_;
188219 // This index is 0 for non-references, so a zeroed
189220 // memory area represents a valid Type::Any type.
0 commit comments