@@ -46,6 +46,8 @@ class Type {
46
46
FuncRef = -0x10 , // 0x70
47
47
ExternRef = -0x11 , // 0x6f
48
48
Reference = -0x15 , // 0x6b
49
+ Ref = -0x1c , // 0x64
50
+ RefNull = -0x1d , // 0x63
49
51
Func = -0x20 , // 0x60
50
52
Struct = -0x21 , // 0x5f
51
53
Array = -0x22 , // 0x5e
@@ -58,6 +60,12 @@ class Type {
58
60
I32U = 7 , // Not actually specified, but used internally with load/store
59
61
};
60
62
63
+ // Used by FuncRef / ExternRef
64
+ enum GenericReferenceType : uint32_t {
65
+ ReferenceOrNull = 0 ,
66
+ ReferenceNonNull = 1 ,
67
+ };
68
+
61
69
Type () = default ; // Provided so Type can be member of a union.
62
70
Type (int32_t code)
63
71
: enum_(static_cast <Enum>(code)), type_index_(0 ) {
@@ -67,7 +75,7 @@ class Type {
67
75
assert (!EnumIsReferenceWithIndex (enum_));
68
76
}
69
77
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)) );
71
79
}
72
80
constexpr operator Enum () const { return enum_; }
73
81
@@ -90,14 +98,25 @@ class Type {
90
98
91
99
bool IsRef () const {
92
100
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);
94
109
}
95
110
96
111
bool IsReferenceWithIndex () const { return EnumIsReferenceWithIndex (enum_); }
97
112
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;
101
120
}
102
121
103
122
std::string GetName () const {
@@ -110,13 +129,18 @@ class Type {
110
129
case Type::I8: return " i8" ;
111
130
case Type::I16: return " i16" ;
112
131
case Type::ExnRef: return " exnref" ;
113
- case Type::FuncRef: return " funcref" ;
114
132
case Type::Func: return " func" ;
115
133
case Type::Void: return " void" ;
116
134
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)" ;
118
139
case Type::Reference:
140
+ case Type::Ref:
119
141
return StringPrintf (" (ref %d)" , type_index_);
142
+ case Type::RefNull:
143
+ return StringPrintf (" (ref null %d)" , type_index_);
120
144
default :
121
145
return StringPrintf (" <type_index[%d]>" , enum_);
122
146
}
@@ -153,7 +177,7 @@ class Type {
153
177
}
154
178
155
179
Index GetReferenceIndex () const {
156
- assert (enum_ == Enum::Reference );
180
+ assert (IsReferenceWithIndex () );
157
181
return type_index_;
158
182
}
159
183
@@ -172,18 +196,25 @@ class Type {
172
196
case Type::ExnRef:
173
197
case Type::ExternRef:
174
198
case Type::Reference:
199
+ case Type::Ref:
200
+ case Type::RefNull:
175
201
return TypeVector (this , this + 1 );
176
202
177
203
default :
178
204
WABT_UNREACHABLE;
179
205
}
180
206
}
181
207
182
- private:
183
208
static bool EnumIsReferenceWithIndex (Enum value) {
184
- return value == Type::Reference;
209
+ return value == Type::Reference || value == Type::Ref ||
210
+ value == Type::RefNull;
185
211
}
186
212
213
+ static bool EnumIsNonTypedRef (Enum value) {
214
+ return value == Type::ExternRef || value == Type::FuncRef;
215
+ }
216
+
217
+ private:
187
218
Enum enum_;
188
219
// This index is 0 for non-references, so a zeroed
189
220
// memory area represents a valid Type::Any type.
0 commit comments