| (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_desc $super (global.get $super.desc1))) | |
| (global $sub.desc (ref (exact $sub.desc)) (struct.new $sub.desc)) | |
| (global $sub (ref $sub) (struct.new_desc $sub (global.get $sub.desc))) | |
| ;; ref.cast_desc_eq (ref null ht) | |
| (func $ref.cast_desc_eq-null-unreachable (result anyref) | |
| (unreachable) | |
| (ref.cast_desc_eq (ref null $super)) | |
| ) | |
| (func $ref.cast_desc_eq-null-null (param anyref) (result anyref) | |
| (ref.cast_desc_eq (ref null $super) | |
| (ref.null none) | |
| (ref.null none) | |
| ) | |
| ) | |
| (func $ref.cast_desc_eq-null-upcast (param $sub (ref null $sub)) (param $super.desc (ref null $super.desc)) (result (ref null $super)) | |
| (ref.cast_desc_eq (ref null $super) | |
| (local.get $sub) | |
| (local.get $super.desc) | |
| ) | |
| ) | |
| (func $ref.cast_desc_eq-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_eq (ref null (exact $super)) | |
| (local.get $any) | |
| (local.get $super.desc) | |
| ) | |
| ) | |
| (func (export "cast-success") | |
| (drop | |
| (ref.cast_desc_eq (ref null $super) | |
| (global.get $super1) | |
| (global.get $super.desc1) | |
| ) | |
| ) | |
| ) | |
| (func (export "cast-success-supertype") | |
| (drop | |
| (ref.cast_desc_eq (ref null $super) | |
| (global.get $sub) | |
| (global.get $sub.desc) | |
| ) | |
| ) | |
| ) | |
| (func (export "cast-success-null") | |
| (drop | |
| (ref.cast_desc_eq (ref null $super) | |
| (ref.null none) | |
| (global.get $super.desc1) | |
| ) | |
| ) | |
| ) | |
| (func (export "cast-fail-wrong-desc") | |
| (drop | |
| (ref.cast_desc_eq (ref null $super) | |
| (global.get $super1) | |
| (global.get $super.desc2) | |
| ) | |
| ) | |
| ) | |
| (func (export "cast-fail-null-desc") | |
| (drop | |
| (ref.cast_desc_eq (ref null $super) | |
| (global.get $super1) | |
| (ref.null none) | |
| ) | |
| ) | |
| ) | |
| ;; ref.cast_desc_eq (ref ht) | |
| (func $ref.cast_desc_eq-nn-unreachable (result anyref) | |
| (unreachable) | |
| (ref.cast_desc_eq (ref $super)) | |
| ) | |
| (func $ref.cast_desc_eq-nn-null (param anyref) (result anyref) | |
| (ref.cast_desc_eq (ref $super) | |
| (ref.null none) | |
| (ref.null none) | |
| ) | |
| ) | |
| (func $ref.cast_desc_eq-nn-upcast (param $sub (ref null $sub)) (param $super.desc (ref null $super.desc)) (result (ref null $super)) | |
| (ref.cast_desc_eq (ref $super) | |
| (local.get $sub) | |
| (local.get $super.desc) | |
| ) | |
| ) | |
| (func $ref.cast_desc_eq-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_eq (ref (exact $super)) | |
| (local.get $any) | |
| (local.get $super.desc) | |
| ) | |
| ) | |
| (func (export "cast-nn-success") | |
| (drop | |
| (ref.cast_desc_eq (ref $super) | |
| (global.get $super1) | |
| (global.get $super.desc1) | |
| ) | |
| ) | |
| ) | |
| (func (export "cast-nn-success-supertype") | |
| (drop | |
| (ref.cast_desc_eq (ref $super) | |
| (global.get $sub) | |
| (global.get $sub.desc) | |
| ) | |
| ) | |
| ) | |
| (func (export "cast-nn-fail-null") | |
| (drop | |
| (ref.cast_desc_eq (ref $super) | |
| (ref.null none) | |
| (global.get $super.desc1) | |
| ) | |
| ) | |
| ) | |
| (func (export "cast-nn-fail-wrong-desc") | |
| (drop | |
| (ref.cast_desc_eq (ref $super) | |
| (global.get $super1) | |
| (global.get $super.desc2) | |
| ) | |
| ) | |
| ) | |
| (func (export "cast-nn-fail-null-desc") | |
| (drop | |
| (ref.cast_desc_eq (ref $super) | |
| (global.get $super1) | |
| (ref.null none) | |
| ) | |
| ) | |
| ) | |
| (func (export "cast-branch-ref") (result i32) | |
| (drop | |
| (ref.cast_desc_eq (ref $super) | |
| (return (i32.const 1)) | |
| (ref.null none) | |
| ) | |
| ) | |
| (i32.const 0) | |
| ) | |
| (func (export "cast-branch-desc") (result i32) | |
| (drop | |
| (ref.cast_desc_eq (ref $super) | |
| (ref.null none) | |
| (return (i32.const 1)) | |
| ) | |
| ) | |
| (i32.const 0) | |
| ) | |
| (func (export "cast-i31ref") | |
| (drop | |
| (ref.cast_desc_eq (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_eq 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_eq (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_eq (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_eq (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_eq (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_eq (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_eq (ref (exact $struct)) | |
| (local.get $any) | |
| (local.get $desc) | |
| ) | |
| ) | |
| ) | |
| "invalid type on stack" | |
| ) |