summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm/literal.cpp30
-rw-r--r--test/lit/ctor-eval/shared-i31.wast9
-rw-r--r--test/lit/exec/strings.wast26
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