diff options
-rw-r--r-- | src/wasm/literal.cpp | 30 | ||||
-rw-r--r-- | test/lit/ctor-eval/shared-i31.wast | 9 | ||||
-rw-r--r-- | test/lit/exec/strings.wast | 26 |
3 files changed, 47 insertions, 18 deletions
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp index 6e9c3eaf4..b3128025e 100644 --- a/src/wasm/literal.cpp +++ b/src/wasm/literal.cpp @@ -74,7 +74,8 @@ Literal::Literal(std::shared_ptr<GCData> gcData, HeapType type) : gcData(gcData), type(type, gcData ? NonNullable : Nullable) { // The type must be a proper type for GC data: either a struct, array, or // string; or an externalized version of the same; or a null. - assert((isData() && gcData) || (type == HeapType::ext && gcData) || + assert((isData() && gcData) || + (type.isMaybeShared(HeapType::ext) && gcData) || (type.isBottom() && !gcData)); } @@ -115,7 +116,7 @@ Literal::Literal(const Literal& other) : type(other.type) { new (&gcData) std::shared_ptr<GCData>(); return; } - if (other.isData() || other.type.getHeapType() == HeapType::ext) { + if (other.isData() || other.type.getHeapType().isMaybeShared(HeapType::ext)) { new (&gcData) std::shared_ptr<GCData>(other.gcData); return; } @@ -160,7 +161,7 @@ Literal::~Literal() { if (type.isBasic()) { return; } - if (isNull() || isData() || type.getHeapType() == HeapType::ext) { + if (isNull() || isData() || type.getHeapType().isMaybeShared(HeapType::ext)) { gcData.~shared_ptr(); } } @@ -2684,36 +2685,29 @@ Literal Literal::relaxedFmsF64x2(const Literal& left, } Literal Literal::externalize() const { - assert(Type::isSubType(type, Type(HeapType::any, Nullable)) && + assert(type.isRef() && type.getHeapType().getUnsharedTop() == HeapType::any && "can only externalize internal references"); if (isNull()) { return Literal(std::shared_ptr<GCData>{}, HeapType::noext); } auto heapType = type.getHeapType(); auto extType = HeapTypes::ext.getBasic(heapType.getShared()); - if (heapType.isBasic()) { - switch (heapType.getBasic(Unshared)) { - case HeapType::i31: { - return Literal(std::make_shared<GCData>(HeapType::i31, Literals{*this}), - extType); - } - case HeapType::string: - WASM_UNREACHABLE("TODO: string literals"); - default: - WASM_UNREACHABLE("unexpected type"); - } + if (heapType.isMaybeShared(HeapType::i31)) { + return Literal(std::make_shared<GCData>(heapType, Literals{*this}), + extType); } return Literal(gcData, extType); } Literal Literal::internalize() const { - assert(Type::isSubType(type, Type(HeapType::ext, Nullable)) && + auto extType = HeapTypes::ext.getBasic(type.getHeapType().getShared()); + assert(Type::isSubType(type, Type(extType, Nullable)) && "can only internalize external references"); if (isNull()) { return Literal(std::shared_ptr<GCData>{}, HeapType::none); } - if (gcData->type == HeapType::i31) { - assert(gcData->values[0].type.getHeapType() == HeapType::i31); + if (gcData->type.isMaybeShared(HeapType::i31)) { + assert(gcData->values[0].type.getHeapType().isMaybeShared(HeapType::i31)); return gcData->values[0]; } return Literal(gcData, gcData->type); diff --git a/test/lit/ctor-eval/shared-i31.wast b/test/lit/ctor-eval/shared-i31.wast index 2c1d8da59..fe79ce412 100644 --- a/test/lit/ctor-eval/shared-i31.wast +++ b/test/lit/ctor-eval/shared-i31.wast @@ -17,6 +17,15 @@ (i32.const 42) ) ) + ;; Also externalizing and internalizing works: this code can be precomputed + ;; and hence removed. + (drop + (any.convert_extern + (extern.convert_any + (global.get $global) + ) + ) + ) (global.get $global) ) diff --git a/test/lit/exec/strings.wast b/test/lit/exec/strings.wast index f0c659d19..f4ba59844 100644 --- a/test/lit/exec/strings.wast +++ b/test/lit/exec/strings.wast @@ -476,6 +476,24 @@ (string.const "five!") ) ) + + ;; CHECK: [fuzz-exec] calling extern + ;; CHECK-NEXT: [fuzz-exec] note result: extern => string("string") + (func $extern (export "extern") (result externref) + (extern.convert_any + (string.const "string") + ) + ) + + ;; CHECK: [fuzz-exec] calling extern-intern + ;; CHECK-NEXT: [fuzz-exec] note result: extern-intern => string("string") + (func $extern-intern (export "extern-intern") (result anyref) + (any.convert_extern + (extern.convert_any + (string.const "string") + ) + ) + ) ) ;; CHECK: [fuzz-exec] calling new_wtf16_array ;; CHECK-NEXT: [fuzz-exec] note result: new_wtf16_array => string("ello") @@ -604,6 +622,12 @@ ;; CHECK: [fuzz-exec] calling string.measure ;; CHECK-NEXT: [fuzz-exec] note result: string.measure => 5 + +;; CHECK: [fuzz-exec] calling extern +;; CHECK-NEXT: [fuzz-exec] note result: extern => string("string") + +;; CHECK: [fuzz-exec] calling extern-intern +;; CHECK-NEXT: [fuzz-exec] note result: extern-intern => string("string") ;; CHECK-NEXT: [fuzz-exec] comparing compare.1 ;; CHECK-NEXT: [fuzz-exec] comparing compare.10 ;; CHECK-NEXT: [fuzz-exec] comparing compare.2 @@ -624,6 +648,8 @@ ;; CHECK-NEXT: [fuzz-exec] comparing eq.3 ;; CHECK-NEXT: [fuzz-exec] comparing eq.4 ;; CHECK-NEXT: [fuzz-exec] comparing eq.5 +;; CHECK-NEXT: [fuzz-exec] comparing extern +;; CHECK-NEXT: [fuzz-exec] comparing extern-intern ;; CHECK-NEXT: [fuzz-exec] comparing get_codeunit ;; CHECK-NEXT: [fuzz-exec] comparing invalid_code_point ;; CHECK-NEXT: [fuzz-exec] comparing isolated_high_code_point |