@@ -76,10 +76,13 @@ Literal::Literal(std::shared_ptr<GCData> gcData, HeapType type)
7676 type (type, gcData ? NonNullable : Nullable, gcData ? Inexact : Exact) {
7777 // TODO: Use exact types for more than just nulls.
7878 // 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).
8081 assert ((isData () && gcData) ||
8182 (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)));
8386}
8487
8588Literal::Literal (std::shared_ptr<ExnData> exnData)
@@ -153,6 +156,11 @@ Literal::Literal(const Literal& other) : type(other.type) {
153156 case HeapType::nocont:
154157 WASM_UNREACHABLE (" null literals should already have been handled" );
155158 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 ;
156164 case HeapType::eq:
157165 case HeapType::func:
158166 case HeapType::cont:
@@ -169,7 +177,8 @@ Literal::~Literal() {
169177 if (type.isBasic ()) {
170178 return ;
171179 }
172- if (isNull () || isData () || type.getHeapType ().isMaybeShared (HeapType::ext)) {
180+ if (isNull () || isData () || type.getHeapType ().isMaybeShared (HeapType::ext) ||
181+ type.getHeapType ().isMaybeShared (HeapType::any)) {
173182 gcData.~shared_ptr ();
174183 } else if (isExn ()) {
175184 exnData.~shared_ptr ();
@@ -652,13 +661,14 @@ std::ostream& operator<<(std::ostream& o, Literal literal) {
652661 case HeapType::exn:
653662 o << " exnref" ;
654663 break ;
655- case HeapType::any:
656664 case HeapType::eq:
657665 case HeapType::func:
658666 case HeapType::cont:
659667 case HeapType::struct_:
660668 case HeapType::array:
661669 WASM_UNREACHABLE (" invalid type" );
670+ case HeapType::any:
671+ // Anyref literals contain strings.
662672 case HeapType::string: {
663673 auto data = literal.getGCData ();
664674 if (!data) {
@@ -2868,6 +2878,11 @@ Literal Literal::externalize() const {
28682878 return Literal (std::make_shared<GCData>(heapType, Literals{*this }),
28692879 extType);
28702880 }
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+ }
28712886 return Literal (gcData, extType);
28722887}
28732888
@@ -2883,6 +2898,10 @@ Literal Literal::internalize() const {
28832898 assert (gcData->values [0 ].type .getHeapType ().isMaybeShared (HeapType::i31));
28842899 return gcData->values [0 ];
28852900 }
2901+ if (gcData->type .isMaybeShared (HeapType::string)) {
2902+ // Strings turn into anyref literals.
2903+ return Literal (gcData, HeapTypes::any.getBasic (share));
2904+ }
28862905 return Literal (gcData, gcData->type );
28872906}
28882907
0 commit comments