blob: 8e251b2ed4f4f27741c7866d67f161ddb35ec9fe [file] [log] [blame] [edit]
;; NOTE: Assertions have been generated by update_lit_checks.py --output=fuzz-exec and should not be edited.
;; RUN: wasm-opt %s -all --fuzz-exec -o /dev/null 2>&1 | filecheck %s
;; Test the fuzzing-support module imports.
(module
(import "fuzzing-support" "log-i32" (func $log-i32 (param i32)))
(import "fuzzing-support" "log-f64" (func $log-f64 (param f64)))
(import "fuzzing-support" "throw" (func $throw))
(import "fuzzing-support" "table-set" (func $table.set (param i32 funcref)))
(import "fuzzing-support" "table-get" (func $table.get (param i32) (result funcref)))
(import "fuzzing-support" "call-export" (func $call.export (param i32)))
(import "fuzzing-support" "call-export-catch" (func $call.export.catch (param i32) (result i32)))
(import "fuzzing-support" "call-ref" (func $call.ref (param funcref)))
(import "fuzzing-support" "call-ref-catch" (func $call.ref.catch (param funcref) (result i32)))
(import "fuzzing-support" "sleep" (func $sleep (param i32 i32) (result i32)))
(table $table 10 20 funcref)
;; Note that the exported table appears first here, but in the binary and in
;; the IR it is actually last, as we always add function exports first.
(export "table" (table $table))
;; CHECK: [fuzz-exec] calling logging
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
(func $logging (export "logging")
(call $log-i32
(i32.const 42)
)
(call $log-f64
(f64.const 3.14159)
)
)
;; CHECK: [fuzz-exec] calling throwing
;; CHECK-NEXT: [exception thrown: __private ()]
(func $throwing (export "throwing")
(call $throw)
)
;; CHECK: [fuzz-exec] calling table.setting
;; CHECK-NEXT: [exception thrown: __private ()]
(func $table.setting (export "table.setting")
(call $table.set
(i32.const 5)
(ref.func $table.setting)
)
;; Out of bounds sets will throw.
(call $table.set
(i32.const 9999)
(ref.func $table.setting)
)
)
;; CHECK: [fuzz-exec] calling table.getting
;; CHECK-NEXT: [LoggingExternalInterface logging 0]
;; CHECK-NEXT: [LoggingExternalInterface logging 1]
;; CHECK-NEXT: [exception thrown: __private ()]
(func $table.getting (export "table.getting")
;; There is a non-null value at 5, and a null at 6.
(call $log-i32
(ref.is_null
(call $table.get
(i32.const 5)
)
)
)
(call $log-i32
(ref.is_null
(call $table.get
(i32.const 6)
)
)
)
;; Out of bounds gets will throw.
(drop
(call $table.get
(i32.const 9999)
)
)
)
;; CHECK: [fuzz-exec] calling export.calling
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
;; CHECK-NEXT: [exception thrown: __private ()]
(func $export.calling (export "export.calling")
;; At index 0 in the exports we have $logging, so we will do those loggings.
(call $call.export
(i32.const 0)
)
;; At index 999 we have nothing, so we'll error.
(call $call.export
(i32.const 999)
)
)
;; CHECK: [fuzz-exec] calling export.calling.catching
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
;; CHECK-NEXT: [LoggingExternalInterface logging 0]
;; CHECK-NEXT: [LoggingExternalInterface logging 1]
(func $export.calling.catching (export "export.calling.catching")
;; At index 0 in the exports we have $logging, so we will do those loggings,
;; then log a 0 as no exception happens.
(call $log-i32
(call $call.export.catch
(i32.const 0)
)
)
;; At index 999 we have nothing, so we'll error, catch it, and log 1.
(call $log-i32
(call $call.export.catch
(i32.const 999)
)
)
)
;; CHECK: [fuzz-exec] calling ref.calling
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
;; CHECK-NEXT: [exception thrown: __private ()]
(func $ref.calling (export "ref.calling")
;; This will emit some logging.
(call $call.ref
(ref.func $logging)
)
;; This will throw.
(call $call.ref
(ref.null func)
)
)
;; CHECK: [fuzz-exec] calling ref.calling.catching
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
;; CHECK-NEXT: [LoggingExternalInterface logging 0]
;; CHECK-NEXT: [LoggingExternalInterface logging 1]
(func $ref.calling.catching (export "ref.calling.catching")
;; This will emit some logging, then log 0 as we do not error.
(call $log-i32
(call $call.ref.catch
(ref.func $logging)
)
)
;; The exception here is caught, and we'll log 1.
(call $log-i32
(call $call.ref.catch
(ref.null func)
)
)
)
(func $legal (param $x i32) (result i32)
;; Helper for the function below. All types here are legal for JS.
(call $log-i32
(i32.const 12)
)
;; Also log the param to show it is 0, which is what $call.ref does for all
;; params.
(call $log-i32
(local.get $x)
)
(i32.const 34)
)
;; CHECK: [fuzz-exec] calling ref.calling.legal
;; CHECK-NEXT: [LoggingExternalInterface logging 12]
;; CHECK-NEXT: [LoggingExternalInterface logging 0]
(func $ref.calling.legal (export "ref.calling.legal")
;; It is fine to call-ref a function with params and results. The params get
;; default values, and the results are ignored. All we will see here is the
;; logging from the function, "12".
(call $call.ref
(ref.func $legal)
)
)
(func $illegal (param $x i64)
;; Helper for the function below. The param, an i64, causes a problem: when we
;; call from JS we provide 0, but 0 throws when it tries to convert to BigInt.
(call $log-i32
(i32.const 56)
)
)
;; CHECK: [fuzz-exec] calling ref.calling.illegal
;; CHECK-NEXT: [LoggingExternalInterface logging 1]
(func $ref.calling.illegal (export "ref.calling.illegal")
;; The i64 param causes an error here, so we will only log 1 because we catch an exception.
(call $log-i32
(call $call.ref.catch
(ref.func $illegal)
)
)
)
(func $illegal-v128 (param $x v128)
;; Helper for the function below.
(call $log-i32
(i32.const 56)
)
)
;; CHECK: [fuzz-exec] calling ref.calling.illegal-v128
;; CHECK-NEXT: [LoggingExternalInterface logging 1]
(func $ref.calling.illegal-v128 (export "ref.calling.illegal-v128")
;; As above, we throw on the v128 param, and log 1.
(call $log-i32
(call $call.ref.catch
(ref.func $illegal-v128)
)
)
)
(func $illegal-exnref (param $x exnref)
;; Helper for the function below.
(call $log-i32
(i32.const 57)
)
)
;; CHECK: [fuzz-exec] calling ref.calling.illegal-exnref
;; CHECK-NEXT: [LoggingExternalInterface logging 1]
(func $ref.calling.illegal-exnref (export "ref.calling.illegal-exnref")
;; As above, we throw on the exnref param, and log 1.
(call $log-i32
(call $call.ref.catch
(ref.func $illegal-exnref)
)
)
)
(func $illegal-result (result v128)
;; Helper for the function below. The result is illegal for JS.
(call $log-i32
(i32.const 910)
)
(v128.const i32x4 1 2 3 4)
)
;; CHECK: [fuzz-exec] calling ref.calling.illegal-result
;; CHECK-NEXT: [LoggingExternalInterface logging 1]
(func $ref.calling.illegal-result (export "ref.calling.illegal-result")
;; The v128 result causes an error here, so we will log 1 as an exception. The JS
;; semantics determine that we do that check *before* the call, so the logging
;; of 910 does not go through.
(call $log-i32
(call $call.ref.catch
(ref.func $illegal-result)
)
)
)
(func $legal-result (result i64)
;; Helper for the function below.
(call $log-i32
(i32.const 910)
)
(i64.const 90)
)
;; CHECK: [fuzz-exec] calling ref.calling.legal-result
;; CHECK-NEXT: [LoggingExternalInterface logging 910]
;; CHECK-NEXT: [LoggingExternalInterface logging 0]
(func $ref.calling.legal-result (export "ref.calling.legal-result")
;; Unlike v128, i64 is legal in a result. The JS VM just returns a BigInt.
(call $log-i32
(call $call.ref.catch
(ref.func $legal-result)
)
)
)
(func $trap
;; Helper for the function below.
(unreachable)
)
;; CHECK: [fuzz-exec] calling ref.calling.trap
;; CHECK-NEXT: [trap unreachable]
(func $ref.calling.trap (export "ref.calling.trap")
;; We try to catch an exception here, but the target function traps, which is
;; not something we can catch. We will trap here, and not log at all.
(call $log-i32
(call $call.ref.catch
(ref.func $trap)
)
)
)
;; CHECK: [fuzz-exec] calling do-sleep
;; CHECK-NEXT: [fuzz-exec] note result: do-sleep => 42
;; CHECK-NEXT: warning: no passes specified, not doing any work
(func $do-sleep (export "do-sleep") (result i32)
(call $sleep
;; A ridiculous amount of ms, but in the interpreter it is ignored anyhow.
(i32.const -1)
;; An id, that is returned back to us.
(i32.const 42)
)
)
)
;; CHECK: [fuzz-exec] calling logging
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
;; CHECK: [fuzz-exec] calling throwing
;; CHECK-NEXT: [exception thrown: __private ()]
;; CHECK: [fuzz-exec] calling table.setting
;; CHECK-NEXT: [exception thrown: __private ()]
;; CHECK: [fuzz-exec] calling table.getting
;; CHECK-NEXT: [LoggingExternalInterface logging 0]
;; CHECK-NEXT: [LoggingExternalInterface logging 1]
;; CHECK-NEXT: [exception thrown: __private ()]
;; CHECK: [fuzz-exec] calling export.calling
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
;; CHECK-NEXT: [exception thrown: __private ()]
;; CHECK: [fuzz-exec] calling export.calling.catching
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
;; CHECK-NEXT: [LoggingExternalInterface logging 0]
;; CHECK-NEXT: [LoggingExternalInterface logging 1]
;; CHECK: [fuzz-exec] calling ref.calling
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
;; CHECK-NEXT: [exception thrown: __private ()]
;; CHECK: [fuzz-exec] calling ref.calling.catching
;; CHECK-NEXT: [LoggingExternalInterface logging 42]
;; CHECK-NEXT: [LoggingExternalInterface logging 3.14159]
;; CHECK-NEXT: [LoggingExternalInterface logging 0]
;; CHECK-NEXT: [LoggingExternalInterface logging 1]
;; CHECK: [fuzz-exec] calling ref.calling.legal
;; CHECK-NEXT: [LoggingExternalInterface logging 12]
;; CHECK-NEXT: [LoggingExternalInterface logging 0]
;; CHECK: [fuzz-exec] calling ref.calling.illegal
;; CHECK-NEXT: [LoggingExternalInterface logging 1]
;; CHECK: [fuzz-exec] calling ref.calling.illegal-v128
;; CHECK-NEXT: [LoggingExternalInterface logging 1]
;; CHECK: [fuzz-exec] calling ref.calling.illegal-exnref
;; CHECK-NEXT: [LoggingExternalInterface logging 1]
;; CHECK: [fuzz-exec] calling ref.calling.illegal-result
;; CHECK-NEXT: [LoggingExternalInterface logging 1]
;; CHECK: [fuzz-exec] calling ref.calling.legal-result
;; CHECK-NEXT: [LoggingExternalInterface logging 910]
;; CHECK-NEXT: [LoggingExternalInterface logging 0]
;; CHECK: [fuzz-exec] calling ref.calling.trap
;; CHECK-NEXT: [trap unreachable]
;; CHECK: [fuzz-exec] calling do-sleep
;; CHECK-NEXT: [fuzz-exec] note result: do-sleep => 42
;; CHECK-NEXT: [fuzz-exec] comparing do-sleep
;; CHECK-NEXT: [fuzz-exec] comparing export.calling
;; CHECK-NEXT: [fuzz-exec] comparing export.calling.catching
;; CHECK-NEXT: [fuzz-exec] comparing logging
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.catching
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.illegal
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.illegal-exnref
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.illegal-result
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.illegal-v128
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.legal
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.legal-result
;; CHECK-NEXT: [fuzz-exec] comparing ref.calling.trap
;; CHECK-NEXT: [fuzz-exec] comparing table.getting
;; CHECK-NEXT: [fuzz-exec] comparing table.setting
;; CHECK-NEXT: [fuzz-exec] comparing throwing