@ 261106.8
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

;; Test suspend/resume through a return call. $cont return_calls $sub, which
;; then suspends. The return_call removes $cont from the stack before that
;; suspend, so we should jump into $sub during resuming, and not hit any errors.

(module
 (type $i32 (func (result i32)))
 (type $cont (cont $i32))
 (type $none (func))

 (import "fuzzing-support" "log-i32" (func $log (param i32)))

 (tag $tag (type $none))

 ;; CHECK:      [fuzz-exec] export main
 ;; CHECK-NEXT: [LoggingExternalInterface logging 50]
 ;; CHECK-NEXT: [LoggingExternalInterface logging -1]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 100]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 200]
 ;; CHECK-NEXT: [LoggingExternalInterface logging -1]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 300]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 400]
 ;; CHECK-NEXT: [LoggingExternalInterface logging -1]
 ;; CHECK-NEXT: [LoggingExternalInterface logging 500]
 ;; CHECK-NEXT: [trap unreachable]
 (func $main (export "main")
  (local $c (ref $cont))
  ;; Create a continuation and keep resuming it while it suspends.
  (local.set $c
   (cont.new $cont
    (ref.func $cont)
   )
  )
  (loop $label
   (local.set $c
    (block $block (result (ref $cont))
     (drop
      (resume $cont (on $tag $block)
       (local.get $c)
      )
     )
     (unreachable)
    )
   )
   (call $log (i32.const -1)) ;; logged each time we suspend
   (br $label)
  )
 )

 (func $cont (type $i32) (result i32)
  (call $log (i32.const 50)) ;; only reached once
  (suspend $tag)
  (call $log (i32.const 100)) ;; only reached once
  (return_call $sub)
  (call $log (i32.const -100)) ;; never reached
 )

 (func $sub (result i32)
  (call $log (i32.const 200))
  (suspend $tag)
  (call $log (i32.const 300))
  (return_call $subsub)
 )

 (func $subsub (result i32)
  (call $log (i32.const 400))
  (suspend $tag)
  (call $log (i32.const 500))
  (i32.const 0)
 )
)