| ;; NOTE: Assertions have been generated by update_lit_checks.py --output=fuzz-exec and should not be edited. |
| |
| ;; RUN: foreach %s %t wasm-opt -all --fuzz-exec-before -q -o /dev/null 2>&1 | filecheck %s |
| |
| (module |
| (type $f (func)) |
| (type $k (cont $f)) |
| |
| (type $f-i32 (func (result i32))) |
| (type $k-i32 (cont $f-i32)) |
| |
| (type $f-get-i32 (func (param i32))) |
| (type $k-get-i32 (cont $f-get-i32)) |
| |
| (import "fuzzing-support" "log" (func $log (param i32))) |
| |
| (tag $more) |
| (tag $more-i32 (result i32)) |
| |
| (table $table 10 10 funcref) |
| |
| (func $run (param $k (ref $k)) |
| ;; Run a coroutine, continuing to resume it until it is complete. |
| (call $log (i32.const 100)) ;; start |
| (loop $loop |
| (block $on (result (ref $k)) |
| (resume $k (on $more $on) |
| (local.get $k) |
| ) |
| (call $log (i32.const 300)) ;; stop |
| (return) |
| ) |
| (call $log (i32.const 200)) ;; continue |
| (local.set $k) |
| (br $loop) |
| ) |
| (unreachable) |
| ) |
| |
| ;; A coroutine with only control flow in a single basic block (no locals, no |
| ;; params, no branching, no value stack). When $run-block, below, runs this, |
| ;; the result should be to log -1, -2, -3 (with interleaved logging from |
| ;; $run itself, above, 100, 200, 200, 300). |
| (func $block |
| (call $log (i32.const -1)) |
| (suspend $more) |
| (call $log (i32.const -2)) |
| (suspend $more) |
| (call $log (i32.const -3)) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-block |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -1] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -2] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -3] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-block (export "run-block") |
| (call $run |
| (cont.new $k (ref.func $block)) |
| ) |
| ) |
| |
| ;; Nested blocks, so when we suspend/resume we must traverse that stack |
| ;; properly. |
| (func $block-nested |
| (block $a |
| (call $log (i32.const -1)) |
| (suspend $more) |
| (block $b |
| (block $c |
| (call $log (i32.const -2)) |
| (suspend $more) |
| (call $log (i32.const -3)) |
| ) |
| (call $log (i32.const -4)) |
| ) |
| (suspend $more) |
| (call $log (i32.const -5)) |
| (suspend $more) |
| ) |
| (call $log (i32.const -6)) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-block-nested |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -1] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -2] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -3] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -4] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -5] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -6] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-block-nested (export "run-block-nested") |
| (call $run |
| (cont.new $k (ref.func $block-nested)) |
| ) |
| ) |
| |
| ;; The local's state must be saved and restored. |
| (func $local |
| (local $x i32) |
| (local.set $x (i32.const 42)) |
| (suspend $more) |
| (call $log (local.get $x)) |
| (local.set $x (i32.const 1337)) |
| (suspend $more) |
| (call $log (local.get $x)) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-local |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 42] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 1337] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-local (export "run-local") |
| (call $run |
| (cont.new $k (ref.func $local)) |
| ) |
| ) |
| |
| (func $multi-locals |
| (local $i32 i32) |
| (local $f64 f64) |
| (local.set $i32 (i32.const 42)) |
| (local.set $f64 (f64.const 3.14159)) |
| (suspend $more) |
| (call $log |
| (local.get $i32) |
| ) |
| (call $log |
| (i32.trunc_f64_s |
| (local.get $f64) |
| ) |
| ) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-multi-locals |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 42] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 3] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-multi-locals (export "run-multi-locals") |
| (call $run |
| (cont.new $k (ref.func $multi-locals)) |
| ) |
| ) |
| |
| ;; This loop should suspend 4 times and log 3, 2, 1, 0. |
| (func $loop |
| (local $x i32) |
| (local.set $x (i32.const 4)) |
| (loop $loop |
| (local.set $x |
| (i32.sub |
| (local.get $x) |
| (i32.const 1) |
| ) |
| ) |
| (call $log (local.get $x)) |
| (suspend $more) |
| (br_if $loop |
| (local.get $x) |
| ) |
| ) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-loop |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 3] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 2] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 1] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 0] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-loop (export "run-loop") |
| (call $run |
| (cont.new $k (ref.func $loop)) |
| ) |
| ) |
| |
| ;; We should log -1, -2, -3, -4 |
| (func $if |
| (local $x i32) |
| (if |
| (local.get $x) |
| (then |
| (unreachable) |
| ) |
| (else |
| ;; We should get here. |
| (call $log (i32.const -1)) |
| (local.set $x (i32.const 1)) |
| (suspend $more) |
| ;; A nested if. |
| (if |
| (local.get $x) |
| (then |
| ;; We should get here |
| (suspend $more) |
| (call $log (i32.const -2)) |
| ) |
| (else |
| (unreachable) |
| ) |
| ) |
| ) |
| ) |
| ;; If with one arm. |
| (if |
| (local.get $x) |
| (then |
| ;; We should get here. |
| (call $log (i32.const -3)) |
| (suspend $more) |
| (call $log (i32.const -4)) |
| ) |
| ) |
| (if |
| (i32.eqz |
| (local.get $x) |
| ) |
| (then |
| (unreachable) |
| ) |
| ) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-if |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -1] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -2] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -3] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -4] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-if (export "run-if") |
| (call $run |
| (cont.new $k (ref.func $if)) |
| ) |
| ) |
| |
| ;; Suspend in the if's condition. |
| (func $if-condition |
| (if |
| (block (result i32) |
| (call $log (i32.const -1)) |
| (suspend $more) |
| (call $log (i32.const -2)) |
| (i32.const 1) |
| ) |
| (then |
| (call $log (i32.const -3)) |
| ) |
| ) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-if-condition |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -1] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -2] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -3] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-if-condition (export "run-if-condition") |
| (call $run |
| (cont.new $k (ref.func $if-condition)) |
| ) |
| ) |
| |
| ;; Check that we properly stash things on the value stack. |
| (func $value-stack |
| ;; Suspend on the left. No value is actually saved on the stack, as we |
| ;; resume before we execute the right side. |
| (call $log |
| (i32.sub ;; 1 - 2 => -1 |
| (block (result i32) |
| (suspend $more) |
| (i32.const 1) |
| ) |
| (i32.const 2) |
| ) |
| ) |
| ;; On the right. Now we save the 2 when we suspend. |
| (call $log |
| (i32.sub ;; 2 - 4 => -2 |
| (i32.const 2) |
| (block (result i32) |
| (suspend $more) |
| (i32.const 4) |
| ) |
| ) |
| ) |
| ;; Both sides suspend. |
| (call $log |
| (i32.sub ;; 3 - 6 => -3 |
| (block (result i32) |
| (suspend $more) |
| (i32.const 3) |
| ) |
| (block (result i32) |
| (suspend $more) |
| (i32.const 6) |
| ) |
| ) |
| ) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-value-stack |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -1] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -2] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -3] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-value-stack (export "run-value-stack") |
| (call $run |
| (cont.new $k (ref.func $value-stack)) |
| ) |
| ) |
| |
| (func $nested-unary |
| ;; Suspend at the top. |
| (call $log |
| (i32.eqz |
| (i32.eqz |
| (i32.eqz |
| (block (result i32) |
| (suspend $more) |
| (i32.const 1) |
| ) |
| ) |
| ) |
| ) |
| ) |
| ;; Suspend everywhere. |
| (call $log |
| (block (result i32) |
| (suspend $more) |
| (i32.eqz |
| (block (result i32) |
| (suspend $more) |
| (i32.eqz |
| (block (result i32) |
| (suspend $more) |
| (i32.eqz |
| (block (result i32) |
| (suspend $more) |
| (i32.const 0) |
| ) |
| ) |
| ) |
| ) |
| ) |
| ) |
| ) |
| ) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-nested-unary |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 0] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 1] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-nested-unary (export "run-nested-unary") |
| (call $run |
| (cont.new $k (ref.func $nested-unary)) |
| ) |
| ) |
| |
| (func $nested-unary-more |
| (local $temp i32) |
| ;; Suspend before and after each operation. |
| (call $log |
| (block (result i32) |
| i32.const 0 |
| suspend $more |
| i32.eqz |
| suspend $more |
| i32.eqz |
| suspend $more |
| i32.eqz |
| suspend $more |
| ) |
| ) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-nested-unary-more |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 1] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-nested-unary-more (export "run-nested-unary-more") |
| (call $run |
| (cont.new $k (ref.func $nested-unary-more)) |
| ) |
| ) |
| |
| (func $nested-binary |
| (local $temp i32) |
| ;; Both sides suspend, in different places. |
| (call $log ;; (2 + 1) - (4 + 2) => -3 |
| (i32.sub |
| (block (result i32) |
| (i32.add |
| (block (result i32) |
| (suspend $more) |
| (i32.const 2) |
| ) |
| (i32.const 1) |
| ) |
| ) |
| (block (result i32) |
| (suspend $more) |
| (i32.add |
| (i32.const 4) |
| (i32.const 2) |
| ) |
| ) |
| ) |
| ) |
| ;; Ditto, but with suspensions moved in the arms, and others on the |
| ;; outside. Also add 1. |
| (call $log |
| (block (result i32) |
| (suspend $more) |
| (local.set $temp |
| (i32.sub |
| (block (result i32) |
| (suspend $more) |
| (i32.add |
| (i32.const 3) |
| (i32.const 1) |
| ) |
| ) |
| (block (result i32) |
| (i32.add |
| (i32.const 4) |
| (block (result i32) |
| (suspend $more) |
| (i32.const 2) |
| ) |
| ) |
| ) |
| ) |
| ) |
| (suspend $more) |
| (local.get $temp) |
| ) |
| ) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-nested-binary |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -3] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -2] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-nested-binary (export "run-nested-binary") |
| (call $run |
| (cont.new $k (ref.func $nested-binary)) |
| ) |
| ) |
| |
| (func $trinary |
| ;; Suspend in one of the arms. |
| (call $log |
| (select |
| (block (result i32) |
| (suspend $more) |
| (i32.const 1) |
| ) |
| (i32.const 2) |
| (i32.const 3) |
| ) |
| ) |
| (call $log |
| (select |
| (i32.const 4) |
| (block (result i32) |
| (suspend $more) |
| (i32.const 5) |
| ) |
| (i32.const 6) |
| ) |
| ) |
| (call $log |
| (select |
| (i32.const 7) |
| (i32.const 8) |
| (block (result i32) |
| (suspend $more) |
| (i32.const 9) |
| ) |
| ) |
| ) |
| ;; Suspend in them all. |
| (call $log |
| (select |
| (block (result i32) |
| (suspend $more) |
| (i32.const 10) |
| ) |
| (block (result i32) |
| (suspend $more) |
| (i32.const 11) |
| ) |
| (block (result i32) |
| (suspend $more) |
| (i32.const 12) |
| ) |
| ) |
| ) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-trinary |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 1] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 4] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 7] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 10] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-trinary (export "run-trinary") |
| (call $run |
| (cont.new $k (ref.func $trinary)) |
| ) |
| ) |
| |
| (func $run-i32 (param $k-i32 (ref $k-i32)) (result i32) |
| ;; As $run, but the coroutine returns an i32. |
| (call $log (i32.const 100)) ;; start |
| (loop $loop |
| (block $on (result (ref $k-i32)) |
| (resume $k-i32 (on $more $on) |
| (local.get $k-i32) |
| ) |
| (call $log (i32.const 300)) ;; stop |
| (return) |
| ) |
| (call $log (i32.const 200)) ;; continue |
| (local.set $k-i32) |
| (br $loop) |
| ) |
| (unreachable) |
| ) |
| |
| (func $ret-i32 (result i32) |
| ;; Just immediately return. |
| (i32.const 42) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-ret-i32 |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| ;; CHECK-NEXT: [fuzz-exec] note result: run-ret-i32 => 42 |
| (func $run-ret-i32 (export "run-ret-i32") (result i32) |
| (call $run-i32 |
| (cont.new $k-i32 (ref.func $ret-i32)) |
| ) |
| ) |
| |
| (func $pause-i32 (result i32) |
| (local $x i32) |
| ;; Pause before returning. |
| (local.set $x |
| (i32.const 1336) |
| ) |
| (suspend $more) |
| (i32.add |
| (local.get $x) |
| (i32.const 1) |
| ) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-pause-i32 |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| ;; CHECK-NEXT: [fuzz-exec] note result: run-pause-i32 => 1337 |
| (func $run-pause-i32 (export "run-pause-i32") (result i32) |
| (call $run-i32 |
| (cont.new $k-i32 (ref.func $pause-i32)) |
| ) |
| ) |
| |
| (func $run-get-i32 (param $x i32) (param $k-get-i32 (ref $k-get-i32)) |
| ;; As $run, but the coroutine receives an i32. |
| (call $log (i32.const 100)) ;; start |
| (loop $loop |
| (block $on (result (ref $k-get-i32)) |
| (resume $k-get-i32 (on $more-i32 $on) |
| (local.get $x) |
| (local.get $k-get-i32) |
| ) |
| (call $log (i32.const 300)) ;; stop |
| (return) |
| ) |
| (call $log (i32.const 200)) ;; continue |
| ;; Modify $x, so we can see differences in the loggings. |
| (local.set $x |
| (i32.sub |
| (local.get $x) |
| (i32.const 1) |
| ) |
| ) |
| (local.set $k-get-i32) |
| (br $loop) |
| ) |
| (unreachable) |
| ) |
| |
| (func $param (param $x i32) |
| (call $log (local.get $x)) |
| (local.set $x |
| (i32.add |
| (local.get $x) |
| (i32.const 1295) |
| ) |
| ) |
| (call $log (suspend $more-i32)) |
| (call $log (local.get $x)) |
| (call $log (suspend $more-i32)) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-param |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 42] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 41] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 1337] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 40] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-param (export "run-param") |
| (call $run-get-i32 |
| (i32.const 42) |
| (cont.new $k-get-i32 (ref.func $param)) |
| ) |
| ) |
| |
| (func $calls |
| ;; Suspend before and after calling a child, who also suspends. |
| (local $x i32) |
| ;; Set a value here to check that we do not get confused between locals in |
| ;; different scopes. |
| (local.set $x (i32.const -1)) |
| (suspend $more) |
| (call $calls-child (i32.const 41)) |
| (suspend $more) |
| (call $calls-child (i32.const 1336)) |
| (suspend $more) |
| (call $log (local.get $x)) |
| ) |
| |
| (func $calls-child (param $x i32) |
| (suspend $more) |
| (local.set $x |
| (i32.add |
| (local.get $x) |
| (i32.const 1) |
| ) |
| ) |
| (suspend $more) |
| (call $log (local.get $x)) |
| (suspend $more) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-calls |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 42] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 1337] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -1] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-calls (export "run-calls") |
| (call $run |
| (cont.new $k (ref.func $calls)) |
| ) |
| ) |
| |
| (func $call_indirect |
| ;; Test that indirect calls go to the right place, even if we modify the |
| ;; table in between. |
| (table.set $table |
| (i32.const 7) |
| (ref.func $call_indirect-child) |
| ) |
| (call $log (i32.const -1)) |
| (call_indirect (type $f) |
| (i32.const 7) |
| ) |
| (call $log (i32.const -2)) |
| ) |
| |
| (func $call_indirect-child |
| ;; When we resume the suspend below, the table entry will have null, but we |
| ;; should still rewind the stack properly. |
| (call $log (i32.const -10)) |
| (call $log |
| (ref.is_null |
| (table.get $table |
| (i32.const 7) |
| ) |
| ) |
| ) |
| (table.set $table |
| (i32.const 7) |
| (ref.null func) |
| ) |
| (suspend $more) |
| (call $log (i32.const -20)) |
| (call $log |
| (ref.is_null |
| (table.get $table |
| (i32.const 7) |
| ) |
| ) |
| ) |
| (suspend $more) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-call_indirect |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -1] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -10] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 0] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -20] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 1] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -2] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-call_indirect (export "run-call_indirect") |
| (call $run |
| (cont.new $k (ref.func $call_indirect)) |
| ) |
| ) |
| |
| (func $call_ref |
| (suspend $more) |
| (call_ref $f |
| (ref.func $call_ref-child) |
| ) |
| (suspend $more) |
| ) |
| |
| (func $call_ref-child |
| (suspend $more) |
| (call $log (i32.const -20)) |
| (suspend $more) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-call_ref |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging -20] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-call_ref (export "run-call_ref") |
| (call $run |
| (cont.new $k (ref.func $call_ref)) |
| ) |
| ) |
| |
| (func $bind (param $x i32) |
| ;; Test that cont.bind works when used on this. |
| (suspend $more) |
| (call $log (local.get $x)) |
| (suspend $more) |
| ;; Test that the bound arguments do not get applied to child calls. |
| (call $bind-child |
| (i32.const 1337) |
| ) |
| (suspend $more) |
| ) |
| |
| (func $bind-child (param $x i32) |
| (suspend $more) |
| (call $log (local.get $x)) |
| (suspend $more) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling run-bind |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 100] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 42] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 1337] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 200] |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 300] |
| (func $run-bind (export "run-bind") |
| (call $run |
| (cont.bind $k-get-i32 $k |
| (i32.const 42) |
| (cont.new $k-get-i32 (ref.func $bind)) |
| ) |
| ) |
| ) |
| |
| (func $never |
| ;; This will be resume_throw'd on the first execution, so this code is never |
| ;; reached. |
| (call $log (i32.const 1337)) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling resume_throw-never |
| ;; CHECK-NEXT: [LoggingExternalInterface logging 42] |
| (func $resume_throw-never (export "resume_throw-never") |
| (block $more |
| (try_table (catch $more $more) |
| (resume_throw $k $more |
| (cont.new $k (ref.func $never)) |
| ) |
| ) |
| ) |
| ;; This will be reached. |
| (call $log (i32.const 42)) |
| ) |
| |
| ;; CHECK: [fuzz-exec] calling suspend-unhandled-block |
| ;; CHECK-NEXT: [exception thrown: unhandled suspend] |
| (func $suspend-unhandled-block (export "suspend-unhandled-block") |
| ;; The nop here means that we are inside a block. The block will try to save |
| ;; resume data, but we should skip that without erroring, and just report an |
| ;; unhandled suspend. |
| (suspend $more) |
| (nop) |
| ) |
| ) |