Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/wasm/wasm-ir-builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1323,7 +1323,7 @@ Result<> IRBuilder::makePop(Type type) {
"pop instructions may only appear at the beginning of catch blocks"};
}
auto expectedType = scope.exprStack[0]->type;
if (type != expectedType) {
if (!Type::isSubType(expectedType, type)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be flipped? That is, the seen type should be a subtype of the expected type?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, in this case if I catch e.g. eqref, it would be valid and safe to overapproximate and have a pop anyref, but it would not be safe or valid to have pop i31ref, since the eqref I'm catching may not be an i31ref.

return Err{std::string("Expected pop of type ") + expectedType.toString()};
}
return Ok{};
Expand Down
101 changes: 16 additions & 85 deletions src/wasm/wasm-s-parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3253,55 +3253,28 @@ Expression* SExpressionWasmBuilder::makeRefAs(Element& s, RefAsOp op) {

Expression*
SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op, bool try_) {
size_t i = 1;
Expression* length = nullptr;
if (op == StringNewWTF8) {
if (s[i]->isStr()) {
// legacy syntax
std::string_view str = s[i++]->str().str;
if (str == "utf8") {
op = StringNewUTF8;
} else if (str == "wtf8") {
op = StringNewWTF8;
} else if (str == "replace") {
op = StringNewLossyUTF8;
} else {
throw SParseException("bad string.new op", s);
}
}
length = parseExpression(s[i + 1]);
return Builder(wasm).makeStringNew(op, parseExpression(s[i]), length, try_);
length = parseExpression(s[2]);
return Builder(wasm).makeStringNew(op, parseExpression(s[1]), length, try_);
} else if (op == StringNewUTF8 || op == StringNewLossyUTF8 ||
op == StringNewWTF16) {
length = parseExpression(s[i + 1]);
return Builder(wasm).makeStringNew(op, parseExpression(s[i]), length, try_);
length = parseExpression(s[2]);
return Builder(wasm).makeStringNew(op, parseExpression(s[1]), length, try_);
} else if (op == StringNewWTF8Array) {
if (s[i]->isStr()) {
// legacy syntax
std::string_view str = s[i++]->str().str;
if (str == "utf8") {
op = StringNewUTF8Array;
} else if (str == "wtf8") {
op = StringNewWTF8Array;
} else if (str == "replace") {
op = StringNewLossyUTF8Array;
} else {
throw SParseException("bad string.new op", s);
}
}
auto* start = parseExpression(s[i + 1]);
auto* end = parseExpression(s[i + 2]);
auto* start = parseExpression(s[2]);
auto* end = parseExpression(s[3]);
return Builder(wasm).makeStringNew(
op, parseExpression(s[i]), start, end, try_);
op, parseExpression(s[1]), start, end, try_);
} else if (op == StringNewUTF8Array || op == StringNewLossyUTF8Array ||
op == StringNewWTF16Array) {
auto* start = parseExpression(s[i + 1]);
auto* end = parseExpression(s[i + 2]);
auto* start = parseExpression(s[2]);
auto* end = parseExpression(s[3]);
return Builder(wasm).makeStringNew(
op, parseExpression(s[i]), start, end, try_);
op, parseExpression(s[1]), start, end, try_);
} else if (op == StringNewFromCodePoint) {
return Builder(wasm).makeStringNew(
op, parseExpression(s[i]), nullptr, try_);
op, parseExpression(s[1]), nullptr, try_);
} else {
throw SParseException("bad string.new op", s);
}
Expand All @@ -3316,60 +3289,18 @@ Expression* SExpressionWasmBuilder::makeStringConst(Element& s) {

Expression* SExpressionWasmBuilder::makeStringMeasure(Element& s,
StringMeasureOp op) {
size_t i = 1;
if (op == StringMeasureWTF8 && s[i]->isStr()) {
// legacy syntax
std::string_view str = s[i++]->str().str;
if (str == "utf8") {
op = StringMeasureUTF8;
} else if (str == "wtf8") {
op = StringMeasureWTF8;
} else {
throw SParseException("bad string.measure op", s);
}
}
return Builder(wasm).makeStringMeasure(op, parseExpression(s[i]));
return Builder(wasm).makeStringMeasure(op, parseExpression(s[1]));
}

Expression* SExpressionWasmBuilder::makeStringEncode(Element& s,
StringEncodeOp op) {
size_t i = 1;
Expression* start = nullptr;
if (op == StringEncodeWTF8) {
if (s[i]->isStr()) {
// legacy syntax
std::string_view str = s[i++]->str().str;
if (str == "utf8") {
op = StringEncodeUTF8;
} else if (str == "replace") {
op = StringEncodeLossyUTF8;
} else if (str == "wtf8") {
op = StringEncodeWTF8;
} else {
throw SParseException("bad string.new op", s);
}
}
} else if (op == StringEncodeWTF8Array) {
if (s[i]->isStr()) {
// legacy syntax
std::string_view str = s[i++]->str().str;
if (str == "utf8") {
op = StringEncodeUTF8Array;
} else if (str == "replace") {
op = StringEncodeLossyUTF8Array;
} else if (str == "wtf8") {
op = StringEncodeWTF8Array;
} else {
throw SParseException("bad string.new op", s);
}
}
start = parseExpression(s[i + 2]);
} else if (op == StringEncodeUTF8Array || op == StringEncodeLossyUTF8Array ||
op == StringEncodeWTF16Array) {
start = parseExpression(s[i + 2]);
if (op == StringEncodeWTF8Array || op == StringEncodeUTF8Array ||
op == StringEncodeLossyUTF8Array || op == StringEncodeWTF16Array) {
start = parseExpression(s[3]);
}
return Builder(wasm).makeStringEncode(
op, parseExpression(s[i]), parseExpression(s[i + 1]), start);
op, parseExpression(s[1]), parseExpression(s[2]), start);
}

Expression* SExpressionWasmBuilder::makeStringConcat(Element& s) {
Expand Down
5 changes: 2 additions & 3 deletions test/lit/basic/multi-table.wast
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,16 @@
(type $none_=>_none (func))
(type $A (struct))
;; CHECK-TEXT: (import "a" "b" (table $t1 1 10 funcref))

;; CHECK-TEXT: (global $g1 (ref null $none_=>_none) (ref.func $f))
;; CHECK-BIN: (import "a" "b" (table $t1 1 10 funcref))
(import "a" "b" (table $t1 1 10 funcref))

;; CHECK-TEXT: (global $g1 (ref null $none_=>_none) (ref.func $f))
;; CHECK-BIN: (global $g1 (ref null $none_=>_none) (ref.func $f))
(global $g1 (ref null $none_=>_none) (ref.func $f))
;; CHECK-TEXT: (global $g2 i32 (i32.const 0))
;; CHECK-BIN: (global $g2 i32 (i32.const 0))
(global $g2 i32 (i32.const 0))

(import "a" "b" (table $t1 1 10 funcref))
;; CHECK-TEXT: (table $t2 3 3 funcref)
;; CHECK-BIN: (table $t2 3 3 funcref)
(table $t2 3 3 funcref)
Expand Down
27 changes: 13 additions & 14 deletions test/lit/basic/reference-types.wast
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@
;; CHECK-TEXT: (import "env" "import_global" (global $import_global eqref))

;; CHECK-TEXT: (import "env" "import_func" (func $import_func (type $8) (param eqref) (result funcref)))
;; CHECK-BIN: (type $5 (func))

;; CHECK-BIN: (type $6 (func (result eqref)))

;; CHECK-BIN: (type $7 (func (param i32)))

;; CHECK-BIN: (type $8 (func (param eqref) (result funcref)))

;; CHECK-BIN: (import "env" "import_global" (global $import_global eqref))

;; CHECK-BIN: (import "env" "import_func" (func $import_func (type $8) (param eqref) (result funcref)))
(import "env" "import_func" (func $import_func (param eqref) (result funcref)))
(import "env" "import_global" (global $import_global eqref))

;; CHECK-TEXT: (global $global_eqref (mut eqref) (ref.null none))

Expand All @@ -69,18 +82,6 @@
;; CHECK-TEXT: (func $take_eqref (type $sig_eqref) (param $0 eqref)
;; CHECK-TEXT-NEXT: (nop)
;; CHECK-TEXT-NEXT: )
;; CHECK-BIN: (type $5 (func))

;; CHECK-BIN: (type $6 (func (result eqref)))

;; CHECK-BIN: (type $7 (func (param i32)))

;; CHECK-BIN: (type $8 (func (param eqref) (result funcref)))

;; CHECK-BIN: (import "env" "import_global" (global $import_global eqref))

;; CHECK-BIN: (import "env" "import_func" (func $import_func (type $8) (param eqref) (result funcref)))

;; CHECK-BIN: (global $global_eqref (mut eqref) (ref.null none))

;; CHECK-BIN: (global $global_funcref (mut funcref) (ref.null nofunc))
Expand Down Expand Up @@ -172,8 +173,6 @@
;; CHECK-BIN-NODEBUG: (elem declare func $23 $3)
(elem declare func $ref-taken-but-not-in-table)

(import "env" "import_func" (func $import_func (param eqref) (result funcref)))
(import "env" "import_global" (global $import_global eqref))
(export "export_func" (func $import_func))
(export "export_global" (global $import_global))

Expand Down
6 changes: 4 additions & 2 deletions test/lit/basic/tags.wast
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
;; Test tags

(module
(tag $e-import (import "env" "im0") (param i32))
(import "env" "im1" (tag (param i32 f32)))

(tag (param i32))

;; CHECK-TEXT: (type $0 (func (param i32 f32)))

;; CHECK-TEXT: (type $1 (func (param i32)))
Expand Down Expand Up @@ -54,9 +58,7 @@
;; CHECK-TEXT: (tag $e-export (param i32))
;; CHECK-BIN: (tag $e-export (param i32))
(tag $e-export (export "ex0") (param i32))
(tag $e-import (import "env" "im0") (param i32))

(import "env" "im1" (tag (param i32 f32)))
;; CHECK-TEXT: (export "ex0" (tag $e-export))

;; CHECK-TEXT: (export "ex1" (tag $e))
Expand Down
1 change: 1 addition & 0 deletions test/lit/exec/strings.wast
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

(module
(type $array16 (array (mut i16)))
(memory 1 1)

;; CHECK: [fuzz-exec] calling new_wtf16_array
;; CHECK-NEXT: [fuzz-exec] note result: new_wtf16_array => string("ello")
Expand Down
7 changes: 4 additions & 3 deletions test/lit/merge/fusing.wat.second
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
;; Use a different prefix than in first ($main instead of $other).
(import "first" "bar" (func $main.bar))

(import "first" "mem" (memory $other.mem 1))

(import "first" "exn" (tag $exn))

(memory $second.mem 2)

(export "mem" (memory $second.mem))
Expand All @@ -26,15 +30,12 @@
)
)

(import "first" "mem" (memory $other.mem 1))

(func $keepalive2 (export "keepalive2") (result i32)
;; Load from the memory imported from the second module.
(i32.load $other.mem
(i32.const 10)
)
)

(import "first" "exn" (tag $exn))
(func $keepalive3 (export "keepalive3") (throw $exn))
)
6 changes: 3 additions & 3 deletions test/lit/merge/memory_data.wat.second
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
(module
;; Test that the import remains
(import "import" "mem" (memory $imported 10000))

(memory $other 100)

(memory $bar 1000)

;; Test that the import remains
(import "import" "mem" (memory $imported 10000))

(data $a (memory $other) (i32.const 0) "a2")

(data $b (memory $bar) (i32.const 0) "b2")
Expand Down
6 changes: 3 additions & 3 deletions test/lit/merge/renamings.wat.second
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
(module
(type $array (array (mut (ref null func))))

;; Test that the import remains
(import "elsewhere" "some.tag" (tag $imported (param f64)))

(tag $foo (param f32))

(tag $other (param f64))

;; Test that the import remains
(import "elsewhere" "some.tag" (tag $imported (param f64)))

(memory $foo 50 60)

(memory $other 70 80)
Expand Down
4 changes: 3 additions & 1 deletion test/lit/passes/asyncify-wasm64.wast
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

;; CHECK: (type $f (func (param i32)))
(type $f (func (param i32)))
(memory i64 1 2)
;; CHECK: (type $2 (func))

;; CHECK: (type $3 (func (param i64)))
Expand All @@ -18,6 +17,9 @@
(import "env" "import" (func $import))
;; CHECK: (import "env" "import2" (func $import2 (param i32)))
(import "env" "import2" (func $import2 (param i32)))

(memory i64 1 2)

(table funcref (elem $liveness2 $liveness2))
;; CHECK: (global $__asyncify_state (mut i32) (i32.const 0))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
;; RUN: wasm-opt --enable-memory64 --enable-multimemory --asyncify --pass-arg=asyncify-in-secondary-memory %s -S -o - | filecheck %s

(module
(memory i64 1 2)
;; CHECK: (type $0 (func))

;; CHECK: (type $1 (func (param i32)))
Expand All @@ -14,6 +13,9 @@

;; CHECK: (import "env" "import" (func $import))
(import "env" "import" (func $import))

(memory i64 1 2)

;; CHECK: (global $__asyncify_state (mut i32) (i32.const 0))

;; CHECK: (global $__asyncify_data (mut i32) (i32.const 0))
Expand Down
10 changes: 5 additions & 5 deletions test/lit/passes/asyncify.wast
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
(module
;; CHECK: (type $f (func (param i32)))
(type $f (func (param i32)))
(memory 1 2)
;; CHECK: (type $1 (func (param i32 i32)))

;; CHECK: (type $2 (func))
Expand All @@ -17,15 +16,16 @@
(import "env" "import" (func $import))
;; CHECK: (import "env" "import2" (func $import2 (param i32)))
(import "env" "import2" (func $import2 (param i32)))
(table funcref (elem $liveness2 $liveness2))

;; CHECK: (global $__asyncify_state (mut i32) (i32.const 0))

;; CHECK: (global $__asyncify_data (mut i32) (i32.const 0))

;; CHECK: (memory $0 1 2)

;; CHECK: (table $0 2 2 funcref)
;; CHECK: (memory $m 1 2)
(memory $m 1 2)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why add a name here rather than just move it around?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to improve the output ordering. Adding the name doesn't affect whether the new parser can parse it.


;; CHECK: (table $t 2 2 funcref)
(table $t funcref (elem $liveness2 $liveness2))
;; CHECK: (elem $0 (i32.const 0) $liveness2 $liveness2)

;; CHECK: (export "asyncify_start_unwind" (func $asyncify_start_unwind))
Expand Down
6 changes: 4 additions & 2 deletions test/lit/passes/asyncify_enable-multivalue.wast
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@

;; Pre-existing imports that the pass turns into the implementations.
(module
(memory 1 2)
(import "asyncify" "start_unwind" (func $asyncify_start_unwind (param i32)))
(import "asyncify" "stop_unwind" (func $asyncify_stop_unwind))
(import "asyncify" "start_rewind" (func $asyncify_start_rewind (param i32)))
(import "asyncify" "stop_rewind" (func $asyncify_stop_rewind))

(memory 1 2)
;; CHECK: (type $0 (func))

;; CHECK: (type $1 (func (param i32)))
Expand Down Expand Up @@ -404,7 +405,6 @@
;; CHECK-NEXT: (global.get $__asyncify_state)
;; CHECK-NEXT: )
(module
(memory 1 2)
;; CHECK: (type $0 (func))

;; CHECK: (type $1 (func (param i32)))
Expand All @@ -423,6 +423,8 @@
(import "env" "import3" (func $import3 (param i32)))
;; CHECK: (import "env" "import-mv" (func $import-mv (result i32 i64)))
(import "env" "import-mv" (func $import-mv (result i32 i64)))

(memory 1 2)
;; CHECK: (global $__asyncify_state (mut i32) (i32.const 0))

;; CHECK: (global $__asyncify_data (mut i32) (i32.const 0))
Expand Down
Loading