blob: 1e4b661665fb1f378fd123c06f9b6fbe4839d2fc [file] [log] [blame] [edit]
;; Auxiliary module to import from
(module
(func (export "func"))
(func (export "func-i32") (param i32))
(func (export "func-f32") (param f32))
(func (export "func->i32") (result i32) (i32.const 22))
(func (export "func->f32") (result f32) (f32.const 11))
(func (export "func-i32->i32") (param i32) (result i32) (local.get 0))
(func (export "func-i64->i64") (param i64) (result i64) (local.get 0))
(global (export "global-i32") i32 (i32.const 55))
(global (export "global-f32") f32 (f32.const 44))
;;; FIXME: Exporting a mutable global is currently not supported. Make mutable
;;; when support is added.
(global (export "global-mut-i64") i64 (i64.const 66))
(table (export "table-10-inf") 10 funcref)
(table (export "table-10-20") 10 20 funcref)
(memory (export "memory-2-inf") 2)
;; Multiple memories are not yet supported
;; (memory (export "memory-2-4") 2 4)
)
(register "test")
;; Functions
(module
(type $func_i32 (func (param i32)))
(type $func_i64 (func (param i64)))
(type $func_f32 (func (param f32)))
(type $func_f64 (func (param f64)))
(import "spectest" "print_i32" (func (param i32)))
;; JavaScript can't handle i64 yet.
;; (func (import "spectest" "print_i64") (param i64))
(import "spectest" "print_i32" (func $print_i32 (param i32)))
;; JavaScript can't handle i64 yet.
;; (import "spectest" "print_i64" (func $print_i64 (param i64)))
(import "spectest" "print_f32" (func $print_f32 (param f32)))
(import "spectest" "print_f64" (func $print_f64 (param f64)))
(import "spectest" "print_i32_f32" (func $print_i32_f32 (param i32 f32)))
(import "spectest" "print_f64_f64" (func $print_f64_f64 (param f64 f64)))
(func $print_i32-2 (import "spectest" "print_i32") (param i32))
(func $print_f64-2 (import "spectest" "print_f64") (param f64))
(import "test" "func-i64->i64" (func $i64->i64 (param i64) (result i64)))
(func (export "p1") (import "spectest" "print_i32") (param i32))
(func $p (export "p2") (import "spectest" "print_i32") (param i32))
(func (import "spectest" "print_i32") (param i32))
(func (export "p5") (import "spectest" "print_i32") (type 0))
(func (export "p6") (import "spectest" "print_i32") (type 0) (param i32) (result))
;; (export "p3" (func $print_i32))
;; (export "p4" (func $print_i32))
(import "spectest" "print_i32" (func (type $forward)))
(func (import "spectest" "print_i32") (type $forward))
(type $forward (func (param i32)))
(table funcref (elem $print_i32 $print_f64))
(func (export "print32") (param $i i32)
(local $x f32)
(local.set $x (f32.convert_i32_s (local.get $i)))
(call 0 (local.get $i))
(call $print_i32_f32
(i32.add (local.get $i) (i32.const 1))
(f32.const 42)
)
(call $print_i32 (local.get $i))
(call $print_i32-2 (local.get $i))
(call $print_f32 (local.get $x))
(call_indirect (type $func_i32) (local.get $i) (i32.const 0))
)
(func (export "print64") (param $i i64)
(local $x f64)
(local.set $x (f64.convert_i64_s (call $i64->i64 (local.get $i))))
;; JavaScript can't handle i64 yet.
;; (call 1 (local.get $i))
(call $print_f64_f64
(f64.add (local.get $x) (f64.const 1))
(f64.const 53)
)
;; JavaScript can't handle i64 yet.
;; (call $print_i64 (local.get $i))
(call $print_f64 (local.get $x))
(call $print_f64-2 (local.get $x))
(call_indirect (type $func_f64) (local.get $x) (i32.const 1))
)
)
(assert_return (invoke "print32" (i32.const 13)))
(assert_return (invoke "print64" (i64.const 24)))
(assert_invalid
(module
(type (func (result i32)))
(import "test" "func" (func (type 1)))
)
"unknown type"
)
;; Export sharing name with import
(module
(import "spectest" "print_i32" (func $imported_print (param i32)))
(func (export "print_i32") (param $i i32)
(call $imported_print (local.get $i))
)
)
(assert_return (invoke "print_i32" (i32.const 13)))
;; Export sharing name with import
(module
(import "spectest" "print_i32" (func $imported_print (param i32)))
(func (export "print_i32") (param $i i32) (param $j i32) (result i32)
(i32.add (local.get $i) (local.get $j))
)
)
(assert_return (invoke "print_i32" (i32.const 5) (i32.const 11)) (i32.const 16))
(module (import "test" "func" (func)))
(module (import "test" "func-i32" (func (param i32))))
(module (import "test" "func-f32" (func (param f32))))
(module (import "test" "func->i32" (func (result i32))))
(module (import "test" "func->f32" (func (result f32))))
(module (import "test" "func-i32->i32" (func (param i32) (result i32))))
(module (import "test" "func-i64->i64" (func (param i64) (result i64))))
;; (assert_unlinkable
;; (module (import "test" "unknown" (func)))
;; "unknown import"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "unknown" (func)))
;; "unknown import"
;; )
;; (assert_unlinkable
;; (module (import "test" "func" (func (param i32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func" (func (result i32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func" (func (param i32) (result i32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func-i32" (func)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func-i32" (func (result i32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func-i32" (func (param f32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func-i32" (func (param i64))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func-i32" (func (param i32) (result i32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func->i32" (func)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func->i32" (func (param i32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func->i32" (func (result f32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func->i32" (func (result i64))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func->i32" (func (param i32) (result i32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func-i32->i32" (func)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func-i32->i32" (func (param i32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func-i32->i32" (func (result i32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "global-i32" (func (result i32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "table-10-inf" (func)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "memory-2-inf" (func)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "global_i32" (func)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "table" (func)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "memory" (func)))
;; "incompatible import type"
;; )
;; Globals
(module
(import "spectest" "global_i32" (global i32))
(global (import "spectest" "global_i32") i32)
(import "spectest" "global_i32" (global $x i32))
(global $y (import "spectest" "global_i32") i32)
;; JavaScript can't handle i64 yet.
;; (import "spectest" "global_i64" (global i64))
(import "spectest" "global_f32" (global f32))
(import "spectest" "global_f64" (global f64))
(func (export "get-0") (result i32) (global.get 0))
(func (export "get-1") (result i32) (global.get 1))
(func (export "get-x") (result i32) (global.get $x))
(func (export "get-y") (result i32) (global.get $y))
)
(assert_return (invoke "get-0") (i32.const 666))
(assert_return (invoke "get-1") (i32.const 666))
(assert_return (invoke "get-x") (i32.const 666))
(assert_return (invoke "get-y") (i32.const 666))
(module (import "test" "global-i32" (global i32)))
(module (import "test" "global-f32" (global f32)))
(module (import "test" "global-mut-i64" (global (mut i64))))
;; (assert_unlinkable
;; (module (import "test" "unknown" (global i32)))
;; "unknown import"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "unknown" (global i32)))
;; "unknown import"
;; )
;; (assert_unlinkable
;; (module (import "test" "global-i32" (global i64)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "global-i32" (global f32)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "global-i32" (global f64)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "global-i32" (global (mut i32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "global-f32" (global i32)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "global-f32" (global i64)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "global-f32" (global f64)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "global-f32" (global (mut f32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "global-mut-i64" (global (mut i32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "global-mut-i64" (global (mut f32))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "global-mut-i64" (global (mut f64))))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "global-mut-i64" (global i64)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func" (global i32)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "table-10-inf" (global i32)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "memory-2-inf" (global i32)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "print_i32" (global i32)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "table" (global i32)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "memory" (global i32)))
;; "incompatible import type"
;; )
;; Tables
(module
(type (func (result i32)))
(import "spectest" "table" (table $tab 10 20 funcref))
(elem (table $tab) (i32.const 1) func $f $g)
(func (export "call") (param i32) (result i32)
(call_indirect $tab (type 0) (local.get 0))
)
(func $f (result i32) (i32.const 11))
(func $g (result i32) (i32.const 22))
)
(assert_trap (invoke "call" (i32.const 0)) "uninitialized element")
(assert_return (invoke "call" (i32.const 1)) (i32.const 11))
(assert_return (invoke "call" (i32.const 2)) (i32.const 22))
(assert_trap (invoke "call" (i32.const 3)) "uninitialized element")
(assert_trap (invoke "call" (i32.const 100)) "undefined element")
(module
(type (func (result i32)))
(table $tab (import "spectest" "table") 10 20 funcref)
(elem (table $tab) (i32.const 1) func $f $g)
(func (export "call") (param i32) (result i32)
(call_indirect $tab (type 0) (local.get 0))
)
(func $f (result i32) (i32.const 11))
(func $g (result i32) (i32.const 22))
)
(assert_trap (invoke "call" (i32.const 0)) "uninitialized element")
(assert_return (invoke "call" (i32.const 1)) (i32.const 11))
(assert_return (invoke "call" (i32.const 2)) (i32.const 22))
(assert_trap (invoke "call" (i32.const 3)) "uninitialized element")
(assert_trap (invoke "call" (i32.const 100)) "undefined element")
(module
(import "spectest" "table" (table 0 funcref))
(import "spectest" "table" (table 0 funcref))
(table 10 funcref)
(table 10 funcref)
)
(module (import "test" "table-10-inf" (table 10 funcref)))
(module (import "test" "table-10-inf" (table 5 funcref)))
(module (import "test" "table-10-inf" (table 0 funcref)))
(module (import "test" "table-10-20" (table 10 funcref)))
(module (import "test" "table-10-20" (table 5 funcref)))
(module (import "test" "table-10-20" (table 0 funcref)))
(module (import "test" "table-10-20" (table 10 20 funcref)))
(module (import "test" "table-10-20" (table 5 20 funcref)))
(module (import "test" "table-10-20" (table 0 20 funcref)))
(module (import "test" "table-10-20" (table 10 25 funcref)))
(module (import "test" "table-10-20" (table 5 25 funcref)))
(module (import "test" "table-10-20" (table 0 25 funcref)))
(module (import "spectest" "table" (table 10 funcref)))
(module (import "spectest" "table" (table 5 funcref)))
(module (import "spectest" "table" (table 0 funcref)))
(module (import "spectest" "table" (table 10 20 funcref)))
(module (import "spectest" "table" (table 5 20 funcref)))
(module (import "spectest" "table" (table 0 20 funcref)))
(module (import "spectest" "table" (table 10 25 funcref)))
(module (import "spectest" "table" (table 5 25 funcref)))
;; (assert_unlinkable
;; (module (import "test" "unknown" (table 10 funcref)))
;; "unknown import"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "unknown" (table 10 funcref)))
;; "unknown import"
;; )
;; (assert_unlinkable
;; (module (import "test" "table-10-inf" (table 12 funcref)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "table-10-inf" (table 10 20 funcref)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "table-10-20" (table 12 20 funcref)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "table-10-20" (table 10 18 funcref)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "table" (table 12 funcref)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "table" (table 10 15 funcref)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func" (table 10 funcref)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "global-i32" (table 10 funcref)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "memory-2-inf" (table 10 funcref)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "print_i32" (table 10 funcref)))
;; "incompatible import type"
;; )
;; Memories
(module
(import "spectest" "memory" (memory 1 2))
(data (memory 0) (i32.const 10) "\10")
(func (export "load") (param i32) (result i32) (i32.load (local.get 0)))
)
(assert_return (invoke "load" (i32.const 0)) (i32.const 0))
(assert_return (invoke "load" (i32.const 10)) (i32.const 16))
(assert_return (invoke "load" (i32.const 8)) (i32.const 0x100000))
(assert_trap (invoke "load" (i32.const 1000000)) "out of bounds memory access")
(module
(memory (import "spectest" "memory") 1 2)
(data (memory 0) (i32.const 10) "\10")
(func (export "load") (param i32) (result i32) (i32.load (local.get 0)))
)
(assert_return (invoke "load" (i32.const 0)) (i32.const 0))
(assert_return (invoke "load" (i32.const 10)) (i32.const 16))
(assert_return (invoke "load" (i32.const 8)) (i32.const 0x100000))
(assert_trap (invoke "load" (i32.const 1000000)) "out of bounds memory access")
(module (import "test" "memory-2-inf" (memory 2)))
(module (import "test" "memory-2-inf" (memory 1)))
(module (import "test" "memory-2-inf" (memory 0)))
(module (import "spectest" "memory" (memory 1)))
(module (import "spectest" "memory" (memory 0)))
(module (import "spectest" "memory" (memory 1 2)))
(module (import "spectest" "memory" (memory 0 2)))
(module (import "spectest" "memory" (memory 1 3)))
(module (import "spectest" "memory" (memory 0 3)))
;; (assert_unlinkable
;; (module (import "test" "unknown" (memory 1)))
;; "unknown import"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "unknown" (memory 1)))
;; "unknown import"
;; )
;; (assert_unlinkable
;; (module (import "test" "memory-2-inf" (memory 3)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "memory-2-inf" (memory 2 3)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "memory" (memory 2)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "memory" (memory 1 1)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "func-i32" (memory 1)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "global-i32" (memory 1)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "test" "table-10-inf" (memory 1)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "print_i32" (memory 1)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "global_i32" (memory 1)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "table" (memory 1)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "memory" (memory 2)))
;; "incompatible import type"
;; )
;; (assert_unlinkable
;; (module (import "spectest" "memory" (memory 1 1)))
;; "incompatible import type"
;; )
(module
(import "spectest" "memory" (memory 0 3)) ;; actual has max size 2
(func (export "grow") (param i32) (result i32) (memory.grow (local.get 0)))
)
(assert_return (invoke "grow" (i32.const 0)) (i32.const 1))
(assert_return (invoke "grow" (i32.const 1)) (i32.const 1))
(assert_return (invoke "grow" (i32.const 0)) (i32.const 2))
(assert_return (invoke "grow" (i32.const 1)) (i32.const -1))
(assert_return (invoke "grow" (i32.const 0)) (i32.const 2))
(module $Mgm
(memory (export "memory") 1) ;; initial size is 1
(func (export "grow") (result i32) (memory.grow (i32.const 1)))
)
(register "grown-memory" $Mgm)
(assert_return (invoke $Mgm "grow") (i32.const 1)) ;; now size is 2
(module $Mgim1
;; imported memory limits should match, because external memory size is 2 now
(memory (import "grown-memory" "memory") 2)
(export "memory" (memory 0))
(func (export "grow") (result i32) (memory.grow (i32.const 1)))
)
(register "grown-imported-memory" $Mgim1)
(assert_return (invoke $Mgim1 "grow") (i32.const 2)) ;; now size is 3
(module $Mgim2
;; imported memory limits should match, because external memory size is 3 now
(import "grown-imported-memory" "memory" (memory 3))
(func (export "size") (result i32) (memory.size))
)
(assert_return (invoke $Mgim2 "size") (i32.const 3))
;; Syntax errors
(assert_malformed
(module quote "(func) (import \"\" \"\" (func))")
"import after function"
)
(assert_malformed
(module quote "(func) (import \"\" \"\" (global i64))")
"import after function"
)
(assert_malformed
(module quote "(func) (import \"\" \"\" (table 0 funcref))")
"import after function"
)
(assert_malformed
(module quote "(func) (import \"\" \"\" (memory 0))")
"import after function"
)
(assert_malformed
(module quote "(global i64 (i64.const 0)) (import \"\" \"\" (func))")
"import after global"
)
(assert_malformed
(module quote "(global i64 (i64.const 0)) (import \"\" \"\" (global f32))")
"import after global"
)
(assert_malformed
(module quote "(global i64 (i64.const 0)) (import \"\" \"\" (table 0 funcref))")
"import after global"
)
(assert_malformed
(module quote "(global i64 (i64.const 0)) (import \"\" \"\" (memory 0))")
"import after global"
)
(assert_malformed
(module quote "(table 0 funcref) (import \"\" \"\" (func))")
"import after table"
)
(assert_malformed
(module quote "(table 0 funcref) (import \"\" \"\" (global i32))")
"import after table"
)
(assert_malformed
(module quote "(table 0 funcref) (import \"\" \"\" (table 0 funcref))")
"import after table"
)
(assert_malformed
(module quote "(table 0 funcref) (import \"\" \"\" (memory 0))")
"import after table"
)
(assert_malformed
(module quote "(memory 0) (import \"\" \"\" (func))")
"import after memory"
)
(assert_malformed
(module quote "(memory 0) (import \"\" \"\" (global i32))")
"import after memory"
)
(assert_malformed
(module quote "(memory 0) (import \"\" \"\" (table 1 3 funcref))")
"import after memory"
)
(assert_malformed
(module quote "(memory 0) (import \"\" \"\" (memory 1 2))")
"import after memory"
)
;; This module is required to validate, regardless of whether it can be
;; linked. Overloading is not possible in wasm itself, but it is possible
;; in modules from which wasm can import.
(module)
(register "not wasm")
;; (assert_unlinkable
;; (module
;; (import "not wasm" "overloaded" (func))
;; (import "not wasm" "overloaded" (func (param i32)))
;; (import "not wasm" "overloaded" (func (param i32 i32)))
;; (import "not wasm" "overloaded" (func (param i64)))
;; (import "not wasm" "overloaded" (func (param f32)))
;; (import "not wasm" "overloaded" (func (param f64)))
;; (import "not wasm" "overloaded" (func (result i32)))
;; (import "not wasm" "overloaded" (func (result i64)))
;; (import "not wasm" "overloaded" (func (result f32)))
;; (import "not wasm" "overloaded" (func (result f64)))
;; (import "not wasm" "overloaded" (global i32))
;; (import "not wasm" "overloaded" (global i64))
;; (import "not wasm" "overloaded" (global f32))
;; (import "not wasm" "overloaded" (global f64))
;; (import "not wasm" "overloaded" (table 0 funcref))
;; (import "not wasm" "overloaded" (memory 0))
;; )
;; "unknown import"
;; )