diff options
author | Thomas Lively <tlively@google.com> | 2024-01-03 12:55:00 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-03 12:55:00 -0800 |
commit | a6bc9542e98b4164d3a26c67c94b1136b4fc8b86 (patch) | |
tree | 50c3408c4a9a0d9a6cef73780364caff8826fe90 | |
parent | 260fdfcdaaeba3f4a47ef057db28c61203c8d3b1 (diff) | |
download | binaryen-a6bc9542e98b4164d3a26c67c94b1136b4fc8b86.tar.gz binaryen-a6bc9542e98b4164d3a26c67c94b1136b4fc8b86.tar.bz2 binaryen-a6bc9542e98b4164d3a26c67c94b1136b4fc8b86.zip |
[Parser] Parse folded instructions that contain parentheses (#6196)
To parse folded instructions in the right order, we need to defer parsing each
instruction until we have parsed each of its children and found its closing
parenthesis. Previously we naively looked for parentheses to determine where
instructions began and ended before we parsed them, but that scheme did not
correctly handle instructions that can contain parentheses in their immediates,
such as call_indirect.
Fix the problem by using the actual instruction parser functions with a
placeholder context to find the end of the instructions, including any kind of
immediates they might have.
-rw-r--r-- | src/parser/contexts.h | 8 | ||||
-rw-r--r-- | src/parser/parsers.h | 81 | ||||
-rw-r--r-- | test/lit/wat-kitchen-sink.wast | 376 |
3 files changed, 310 insertions, 155 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 503f4dc3a..2565a4817 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -517,6 +517,14 @@ struct NullInstrParserCtx { Result<> makeStringSliceIter(Index) { return Ok{}; } }; +struct NullCtx : NullTypeParserCtx, NullInstrParserCtx { + ParseInput in; + NullCtx(const ParseInput& in) : in(in) {} + Result<> makeTypeUse(Index, std::optional<HeapTypeT>, ParamsT*, ResultsT*) { + return Ok{}; + } +}; + // Phase 1: Parse definition spans for top-level module elements and determine // their indices and names. struct ParseDeclsCtx : NullTypeParserCtx, NullInstrParserCtx { diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 6dd617309..9302f4fc9 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -18,6 +18,7 @@ #define parser_parsers_h #include "common.h" +#include "contexts.h" #include "input.h" namespace wasm::WATParser { @@ -706,14 +707,13 @@ template<typename Ctx> MaybeResult<> instr(Ctx& ctx) { } template<typename Ctx> MaybeResult<> foldedinstr(Ctx& ctx) { - // Check for valid strings that are not instructions. - if (ctx.in.peekSExprStart("then"sv) || ctx.in.peekSExprStart("else")) { + // We must have an '(' to start a folded instruction. + if (auto tok = ctx.in.peek(); !tok || !tok->isLParen()) { return {}; } - if (auto inst = foldedBlockinstr(ctx)) { - return inst; - } - if (!ctx.in.takeLParen()) { + + // Check for valid strings that look like folded instructions but are not. + if (ctx.in.peekSExprStart("then"sv) || ctx.in.peekSExprStart("else")) { return {}; } @@ -721,47 +721,52 @@ template<typename Ctx> MaybeResult<> foldedinstr(Ctx& ctx) { // instructions that need to be parsed after their folded children. std::vector<std::pair<Index, std::optional<Index>>> foldedInstrs; - // Begin a folded instruction. Push its start position and a placeholder - // end position. - foldedInstrs.push_back({ctx.in.getPos(), {}}); - while (!foldedInstrs.empty()) { - // Consume everything up to the next paren. This span will be parsed as - // an instruction later after its folded children have been parsed. - if (!ctx.in.takeUntilParen()) { - return ctx.in.err(foldedInstrs.back().first, - "unterminated folded instruction"); - } + do { + if (ctx.in.takeRParen()) { + // We've reached the end of a folded instruction. Parse it for real. + auto [start, end] = foldedInstrs.back(); + if (!end) { + return ctx.in.err("unexpected end of folded instruction"); + } + foldedInstrs.pop_back(); - if (!foldedInstrs.back().second) { - // The folded instruction we just started should end here. - foldedInstrs.back().second = ctx.in.getPos(); + WithPosition with(ctx, start); + auto inst = plaininstr(ctx); + assert(inst && "unexpectedly failed to parse instruction"); + CHECK_ERR(inst); + assert(ctx.in.getPos() == *end && "expected end of instruction"); + continue; } - // We have either the start of a new folded child or the end of the last - // one. + // We're not ending an instruction, so we must be starting a new one. Maybe + // it is a block instruction. if (auto blockinst = foldedBlockinstr(ctx)) { CHECK_ERR(blockinst); - } else if (ctx.in.takeLParen()) { - foldedInstrs.push_back({ctx.in.getPos(), {}}); - } else if (ctx.in.takeRParen()) { - auto [start, end] = foldedInstrs.back(); - assert(end && "Should have found end of instruction"); - foldedInstrs.pop_back(); + continue; + } - WithPosition with(ctx, start); - if (auto inst = plaininstr(ctx)) { - CHECK_ERR(inst); - } else { - return ctx.in.err(start, "expected folded instruction"); - } + // We must be starting a new plain instruction. + if (!ctx.in.takeLParen()) { + return ctx.in.err("expected folded instruction"); + } + foldedInstrs.push_back({ctx.in.getPos(), {}}); - if (ctx.in.getPos() != *end) { - return ctx.in.err("expected end of instruction"); - } + // Consume the span for the instruction without meaningfully parsing it yet. + // It will be parsed for real using the real context after its s-expression + // children have been found and parsed. + NullCtx nullCtx(ctx.in); + if (auto inst = plaininstr(nullCtx)) { + CHECK_ERR(inst); + ctx.in = nullCtx.in; } else { - WASM_UNREACHABLE("expected paren"); + return ctx.in.err("expected instruction"); } - } + + // The folded instruction we just started ends here. + assert(!foldedInstrs.back().second); + foldedInstrs.back().second = ctx.in.getPos(); + } while (!foldedInstrs.empty()); + return Ok{}; } diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast index 9cf3c1494..303cfc53b 100644 --- a/test/lit/wat-kitchen-sink.wast +++ b/test/lit/wat-kitchen-sink.wast @@ -25,6 +25,8 @@ ;; CHECK: (type $8 (func (param anyref))) + ;; CHECK: (type $9 (func (param i32 i64 v128))) + ;; CHECK: (rec ;; CHECK-NEXT: (type $s0 (struct )) (type $s0 (sub (struct))) @@ -34,15 +36,13 @@ (rec) - ;; CHECK: (type $11 (func)) + ;; CHECK: (type $12 (func)) ;; CHECK: (type $packed-i8 (array (mut i8))) ;; CHECK: (type $many (sub (func (param i32 i64 f32 f64) (result anyref (ref func))))) - ;; CHECK: (type $14 (func (param i32))) - - ;; CHECK: (type $15 (func (param i32 i64 v128))) + ;; CHECK: (type $15 (func (param i32))) ;; CHECK: (type $a0 (array i32)) @@ -60,113 +60,113 @@ ;; CHECK: (type $23 (func (param i32 i64) (result f32))) - ;; CHECK: (type $24 (func (param i32 i32))) + ;; CHECK: (type $24 (func (param i64 v128) (result v128))) - ;; CHECK: (type $25 (func (param i32 i32 f64 f64))) + ;; CHECK: (type $25 (func (param i64 v128))) - ;; CHECK: (type $26 (func (param i64))) + ;; CHECK: (type $26 (func (param i32 i32))) - ;; CHECK: (type $27 (func (param v128) (result i32))) + ;; CHECK: (type $27 (func (param i32 i32 f64 f64))) - ;; CHECK: (type $28 (func (param v128 v128) (result v128))) + ;; CHECK: (type $28 (func (param i64))) - ;; CHECK: (type $29 (func (param v128 v128 v128) (result v128))) + ;; CHECK: (type $29 (func (param v128) (result i32))) - ;; CHECK: (type $30 (func (param i32 i32 i64 i64))) + ;; CHECK: (type $30 (func (param v128 v128) (result v128))) - ;; CHECK: (type $31 (func (param i32) (result i32))) + ;; CHECK: (type $31 (func (param v128 v128 v128) (result v128))) - ;; CHECK: (type $32 (func (param i32 i64) (result i32 i64))) + ;; CHECK: (type $32 (func (param i32 i32 i64 i64))) - ;; CHECK: (type $33 (func (param i64) (result i32 i64))) + ;; CHECK: (type $33 (func (param i32) (result i32))) - ;; CHECK: (type $34 (func (param i32) (result i32 i64))) + ;; CHECK: (type $34 (func (param i32 i64) (result i32 i64))) - ;; CHECK: (type $35 (func (param anyref) (result i32))) + ;; CHECK: (type $35 (func (param i64) (result i32 i64))) - ;; CHECK: (type $36 (func (param eqref eqref) (result i32))) + ;; CHECK: (type $36 (func (param i32) (result i32 i64))) - ;; CHECK: (type $37 (func (param i32) (result i31ref))) + ;; CHECK: (type $37 (func (param anyref) (result i32))) - ;; CHECK: (type $38 (func (param i31ref))) + ;; CHECK: (type $38 (func (param eqref eqref) (result i32))) - ;; CHECK: (type $39 (func (param i32 i64) (result (ref $pair)))) + ;; CHECK: (type $39 (func (param i32) (result i31ref))) - ;; CHECK: (type $40 (func (result (ref $pair)))) + ;; CHECK: (type $40 (func (param i31ref))) - ;; CHECK: (type $41 (func (param (ref $pair)) (result i32))) + ;; CHECK: (type $41 (func (param i32 i64) (result (ref $pair)))) - ;; CHECK: (type $42 (func (param (ref $pair)) (result i64))) + ;; CHECK: (type $42 (func (result (ref $pair)))) - ;; CHECK: (type $43 (func (param (ref $pair) i32))) + ;; CHECK: (type $43 (func (param (ref $pair)) (result i32))) - ;; CHECK: (type $44 (func (param (ref $pair) i64))) + ;; CHECK: (type $44 (func (param (ref $pair)) (result i64))) - ;; CHECK: (type $45 (func (param i64 i32) (result (ref $a1)))) + ;; CHECK: (type $45 (func (param (ref $pair) i32))) - ;; CHECK: (type $46 (func (param i32) (result (ref $a1)))) + ;; CHECK: (type $46 (func (param (ref $pair) i64))) - ;; CHECK: (type $47 (func (param i32 i32) (result (ref $a1)))) + ;; CHECK: (type $47 (func (param i64 i32) (result (ref $a1)))) - ;; CHECK: (type $48 (func (param (ref $a1) i32) (result i64))) + ;; CHECK: (type $48 (func (param i32) (result (ref $a1)))) - ;; CHECK: (type $49 (func (param (ref $packed-i8) i32) (result i32))) + ;; CHECK: (type $49 (func (param i32 i32) (result (ref $a1)))) - ;; CHECK: (type $50 (func (param (ref $packed-i16) i32) (result i32))) + ;; CHECK: (type $50 (func (param (ref $a1) i32) (result i64))) - ;; CHECK: (type $51 (func (param (ref $a2) i32 f32))) + ;; CHECK: (type $51 (func (param (ref $packed-i8) i32) (result i32))) - ;; CHECK: (type $52 (func (param arrayref) (result i32))) + ;; CHECK: (type $52 (func (param (ref $packed-i16) i32) (result i32))) - ;; CHECK: (type $53 (func (param (ref $a2) i32 (ref $a2) i32 i32))) + ;; CHECK: (type $53 (func (param (ref $a2) i32 f32))) - ;; CHECK: (type $54 (func (param (ref $a2) i32 f32 i32))) + ;; CHECK: (type $54 (func (param arrayref) (result i32))) - ;; CHECK: (type $55 (func (param (ref $a2) i32 i32 i32))) + ;; CHECK: (type $55 (func (param (ref $a2) i32 (ref $a2) i32 i32))) - ;; CHECK: (type $56 (func (param (ref $any-array) i32 i32 i32))) + ;; CHECK: (type $56 (func (param (ref $a2) i32 f32 i32))) - ;; CHECK: (type $57 (func (param externref))) + ;; CHECK: (type $57 (func (param (ref $a2) i32 i32 i32))) - ;; CHECK: (type $58 (func (param i32 i32) (result stringref))) + ;; CHECK: (type $58 (func (param (ref $any-array) i32 i32 i32))) - ;; CHECK: (type $59 (func (param (ref $packed-i8) i32 i32) (result stringref))) + ;; CHECK: (type $59 (func (param externref))) - ;; CHECK: (type $60 (func (param i32) (result stringref))) + ;; CHECK: (type $60 (func (param i32 i32) (result stringref))) - ;; CHECK: (type $61 (func (result (ref string)))) + ;; CHECK: (type $61 (func (param (ref $packed-i8) i32 i32) (result stringref))) - ;; CHECK: (type $62 (func (param stringref) (result i32))) + ;; CHECK: (type $62 (func (param i32) (result stringref))) - ;; CHECK: (type $63 (func (param stringview_wtf16) (result i32))) + ;; CHECK: (type $63 (func (result (ref string)))) - ;; CHECK: (type $64 (func (param stringref (ref $packed-i8) i32) (result i32))) + ;; CHECK: (type $64 (func (param stringref) (result i32))) - ;; CHECK: (type $65 (func (param stringref stringref) (result (ref string)))) + ;; CHECK: (type $65 (func (param stringview_wtf16) (result i32))) - ;; CHECK: (type $66 (func (param stringref) (result stringview_wtf8))) + ;; CHECK: (type $66 (func (param stringref (ref $packed-i8) i32) (result i32))) - ;; CHECK: (type $67 (func (param stringref) (result (ref stringview_wtf16)))) + ;; CHECK: (type $67 (func (param stringref stringref) (result (ref string)))) - ;; CHECK: (type $68 (func (param stringref) (result stringview_iter))) + ;; CHECK: (type $68 (func (param stringref) (result stringview_wtf8))) - ;; CHECK: (type $69 (func (param (ref stringview_wtf8) i32 i32) (result i32))) + ;; CHECK: (type $69 (func (param stringref) (result (ref stringview_wtf16)))) - ;; CHECK: (type $70 (func (param stringview_wtf16 i32) (result i32))) + ;; CHECK: (type $70 (func (param stringref) (result stringview_iter))) - ;; CHECK: (type $71 (func (param stringview_iter) (result i32))) + ;; CHECK: (type $71 (func (param (ref stringview_wtf8) i32 i32) (result i32))) - ;; CHECK: (type $72 (func (param stringview_iter i32) (result i32))) + ;; CHECK: (type $72 (func (param stringview_wtf16 i32) (result i32))) - ;; CHECK: (type $73 (func (param (ref stringview_iter) i32) (result i32))) + ;; CHECK: (type $73 (func (param stringview_iter) (result i32))) - ;; CHECK: (type $74 (func (param stringview_wtf8 stringview_wtf16 i32 i32))) + ;; CHECK: (type $74 (func (param stringview_iter i32) (result i32))) - ;; CHECK: (type $75 (func (param stringview_iter i32) (result (ref string)))) + ;; CHECK: (type $75 (func (param (ref stringview_iter) i32) (result i32))) - ;; CHECK: (type $76 (func (param i64 v128) (result v128))) + ;; CHECK: (type $76 (func (param stringview_wtf8 stringview_wtf16 i32 i32))) - ;; CHECK: (type $77 (func (param i64 v128))) + ;; CHECK: (type $77 (func (param stringview_iter i32) (result (ref string)))) ;; CHECK: (type $s2 (struct (field i32))) (type $s2 (struct i32)) @@ -409,11 +409,11 @@ ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) - ;; CHECK: (func $f1 (type $14) (param $0 i32) + ;; CHECK: (func $f1 (type $15) (param $0 i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $f1 (param i32)) - ;; CHECK: (func $f2 (type $14) (param $x i32) + ;; CHECK: (func $f2 (type $15) (param $x i32) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) (func $f2 (param $x i32)) @@ -856,7 +856,7 @@ drop ) - ;; CHECK: (func $locals (type $24) (param $0 i32) (param $x i32) + ;; CHECK: (func $locals (type $26) (param $0 i32) (param $x i32) ;; CHECK-NEXT: (local $2 i32) ;; CHECK-NEXT: (local $y i32) ;; CHECK-NEXT: (drop @@ -2541,7 +2541,7 @@ ) - ;; CHECK: (func $binary (type $25) (param $0 i32) (param $1 i32) (param $2 f64) (param $3 f64) + ;; CHECK: (func $binary (type $27) (param $0 i32) (param $1 i32) (param $2 f64) (param $3 f64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i32.add ;; CHECK-NEXT: (local.get $0) @@ -2566,7 +2566,7 @@ drop ) - ;; CHECK: (func $unary (type $26) (param $0 i64) + ;; CHECK: (func $unary (type $28) (param $0 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i64.eqz ;; CHECK-NEXT: (local.get $0) @@ -2861,7 +2861,7 @@ atomic.fence ) - ;; CHECK: (func $simd-extract (type $27) (param $0 v128) (result i32) + ;; CHECK: (func $simd-extract (type $29) (param $0 v128) (result i32) ;; CHECK-NEXT: (i32x4.extract_lane 3 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -2883,7 +2883,7 @@ i32x4.replace_lane 2 ) - ;; CHECK: (func $simd-shuffle (type $28) (param $0 v128) (param $1 v128) (result v128) + ;; CHECK: (func $simd-shuffle (type $30) (param $0 v128) (param $1 v128) (result v128) ;; CHECK-NEXT: (i8x16.shuffle 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2895,7 +2895,7 @@ i8x16.shuffle 0 1 2 3 4 5 6 7 16 17 18 19 20 21 22 23 ) - ;; CHECK: (func $simd-ternary (type $29) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) + ;; CHECK: (func $simd-ternary (type $31) (param $0 v128) (param $1 v128) (param $2 v128) (result v128) ;; CHECK-NEXT: (v128.bitselect ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -2942,7 +2942,7 @@ drop ) - ;; CHECK: (func $simd-load-store-lane (type $15) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK: (func $simd-load-store-lane (type $9) (param $0 i32) (param $1 i64) (param $2 v128) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (v128.load16_lane $mimport$0 7 ;; CHECK-NEXT: (local.get $0) @@ -3005,7 +3005,7 @@ data.drop $passive ) - ;; CHECK: (func $memory-copy (type $30) (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i64) + ;; CHECK: (func $memory-copy (type $32) (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i64) ;; CHECK-NEXT: (memory.copy $mimport$0 $mimport$0 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3076,7 +3076,7 @@ return ) - ;; CHECK: (func $return-one (type $31) (param $0 i32) (result i32) + ;; CHECK: (func $return-one (type $33) (param $0 i32) (result i32) ;; CHECK-NEXT: (return ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3086,7 +3086,7 @@ return ) - ;; CHECK: (func $return-two (type $32) (param $0 i32) (param $1 i64) (result i32 i64) + ;; CHECK: (func $return-two (type $34) (param $0 i32) (param $1 i64) (result i32 i64) ;; CHECK-NEXT: (return ;; CHECK-NEXT: (tuple.make 2 ;; CHECK-NEXT: (local.get $0) @@ -3100,7 +3100,7 @@ return ) - ;; CHECK: (func $return-two-first-unreachable (type $33) (param $0 i64) (result i32 i64) + ;; CHECK: (func $return-two-first-unreachable (type $35) (param $0 i64) (result i32 i64) ;; CHECK-NEXT: (return ;; CHECK-NEXT: (tuple.make 2 ;; CHECK-NEXT: (unreachable) @@ -3114,7 +3114,7 @@ return ) - ;; CHECK: (func $return-two-second-unreachable (type $34) (param $0 i32) (result i32 i64) + ;; CHECK: (func $return-two-second-unreachable (type $36) (param $0 i32) (result i32 i64) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3131,7 +3131,7 @@ return ) - ;; CHECK: (func $ref-is-null (type $35) (param $0 anyref) (result i32) + ;; CHECK: (func $ref-is-null (type $37) (param $0 anyref) (result i32) ;; CHECK-NEXT: (ref.is_null ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3175,7 +3175,7 @@ throw $tag-pair ) - ;; CHECK: (func $ref-eq (type $36) (param $0 eqref) (param $1 eqref) (result i32) + ;; CHECK: (func $ref-eq (type $38) (param $0 eqref) (param $1 eqref) (result i32) ;; CHECK-NEXT: (ref.eq ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3352,7 +3352,7 @@ table.copy 2 $funcs ) - ;; CHECK: (func $i31-new (type $37) (param $0 i32) (result i31ref) + ;; CHECK: (func $i31-new (type $39) (param $0 i32) (result i31ref) ;; CHECK-NEXT: (ref.i31 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3362,7 +3362,7 @@ ref.i31 ) - ;; CHECK: (func $i31-get (type $38) (param $0 i31ref) + ;; CHECK: (func $i31-get (type $40) (param $0 i31ref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (i31.get_s ;; CHECK-NEXT: (local.get $0) @@ -3581,7 +3581,7 @@ drop ) - ;; CHECK: (func $struct-new (type $39) (param $0 i32) (param $1 i64) (result (ref $pair)) + ;; CHECK: (func $struct-new (type $41) (param $0 i32) (param $1 i64) (result (ref $pair)) ;; CHECK-NEXT: (struct.new $pair ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3593,14 +3593,14 @@ struct.new $pair ) - ;; CHECK: (func $struct-new-default (type $40) (result (ref $pair)) + ;; CHECK: (func $struct-new-default (type $42) (result (ref $pair)) ;; CHECK-NEXT: (struct.new_default $pair) ;; CHECK-NEXT: ) (func $struct-new-default (result (ref $pair)) struct.new_default 14 ) - ;; CHECK: (func $struct-get-0 (type $41) (param $0 (ref $pair)) (result i32) + ;; CHECK: (func $struct-get-0 (type $43) (param $0 (ref $pair)) (result i32) ;; CHECK-NEXT: (struct.get $pair 0 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3610,7 +3610,7 @@ struct.get 14 0 ) - ;; CHECK: (func $struct-get-1 (type $42) (param $0 (ref $pair)) (result i64) + ;; CHECK: (func $struct-get-1 (type $44) (param $0 (ref $pair)) (result i64) ;; CHECK-NEXT: (struct.get $pair 1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3620,7 +3620,7 @@ struct.get $pair 1 ) - ;; CHECK: (func $struct-set-0 (type $43) (param $0 (ref $pair)) (param $1 i32) + ;; CHECK: (func $struct-set-0 (type $45) (param $0 (ref $pair)) (param $1 i32) ;; CHECK-NEXT: (struct.set $pair 0 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3632,7 +3632,7 @@ struct.set $pair 0 ) - ;; CHECK: (func $struct-set-1 (type $44) (param $0 (ref $pair)) (param $1 i64) + ;; CHECK: (func $struct-set-1 (type $46) (param $0 (ref $pair)) (param $1 i64) ;; CHECK-NEXT: (struct.set $pair 1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3644,7 +3644,7 @@ struct.set 14 1 ) - ;; CHECK: (func $array-new (type $45) (param $0 i64) (param $1 i32) (result (ref $a1)) + ;; CHECK: (func $array-new (type $47) (param $0 i64) (param $1 i32) (result (ref $a1)) ;; CHECK-NEXT: (array.new $a1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3656,7 +3656,7 @@ array.new $a1 ) - ;; CHECK: (func $array-new-default (type $46) (param $0 i32) (result (ref $a1)) + ;; CHECK: (func $array-new-default (type $48) (param $0 i32) (result (ref $a1)) ;; CHECK-NEXT: (array.new_default $a1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3666,7 +3666,7 @@ array.new_default 11 ) - ;; CHECK: (func $array-new-data (type $47) (param $0 i32) (param $1 i32) (result (ref $a1)) + ;; CHECK: (func $array-new-data (type $49) (param $0 i32) (param $1 i32) (result (ref $a1)) ;; CHECK-NEXT: (array.new_data $a1 $implicit-data ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3700,7 +3700,7 @@ drop ) - ;; CHECK: (func $array-get (type $48) (param $0 (ref $a1)) (param $1 i32) (result i64) + ;; CHECK: (func $array-get (type $50) (param $0 (ref $a1)) (param $1 i32) (result i64) ;; CHECK-NEXT: (array.get $a1 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3712,7 +3712,7 @@ array.get $a1 ) - ;; CHECK: (func $array-get-s (type $49) (param $0 (ref $packed-i8)) (param $1 i32) (result i32) + ;; CHECK: (func $array-get-s (type $51) (param $0 (ref $packed-i8)) (param $1 i32) (result i32) ;; CHECK-NEXT: (array.get_s $packed-i8 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3724,7 +3724,7 @@ array.get_s 15 ) - ;; CHECK: (func $array-get-u (type $50) (param $0 (ref $packed-i16)) (param $1 i32) (result i32) + ;; CHECK: (func $array-get-u (type $52) (param $0 (ref $packed-i16)) (param $1 i32) (result i32) ;; CHECK-NEXT: (array.get_u $packed-i16 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3736,7 +3736,7 @@ array.get_u $packed-i16 ) - ;; CHECK: (func $array-set (type $51) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) + ;; CHECK: (func $array-set (type $53) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) ;; CHECK-NEXT: (array.set $a2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3750,7 +3750,7 @@ array.set $a2 ) - ;; CHECK: (func $array-len (type $52) (param $0 arrayref) (result i32) + ;; CHECK: (func $array-len (type $54) (param $0 arrayref) (result i32) ;; CHECK-NEXT: (array.len ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3760,7 +3760,7 @@ array.len ) - ;; CHECK: (func $array-copy (type $53) (param $0 (ref $a2)) (param $1 i32) (param $2 (ref $a2)) (param $3 i32) (param $4 i32) + ;; CHECK: (func $array-copy (type $55) (param $0 (ref $a2)) (param $1 i32) (param $2 (ref $a2)) (param $3 i32) (param $4 i32) ;; CHECK-NEXT: (array.copy $a2 $a2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3778,7 +3778,7 @@ array.copy $a2 $a2 ) - ;; CHECK: (func $array-fill (type $54) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) (param $3 i32) + ;; CHECK: (func $array-fill (type $56) (param $0 (ref $a2)) (param $1 i32) (param $2 f32) (param $3 i32) ;; CHECK-NEXT: (array.fill $a2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3794,7 +3794,7 @@ array.fill $a2 ) - ;; CHECK: (func $array-init-data (type $55) (param $0 (ref $a2)) (param $1 i32) (param $2 i32) (param $3 i32) + ;; CHECK: (func $array-init-data (type $57) (param $0 (ref $a2)) (param $1 i32) (param $2 i32) (param $3 i32) ;; CHECK-NEXT: (array.init_data $a2 $implicit-data ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3810,7 +3810,7 @@ array.init_data $a2 0 ) - ;; CHECK: (func $array-init-elem (type $56) (param $0 (ref $any-array)) (param $1 i32) (param $2 i32) (param $3 i32) + ;; CHECK: (func $array-init-elem (type $58) (param $0 (ref $any-array)) (param $1 i32) (param $2 i32) (param $3 i32) ;; CHECK-NEXT: (array.init_elem $any-array $passive-2 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3839,7 +3839,7 @@ drop ) - ;; CHECK: (func $any-convert-extern (type $57) (param $0 externref) + ;; CHECK: (func $any-convert-extern (type $59) (param $0 externref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (extern.internalize ;; CHECK-NEXT: (local.get $0) @@ -3865,7 +3865,7 @@ drop ) - ;; CHECK: (func $string-new (type $58) (param $0 i32) (param $1 i32) (result stringref) + ;; CHECK: (func $string-new (type $60) (param $0 i32) (param $1 i32) (result stringref) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.new_utf8_try ;; CHECK-NEXT: (local.get $0) @@ -3907,7 +3907,7 @@ string.new_wtf16 ) - ;; CHECK: (func $string-new-gc (type $59) (param $0 (ref $packed-i8)) (param $1 i32) (param $2 i32) (result stringref) + ;; CHECK: (func $string-new-gc (type $61) (param $0 (ref $packed-i8)) (param $1 i32) (param $2 i32) (result stringref) ;; CHECK-NEXT: (string.new_utf8_array ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -3921,7 +3921,7 @@ string.new_utf8_array ) - ;; CHECK: (func $string-new-code-point (type $60) (param $0 i32) (result stringref) + ;; CHECK: (func $string-new-code-point (type $62) (param $0 i32) (result stringref) ;; CHECK-NEXT: (string.from_code_point ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3931,7 +3931,7 @@ string.from_code_point ) - ;; CHECK: (func $string-const (type $61) (result (ref string)) + ;; CHECK: (func $string-const (type $63) (result (ref string)) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (string.const "foobar") ;; CHECK-NEXT: ) @@ -3980,7 +3980,7 @@ drop ) - ;; CHECK: (func $string-hash (type $62) (param $0 stringref) (result i32) + ;; CHECK: (func $string-hash (type $64) (param $0 stringref) (result i32) ;; CHECK-NEXT: (string.hash ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -3990,7 +3990,7 @@ string.hash ) - ;; CHECK: (func $stringview-length (type $63) (param $0 stringview_wtf16) (result i32) + ;; CHECK: (func $stringview-length (type $65) (param $0 stringview_wtf16) (result i32) ;; CHECK-NEXT: (stringview_wtf16.length ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4045,7 +4045,7 @@ drop ) - ;; CHECK: (func $string-encode-gc (type $64) (param $0 stringref) (param $1 (ref $packed-i8)) (param $2 i32) (result i32) + ;; CHECK: (func $string-encode-gc (type $66) (param $0 stringref) (param $1 (ref $packed-i8)) (param $2 i32) (result i32) ;; CHECK-NEXT: (string.encode_wtf8_array ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4059,7 +4059,7 @@ string.encode_wtf8_array ) - ;; CHECK: (func $string-concat (type $65) (param $0 stringref) (param $1 stringref) (result (ref string)) + ;; CHECK: (func $string-concat (type $67) (param $0 stringref) (param $1 stringref) (result (ref string)) ;; CHECK-NEXT: (string.concat ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4095,7 +4095,7 @@ string.compare ) - ;; CHECK: (func $string-as-wtf8 (type $66) (param $0 stringref) (result stringview_wtf8) + ;; CHECK: (func $string-as-wtf8 (type $68) (param $0 stringref) (result stringview_wtf8) ;; CHECK-NEXT: (string.as_wtf8 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4105,7 +4105,7 @@ string.as_wtf8 ) - ;; CHECK: (func $string-as-wtf16 (type $67) (param $0 stringref) (result (ref stringview_wtf16)) + ;; CHECK: (func $string-as-wtf16 (type $69) (param $0 stringref) (result (ref stringview_wtf16)) ;; CHECK-NEXT: (string.as_wtf16 ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4115,7 +4115,7 @@ string.as_wtf16 ) - ;; CHECK: (func $string-as-iter (type $68) (param $0 stringref) (result stringview_iter) + ;; CHECK: (func $string-as-iter (type $70) (param $0 stringref) (result stringview_iter) ;; CHECK-NEXT: (string.as_iter ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4125,7 +4125,7 @@ string.as_iter ) - ;; CHECK: (func $string-advance (type $69) (param $0 (ref stringview_wtf8)) (param $1 i32) (param $2 i32) (result i32) + ;; CHECK: (func $string-advance (type $71) (param $0 (ref stringview_wtf8)) (param $1 i32) (param $2 i32) (result i32) ;; CHECK-NEXT: (stringview_wtf8.advance ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4139,7 +4139,7 @@ stringview_wtf8.advance ) - ;; CHECK: (func $string-get (type $70) (param $0 stringview_wtf16) (param $1 i32) (result i32) + ;; CHECK: (func $string-get (type $72) (param $0 stringview_wtf16) (param $1 i32) (result i32) ;; CHECK-NEXT: (stringview_wtf16.get_codeunit ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4151,7 +4151,7 @@ stringview_wtf16.get_codeunit ) - ;; CHECK: (func $string-iter-next (type $71) (param $0 stringview_iter) (result i32) + ;; CHECK: (func $string-iter-next (type $73) (param $0 stringview_iter) (result i32) ;; CHECK-NEXT: (stringview_iter.next ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4161,7 +4161,7 @@ stringview_iter.next ) - ;; CHECK: (func $string-iter-advance (type $72) (param $0 stringview_iter) (param $1 i32) (result i32) + ;; CHECK: (func $string-iter-advance (type $74) (param $0 stringview_iter) (param $1 i32) (result i32) ;; CHECK-NEXT: (stringview_iter.advance ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4173,7 +4173,7 @@ stringview_iter.advance ) - ;; CHECK: (func $string-iter-rewind (type $73) (param $0 (ref stringview_iter)) (param $1 i32) (result i32) + ;; CHECK: (func $string-iter-rewind (type $75) (param $0 (ref stringview_iter)) (param $1 i32) (result i32) ;; CHECK-NEXT: (stringview_iter.rewind ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4185,7 +4185,7 @@ stringview_iter.rewind ) - ;; CHECK: (func $string-slice (type $74) (param $0 stringview_wtf8) (param $1 stringview_wtf16) (param $2 i32) (param $3 i32) + ;; CHECK: (func $string-slice (type $76) (param $0 stringview_wtf8) (param $1 stringview_wtf16) (param $2 i32) (param $3 i32) ;; CHECK-NEXT: (drop ;; CHECK-NEXT: (stringview_wtf8.slice ;; CHECK-NEXT: (local.get $0) @@ -4214,7 +4214,7 @@ drop ) - ;; CHECK: (func $string-iter-slice (type $75) (param $0 stringview_iter) (param $1 i32) (result (ref string)) + ;; CHECK: (func $string-iter-slice (type $77) (param $0 stringview_iter) (param $1 i32) (result (ref string)) ;; CHECK-NEXT: (stringview_iter.slice ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: (local.get $1) @@ -4250,7 +4250,7 @@ return_call $return_call ) - ;; CHECK: (func $call-indirect (type $15) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK: (func $call-indirect (type $9) (param $0 i32) (param $1 i64) (param $2 v128) ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4279,7 +4279,7 @@ ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) ;; CHECK-NEXT: (drop - ;; CHECK-NEXT: (call_indirect $timport$0 (type $76) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $24) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -4312,7 +4312,80 @@ drop ) - ;; CHECK: (func $return-call-indirect (type $15) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK: (func $call-indirect-folded (type $9) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (call_indirect $timport$0 (type $24) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $call-indirect-folded (param i32 i64 v128) + (call_indirect + (local.get 0) + ) + (call_indirect 2 + (local.get 0) + ) + (call_indirect $funcs + (local.get 0) + ) + (call_indirect (type $void) + (local.get 0) + ) + (call_indirect 2 (type $void) (param) (result) + (local.get 0) + ) + (call_indirect $funcs (type $void) + (local.get 0) + ) + (call_indirect (param) (result) + (local.get 0) + ) + (call_indirect 2 (param) (result) + (local.get 0) + ) + (call_indirect $funcs (param) (result) + (local.get 0) + ) + (drop + (call_indirect (param i64 v128) (result v128) + (local.get 1) + (local.get 2) + (local.get 0) + ) + ) + ) + + ;; CHECK: (func $return-call-indirect (type $9) (param $0 i32) (param $1 i64) (param $2 v128) ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) @@ -4340,7 +4413,7 @@ ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) ;; CHECK-NEXT: (local.get $0) ;; CHECK-NEXT: ) - ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $77) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $25) ;; CHECK-NEXT: (local.get $1) ;; CHECK-NEXT: (local.get $2) ;; CHECK-NEXT: (local.get $0) @@ -4371,6 +4444,75 @@ return_call_indirect (param i64 v128) ) + ;; CHECK: (func $return-call-indirect-folded (type $9) (param $0 i32) (param $1 i64) (param $2 v128) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $funcs (type $void) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return_call_indirect $timport$0 (type $25) + ;; CHECK-NEXT: (local.get $1) + ;; CHECK-NEXT: (local.get $2) + ;; CHECK-NEXT: (local.get $0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (func $return-call-indirect-folded (param i32 i64 v128) + (return_call_indirect + (local.get 0) + ) + (return_call_indirect 2 + (local.get 0) + ) + (return_call_indirect $funcs + (local.get 0) + ) + (return_call_indirect (type $void) + (local.get 0) + ) + (return_call_indirect 2 (type $void) (param) (result) + (local.get 0) + ) + (return_call_indirect $funcs (type $void) + (local.get 0) + ) + (return_call_indirect (param) (result) + (local.get 0) + ) + (return_call_indirect 2 (param) (result) + (local.get 0) + ) + (return_call_indirect $funcs (param) (result) + (local.get 0) + ) + (return_call_indirect (param i64 v128) + (local.get 1) + (local.get 2) + (local.get 0) + ) + ) + ;; CHECK: (func $use-types (type $88) (param $0 (ref $s0)) (param $1 (ref $s1)) (param $2 (ref $s2)) (param $3 (ref $s3)) (param $4 (ref $s4)) (param $5 (ref $s5)) (param $6 (ref $s6)) (param $7 (ref $s7)) (param $8 (ref $s8)) (param $9 (ref $a0)) (param $10 (ref $a1)) (param $11 (ref $a2)) (param $12 (ref $a3)) (param $13 (ref $subvoid)) (param $14 (ref $submany)) ;; CHECK-NEXT: (nop) ;; CHECK-NEXT: ) |