@@ -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,25 +60,52 @@ 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 = kInvalidIndex ,
66
+ ReferenceNonNull = kInvalidIndex - 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_(kInvalidIndex ) {}
64
72
Type (Enum e) : enum_(e), type_index_(kInvalidIndex ) {}
65
73
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 );
67
77
}
68
78
constexpr operator Enum () const { return enum_; }
69
79
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
+
70
86
bool IsRef () const {
71
87
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;
73
90
}
74
91
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
+ }
76
96
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_ ;
80
109
}
81
110
82
111
std::string GetName () const {
@@ -89,13 +118,18 @@ class Type {
89
118
case Type::I8: return " i8" ;
90
119
case Type::I16: return " i16" ;
91
120
case Type::ExnRef: return " exnref" ;
92
- case Type::FuncRef: return " funcref" ;
93
121
case Type::Func: return " func" ;
94
122
case Type::Void: return " void" ;
95
123
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)" ;
97
128
case Type::Reference:
129
+ case Type::Ref:
98
130
return StringPrintf (" (ref %d)" , type_index_);
131
+ case Type::RefNull:
132
+ return StringPrintf (" (ref null %d)" , type_index_);
99
133
default :
100
134
return StringPrintf (" <type_index[%d]>" , enum_);
101
135
}
@@ -132,7 +166,7 @@ class Type {
132
166
}
133
167
134
168
Index GetReferenceIndex () const {
135
- assert (enum_ == Enum::Reference );
169
+ assert (IsReferenceWithIndex () );
136
170
return type_index_;
137
171
}
138
172
@@ -151,6 +185,8 @@ class Type {
151
185
case Type::ExnRef:
152
186
case Type::ExternRef:
153
187
case Type::Reference:
188
+ case Type::Ref:
189
+ case Type::RefNull:
154
190
return TypeVector (this , this + 1 );
155
191
156
192
default :
0 commit comments