Fix
diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index a948f25..339753a 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp
@@ -890,11 +890,11 @@ value.type.getHeapType().isMaybeShared(HeapType::i31)); } - // GC data (structs and arrays) must be handled with the special global- - // creating logic later down. But MVP types as well as i31s (even - // externalized i31s) can be handled by the general makeConstantExpression - // logic (which knows how to handle externalization, for i31s; and it also - // can handle string constants). + // GC data (structs, arrays, and waitqueues) must be handled with the + // special global- creating logic later down. But MVP types as well as i31s + // (even externalized i31s) can be handled by the general + // makeConstantExpression logic (which knows how to handle externalization, + // for i31s; and it also can handle string constants). if (!value.isData() || value.isString()) { return builder.makeConstantExpression(original); } @@ -956,6 +956,8 @@ } else if (heapType.isArray()) { // TODO: for repeated identical values, can use ArrayNew init = builder.makeArrayNewFixed(heapType, args); + } else if (heapType == HeapTypes::sharedWaitqueue) { + init = builder.makeWaitqueueNew(); } else { WASM_UNREACHABLE("bad gc type"); }
diff --git a/src/wasm-type.h b/src/wasm-type.h index 96fb08d..7a8d5da 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h
@@ -1194,8 +1194,8 @@ inline bool HeapType::isData() const { auto kind = getKind(); - return isMaybeShared(string) || kind == HeapTypeKind::Struct || - kind == HeapTypeKind::Array; + return isMaybeShared(string) || isMaybeShared(waitqueue) || + kind == HeapTypeKind::Struct || kind == HeapTypeKind::Array; } inline bool HeapType::isSignature() const {
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 272cc5a..d8b14c2 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp
@@ -73,6 +73,9 @@ if (type.isRef() && type.getHeapType().isMaybeShared(HeapType::waitqueue)) { assert(type.isNonNullable()); + // See ~Literal and isData(). isData() is true for waitqueues so we expect + // gcData to be present even if null. + new (&gcData) std::shared_ptr<GCData>(); return; } @@ -113,7 +116,6 @@ assert((isData() && gcData) || (type.isMaybeShared(HeapType::ext) && gcData) || (type.isMaybeShared(HeapType::string) && gcData) || - (type.isMaybeShared(HeapType::waitqueue) && gcData) || (type.isMaybeShared(HeapType::any) && gcData) || (type.isBottom() && !gcData)); } @@ -189,7 +191,6 @@ return; case HeapType::ext: case HeapType::any: - case HeapType::waitqueue: // Externalized or internalized reference/payload. new (&gcData) std::shared_ptr<GCData>(other.gcData); return; @@ -205,6 +206,7 @@ case HeapType::cont: case HeapType::struct_: case HeapType::array: + case HeapType::waitqueue: WASM_UNREACHABLE("invalid type"); case HeapType::string: WASM_UNREACHABLE("TODO: string literals"); @@ -371,10 +373,8 @@ } std::shared_ptr<GCData> Literal::getGCData() const { - assert( - isNull() || isData() || - (type.isRef() && (type.getHeapType().isMaybeShared(HeapType::ext) || - type.getHeapType().isMaybeShared(HeapType::waitqueue)))); + assert(isNull() || isData() || + (type.isRef() && (type.getHeapType().isMaybeShared(HeapType::ext)))); return gcData; }