/* 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/func_ptrs.wast
// ./test/core/func_ptrs.wast:1
let $0 = instantiate(`(module
(type (func)) ;; 0:
void ->
void
(type $$S (func)) ;; 1:
void ->
void
(type (func (param))) ;; 2:
void ->
void
(type (func (result i32))) ;; 3:
void -> i32
(type (func (param) (result i32))) ;; 4:
void -> i32
(type $$T (func (param i32) (result i32))) ;; 5: i32 -> i32
(type $$U (func (param i32))) ;; 6: i32 ->
void
(func $$print (
import "spectest" "print_i32") (type 6))
(func (type 0))
(func (type $$S))
(func (export
"one") (type 4) (i32.
const 13))
(func (export
"two") (type $$T) (i32.add (local.get 0) (i32.
const 1)))
;; Both signature and parameters are allowed (and required to match)
;; since
this allows the naming of parameters.
(func (export
"three") (type $$T) (param $$a i32) (result i32)
(i32.sub (local.get 0) (i32.
const 2))
)
(func (export
"four") (type $$U) (call $$print (local.get 0)))
)`);
// ./test/core/func_ptrs.wast:27
assert_return(() => invoke($0, `one`, []), [value(
"i32", 13)]);
// ./test/core/func_ptrs.wast:28
assert_return(() => invoke($0, `two`, [13]), [value(
"i32", 14)]);
// ./test/core/func_ptrs.wast:29
assert_return(() => invoke($0, `three`, [13]), [value(
"i32", 11)]);
// ./test/core/func_ptrs.wast:30
invoke($0, `four`, [83]);
// ./test/core/func_ptrs.wast:32
assert_invalid(() => instantiate(`(module (elem (i32.
const 0)))`), `unknown table`);
// ./test/core/func_ptrs.wast:33
assert_invalid(
() => instantiate(`(module (elem (i32.
const 0) 0) (func))`),
`unknown table`,
);
// ./test/core/func_ptrs.wast:35
assert_invalid(
() => instantiate(`(module (table 1 funcref) (elem (i64.
const 0)))`),
`type mismatch`,
);
// ./test/core/func_ptrs.wast:39
assert_invalid(
() => instantiate(`(module (table 1 funcref) (elem (i32.ctz (i32.
const 0))))`),
`constant expression required`,
);
// ./test/core/func_ptrs.wast:43
assert_invalid(
() => instantiate(`(module (table 1 funcref) (elem (nop)))`),
`constant expression required`,
);
// ./test/core/func_ptrs.wast:48
assert_invalid(() => instantiate(`(module (func (type 42)))`), `unknown type`);
// ./test/core/func_ptrs.wast:49
assert_invalid(
() => instantiate(`(module (
import "spectest" "print_i32" (func (type 43))))`),
`unknown type`,
);
// ./test/core/func_ptrs.wast:51
let $1 = instantiate(`(module
(type $$T (func (param) (result i32)))
(type $$U (func (param) (result i32)))
(table funcref (elem $$t1 $$t2 $$t3 $$u1 $$u2 $$t1 $$t3))
(func $$t1 (type $$T) (i32.
const 1))
(func $$t2 (type $$T) (i32.
const 2))
(func $$t3 (type $$T) (i32.
const 3))
(func $$u1 (type $$U) (i32.
const 4))
(func $$u2 (type $$U) (i32.
const 5))
(func (export
"callt") (param $$i i32) (result i32)
(call_indirect (type $$T) (local.get $$i))
)
(func (export
"callu") (param $$i i32) (result i32)
(call_indirect (type $$U) (local.get $$i))
)
)`);
// ./test/core/func_ptrs.wast:71
assert_return(() => invoke($1, `callt`, [0]), [value(
"i32", 1)]);
// ./test/core/func_ptrs.wast:72
assert_return(() => invoke($1, `callt`, [1]), [value(
"i32", 2)]);
// ./test/core/func_ptrs.wast:73
assert_return(() => invoke($1, `callt`, [2]), [value(
"i32", 3)]);
// ./test/core/func_ptrs.wast:74
assert_return(() => invoke($1, `callt`, [3]), [value(
"i32", 4)]);
// ./test/core/func_ptrs.wast:75
assert_return(() => invoke($1, `callt`, [4]), [value(
"i32", 5)]);
// ./test/core/func_ptrs.wast:76
assert_return(() => invoke($1, `callt`, [5]), [value(
"i32", 1)]);
// ./test/core/func_ptrs.wast:77
assert_return(() => invoke($1, `callt`, [6]), [value(
"i32", 3)]);
// ./test/core/func_ptrs.wast:78
assert_trap(() => invoke($1, `callt`, [7]), `undefined element`);
// ./test/core/func_ptrs.wast:79
assert_trap(() => invoke($1, `callt`, [100]), `undefined element`);
// ./test/core/func_ptrs.wast:80
assert_trap(() => invoke($1, `callt`, [-1]), `undefined element`);
// ./test/core/func_ptrs.wast:82
assert_return(() => invoke($1, `callu`, [0]), [value(
"i32", 1)]);
// ./test/core/func_ptrs.wast:83
assert_return(() => invoke($1, `callu`, [1]), [value(
"i32", 2)]);
// ./test/core/func_ptrs.wast:84
assert_return(() => invoke($1, `callu`, [2]), [value(
"i32", 3)]);
// ./test/core/func_ptrs.wast:85
assert_return(() => invoke($1, `callu`, [3]), [value(
"i32", 4)]);
// ./test/core/func_ptrs.wast:86
assert_return(() => invoke($1, `callu`, [4]), [value(
"i32", 5)]);
// ./test/core/func_ptrs.wast:87
assert_return(() => invoke($1, `callu`, [5]), [value(
"i32", 1)]);
// ./test/core/func_ptrs.wast:88
assert_return(() => invoke($1, `callu`, [6]), [value(
"i32", 3)]);
// ./test/core/func_ptrs.wast:89
assert_trap(() => invoke($1, `callu`, [7]), `undefined element`);
// ./test/core/func_ptrs.wast:90
assert_trap(() => invoke($1, `callu`, [100]), `undefined element`);
// ./test/core/func_ptrs.wast:91
assert_trap(() => invoke($1, `callu`, [-1]), `undefined element`);
// ./test/core/func_ptrs.wast:93
let $2 = instantiate(`(module
(type $$T (func (result i32)))
(table funcref (elem 0 1))
(func $$t1 (type $$T) (i32.
const 1))
(func $$t2 (type $$T) (i32.
const 2))
(func (export
"callt") (param $$i i32) (result i32)
(call_indirect (type $$T) (local.get $$i))
)
)`);
// ./test/core/func_ptrs.wast:105
assert_return(() => invoke($2, `callt`, [0]), [value(
"i32", 1)]);
// ./test/core/func_ptrs.wast:106
assert_return(() => invoke($2, `callt`, [1]), [value(
"i32", 2)]);