@@ -76,10 +76,13 @@ Literal::Literal(std::shared_ptr<GCData> gcData, HeapType type)
76
76
type (type, gcData ? NonNullable : Nullable, gcData ? Inexact : Exact) {
77
77
// TODO: Use exact types for more than just nulls.
78
78
// The type must be a proper type for GC data: either a struct, array, or
79
- // string; or an externalized version of the same; or a null.
79
+ // string; or an externalized version of the same; or a null; or an
80
+ // internalized string (which appears as an anyref).
80
81
assert ((isData () && gcData) ||
81
82
(type.isMaybeShared (HeapType::ext) && gcData) ||
82
- (type.isBottom () && !gcData));
83
+ (type.isBottom () && !gcData) ||
84
+ (type.isMaybeShared (HeapType::any) && gcData &&
85
+ gcData->type .isMaybeShared (HeapType::string)));
83
86
}
84
87
85
88
Literal::Literal (std::shared_ptr<ExnData> exnData)
@@ -153,6 +156,11 @@ Literal::Literal(const Literal& other) : type(other.type) {
153
156
case HeapType::nocont:
154
157
WASM_UNREACHABLE (" null literals should already have been handled" );
155
158
case HeapType::any:
159
+ // This must be an anyref literal, which is an internalized string.
160
+ assert (other.gcData &&
161
+ other.gcData ->type .isMaybeShared (HeapType::string));
162
+ new (&gcData) std::shared_ptr<GCData>(other.gcData );
163
+ return ;
156
164
case HeapType::eq:
157
165
case HeapType::func:
158
166
case HeapType::cont:
@@ -169,7 +177,8 @@ Literal::~Literal() {
169
177
if (type.isBasic ()) {
170
178
return ;
171
179
}
172
- if (isNull () || isData () || type.getHeapType ().isMaybeShared (HeapType::ext)) {
180
+ if (isNull () || isData () || type.getHeapType ().isMaybeShared (HeapType::ext) ||
181
+ type.getHeapType ().isMaybeShared (HeapType::any)) {
173
182
gcData.~shared_ptr ();
174
183
} else if (isExn ()) {
175
184
exnData.~shared_ptr ();
@@ -652,13 +661,14 @@ std::ostream& operator<<(std::ostream& o, Literal literal) {
652
661
case HeapType::exn:
653
662
o << " exnref" ;
654
663
break ;
655
- case HeapType::any:
656
664
case HeapType::eq:
657
665
case HeapType::func:
658
666
case HeapType::cont:
659
667
case HeapType::struct_:
660
668
case HeapType::array:
661
669
WASM_UNREACHABLE (" invalid type" );
670
+ case HeapType::any:
671
+ // Anyref literals contain strings.
662
672
case HeapType::string: {
663
673
auto data = literal.getGCData ();
664
674
if (!data) {
@@ -2868,6 +2878,11 @@ Literal Literal::externalize() const {
2868
2878
return Literal (std::make_shared<GCData>(heapType, Literals{*this }),
2869
2879
extType);
2870
2880
}
2881
+ if (heapType.isMaybeShared (HeapType::any)) {
2882
+ // Anyref literals turn into strings (if we add any other anyref literals,
2883
+ // we will need to be more careful here).
2884
+ return Literal (gcData, HeapTypes::string.getBasic (share));
2885
+ }
2871
2886
return Literal (gcData, extType);
2872
2887
}
2873
2888
@@ -2883,6 +2898,10 @@ Literal Literal::internalize() const {
2883
2898
assert (gcData->values [0 ].type .getHeapType ().isMaybeShared (HeapType::i31));
2884
2899
return gcData->values [0 ];
2885
2900
}
2901
+ if (gcData->type .isMaybeShared (HeapType::string)) {
2902
+ // Strings turn into anyref literals.
2903
+ return Literal (gcData, HeapTypes::any.getBasic (share));
2904
+ }
2886
2905
return Literal (gcData, gcData->type );
2887
2906
}
2888
2907
0 commit comments