blob: e8070dbb56f0a8a06f42c9b7c216b65487d46e91 [file] [edit]
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
;; Test that we do not error on trying to serialize continuations (which cannot
;; be serialized). When we do not pass --kept-exports, we can at least remove
;; that "test" export, since we don't need to serialize anything when it doesn't
;; stick around.
;; RUN: foreach %s %t wasm-ctor-eval --ctors=test --kept-exports=test -all --ignore-external-input -S -o - | filecheck %s
;; RUN: foreach %s %t wasm-ctor-eval --ctors=test -all --ignore-external-input -S -o - | filecheck %s --check-prefix=NOKEEP
(module
;; CHECK: (type $func (func))
(type $func (func))
;; CHECK: (type $cont (cont $func))
(type $cont (cont $func))
;; CHECK: (type $2 (func (result i32)))
;; CHECK: (type $3 (func (result (ref $cont))))
;; CHECK: (global $global (mut i32) (i32.const 1))
;; NOKEEP: (type $0 (func (result i32)))
;; NOKEEP: (global $global (mut i32) (i32.const 1))
(global $global (mut i32) (i32.const 0))
(export "test" (func $test))
;; CHECK: (elem declare func $func)
;; CHECK: (export "read" (func $read))
;; CHECK: (export "test" (func $test_3))
;; CHECK: (func $func (type $func)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $func
)
(func $test (result (ref $cont))
;; An effect before the cont.new. We can precompute it and remove it from
;; here, applying the 1 to the global.
(global.set $global
(i32.const 1)
)
(cont.new $cont
(ref.func $func)
)
)
;; CHECK: (func $read (type $2) (result i32)
;; CHECK-NEXT: (global.get $global)
;; CHECK-NEXT: )
;; NOKEEP: (export "read" (func $read))
;; NOKEEP: (func $read (type $0) (result i32)
;; NOKEEP-NEXT: (global.get $global)
;; NOKEEP-NEXT: )
(func $read (export "read") (result i32)
(global.get $global)
)
)
;; CHECK: (func $test_3 (type $3) (result (ref $cont))
;; CHECK-NEXT: (cont.new $cont
;; CHECK-NEXT: (ref.func $func)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(module
;; As above, but there is another use of $test.
;; CHECK: (type $func (func))
;; NOKEEP: (type $func (func))
(type $func (func))
;; CHECK: (type $cont (cont $func))
;; NOKEEP: (type $cont (cont $func))
(type $cont (cont $func))
;; CHECK: (type $2 (func (result (ref $cont))))
;; CHECK: (elem declare func $func)
;; CHECK: (export "export" (func $export))
;; CHECK: (export "test" (func $test))
(export "test" (func $test))
;; CHECK: (func $func (type $func)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
;; NOKEEP: (type $2 (func (result (ref $cont))))
;; NOKEEP: (elem declare func $func)
;; NOKEEP: (export "export" (func $export))
;; NOKEEP: (func $func (type $func)
;; NOKEEP-NEXT: (nop)
;; NOKEEP-NEXT: )
(func $func
)
;; CHECK: (func $test (type $2) (result (ref $cont))
;; CHECK-NEXT: (cont.new $cont
;; CHECK-NEXT: (ref.func $func)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOKEEP: (func $test (type $2) (result (ref $cont))
;; NOKEEP-NEXT: (cont.new $cont
;; NOKEEP-NEXT: (ref.func $func)
;; NOKEEP-NEXT: )
;; NOKEEP-NEXT: )
(func $test (result (ref $cont))
(cont.new $cont
(ref.func $func)
)
)
;; CHECK: (func $export (type $func)
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (call $test)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; NOKEEP: (func $export (type $func)
;; NOKEEP-NEXT: (drop
;; NOKEEP-NEXT: (call $test)
;; NOKEEP-NEXT: )
;; NOKEEP-NEXT: )
(func $export (export "export")
;; Call $test internally. This keeps $test alive in NOKEEP as well (but not
;; the export "test").
(drop
(call $test)
)
)
)
;; As the original testcase, but the serialization problem happens in a local.
(module
;; CHECK: (type $func (func))
;; NOKEEP: (type $func (func))
(type $func (func))
;; CHECK: (type $cont (cont $func))
;; NOKEEP: (type $cont (cont $func))
(type $cont (cont $func))
;; CHECK: (elem declare func $func)
;; CHECK: (export "export" (func $export))
;; CHECK: (export "test" (func $test))
;; NOKEEP: (elem declare func $func)
;; NOKEEP: (export "export" (func $export))
;; NOKEEP: (export "test" (func $test))
(export "test" (func $test))
;; CHECK: (func $func (type $func)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
;; NOKEEP: (func $func (type $func)
;; NOKEEP-NEXT: (nop)
;; NOKEEP-NEXT: )
(func $func
)
;; CHECK: (func $test (type $func)
;; CHECK-NEXT: (local $cont (ref $cont))
;; CHECK-NEXT: (local.set $cont
;; CHECK-NEXT: (cont.new $cont
;; CHECK-NEXT: (ref.func $func)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; NOKEEP: (func $test (type $func)
;; NOKEEP-NEXT: (local $cont (ref $cont))
;; NOKEEP-NEXT: (local.set $cont
;; NOKEEP-NEXT: (cont.new $cont
;; NOKEEP-NEXT: (ref.func $func)
;; NOKEEP-NEXT: )
;; NOKEEP-NEXT: )
;; NOKEEP-NEXT: (unreachable)
;; NOKEEP-NEXT: )
(func $test
(local $cont (ref $cont))
(local.set $cont
(cont.new $cont
(ref.func $func)
)
)
;; An effect, so the function cannot be fully precomputed - we precompute up
;; to here, and try to stash in locals, but fail.
(unreachable)
)
;; CHECK: (func $export (type $func)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
;; NOKEEP: (func $export (type $func)
;; NOKEEP-NEXT: (nop)
;; NOKEEP-NEXT: )
(func $export (export "export")
;; Keep the testcase from being trivial in the NOKEEP case.
)
)
;; As the original testcase, but the serialization problem happens in a
;; return_call param.
(module
;; CHECK: (type $func (func))
;; NOKEEP: (type $func (func))
(type $func (func))
;; CHECK: (type $1 (func (param contref)))
;; CHECK: (type $cont (cont $func))
;; NOKEEP: (type $1 (func (param contref)))
;; NOKEEP: (type $cont (cont $func))
(type $cont (cont $func))
;; CHECK: (elem declare func $func)
;; CHECK: (export "export" (func $export))
;; CHECK: (export "test" (func $test))
;; NOKEEP: (elem declare func $func)
;; NOKEEP: (export "export" (func $export))
;; NOKEEP: (export "test" (func $test))
(export "test" (func $test))
;; CHECK: (func $func (type $func)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
;; NOKEEP: (func $func (type $func)
;; NOKEEP-NEXT: (nop)
;; NOKEEP-NEXT: )
(func $func
)
;; CHECK: (func $test (type $1) (param $cont contref)
;; CHECK-NEXT: (if
;; CHECK-NEXT: (ref.is_null
;; CHECK-NEXT: (local.get $cont)
;; CHECK-NEXT: )
;; CHECK-NEXT: (then
;; CHECK-NEXT: (return_call $test
;; CHECK-NEXT: (cont.new $cont
;; CHECK-NEXT: (ref.func $func)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: (unreachable)
;; CHECK-NEXT: )
;; NOKEEP: (func $test (type $1) (param $cont contref)
;; NOKEEP-NEXT: (if
;; NOKEEP-NEXT: (ref.is_null
;; NOKEEP-NEXT: (local.get $cont)
;; NOKEEP-NEXT: )
;; NOKEEP-NEXT: (then
;; NOKEEP-NEXT: (return_call $test
;; NOKEEP-NEXT: (cont.new $cont
;; NOKEEP-NEXT: (ref.func $func)
;; NOKEEP-NEXT: )
;; NOKEEP-NEXT: )
;; NOKEEP-NEXT: )
;; NOKEEP-NEXT: )
;; NOKEEP-NEXT: (unreachable)
;; NOKEEP-NEXT: )
(func $test (param $cont (ref null cont))
(if
(ref.is_null
(local.get $cont)
)
(then
(return_call $test
(cont.new $cont
(ref.func $func)
)
)
)
)
(unreachable)
)
;; CHECK: (func $export (type $func)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
;; NOKEEP: (func $export (type $func)
;; NOKEEP-NEXT: (nop)
;; NOKEEP-NEXT: )
(func $export (export "export")
)
)
;; As the original testcase, but the problem happens in a nested GC value.
(module
;; CHECK: (type $func (func))
;; NOKEEP: (type $func (func))
(type $func (func))
;; CHECK: (type $cont (cont $func))
(type $cont (cont $func))
;; CHECK: (type $2 (func (result anyref)))
;; CHECK: (type $struct (struct (field $cont (ref $cont))))
(type $struct (struct (field $cont (ref $cont))))
;; CHECK: (elem declare func $func)
;; CHECK: (export "export" (func $export))
;; CHECK: (export "test" (func $test))
(export "test" (func $test))
;; CHECK: (func $func (type $func)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
(func $func
)
;; CHECK: (func $test (type $2) (result anyref)
;; CHECK-NEXT: (struct.new $struct
;; CHECK-NEXT: (cont.new $cont
;; CHECK-NEXT: (ref.func $func)
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
(func $test (result anyref)
(struct.new $struct
(cont.new $cont
(ref.func $func)
)
)
)
;; CHECK: (func $export (type $func)
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
;; NOKEEP: (export "export" (func $export))
;; NOKEEP: (func $export (type $func)
;; NOKEEP-NEXT: (nop)
;; NOKEEP-NEXT: )
(func $export (export "export")
)
)