@ 261106.8 · fetching
current
;; 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
 (import "fuzzing-support" "log-i32" (func $log-i32 (param i32)))
 (import "fuzzing-support" "log-f64" (func $log-f64 (param f64)))

 (rec
  (type $F1 (func (param i32 f64)))
  (type $F2 (func (param f64)))
  (type $F3 (func))
  (type $F6 (func (param i32 i32 i32 i32 i32 i32)))
  (type $F4 (func (param i32 i32 i32 i32)))
  (type $F2-i32 (func (param i32 i32)))

  (type $C1 (cont $F1))
  (type $C2 (cont $F2))
  (type $C3 (cont $F3))
  (type $C6 (cont $F6))
  (type $C4 (cont $F4))
  (type $C2-i32 (cont $F2-i32))
 )

 (tag $tag (param i32))

 (func $f1 (type $F1) (param $x i32) (param $y f64)
  (call $log-i32
   (local.get $x)
  )
  (call $log-f64
   (local.get $y)
  )
 )

 (func $f6 (type $F6) (param $a i32) (param $b i32) (param $c i32) (param $d i32) (param $e i32) (param $f i32)
  (call $log-i32
   (local.get $a)
  )
  (call $log-i32
   (local.get $b)
  )
  (call $log-i32
   (local.get $c)
  )
  (call $log-i32
   (local.get $d)
  )
  (call $log-i32
   (local.get $e)
  )
  (call $log-i32
   (local.get $f)
  )
 )

 ;; CHECK:      [fuzz-exec] export bindings
 ;; CHECK-NEXT: [LoggingExternalInterface logging 42]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
 (func $bindings (export "bindings")
  ;; Start with an $F1 with two params, then bind each param in successive
  ;; operations.
  (resume $C3
   (cont.bind $C2 $C3
    (f64.const 3.14159)
    (cont.bind $C1 $C2
     (i32.const 42)
     (cont.new $C1
      (ref.func $f1)
     )
    )
   )
  )
 )

 ;; CHECK:      [fuzz-exec] export partial-bindings
 ;; CHECK-NEXT: [LoggingExternalInterface logging 42]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
 (func $partial-bindings (export "partial-bindings")
  ;; Bind the first param with cont.bind and pass the remaining param in resume.
  (resume $C2
   (f64.const 3.14159)
   (cont.bind $C1 $C2
    (i32.const 42)
    (cont.new $C1
     (ref.func $f1)
    )
   )
  )
 )

 ;; CHECK:      [fuzz-exec] export multi-partial-bindings
 ;; CHECK-NEXT: [LoggingExternalInterface logging 1]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 2]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 3]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 4]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 5]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 6]
 (func $multi-partial-bindings (export "multi-partial-bindings")
  ;; Use multiple cont.binds in a row and then pass the remaining operands in
  ;; resume, verifying all operands are passed in the expected order.
  (resume $C2-i32
   (i32.const 5)
   (i32.const 6)
   (cont.bind $C4 $C2-i32
    (i32.const 3)
    (i32.const 4)
    (cont.bind $C6 $C4
     (i32.const 1)
     (i32.const 2)
     (cont.new $C6
      (ref.func $f6)
     )
    )
   )
  )
 )

 ;; CHECK:      [fuzz-exec] export bind-then-resume-throw
 ;; CHECK-NEXT: [LoggingExternalInterface logging 99]
 (func $bind-then-resume-throw (export "bind-then-resume-throw")
  ;; Ensure resume_throw uses the exception tag arguments rather than any
  ;; previously bound continuation arguments.
  (call $log-i32
   (block $catch (result i32)
    (try_table (catch $tag $catch)
     (resume_throw $C2 $tag
      (i32.const 99)
      (cont.bind $C1 $C2
       (i32.const 42)
       (cont.new $C1
        (ref.func $f1)
       )
      )
     )
    )
    (i32.const -1)
   )
  )
 )

 ;; CHECK:      [fuzz-exec] export bind-then-resume-throw-ref
 ;; CHECK-NEXT: [LoggingExternalInterface logging 99]
 (func $bind-then-resume-throw-ref (export "bind-then-resume-throw-ref")
  ;; Ensure resume_throw_ref throws the given exnref on a continuation with
  ;; bound arguments.
  (local $exn exnref)
  (local.set $exn
   (tuple.extract 2 1
    (block $make-exn (result i32 exnref)
     (try_table (catch_ref $tag $make-exn)
      (throw $tag
       (i32.const 99)
      )
     )
     (unreachable)
    )
   )
  )
  (call $log-i32
   (block $catch (result i32)
    (try_table (catch $tag $catch)
     (resume_throw_ref $C2
      (local.get $exn)
      (cont.bind $C1 $C2
       (i32.const 42)
       (cont.new $C1
        (ref.func $f1)
       )
      )
     )
    )
    (i32.const -1)
   )
  )
 )

 ;; CHECK:      [fuzz-exec] export null-binding
 ;; CHECK-NEXT: [trap null ref]
 (func $null-binding (export "null-binding")
  (drop
   (cont.bind $C1 $C2
    (i32.const 42)
    (ref.null $C1)
   )
  )
 )

 ;; CHECK:      [fuzz-exec] export already-executed-binding
 ;; CHECK-NEXT: [trap continuation already executed]
 (func $already-executed-binding (export "already-executed-binding")
  ;; Binding a continuation that has already been consumed must trap.
  (local $c (ref null $C1))
  (local.set $c
   (cont.new $C1
    (ref.func $f1)
   )
  )
  (drop
   (cont.bind $C1 $C2
    (i32.const 42)
    (local.get $c)
   )
  )
  (drop
   (cont.bind $C1 $C2
    (i32.const 42)
    (local.get $c)
   )
  )
 )
)