/* Copyright 2021 Mozilla Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // ./test/core/stack-switching/validation_gc.wast // ./test/core/stack-switching/validation_gc.wast:8 let $0 = instantiate(`(module (type \$f (func)) (type \$ft1 (sub (func (param (ref \$f)) (result (ref func))))) (type \$ct1 (sub (cont \$ft1))) (type \$ft2 (func (param (ref any)) (result (ref func)))) (type \$ct2 (cont \$ft2)) (type \$ft3 (sub \$ft1 (func (param (ref func)) (result (ref \$f))))) (type \$ct3 (cont \$ft3)) ;; Okay: Continuation types are covariant, have declared \$ft3 <: \$ft1 (type \$ct_sub (sub \$ct1 (cont \$ft3))) (func \$test (param \$p1 (ref \$ct1)) (param \$p2 (ref \$ct_sub)) ;; Okay: (ref \$ct_sub) <: (ref \$ct1) (local.set \$p1 (local.get \$p2)) ) )`); // ./test/core/stack-switching/validation_gc.wast:34 assert_invalid( () => instantiate(`(module (type \$f (func)) (type \$ft1 (sub (func (param (ref \$f)) (result (ref func))))) (type \$ct1 (sub (cont \$ft1))) (type \$ft2 (func (param (ref func)) (result (ref \$f)))) ;; Error: \$ft2 and ft1 have compatible types, but have not declared \$ft2 <: ft1 (type \$error (sub \$ct1 (cont \$ft2))) )`), `sub type 4 does not match super type 2`, ); // ./test/core/stack-switching/validation_gc.wast:50 assert_invalid( () => instantiate(`(module (type \$f (func)) (type \$ft1 (sub (func (param (ref \$f)) (result (ref func))))) (type \$ct1 (sub (cont \$ft1))) (type \$ft2 (func (param (ref func)) (result (ref \$f)))) (type \$ct2 (cont \$ft2)) (func \$test (param \$p1 (ref \$ct1)) (param \$p2 (ref \$ct2)) ;; Error \$ct2 and \$ct1 have generally compatible types, ;; but have not declared \$ft2 <: ft1 or \$ct2 <: \$ct1 ;; Thus, \$ct2 instantiate(`(module (type \$f (func)) (type \$ft1 (sub (func (param (ref \$f)) (result (ref func))))) (type \$ct1 (sub (cont \$ft1))) (type \$ft3 (sub \$ft1 (func (param (ref func)) (result (ref \$f))))) (type \$ct3 (cont \$ft3)) (func \$error (param \$p1 (ref \$ct1)) ;;(param \$p2 (ref \$ct2)) (param \$p3 (ref \$ct3)) ;; Error \$ct3 and \$ct1 have generally compatible types, ;; (in particular: declared \$ft3 <: ft1, ;; but have not declared \$ct3 <: \$ct1 ;; \$ct3 instantiate(`(module (func \$error (param \$p_any (ref any)) (param \$p_cont (ref cont)) ;; Error: cont instantiate(`(module (type \$ft0 (func)) (type \$ct0 (cont \$ft0)) (type \$ft_sup (sub (func (param (ref \$ft0))))) (type \$ct_sup (sub (cont \$ft_sup))) (type \$ft_sub (sub \$ft_sup (func (param (ref func))))) (type \$ct_sub (cont \$ft_sub)) (tag \$t (param (ref \$ct_sub))) (func \$test0 (param \$p (ref \$ct0)) ;; This is similar to \$subtyping1, but this time we use a continuation as payload. ;; But we did not actually declare \$ct_sub <: \$ct_sub. ;; ;; This is mostly just to check the following: ;; For the continuation received by every handler, we see through the ;; continuation type and do structural subtyping on the underlying ;; function type. ;; However, for continuations that are just payloads (\$ct_sup here), we do ;; ordinary nominal subtyping. (block \$handler (result (ref \$ct_sup) (ref \$ct0)) (local.get \$p) (resume \$ct0 (on \$t \$handler)) (return) ) (unreachable) ) )`), `type mismatch`, );