blob: b4e5e910294bc2ab27c5b5225d372f103f64bcc8 [file] [log] [blame] [edit]
;; Binding structure
(module
(type $s0 (struct (field (ref 0) (ref 1) (ref $s0) (ref $s1))))
(type $s1 (struct (field (ref 0) (ref 1) (ref $s0) (ref $s1))))
(func (param (ref $forward)))
(type $forward (struct))
)
(assert_invalid
(module (type (struct (field (ref 1)))))
"unknown type"
)
(assert_invalid
(module (type (struct (field (mut (ref 1))))))
"unknown type"
)
;; Basic instructions
(module
(type $vec (struct (field f32) (field $y (mut f32)) (field $z f32)))
(func $get_0 (param $v (ref $vec)) (result f32)
(struct.get $vec 0 (local.get $v))
)
(func (export "get_0") (result f32)
(call $get_0 (struct.new_default_with_rtt $vec (rtt.canon $vec)))
)
(func $set_get_y (param $v (ref $vec)) (param $y f32) (result f32)
(struct.set $vec $y (local.get $v) (local.get $y))
(struct.get $vec $y (local.get $v))
)
(func (export "set_get_y") (param $y f32) (result f32)
(call $set_get_y (struct.new_default_with_rtt $vec (rtt.canon $vec)) (local.get $y))
)
(func $set_get_1 (param $v (ref $vec)) (param $y f32) (result f32)
(struct.set $vec 1 (local.get $v) (local.get $y))
(struct.get $vec $y (local.get $v))
)
(func (export "set_get_1") (param $y f32) (result f32)
(call $set_get_1 (struct.new_default_with_rtt $vec (rtt.canon $vec)) (local.get $y))
)
)
(assert_return (invoke "get_0") (f32.const 0))
(assert_return (invoke "set_get_y" (f32.const 7)) (f32.const 7))
(assert_return (invoke "set_get_1" (f32.const 7)) (f32.const 7))
(assert_invalid
(module
(type $s (struct (field i64)))
(func (export "struct.set-immutable") (param $s (ref $s))
(struct.set $s 0 (local.get $s) (i64.const 1))
)
)
"field is immutable"
)
;; Null dereference
(module
(type $t (struct (field i32) (field (mut i32))))
(func (export "struct.get-null")
(local (ref null $t)) (drop (struct.get $t 1 (local.get 0)))
)
(func (export "struct.set-null")
(local (ref null $t)) (struct.set $t 1 (local.get 0) (i32.const 0))
)
)
(assert_trap (invoke "struct.get-null") "null structure")
(assert_trap (invoke "struct.set-null") "null structure")
(assert_invalid
(module
(type $t (struct (field i32) (field (mut i32))))
(func (export "struct.new-null")
(local (ref null (rtt $t))) (drop (struct.new $t (i32.const 1) (i32.const 2) (local.get 0)))
)
)
"type mismatch"
)
(assert_invalid
(module
(type $t (struct (field i32) (field (mut i32))))
(func (export "struct.new_default-null")
(local (ref null (rtt $t))) (drop (struct.new_default_with_rtt $t (local.get 0)))
)
)
"type mismatch"
)
(assert_invalid
(module
(type $A (struct (field i32)))
(type $B (struct (field i64)))
(global $glob (rtt $A) (rtt.sub $A (rtt.canon $B)))
)
"invalid rtt"
)
(assert_invalid
(module
(type $vec (struct (field i32)))
(func $test
(drop
;; too many arguments
(struct.new_with_rtt $vec (i32.const 1) (i32.const 2) (rtt.canon $vec))
)
)
)
"invalid number of arguments to struct.new"
)
(assert_invalid
(module
(type $vec (struct (field i32) (field i32)))
(func $test
(drop
;; too few arguments
(struct.new_with_rtt $vec (i32.const 1) (rtt.canon $vec))
)
)
)
"invalid number of arguments to struct.new"
)
;; Packed parsing
(assert_invalid
(module
(type $struct (struct (mut i8)))
(func $foo (param $ref (ref $struct))
(drop (struct.get $struct 0 (local.get $struct)))
)
)
"packed field must be read as packed"
)
(assert_invalid
(module
(type $struct (struct (mut i32)))
(func $foo (param $ref (ref $struct))
(drop (struct.get_s $struct 0 (local.get $struct)))
)
)
"non-packed field must not be read as packed"
)