blob: 8251df0bccf65fe79a41549028a1bb16ae4c647f [file] [log] [blame] [edit]
(module
(rec
(type $super (sub (descriptor $super.desc) (struct)))
(type $super.desc (sub (describes $super) (struct)))
(type $sub (sub $super (descriptor $sub.desc) (struct)))
(type $sub.desc (sub $super.desc (describes $sub) (struct)))
)
(global $super.desc1 (ref (exact $super.desc)) (struct.new $super.desc))
(global $super.desc2 (ref (exact $super.desc)) (struct.new $super.desc))
(global $super1 (ref $super) (struct.new $super (global.get $super.desc1)))
(global $sub.desc (ref (exact $sub.desc)) (struct.new $sub.desc))
(global $sub (ref $sub) (struct.new $sub (global.get $sub.desc)))
;; ref.cast_desc (ref null ht)
(func $ref.cast_desc-null-unreachable (result anyref)
(unreachable)
(ref.cast_desc (ref null $super))
)
(func $ref.cast_desc-null-null (param anyref) (result anyref)
(ref.cast_desc (ref null $super)
(ref.null none)
(ref.null none)
)
)
(func $ref.cast_desc-null-upcast (param $sub (ref null $sub)) (param $super.desc (ref null $super.desc)) (result (ref null $super))
(ref.cast_desc (ref null $super)
(local.get $sub)
(local.get $super.desc)
)
)
(func $ref.cast_desc-null-exact (param $any anyref) (param $super.desc (ref null (exact $super.desc))) (result (ref null (exact $super)))
;; The cast type is exact because the descriptor is exact.
(ref.cast_desc (ref null (exact $super))
(local.get $any)
(local.get $super.desc)
)
)
(func (export "cast-success")
(drop
(ref.cast_desc (ref null $super)
(global.get $super1)
(global.get $super.desc1)
)
)
)
(func (export "cast-success-supertype")
(drop
(ref.cast_desc (ref null $super)
(global.get $sub)
(global.get $sub.desc)
)
)
)
(func (export "cast-success-null")
(drop
(ref.cast_desc (ref null $super)
(ref.null none)
(global.get $super.desc1)
)
)
)
(func (export "cast-fail-wrong-desc")
(drop
(ref.cast_desc (ref null $super)
(global.get $super1)
(global.get $super.desc2)
)
)
)
(func (export "cast-fail-null-desc")
(drop
(ref.cast_desc (ref null $super)
(global.get $super1)
(ref.null none)
)
)
)
;; ref.cast_desc (ref ht)
(func $ref.cast_desc-nn-unreachable (result anyref)
(unreachable)
(ref.cast_desc (ref $super))
)
(func $ref.cast_desc-nn-null (param anyref) (result anyref)
(ref.cast_desc (ref $super)
(ref.null none)
(ref.null none)
)
)
(func $ref.cast_desc-nn-upcast (param $sub (ref null $sub)) (param $super.desc (ref null $super.desc)) (result (ref null $super))
(ref.cast_desc (ref $super)
(local.get $sub)
(local.get $super.desc)
)
)
(func $ref.cast_desc-nn-exact (param $any anyref) (param $super.desc (ref null (exact $super.desc))) (result (ref null (exact $super)))
;; The cast type is exact because the descriptor is exact.
(ref.cast_desc (ref (exact $super))
(local.get $any)
(local.get $super.desc)
)
)
(func (export "cast-nn-success")
(drop
(ref.cast_desc (ref $super)
(global.get $super1)
(global.get $super.desc1)
)
)
)
(func (export "cast-nn-success-supertype")
(drop
(ref.cast_desc (ref $super)
(global.get $sub)
(global.get $sub.desc)
)
)
)
(func (export "cast-nn-fail-null")
(drop
(ref.cast_desc (ref $super)
(ref.null none)
(global.get $super.desc1)
)
)
)
(func (export "cast-nn-fail-wrong-desc")
(drop
(ref.cast_desc (ref $super)
(global.get $super1)
(global.get $super.desc2)
)
)
)
(func (export "cast-nn-fail-null-desc")
(drop
(ref.cast_desc (ref $super)
(global.get $super1)
(ref.null none)
)
)
)
(func (export "cast-branch-ref") (result i32)
(drop
(ref.cast_desc (ref $super)
(return (i32.const 1))
(ref.null none)
)
)
(i32.const 0)
)
(func (export "cast-branch-desc") (result i32)
(drop
(ref.cast_desc (ref $super)
(ref.null none)
(return (i32.const 1))
)
)
(i32.const 0)
)
(func (export "cast-i31ref")
(drop
(ref.cast_desc (ref $super)
(ref.i31 (i32.const 0))
(struct.new $super.desc)
)
)
)
)
(assert_return (invoke "cast-success"))
(assert_return (invoke "cast-success-supertype"))
(assert_return (invoke "cast-success-null"))
(assert_trap (invoke "cast-fail-wrong-desc") "cast error")
(assert_trap (invoke "cast-fail-null-desc") "null descriptor")
(assert_return (invoke "cast-nn-success"))
(assert_return (invoke "cast-nn-success-supertype"))
(assert_trap (invoke "cast-nn-fail-null") "cast error")
(assert_trap (invoke "cast-nn-fail-wrong-desc") "cast error")
(assert_trap (invoke "cast-nn-fail-null-desc") "null descriptor")
(assert_return (invoke "cast-branch-ref") (i32.const 1))
(assert_return (invoke "cast-branch-desc") (i32.const 1))
(assert_trap (invoke "cast-i31ref") "cast error")
(assert_malformed
;; Cast type must be a reference.
(module quote "(module (func (unreachable) (ref.cast_desc i32) (unreachable)))")
"expected reftype"
)
(assert_invalid
(module
(type (struct))
(func (result anyref)
(unreachable)
;; Cannot do a descriptor cast to a type without a descriptor.
(ref.cast_desc (ref null 0))
)
)
"cast target must have descriptor"
)
(assert_invalid
(module
(type (struct))
(func (result anyref)
(unreachable)
;; Cannot do a descriptor cast to a type without a descriptor.
(ref.cast_desc (ref 0))
)
)
"cast target must have descriptor"
)
(assert_invalid
(module
(rec
(type $super (sub (descriptor $super.desc) (struct)))
(type $super.desc (sub (describes $super) (struct)))
(type $sub (sub $super (descriptor $sub.desc) (struct)))
(type $sub.desc (sub $super.desc (describes $sub) (struct)))
)
(func (param $super.desc (ref null $super.desc)) (result anyref)
(ref.cast_desc (ref null $sub)
(local.get 0)
;; This should be a $sub.desc but it is a $super.desc.
(local.get $super.desc)
)
)
)
"invalid type on stack"
)
(assert_invalid
(module
(rec
(type $super (sub (descriptor $super.desc) (struct)))
(type $super.desc (sub (describes $super) (struct)))
(type $sub (sub $super (descriptor $sub.desc) (struct)))
(type $sub.desc (sub $super.desc (describes $sub) (struct)))
)
(func (param $super.desc (ref null $super.desc)) (result anyref)
(ref.cast_desc (ref $sub)
(local.get 0)
;; This should be a $sub.desc but it is a $super.desc.
(local.get $super.desc)
)
)
)
"invalid type on stack"
)
(assert_invalid
(module
(rec
(type $struct (descriptor $desc) (struct))
(type $desc (describes $struct) (struct))
)
(func (param $any anyref) (param $desc (ref null $desc)) (result anyref)
;; The cast type cannot be exact because the descriptor is not exact.
(ref.cast_desc (ref null (exact $struct))
(local.get $any)
(local.get $desc)
)
)
)
"invalid type on stack"
)
(assert_invalid
(module
(rec
(type $struct (descriptor $desc) (struct))
(type $desc (describes $struct) (struct))
)
(func (param $any anyref) (param $desc (ref null $desc)) (result anyref)
;; The cast type cannot be exact because the descriptor is not exact.
(ref.cast_desc (ref (exact $struct))
(local.get $any)
(local.get $desc)
)
)
)
"invalid type on stack"
)