mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 07:21:54 +00:00
Add test cases for the requirements of "gc-aot" feature (#3399)
This commit is contained in:
parent
480ee02615
commit
f729da7656
74
tests/requirement-engineering/README.md
Normal file
74
tests/requirement-engineering/README.md
Normal file
|
@ -0,0 +1,74 @@
|
|||
# Requirement Engineering Tests
|
||||
|
||||
This directory contains requirement engineering test cases. Each directory corresponds to a test case suite for a requirement, comprised of test cases for sub-requirements.
|
||||
|
||||
## How to Run a Requirement Test
|
||||
|
||||
You can use the [all-in-one script](../wamr-test-suites/test_wamr.sh). Here are examples of its usage for testing the "gc-aot" requirement:
|
||||
|
||||
```shell
|
||||
cd ../wamr-test-suites
|
||||
# Run "gc-aot" requirement test on cases corresponding to sub-requirement ids 1, 2, 3
|
||||
./test_wamr.sh -r "gc-aot" 1 2 3
|
||||
# If no sub-requirement id is specified, it will test all cases for this requirement
|
||||
./test_wamr.sh -r "gc-aot"
|
||||
```
|
||||
|
||||
Or, use the helper scripts under a specific requirement directory. Refer to the help information of that helper script:
|
||||
|
||||
```shell
|
||||
cd gc-aot
|
||||
# Build first
|
||||
./build.py
|
||||
|
||||
# Print help info
|
||||
./run.py -h
|
||||
# Test sub-requirement 1, and output to file output.csv
|
||||
./run.py -o output 1
|
||||
# Test all sub-requirements, and output to file output.csv
|
||||
./run.py -o output
|
||||
```
|
||||
|
||||
## How to Add a New Requirement Test
|
||||
|
||||
1. First, create a subdirectory, e.g., `new-requirement`, in this directory. Its name should reflect the requirement, like "gc-aot", and it should contain two helper scripts (`build.py` and `run.py`) to build and run tests under the `new-requirement` sub-directory.
|
||||
|
||||
> If you need to use relative paths in your script, it's fine. The caller Python script [../wamr-test-suites/requirement-engineering-test-script/run_requirement.py](../wamr-test-suites/requirement-engineering-test-script/run_requirement.py) will use `os.chdir()` to change to that sub-directory.
|
||||
|
||||
Start by writing and testing the helper script in that sub-directory, and add anything helpful (for instance, a main function and CLI argument parser).
|
||||
|
||||
2. After finishing the helper script, to let [the all-in-one script `test_wamr.sh`](../wamr-test-suites/test_wamr.sh) -> [../wamr-test-suites/requirement-engineering-test-script/run_requirement.py](../wamr-test-suites/requirement-engineering-test-script/run_requirement.py) invoke the new requirement test, you don't have to modify this script. Just ensure your helper script follows these guidelines:
|
||||
|
||||
- The `build.py` should have a **build** function to build everything necessary for running the requirement tests. The signature should be:
|
||||
|
||||
```Python
|
||||
def build(verbose: bool) -> None:
|
||||
# your implementation
|
||||
```
|
||||
|
||||
- The `run.py` should have a **run** function to execute the test cases. The signature should be:
|
||||
|
||||
```Python
|
||||
def run(output_dir: str, subrequirement_ids: List[int]) -> Dict[int, Dict[Tuple[str, str], bool]]:
|
||||
# your implementation
|
||||
```
|
||||
|
||||
The result should be a dictionary with sub-requirement ids as keys and inner dictionaries as values. The inner dictionary should map tuples of (test_case, test_case_description) to a boolean indicating the test case's success.
|
||||
|
||||
`run.py` should also contain a **SUBREQUIREMENT_DESCRIPTIONS** dictionary, describing each sub-requirement. For example:
|
||||
|
||||
```Python
|
||||
SUBREQUIREMENT_DESCRIPTIONS = {
|
||||
1: ("633", "Modify existing opcodes to conform to the semantics of the GC proposal when needed."),
|
||||
2: ("634", "Supporting new GC opcodes(semantics of GC MVP proposal spec)."),
|
||||
3: ("635", "Supporting new GC opcode(semantics of Binaryen GC spec)."),
|
||||
}
|
||||
```
|
||||
|
||||
> PS: If anything goes wrong during the build and run process, throw an exception and let it crash, so that it can be seen by the top-level caller (shell script).
|
||||
|
||||
3. Now you can test whether [the all-in-one script `test_wamr.sh`](../wamr-test-suites/test_wamr.sh) can correctly execute `new-requirement` and generate a report.
|
||||
|
||||
```shell
|
||||
./test_wamr.sh -r "new-requirement"
|
||||
```
|
74
tests/requirement-engineering/gc-aot/build.py
Normal file
74
tests/requirement-engineering/gc-aot/build.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
#
|
||||
|
||||
import os
|
||||
|
||||
WORK_DIR = os.getcwd()
|
||||
WAMR_DIR = os.path.join(WORK_DIR, "../../../")
|
||||
IWASM_DIR = os.path.join(
|
||||
WORK_DIR, "../../../product-mini/platforms/linux")
|
||||
|
||||
|
||||
def compile_llvm():
|
||||
print("============ compile llvm =============")
|
||||
os.chdir(os.path.join(WAMR_DIR, "wamr-compiler"))
|
||||
exit_status = os.system("./build_llvm.sh")
|
||||
assert exit_status >> 8 == 0, "compile llvm failed, add -v for detail error output"
|
||||
print("============ compile llvm successful =============")
|
||||
|
||||
|
||||
def compile_wamrc(verbose: bool):
|
||||
print("============ compile wamrc =============")
|
||||
os.chdir(os.path.join(WAMR_DIR, "wamr-compiler"))
|
||||
os.system("rm -rf build")
|
||||
os.system("mkdir build")
|
||||
exit_status = os.system(
|
||||
f"cmake -DWAMR_BUILD_GC=1 -B build {'' if verbose else '> /dev/null 2>&1'}")
|
||||
exit_status |= os.system(
|
||||
f"cmake --build build -j {os.cpu_count()} {'' if verbose else '> /dev/null 2>&1'}"
|
||||
)
|
||||
|
||||
assert exit_status >> 8 == 0, "compile wamrc failed, add -v for detail error output"
|
||||
print("============ compile wamrc successful =============")
|
||||
|
||||
|
||||
def compile_iwasm(verbose: bool):
|
||||
print("============ compile iwasm =============")
|
||||
os.chdir(IWASM_DIR)
|
||||
os.system("rm -rf build")
|
||||
os.system("mkdir build")
|
||||
exit_status = os.system(
|
||||
f"cmake -DWAMR_BUILD_AOT=1 -DWAMR_BUILD_GC=1 -DWAMR_BUILD_SPEC_TEST=1 -B build {'' if verbose else '> /dev/null 2>&1'}"
|
||||
)
|
||||
exit_status |= os.system(
|
||||
f"cmake --build build -j {os.cpu_count()} {'' if verbose else '> /dev/null 2>&1'}"
|
||||
)
|
||||
os.chdir(WORK_DIR)
|
||||
|
||||
assert exit_status >> 8 == 0, "compile iwasm failed, add -v for detail error output"
|
||||
print("============ compile iwasm successful =============")
|
||||
|
||||
|
||||
def compile_spec_interpreter():
|
||||
print("============ compile spec interpreter =============")
|
||||
|
||||
os.chdir(WORK_DIR)
|
||||
exit_status = os.system("./build_spec_interpreter.sh")
|
||||
|
||||
assert exit_status >> 8 == 0, "compile spec interpreter failed."
|
||||
print("============ compile spec interpreter successful =============")
|
||||
|
||||
|
||||
def build(verbose: bool) -> None:
|
||||
compile_llvm()
|
||||
compile_wamrc(verbose)
|
||||
compile_iwasm(verbose)
|
||||
compile_spec_interpreter()
|
||||
return
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
build(True)
|
23
tests/requirement-engineering/gc-aot/build_spec_interpreter.sh
Executable file
23
tests/requirement-engineering/gc-aot/build_spec_interpreter.sh
Executable file
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
#
|
||||
|
||||
rm -fr spec
|
||||
# check spec test cases for GC
|
||||
git clone -b main --single-branch https://github.com/WebAssembly/gc.git spec
|
||||
pushd spec
|
||||
|
||||
git restore . && git clean -ffd .
|
||||
# Reset to commit: "[test] Unify the error message."
|
||||
git reset --hard 0caaadc65b5e1910512d8ae228502edcf9d60390
|
||||
git apply ../../../wamr-test-suites/spec-test-script/gc_ignore_cases.patch
|
||||
|
||||
# Set OCaml compiler environment
|
||||
eval $(opam config env)
|
||||
|
||||
echo "compile the reference intepreter"
|
||||
pushd interpreter
|
||||
make
|
||||
popd
|
103
tests/requirement-engineering/gc-aot/run.py
Executable file
103
tests/requirement-engineering/gc-aot/run.py
Executable file
|
@ -0,0 +1,103 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
#
|
||||
|
||||
import os
|
||||
import argparse
|
||||
from typing import List, Dict, Tuple
|
||||
import json
|
||||
|
||||
WORK_DIR = os.getcwd()
|
||||
WAMR_DIR = os.path.join(WORK_DIR, "../../..")
|
||||
IWASM_CMD = os.path.join(
|
||||
WORK_DIR, "../../../product-mini/platforms/linux/build/iwasm")
|
||||
WAMRC_CMD = os.path.join(WORK_DIR, "../../../wamr-compiler/build/wamrc")
|
||||
|
||||
SUBREQUIREMENT_DESCRIPTIONS = {
|
||||
1: ("633", "Modify existing opcodes to conform to the semantics of the GC proposal when needed."),
|
||||
2: ("634", "Supporting new GC opcodes(semantics of GC MVP proposal spec)."),
|
||||
3: ("635", "Supporting new GC opcode(semantics of Binaryen GC spec)."),
|
||||
}
|
||||
|
||||
|
||||
def test_subrequirement(id: int) -> Dict[Tuple[str, str], bool]:
|
||||
print(f"\n============> test gc aot requirement: {id}")
|
||||
|
||||
test_cases = {}
|
||||
result = {}
|
||||
|
||||
with open('test_cases.json') as config_file:
|
||||
config = json.load(config_file)
|
||||
for req in config["sub-requirements"]:
|
||||
if req['req_id'] == id:
|
||||
test_cases = req['cases']
|
||||
break
|
||||
|
||||
for case in test_cases:
|
||||
print(case)
|
||||
print(f"{case['name']}.aot")
|
||||
exit_status = os.system(
|
||||
f"python runtest.py --aot --wast2wasm spec/interpreter/wasm --interpreter {IWASM_CMD} --aot-compiler {WAMRC_CMD} --gc wasm-apps/{case['name']}.wast"
|
||||
)
|
||||
|
||||
if exit_status == 0:
|
||||
result[case['name'], case['description']] = True
|
||||
else:
|
||||
result[case['name'], case['description']] = False
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def run(
|
||||
output_dir: str, subrequirement_ids: List[int]
|
||||
) -> Dict[int, Dict[Tuple[str, str], bool]]:
|
||||
# key: value -> subrequirement id: dict[tuple(test_case_name, test_case_description), is_success]
|
||||
result_dict: Dict[int, Dict[Tuple[str, str], bool]] = {}
|
||||
|
||||
# Default run all subrequirement
|
||||
if not subrequirement_ids:
|
||||
subrequirement_ids = [1, 2, 3]
|
||||
|
||||
for subrequirement_id in subrequirement_ids:
|
||||
if subrequirement_id not in SUBREQUIREMENT_DESCRIPTIONS.keys():
|
||||
print(
|
||||
f"Subrequirement id invalid! It should be a value in {[_ for _ in SUBREQUIREMENT_DESCRIPTIONS.keys()]}"
|
||||
)
|
||||
continue
|
||||
result_dict[subrequirement_id] = test_subrequirement(subrequirement_id)
|
||||
|
||||
return result_dict
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("============> test GC AOT")
|
||||
|
||||
# Create the parser
|
||||
parser = argparse.ArgumentParser(
|
||||
description="A script to process sub-requirement ids, run corresponding test cases, and compile wamrc, iwasm if requested."
|
||||
)
|
||||
|
||||
# The argparse module handles -h and --help by default, no needs to add it
|
||||
# Add an output option `-o` as a flag that, when specified, sets the variable to True
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--output",
|
||||
type=str,
|
||||
required=False,
|
||||
help="Specify the output file name. If provided, the script will write the results to <file name>.csv",
|
||||
)
|
||||
|
||||
# Add positional arguments for integers
|
||||
parser.add_argument(
|
||||
"integers",
|
||||
metavar="N",
|
||||
type=int,
|
||||
nargs="*",
|
||||
help="an integer for the sub-requirement ids",
|
||||
)
|
||||
# Parse arguments
|
||||
args = parser.parse_args()
|
||||
|
||||
run(args.output, args.integers)
|
1589
tests/requirement-engineering/gc-aot/runtest.py
Executable file
1589
tests/requirement-engineering/gc-aot/runtest.py
Executable file
File diff suppressed because it is too large
Load Diff
115
tests/requirement-engineering/gc-aot/test_cases.json
Normal file
115
tests/requirement-engineering/gc-aot/test_cases.json
Normal file
|
@ -0,0 +1,115 @@
|
|||
{
|
||||
"name": "gc-aot-test-suites",
|
||||
"description": "Test suites for GC AOT feature",
|
||||
"sub-requirements": [
|
||||
{
|
||||
"req_id": 1,
|
||||
"issue_id": "633",
|
||||
"desciption": "Modify existing opcodes to conform to the semantics of the GC proposal when needed.",
|
||||
"cases": [
|
||||
{
|
||||
"name": "local_set",
|
||||
"description": "Test opcodes: 'WASM_OP_GET_LOCAL', 'WASM_OP_SET_LOCAL'"
|
||||
},
|
||||
{
|
||||
"name": "local_tee",
|
||||
"description": "Test opcodes: 'WASM_OP_GET_LOCAL', 'WASM_OP_TEE_LOCAL'"
|
||||
},
|
||||
{
|
||||
"name": "table_init",
|
||||
"description": "Test opcodes: 'WASM_OP_TABLE_INIT'"
|
||||
},
|
||||
{
|
||||
"name": "table_grow",
|
||||
"description": "Test opcodes: 'WASM_OP_TABLE_GROW'"
|
||||
},
|
||||
{
|
||||
"name": "table_fill",
|
||||
"description": "Test opcodes: 'WASM_OP_TABLE_FILL'"
|
||||
},
|
||||
{
|
||||
"name": "call_ref",
|
||||
"description": "Test opcodes: 'WASM_OP_CALL_REF'"
|
||||
},
|
||||
{
|
||||
"name": "return_call_ref",
|
||||
"description": "Test opcodes: 'WASM_OP_RETURN_CALL_REF'"
|
||||
},
|
||||
{
|
||||
"name": "table_get",
|
||||
"description": "Test opcodes: 'WASM_OP_TABLE_GET'"
|
||||
},
|
||||
{
|
||||
"name": "table_set",
|
||||
"description": "Test opcodes: 'WASM_OP_TABLE_SET'"
|
||||
},
|
||||
{
|
||||
"name": "select",
|
||||
"description": "Test opcodes: 'WASM_OP_SELECT_T'"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"req_id": 2,
|
||||
"issue_id": "634",
|
||||
"desciption": "Supporting new GC opcodes(semantics of GC MVP proposal spec).",
|
||||
"cases": [
|
||||
{
|
||||
"name": "ref_test",
|
||||
"description": "Test opcodes: 'WASM_OP_TABLE_GET', 'WASM_OP_TABLE_SET', 'WASM_OP_REF_NULL', 'WASM_OP_REF_IS_NULL', 'WASM_OP_REF_TEST', 'WASM_OP_REF_TEST_NULLABLE'"
|
||||
},
|
||||
{
|
||||
"name": "ref_eq",
|
||||
"description": "Test opcodes: 'WASM_OP_REF_EQ', 'WASM_OP_GET_LOCAL'"
|
||||
},
|
||||
{
|
||||
"name": "ref_cast",
|
||||
"description": "Test opcodes: 'WASM_OP_REF_CAST', 'WASM_OP_REF_CAST_NULLABLE', 'WASM_OP_REF_AS_NON_NULL'"
|
||||
},
|
||||
{
|
||||
"name": "type_subtyping",
|
||||
"description": "Test opcodes: 'WASM_OP_CALL_INDIRECT', 'WASM_OP_REF_FUNC'"
|
||||
},
|
||||
{
|
||||
"name": "array",
|
||||
"description": "Test opcodes: 'WASM_OP_ARRAY_NEW', 'WASM_OP_ARRAY_NEW_DEFAULT', 'WASM_OP_ARRAY_NEW_FIXED', 'WASM_OP_ARRAY_NEW_DATA', 'WASM_OP_ARRAY_GET', 'WASM_OP_ARRAY_GET_S', 'WASM_OP_ARRAY_GET_U', 'WASM_OP_ARRAY_SET', 'WASM_OP_ARRAY_LEN'"
|
||||
},
|
||||
{
|
||||
"name": "array_fill",
|
||||
"description": "Test opcodes: 'WASM_OP_ARRAY_FILL'"
|
||||
},
|
||||
{
|
||||
"name": "struct",
|
||||
"description": "Test opcodes: 'WASM_OP_STRUCT_NEW', 'WASM_OP_STRUCT_NEW_DEFAULT', 'WASM_OP_STRUCT_GET', 'WASM_OP_STRUCT_GET_S', 'WASM_OP_STRUCT_GET_U', 'WASM_OP_STRUCT_SET'"
|
||||
},
|
||||
{
|
||||
"name": "i31",
|
||||
"description": "Test opcodes: 'WASM_OP_I31_NEW', 'WASM_OP_I31_GET_S', 'WASM_OP_I31_GET_U'"
|
||||
},
|
||||
{
|
||||
"name": "br_on_cast",
|
||||
"description": "Test opcodes: 'WASM_OP_BR_ON_NULL', 'WASM_OP_BR_ON_CAST'"
|
||||
},
|
||||
{
|
||||
"name": "br_on_cast_fail",
|
||||
"description": "Test opcodes: 'WASM_OP_BR_ON_NON_NULL', 'WASM_OP_BR_ON_CAST_FAIL'"
|
||||
},
|
||||
{
|
||||
"name": "extern",
|
||||
"description": "Test opcodes: 'WASM_OP_ANY_CONVERT_EXTERN', 'WASM_OP_EXTERN_CONVERT_ANY'"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"req_id": 3,
|
||||
"issue_id": "635",
|
||||
"desciption": "Supporting new GC opcode(semantics of Binaryen GC spec).",
|
||||
"cases": [
|
||||
{
|
||||
"name": "array_copy",
|
||||
"description": "Test the opcodes: 'WASM_OP_ARRAY_COPY', 'WASM_OP_SET_LOCAL'"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
308
tests/requirement-engineering/gc-aot/wasm-apps/array.wast
Normal file
308
tests/requirement-engineering/gc-aot/wasm-apps/array.wast
Normal file
|
@ -0,0 +1,308 @@
|
|||
;; Type syntax
|
||||
|
||||
(module
|
||||
(type (array i8))
|
||||
(type (array i16))
|
||||
(type (array i32))
|
||||
(type (array i64))
|
||||
(type (array f32))
|
||||
(type (array f64))
|
||||
(type (array anyref))
|
||||
(type (array (ref struct)))
|
||||
(type (array (ref 0)))
|
||||
(type (array (ref null 1)))
|
||||
(type (array (mut i8)))
|
||||
(type (array (mut i16)))
|
||||
(type (array (mut i32)))
|
||||
(type (array (mut i64)))
|
||||
(type (array (mut i32)))
|
||||
(type (array (mut i64)))
|
||||
(type (array (mut anyref)))
|
||||
(type (array (mut (ref struct))))
|
||||
(type (array (mut (ref 0))))
|
||||
(type (array (mut (ref null i31))))
|
||||
)
|
||||
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type (array (mut (ref null 10))))
|
||||
)
|
||||
"unknown type"
|
||||
)
|
||||
|
||||
|
||||
;; Binding structure
|
||||
|
||||
(module
|
||||
(rec
|
||||
(type $s0 (array (ref $s1)))
|
||||
(type $s1 (array (ref $s0)))
|
||||
)
|
||||
|
||||
(func (param (ref $forward)))
|
||||
|
||||
(type $forward (array i32))
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module (type (array (ref 1))))
|
||||
"unknown type"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (type (array (mut (ref 1)))))
|
||||
"unknown type"
|
||||
)
|
||||
|
||||
|
||||
;; Basic instructions
|
||||
|
||||
(module
|
||||
(type $vec (array f32))
|
||||
(type $mvec (array (mut f32)))
|
||||
|
||||
(global (ref $vec) (array.new $vec (f32.const 1) (i32.const 3)))
|
||||
(global (ref $vec) (array.new_default $vec (i32.const 3)))
|
||||
|
||||
(func $new (export "new") (result (ref $vec))
|
||||
(array.new_default $vec (i32.const 3))
|
||||
)
|
||||
|
||||
(func $get (param $i i32) (param $v (ref $vec)) (result f32)
|
||||
(array.get $vec (local.get $v) (local.get $i))
|
||||
)
|
||||
(func (export "get") (param $i i32) (result f32)
|
||||
(call $get (local.get $i) (call $new))
|
||||
)
|
||||
|
||||
(func $set_get (param $i i32) (param $v (ref $mvec)) (param $y f32) (result f32)
|
||||
(array.set $mvec (local.get $v) (local.get $i) (local.get $y))
|
||||
(array.get $mvec (local.get $v) (local.get $i))
|
||||
)
|
||||
(func (export "set_get") (param $i i32) (param $y f32) (result f32)
|
||||
(call $set_get (local.get $i)
|
||||
(array.new_default $mvec (i32.const 3))
|
||||
(local.get $y)
|
||||
)
|
||||
)
|
||||
|
||||
(func $len (param $v (ref array)) (result i32)
|
||||
(array.len (local.get $v))
|
||||
)
|
||||
(func (export "len") (result i32)
|
||||
(call $len (call $new))
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "new") (ref.array))
|
||||
;; (assert_return (invoke "new") (ref.eq))
|
||||
(assert_return (invoke "get" (i32.const 0)) (f32.const 0))
|
||||
(assert_return (invoke "set_get" (i32.const 1) (f32.const 7)) (f32.const 7))
|
||||
(assert_return (invoke "len") (i32.const 3))
|
||||
|
||||
(assert_trap (invoke "get" (i32.const 10)) "out of bounds array access")
|
||||
(assert_trap (invoke "set_get" (i32.const 10) (f32.const 7)) "out of bounds array access")
|
||||
|
||||
(module
|
||||
(type $vec (array f32))
|
||||
(type $mvec (array (mut f32)))
|
||||
|
||||
(global (ref $vec) (array.new_fixed $vec 2 (f32.const 1) (f32.const 2)))
|
||||
|
||||
(func $new (export "new") (result (ref $vec))
|
||||
(array.new_fixed $vec 2 (f32.const 1) (f32.const 2))
|
||||
)
|
||||
|
||||
(func $get (param $i i32) (param $v (ref $vec)) (result f32)
|
||||
(array.get $vec (local.get $v) (local.get $i))
|
||||
)
|
||||
(func (export "get") (param $i i32) (result f32)
|
||||
(call $get (local.get $i) (call $new))
|
||||
)
|
||||
|
||||
(func $set_get (param $i i32) (param $v (ref $mvec)) (param $y f32) (result f32)
|
||||
(array.set $mvec (local.get $v) (local.get $i) (local.get $y))
|
||||
(array.get $mvec (local.get $v) (local.get $i))
|
||||
)
|
||||
(func (export "set_get") (param $i i32) (param $y f32) (result f32)
|
||||
(call $set_get (local.get $i)
|
||||
(array.new_fixed $mvec 3 (f32.const 1) (f32.const 2) (f32.const 3))
|
||||
(local.get $y)
|
||||
)
|
||||
)
|
||||
|
||||
(func $len (param $v (ref array)) (result i32)
|
||||
(array.len (local.get $v))
|
||||
)
|
||||
(func (export "len") (result i32)
|
||||
(call $len (call $new))
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "new") (ref.array))
|
||||
;; (assert_return (invoke "new") (ref.eq))
|
||||
(assert_return (invoke "get" (i32.const 0)) (f32.const 1))
|
||||
(assert_return (invoke "set_get" (i32.const 1) (f32.const 7)) (f32.const 7))
|
||||
(assert_return (invoke "len") (i32.const 2))
|
||||
|
||||
(assert_trap (invoke "get" (i32.const 10)) "out of bounds array access")
|
||||
(assert_trap (invoke "set_get" (i32.const 10) (f32.const 7)) "out of bounds array access")
|
||||
|
||||
(module
|
||||
(type $vec (array i8))
|
||||
(type $mvec (array (mut i8)))
|
||||
|
||||
(data $d "\00\01\02\03\04")
|
||||
|
||||
(func $new (export "new") (result (ref $vec))
|
||||
(array.new_data $vec $d (i32.const 1) (i32.const 3))
|
||||
)
|
||||
|
||||
(func $get (param $i i32) (param $v (ref $vec)) (result i32)
|
||||
(array.get_u $vec (local.get $v) (local.get $i))
|
||||
)
|
||||
(func (export "get") (param $i i32) (result i32)
|
||||
(call $get (local.get $i) (call $new))
|
||||
)
|
||||
|
||||
(func $set_get (param $i i32) (param $v (ref $mvec)) (param $y i32) (result i32)
|
||||
(array.set $mvec (local.get $v) (local.get $i) (local.get $y))
|
||||
(array.get_u $mvec (local.get $v) (local.get $i))
|
||||
)
|
||||
(func (export "set_get") (param $i i32) (param $y i32) (result i32)
|
||||
(call $set_get (local.get $i)
|
||||
(array.new_data $mvec $d (i32.const 1) (i32.const 3))
|
||||
(local.get $y)
|
||||
)
|
||||
)
|
||||
|
||||
(func $len (param $v (ref array)) (result i32)
|
||||
(array.len (local.get $v))
|
||||
)
|
||||
(func (export "len") (result i32)
|
||||
(call $len (call $new))
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "new") (ref.array))
|
||||
;; (assert_return (invoke "new") (ref.eq))
|
||||
(assert_return (invoke "get" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "set_get" (i32.const 1) (i32.const 7)) (i32.const 7))
|
||||
(assert_return (invoke "len") (i32.const 3))
|
||||
|
||||
(assert_trap (invoke "get" (i32.const 10)) "out of bounds array access")
|
||||
(assert_trap (invoke "set_get" (i32.const 10) (i32.const 7)) "out of bounds array access")
|
||||
|
||||
(; array.new_elem not supported
|
||||
(module
|
||||
(type $bvec (array i8))
|
||||
(type $vec (array (ref $bvec)))
|
||||
(type $mvec (array (mut (ref $bvec))))
|
||||
(type $nvec (array (ref null $bvec)))
|
||||
(type $avec (array (mut anyref)))
|
||||
|
||||
(elem $e (ref $bvec)
|
||||
(array.new $bvec (i32.const 7) (i32.const 3))
|
||||
(array.new_fixed $bvec 2 (i32.const 1) (i32.const 2))
|
||||
)
|
||||
|
||||
(func $new (export "new") (result (ref $vec))
|
||||
(array.new_elem $vec $e (i32.const 0) (i32.const 2))
|
||||
)
|
||||
|
||||
(func $sub1 (result (ref $nvec))
|
||||
(array.new_elem $nvec $e (i32.const 0) (i32.const 2))
|
||||
)
|
||||
(func $sub2 (result (ref $avec))
|
||||
(array.new_elem $avec $e (i32.const 0) (i32.const 2))
|
||||
)
|
||||
|
||||
(func $get (param $i i32) (param $j i32) (param $v (ref $vec)) (result i32)
|
||||
(array.get_u $bvec (array.get $vec (local.get $v) (local.get $i)) (local.get $j))
|
||||
)
|
||||
(func (export "get") (param $i i32) (param $j i32) (result i32)
|
||||
(call $get (local.get $i) (local.get $j) (call $new))
|
||||
)
|
||||
|
||||
(func $set_get (param $i i32) (param $j i32) (param $v (ref $mvec)) (param $y i32) (result i32)
|
||||
(array.set $mvec (local.get $v) (local.get $i) (array.get $mvec (local.get $v) (local.get $y)))
|
||||
(array.get_u $bvec (array.get $mvec (local.get $v) (local.get $i)) (local.get $j))
|
||||
)
|
||||
(func (export "set_get") (param $i i32) (param $j i32) (param $y i32) (result i32)
|
||||
(call $set_get (local.get $i) (local.get $j)
|
||||
(array.new_elem $mvec $e (i32.const 0) (i32.const 2))
|
||||
(local.get $y)
|
||||
)
|
||||
)
|
||||
|
||||
(func $len (param $v (ref array)) (result i32)
|
||||
(array.len (local.get $v))
|
||||
)
|
||||
(func (export "len") (result i32)
|
||||
(call $len (call $new))
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "new") (ref.array))
|
||||
(assert_return (invoke "new") (ref.eq))
|
||||
(assert_return (invoke "get" (i32.const 0) (i32.const 0)) (i32.const 7))
|
||||
(assert_return (invoke "get" (i32.const 1) (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "set_get" (i32.const 0) (i32.const 1) (i32.const 1)) (i32.const 2))
|
||||
(assert_return (invoke "len") (i32.const 2))
|
||||
|
||||
(assert_trap (invoke "get" (i32.const 10) (i32.const 0)) "out of bounds array access")
|
||||
(assert_trap (invoke "set_get" (i32.const 10) (i32.const 0) (i32.const 0)) "out of bounds array access")
|
||||
;)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $a (array i64))
|
||||
(func (export "array.set-immutable") (param $a (ref $a))
|
||||
(array.set $a (local.get $a) (i32.const 0) (i64.const 1))
|
||||
)
|
||||
)
|
||||
"array is immutable"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $bvec (array i8))
|
||||
|
||||
(data $d "\00\01\02\03\04")
|
||||
|
||||
(global (ref $bvec)
|
||||
(array.new_data $bvec $d (i32.const 1) (i32.const 3))
|
||||
)
|
||||
)
|
||||
"constant expression required"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $bvec (array i8))
|
||||
(type $vvec (array (ref $bvec)))
|
||||
|
||||
(elem $e (ref $bvec) (ref.null $bvec))
|
||||
|
||||
(global (ref $vvec)
|
||||
(array.new_elem $vvec $e (i32.const 0) (i32.const 1))
|
||||
)
|
||||
)
|
||||
"constant expression required"
|
||||
)
|
||||
|
||||
|
||||
;; Null dereference
|
||||
|
||||
(module
|
||||
(type $t (array (mut i32)))
|
||||
(func (export "array.get-null")
|
||||
(local (ref null $t)) (drop (array.get $t (local.get 0) (i32.const 0)))
|
||||
)
|
||||
(func (export "array.set-null")
|
||||
(local (ref null $t)) (array.set $t (local.get 0) (i32.const 0) (i32.const 0))
|
||||
)
|
||||
)
|
||||
|
||||
(assert_trap (invoke "array.get-null") "null array")
|
||||
(assert_trap (invoke "array.set-null") "null array")
|
139
tests/requirement-engineering/gc-aot/wasm-apps/array_copy.wast
Normal file
139
tests/requirement-engineering/gc-aot/wasm-apps/array_copy.wast
Normal file
|
@ -0,0 +1,139 @@
|
|||
;; Bulk instructions
|
||||
|
||||
;; invalid uses
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $a (array i8))
|
||||
(type $b (array (mut i8)))
|
||||
|
||||
(func (export "array.copy-immutable") (param $1 (ref $a)) (param $2 (ref $b))
|
||||
(array.copy $a $b (local.get $1) (i32.const 0) (local.get $2) (i32.const 0) (i32.const 0))
|
||||
)
|
||||
)
|
||||
"array is immutable"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $a (array (mut i8)))
|
||||
(type $b (array i16))
|
||||
|
||||
(func (export "array.copy-packed-invalid") (param $1 (ref $a)) (param $2 (ref $b))
|
||||
(array.copy $a $b (local.get $1) (i32.const 0) (local.get $2) (i32.const 0) (i32.const 0))
|
||||
)
|
||||
)
|
||||
"array types do not match"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $a (array (mut i8)))
|
||||
(type $b (array (mut (ref $a))))
|
||||
|
||||
(func (export "array.copy-ref-invalid-1") (param $1 (ref $a)) (param $2 (ref $b))
|
||||
(array.copy $a $b (local.get $1) (i32.const 0) (local.get $2) (i32.const 0) (i32.const 0))
|
||||
)
|
||||
)
|
||||
"array types do not match"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $a (array (mut i8)))
|
||||
(type $b (array (mut (ref $a))))
|
||||
(type $c (array (mut (ref $b))))
|
||||
|
||||
(func (export "array.copy-ref-invalid-1") (param $1 (ref $b)) (param $2 (ref $c))
|
||||
(array.copy $b $c (local.get $1) (i32.const 0) (local.get $2) (i32.const 0) (i32.const 0))
|
||||
)
|
||||
)
|
||||
"array types do not match"
|
||||
)
|
||||
|
||||
(module
|
||||
(type $arr8 (array i8))
|
||||
(type $arr8_mut (array (mut i8)))
|
||||
|
||||
(global $g_arr8 (ref $arr8) (array.new $arr8 (i32.const 10) (i32.const 12)))
|
||||
(global $g_arr8_mut (mut (ref $arr8_mut)) (array.new_default $arr8_mut (i32.const 12)))
|
||||
|
||||
(data $d1 "abcdefghijkl")
|
||||
|
||||
(func (export "array_get_nth") (param $1 i32) (result i32)
|
||||
(array.get_u $arr8_mut (global.get $g_arr8_mut) (local.get $1))
|
||||
)
|
||||
|
||||
(func (export "array_copy-null-left")
|
||||
(array.copy $arr8_mut $arr8 (ref.null $arr8_mut) (i32.const 0) (global.get $g_arr8) (i32.const 0) (i32.const 0))
|
||||
)
|
||||
|
||||
(func (export "array_copy-null-right")
|
||||
(array.copy $arr8_mut $arr8 (global.get $g_arr8_mut) (i32.const 0) (ref.null $arr8) (i32.const 0) (i32.const 0))
|
||||
)
|
||||
|
||||
(func (export "array_copy") (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(array.copy $arr8_mut $arr8 (global.get $g_arr8_mut) (local.get $1) (global.get $g_arr8) (local.get $2) (local.get $3))
|
||||
)
|
||||
|
||||
(func (export "array_copy_overlap_test-1")
|
||||
(local $1 (ref $arr8_mut))
|
||||
(array.new_data $arr8_mut $d1 (i32.const 0) (i32.const 12))
|
||||
(local.set $1)
|
||||
(array.copy $arr8_mut $arr8_mut (local.get $1) (i32.const 1) (local.get $1) (i32.const 0) (i32.const 11))
|
||||
(global.set $g_arr8_mut (local.get $1))
|
||||
)
|
||||
|
||||
(func (export "array_copy_overlap_test-2")
|
||||
(local $1 (ref $arr8_mut))
|
||||
(array.new_data $arr8_mut $d1 (i32.const 0) (i32.const 12))
|
||||
(local.set $1)
|
||||
(array.copy $arr8_mut $arr8_mut (local.get $1) (i32.const 0) (local.get $1) (i32.const 1) (i32.const 11))
|
||||
(global.set $g_arr8_mut (local.get $1))
|
||||
)
|
||||
)
|
||||
|
||||
;; null array argument traps
|
||||
(assert_trap (invoke "array_copy-null-left") "null array reference")
|
||||
(assert_trap (invoke "array_copy-null-right") "null array reference")
|
||||
|
||||
;; OOB initial index traps
|
||||
(assert_trap (invoke "array_copy" (i32.const 13) (i32.const 0) (i32.const 0)) "out of bounds array access")
|
||||
(assert_trap (invoke "array_copy" (i32.const 0) (i32.const 13) (i32.const 0)) "out of bounds array access")
|
||||
|
||||
;; OOB length traps
|
||||
(assert_trap (invoke "array_copy" (i32.const 0) (i32.const 0) (i32.const 13)) "out of bounds array access")
|
||||
(assert_trap (invoke "array_copy" (i32.const 0) (i32.const 0) (i32.const 13)) "out of bounds array access")
|
||||
|
||||
;; start index = array size, len = 0 doesn't trap
|
||||
(assert_return (invoke "array_copy" (i32.const 12) (i32.const 0) (i32.const 0)))
|
||||
(assert_return (invoke "array_copy" (i32.const 0) (i32.const 12) (i32.const 0)))
|
||||
|
||||
;; check arrays were not modified
|
||||
(assert_return (invoke "array_get_nth" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 5)) (i32.const 0))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 11)) (i32.const 0))
|
||||
(assert_trap (invoke "array_get_nth" (i32.const 12)) "out of bounds array access")
|
||||
|
||||
;; normal case
|
||||
(assert_return (invoke "array_copy" (i32.const 0) (i32.const 0) (i32.const 2)))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 0)) (i32.const 10))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 1)) (i32.const 10))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 2)) (i32.const 0))
|
||||
|
||||
;; test that overlapping array.copy works as if intermediate copy taken
|
||||
(assert_return (invoke "array_copy_overlap_test-1"))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 0)) (i32.const 97))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 1)) (i32.const 97))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 2)) (i32.const 98))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 5)) (i32.const 101))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 10)) (i32.const 106))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 11)) (i32.const 107))
|
||||
|
||||
(assert_return (invoke "array_copy_overlap_test-2"))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 0)) (i32.const 98))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 1)) (i32.const 99))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 5)) (i32.const 103))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 9)) (i32.const 107))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 10)) (i32.const 108))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 11)) (i32.const 108))
|
|
@ -0,0 +1,81 @@
|
|||
;; Bulk instructions
|
||||
|
||||
;; invalid uses
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $a (array i8))
|
||||
|
||||
(func (export "array.fill-immutable") (param $1 (ref $a)) (param $2 i32)
|
||||
(array.fill $a (local.get $1) (i32.const 0) (local.get $2) (i32.const 0))
|
||||
)
|
||||
)
|
||||
"array is immutable"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $a (array (mut i8)))
|
||||
|
||||
(func (export "array.fill-invalid-1") (param $1 (ref $a)) (param $2 funcref)
|
||||
(array.fill $a (local.get $1) (i32.const 0) (local.get $2) (i32.const 0))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $b (array (mut funcref)))
|
||||
|
||||
(func (export "array.fill-invalid-1") (param $1 (ref $b)) (param $2 i32)
|
||||
(array.fill $b (local.get $1) (i32.const 0) (local.get $2) (i32.const 0))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(module
|
||||
(type $arr8 (array i8))
|
||||
(type $arr8_mut (array (mut i8)))
|
||||
|
||||
(global $g_arr8 (ref $arr8) (array.new $arr8 (i32.const 10) (i32.const 12)))
|
||||
(global $g_arr8_mut (mut (ref $arr8_mut)) (array.new_default $arr8_mut (i32.const 12)))
|
||||
|
||||
(func (export "array_get_nth") (param $1 i32) (result i32)
|
||||
(array.get_u $arr8_mut (global.get $g_arr8_mut) (local.get $1))
|
||||
)
|
||||
|
||||
(func (export "array_fill-null")
|
||||
(array.fill $arr8_mut (ref.null $arr8_mut) (i32.const 0) (i32.const 0) (i32.const 0))
|
||||
)
|
||||
|
||||
(func (export "array_fill") (param $1 i32) (param $2 i32) (param $3 i32)
|
||||
(array.fill $arr8_mut (global.get $g_arr8_mut) (local.get $1) (local.get $2) (local.get $3))
|
||||
)
|
||||
)
|
||||
|
||||
;; null array argument traps
|
||||
(assert_trap (invoke "array_fill-null") "null array reference")
|
||||
|
||||
;; OOB initial index traps
|
||||
(assert_trap (invoke "array_fill" (i32.const 13) (i32.const 0) (i32.const 0)) "out of bounds array access")
|
||||
|
||||
;; OOB length traps
|
||||
(assert_trap (invoke "array_fill" (i32.const 0) (i32.const 0) (i32.const 13)) "out of bounds array access")
|
||||
|
||||
;; start index = array size, len = 0 doesn't trap
|
||||
(assert_return (invoke "array_fill" (i32.const 12) (i32.const 0) (i32.const 0)))
|
||||
|
||||
;; check arrays were not modified
|
||||
(assert_return (invoke "array_get_nth" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 5)) (i32.const 0))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 11)) (i32.const 0))
|
||||
(assert_trap (invoke "array_get_nth" (i32.const 12)) "out of bounds array access")
|
||||
|
||||
;; normal case
|
||||
(assert_return (invoke "array_fill" (i32.const 2) (i32.const 11) (i32.const 2)))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 1)) (i32.const 0))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 2)) (i32.const 11))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 3)) (i32.const 11))
|
||||
(assert_return (invoke "array_get_nth" (i32.const 4)) (i32.const 0))
|
267
tests/requirement-engineering/gc-aot/wasm-apps/br_on_cast.wast
Normal file
267
tests/requirement-engineering/gc-aot/wasm-apps/br_on_cast.wast
Normal file
|
@ -0,0 +1,267 @@
|
|||
;; Abstract Types
|
||||
|
||||
(module
|
||||
(type $ft (func (result i32)))
|
||||
(type $st (struct (field i16)))
|
||||
(type $at (array i8))
|
||||
|
||||
(table 10 anyref)
|
||||
|
||||
(elem declare func $f)
|
||||
(func $f (result i32) (i32.const 9))
|
||||
|
||||
(func (export "init") (param $x externref)
|
||||
(table.set (i32.const 0) (ref.null any))
|
||||
(table.set (i32.const 1) (ref.i31 (i32.const 7)))
|
||||
(table.set (i32.const 2) (struct.new $st (i32.const 6)))
|
||||
(table.set (i32.const 3) (array.new $at (i32.const 5) (i32.const 3)))
|
||||
(table.set (i32.const 4) (any.convert_extern (local.get $x)))
|
||||
)
|
||||
|
||||
(func (export "br_on_null") (param $i i32) (result i32)
|
||||
(block $l
|
||||
(br_on_null $l (table.get (local.get $i)))
|
||||
(return (i32.const -1))
|
||||
)
|
||||
(i32.const 0)
|
||||
)
|
||||
(func (export "br_on_i31") (param $i i32) (result i32)
|
||||
(block $l (result (ref i31))
|
||||
(br_on_cast $l anyref (ref i31) (table.get (local.get $i)))
|
||||
(return (i32.const -1))
|
||||
)
|
||||
(i31.get_u)
|
||||
)
|
||||
(func (export "br_on_struct") (param $i i32) (result i32)
|
||||
(block $l (result (ref struct))
|
||||
(br_on_cast $l anyref (ref struct) (table.get (local.get $i)))
|
||||
(return (i32.const -1))
|
||||
)
|
||||
(block $l2 (param structref) (result (ref $st))
|
||||
(block $l3 (param structref) (result (ref $at))
|
||||
(br_on_cast $l2 structref (ref $st))
|
||||
(br_on_cast $l3 anyref (ref $at))
|
||||
(return (i32.const -2))
|
||||
)
|
||||
(return (array.get_u $at (i32.const 0)))
|
||||
)
|
||||
(struct.get_s $st 0)
|
||||
)
|
||||
(func (export "br_on_array") (param $i i32) (result i32)
|
||||
(block $l (result (ref array))
|
||||
(br_on_cast $l anyref (ref array) (table.get (local.get $i)))
|
||||
(return (i32.const -1))
|
||||
)
|
||||
(array.len)
|
||||
)
|
||||
|
||||
(func (export "null-diff") (param $i i32) (result i32)
|
||||
(block $l (result (ref null struct))
|
||||
(block (result (ref any))
|
||||
(br_on_cast $l (ref null any) (ref null struct) (table.get (local.get $i)))
|
||||
)
|
||||
(return (i32.const 0))
|
||||
)
|
||||
(return (i32.const 1))
|
||||
)
|
||||
)
|
||||
|
||||
(invoke "init" (ref.extern 0))
|
||||
|
||||
(assert_return (invoke "br_on_null" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "br_on_null" (i32.const 1)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_null" (i32.const 2)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_null" (i32.const 3)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_null" (i32.const 4)) (i32.const -1))
|
||||
|
||||
(assert_return (invoke "br_on_i31" (i32.const 0)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_i31" (i32.const 1)) (i32.const 7))
|
||||
(assert_return (invoke "br_on_i31" (i32.const 2)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_i31" (i32.const 3)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_i31" (i32.const 4)) (i32.const -1))
|
||||
|
||||
(assert_return (invoke "br_on_struct" (i32.const 0)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_struct" (i32.const 1)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_struct" (i32.const 2)) (i32.const 6))
|
||||
(assert_return (invoke "br_on_struct" (i32.const 3)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_struct" (i32.const 4)) (i32.const -1))
|
||||
|
||||
(assert_return (invoke "br_on_array" (i32.const 0)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_array" (i32.const 1)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_array" (i32.const 2)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_array" (i32.const 3)) (i32.const 3))
|
||||
(assert_return (invoke "br_on_array" (i32.const 4)) (i32.const -1))
|
||||
|
||||
(assert_return (invoke "null-diff" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "null-diff" (i32.const 1)) (i32.const 0))
|
||||
(assert_return (invoke "null-diff" (i32.const 2)) (i32.const 1))
|
||||
(assert_return (invoke "null-diff" (i32.const 3)) (i32.const 0))
|
||||
(assert_return (invoke "null-diff" (i32.const 4)) (i32.const 0))
|
||||
|
||||
|
||||
;; Concrete Types
|
||||
|
||||
(module
|
||||
(type $t0 (sub (struct)))
|
||||
(type $t1 (sub $t0 (struct (field i32))))
|
||||
(type $t1' (sub $t0 (struct (field i32))))
|
||||
(type $t2 (sub $t1 (struct (field i32 i32))))
|
||||
(type $t2' (sub $t1' (struct (field i32 i32))))
|
||||
(type $t3 (sub $t0 (struct (field i32 i32))))
|
||||
(type $t0' (sub $t0 (struct)))
|
||||
(type $t4 (sub $t0' (struct (field i32 i32))))
|
||||
|
||||
(table 20 structref)
|
||||
|
||||
(func $init
|
||||
(table.set (i32.const 0) (struct.new_default $t0))
|
||||
(table.set (i32.const 10) (struct.new_default $t0'))
|
||||
(table.set (i32.const 1) (struct.new_default $t1))
|
||||
(table.set (i32.const 11) (struct.new_default $t1'))
|
||||
(table.set (i32.const 2) (struct.new_default $t2))
|
||||
(table.set (i32.const 12) (struct.new_default $t2'))
|
||||
(table.set (i32.const 3) (struct.new_default $t3))
|
||||
(table.set (i32.const 4) (struct.new_default $t4))
|
||||
)
|
||||
|
||||
(func (export "test-sub")
|
||||
(call $init)
|
||||
(block $l (result structref)
|
||||
;; must succeed
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t0) (ref.null struct))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 0)))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 1)))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 2)))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 3)))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 4)))))
|
||||
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t1) (ref.null struct))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t1) (table.get (i32.const 1)))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t1) (table.get (i32.const 2)))))
|
||||
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t2) (ref.null struct))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t2) (table.get (i32.const 2)))))
|
||||
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t3) (ref.null struct))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t3) (table.get (i32.const 3)))))
|
||||
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t4) (ref.null struct))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t4) (table.get (i32.const 4)))))
|
||||
|
||||
;; must not succeed
|
||||
(br_on_cast $l anyref (ref $t1) (table.get (i32.const 0)))
|
||||
(br_on_cast $l anyref (ref $t1) (table.get (i32.const 3)))
|
||||
(br_on_cast $l anyref (ref $t1) (table.get (i32.const 4)))
|
||||
|
||||
(br_on_cast $l anyref (ref $t2) (table.get (i32.const 0)))
|
||||
(br_on_cast $l anyref (ref $t2) (table.get (i32.const 1)))
|
||||
(br_on_cast $l anyref (ref $t2) (table.get (i32.const 3)))
|
||||
(br_on_cast $l anyref (ref $t2) (table.get (i32.const 4)))
|
||||
|
||||
(br_on_cast $l anyref (ref $t3) (table.get (i32.const 0)))
|
||||
(br_on_cast $l anyref (ref $t3) (table.get (i32.const 1)))
|
||||
(br_on_cast $l anyref (ref $t3) (table.get (i32.const 2)))
|
||||
(br_on_cast $l anyref (ref $t3) (table.get (i32.const 4)))
|
||||
|
||||
(br_on_cast $l anyref (ref $t4) (table.get (i32.const 0)))
|
||||
(br_on_cast $l anyref (ref $t4) (table.get (i32.const 1)))
|
||||
(br_on_cast $l anyref (ref $t4) (table.get (i32.const 2)))
|
||||
(br_on_cast $l anyref (ref $t4) (table.get (i32.const 3)))
|
||||
|
||||
(return)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
|
||||
(func (export "test-canon")
|
||||
(call $init)
|
||||
(block $l
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t0') (table.get (i32.const 0)))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t0') (table.get (i32.const 1)))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t0') (table.get (i32.const 2)))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t0') (table.get (i32.const 3)))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t0') (table.get (i32.const 4)))))
|
||||
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 10)))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 11)))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 12)))))
|
||||
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t1') (table.get (i32.const 1)))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t1') (table.get (i32.const 2)))))
|
||||
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t1) (table.get (i32.const 11)))))
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t1) (table.get (i32.const 12)))))
|
||||
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t2') (table.get (i32.const 2)))))
|
||||
|
||||
(drop (block (result structref) (br_on_cast 0 structref (ref $t2) (table.get (i32.const 12)))))
|
||||
|
||||
(return)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(invoke "test-sub")
|
||||
(invoke "test-canon")
|
||||
|
||||
|
||||
;; Cases of nullability
|
||||
|
||||
(module
|
||||
(type $t (struct))
|
||||
|
||||
(func (param (ref any)) (result (ref $t))
|
||||
(block (result (ref any)) (br_on_cast 1 (ref any) (ref $t) (local.get 0))) (unreachable)
|
||||
)
|
||||
(func (param (ref null any)) (result (ref $t))
|
||||
(block (result (ref null any)) (br_on_cast 1 (ref null any) (ref $t) (local.get 0))) (unreachable)
|
||||
)
|
||||
(func (param (ref null any)) (result (ref null $t))
|
||||
(block (result (ref null any)) (br_on_cast 1 (ref null any) (ref null $t) (local.get 0))) (unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (struct))
|
||||
(func (param (ref any)) (result (ref $t))
|
||||
(block (result (ref any)) (br_on_cast 1 (ref null any) (ref null $t) (local.get 0))) (unreachable)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (struct))
|
||||
(func (param (ref any)) (result (ref null $t))
|
||||
(block (result (ref any)) (br_on_cast 1 (ref any) (ref null $t) (local.get 0))) (unreachable)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (struct))
|
||||
(func (param (ref null any)) (result (ref $t))
|
||||
(block (result (ref any)) (br_on_cast 1 (ref null any) (ref $t) (local.get 0))) (unreachable)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func (result anyref)
|
||||
(br_on_cast 0 eqref anyref (unreachable))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func (result anyref)
|
||||
(br_on_cast 0 structref arrayref (unreachable))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
|
@ -0,0 +1,282 @@
|
|||
;; Abstract Types
|
||||
|
||||
(module
|
||||
(type $ft (func (result i32)))
|
||||
(type $st (struct (field i16)))
|
||||
(type $at (array i8))
|
||||
|
||||
(table 10 anyref)
|
||||
|
||||
(elem declare func $f)
|
||||
(func $f (result i32) (i32.const 9))
|
||||
|
||||
(func (export "init") (param $x externref)
|
||||
(table.set (i32.const 0) (ref.null any))
|
||||
(table.set (i32.const 1) (ref.i31 (i32.const 7)))
|
||||
(table.set (i32.const 2) (struct.new $st (i32.const 6)))
|
||||
(table.set (i32.const 3) (array.new $at (i32.const 5) (i32.const 3)))
|
||||
(table.set (i32.const 4) (any.convert_extern (local.get $x)))
|
||||
)
|
||||
|
||||
(func (export "br_on_non_null") (param $i i32) (result i32)
|
||||
(block $l (result (ref any))
|
||||
(br_on_non_null $l (table.get (local.get $i)))
|
||||
(return (i32.const 0))
|
||||
)
|
||||
(return (i32.const -1))
|
||||
)
|
||||
(func (export "br_on_non_i31") (param $i i32) (result i32)
|
||||
(block $l (result anyref)
|
||||
(br_on_cast_fail $l anyref (ref i31) (table.get (local.get $i)))
|
||||
(return (i31.get_u))
|
||||
)
|
||||
(return (i32.const -1))
|
||||
)
|
||||
(func (export "br_on_non_struct") (param $i i32) (result i32)
|
||||
(block $l (result anyref)
|
||||
(br_on_cast_fail $l anyref (ref struct) (table.get (local.get $i)))
|
||||
(block $l2 (param structref) (result (ref $st))
|
||||
(block $l3 (param structref) (result (ref $at))
|
||||
(br_on_cast $l2 structref (ref $st))
|
||||
(br_on_cast $l3 anyref (ref $at))
|
||||
(return (i32.const -2))
|
||||
)
|
||||
(return (array.get_u $at (i32.const 0)))
|
||||
)
|
||||
(return (struct.get_s $st 0))
|
||||
)
|
||||
(return (i32.const -1))
|
||||
)
|
||||
(func (export "br_on_non_array") (param $i i32) (result i32)
|
||||
(block $l (result anyref)
|
||||
(br_on_cast_fail $l anyref (ref array) (table.get (local.get $i)))
|
||||
(return (array.len))
|
||||
)
|
||||
(return (i32.const -1))
|
||||
)
|
||||
|
||||
(func (export "null-diff") (param $i i32) (result i32)
|
||||
(block $l (result (ref any))
|
||||
(block (result (ref null struct))
|
||||
(br_on_cast_fail $l (ref null any) (ref null struct) (table.get (local.get $i)))
|
||||
)
|
||||
(return (i32.const 1))
|
||||
)
|
||||
(return (i32.const 0))
|
||||
)
|
||||
)
|
||||
|
||||
(invoke "init" (ref.extern 0))
|
||||
|
||||
(assert_return (invoke "br_on_non_null" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "br_on_non_null" (i32.const 1)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_non_null" (i32.const 2)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_non_null" (i32.const 3)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_non_null" (i32.const 4)) (i32.const -1))
|
||||
|
||||
(assert_return (invoke "br_on_non_i31" (i32.const 0)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_non_i31" (i32.const 1)) (i32.const 7))
|
||||
(assert_return (invoke "br_on_non_i31" (i32.const 2)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_non_i31" (i32.const 3)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_non_i31" (i32.const 4)) (i32.const -1))
|
||||
|
||||
(assert_return (invoke "br_on_non_struct" (i32.const 0)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_non_struct" (i32.const 1)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_non_struct" (i32.const 2)) (i32.const 6))
|
||||
(assert_return (invoke "br_on_non_struct" (i32.const 3)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_non_struct" (i32.const 4)) (i32.const -1))
|
||||
|
||||
(assert_return (invoke "br_on_non_array" (i32.const 0)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_non_array" (i32.const 1)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_non_array" (i32.const 2)) (i32.const -1))
|
||||
(assert_return (invoke "br_on_non_array" (i32.const 3)) (i32.const 3))
|
||||
(assert_return (invoke "br_on_non_array" (i32.const 4)) (i32.const -1))
|
||||
|
||||
(assert_return (invoke "null-diff" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "null-diff" (i32.const 1)) (i32.const 0))
|
||||
(assert_return (invoke "null-diff" (i32.const 2)) (i32.const 1))
|
||||
(assert_return (invoke "null-diff" (i32.const 3)) (i32.const 0))
|
||||
(assert_return (invoke "null-diff" (i32.const 4)) (i32.const 0))
|
||||
|
||||
|
||||
;; Concrete Types
|
||||
|
||||
(module
|
||||
(type $t0 (sub (struct)))
|
||||
(type $t1 (sub $t0 (struct (field i32))))
|
||||
(type $t1' (sub $t0 (struct (field i32))))
|
||||
(type $t2 (sub $t1 (struct (field i32 i32))))
|
||||
(type $t2' (sub $t1' (struct (field i32 i32))))
|
||||
(type $t3 (sub $t0 (struct (field i32 i32))))
|
||||
(type $t0' (sub $t0 (struct)))
|
||||
(type $t4 (sub $t0' (struct (field i32 i32))))
|
||||
|
||||
(table 20 structref)
|
||||
|
||||
(func $init
|
||||
(table.set (i32.const 0) (struct.new_default $t0))
|
||||
(table.set (i32.const 10) (struct.new_default $t0))
|
||||
(table.set (i32.const 1) (struct.new_default $t1))
|
||||
(table.set (i32.const 11) (struct.new_default $t1'))
|
||||
(table.set (i32.const 2) (struct.new_default $t2))
|
||||
(table.set (i32.const 12) (struct.new_default $t2'))
|
||||
(table.set (i32.const 3) (struct.new_default $t3 ))
|
||||
(table.set (i32.const 4) (struct.new_default $t4))
|
||||
)
|
||||
|
||||
(func (export "test-sub")
|
||||
(call $init)
|
||||
(block $l (result structref)
|
||||
;; must not succeed
|
||||
(br_on_cast_fail $l structref (ref null $t0) (ref.null struct))
|
||||
(br_on_cast_fail $l structref (ref null $t0) (table.get (i32.const 0)))
|
||||
(br_on_cast_fail $l structref (ref null $t0) (table.get (i32.const 1)))
|
||||
(br_on_cast_fail $l structref (ref null $t0) (table.get (i32.const 2)))
|
||||
(br_on_cast_fail $l structref (ref null $t0) (table.get (i32.const 3)))
|
||||
(br_on_cast_fail $l structref (ref null $t0) (table.get (i32.const 4)))
|
||||
(br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 0)))
|
||||
(br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 1)))
|
||||
(br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 2)))
|
||||
(br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 3)))
|
||||
(br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 4)))
|
||||
|
||||
(br_on_cast_fail $l structref (ref null $t1) (ref.null struct))
|
||||
(br_on_cast_fail $l structref (ref null $t1) (table.get (i32.const 1)))
|
||||
(br_on_cast_fail $l structref (ref null $t1) (table.get (i32.const 2)))
|
||||
(br_on_cast_fail $l structref (ref $t1) (table.get (i32.const 1)))
|
||||
(br_on_cast_fail $l structref (ref $t1) (table.get (i32.const 2)))
|
||||
|
||||
(br_on_cast_fail $l structref (ref null $t2) (ref.null struct))
|
||||
(br_on_cast_fail $l structref (ref null $t2) (table.get (i32.const 2)))
|
||||
(br_on_cast_fail $l structref (ref $t2) (table.get (i32.const 2)))
|
||||
|
||||
(br_on_cast_fail $l structref (ref null $t3) (ref.null struct))
|
||||
(br_on_cast_fail $l structref (ref null $t3) (table.get (i32.const 3)))
|
||||
(br_on_cast_fail $l structref (ref $t3) (table.get (i32.const 3)))
|
||||
|
||||
(br_on_cast_fail $l structref (ref null $t4) (ref.null struct))
|
||||
(br_on_cast_fail $l structref (ref null $t4) (table.get (i32.const 4)))
|
||||
(br_on_cast_fail $l structref (ref $t4) (table.get (i32.const 4)))
|
||||
|
||||
;; must succeed
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t0) (ref.null struct))))
|
||||
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t1) (ref.null struct))))
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t1) (table.get (i32.const 0)))))
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t1) (table.get (i32.const 3)))))
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t1) (table.get (i32.const 4)))))
|
||||
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t2) (ref.null struct))))
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t2) (table.get (i32.const 0)))))
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t2) (table.get (i32.const 1)))))
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t2) (table.get (i32.const 3)))))
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t2) (table.get (i32.const 4)))))
|
||||
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t3) (ref.null struct))))
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t3) (table.get (i32.const 0)))))
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t3) (table.get (i32.const 1)))))
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t3) (table.get (i32.const 2)))))
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t3) (table.get (i32.const 4)))))
|
||||
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t4) (ref.null struct))))
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t4) (table.get (i32.const 0)))))
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t4) (table.get (i32.const 1)))))
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t4) (table.get (i32.const 2)))))
|
||||
(drop (block (result structref) (br_on_cast_fail 0 structref (ref $t4) (table.get (i32.const 3)))))
|
||||
|
||||
(return)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
|
||||
(func (export "test-canon")
|
||||
(call $init)
|
||||
(block $l (result structref)
|
||||
(br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 0)))
|
||||
(br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 1)))
|
||||
(br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 2)))
|
||||
(br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 3)))
|
||||
(br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 4)))
|
||||
(br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 10)))
|
||||
(br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 11)))
|
||||
(br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 12)))
|
||||
|
||||
(br_on_cast_fail $l structref (ref $t1') (table.get (i32.const 1)))
|
||||
(br_on_cast_fail $l structref (ref $t1') (table.get (i32.const 2)))
|
||||
|
||||
(br_on_cast_fail $l structref (ref $t1) (table.get (i32.const 11)))
|
||||
(br_on_cast_fail $l structref (ref $t1) (table.get (i32.const 12)))
|
||||
|
||||
(br_on_cast_fail $l structref (ref $t2') (table.get (i32.const 2)))
|
||||
|
||||
(br_on_cast_fail $l structref (ref $t2) (table.get (i32.const 12)))
|
||||
|
||||
(return)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(invoke "test-sub")
|
||||
(invoke "test-canon")
|
||||
|
||||
|
||||
;; Cases of nullability
|
||||
|
||||
(module
|
||||
(type $t (struct))
|
||||
|
||||
(func (param (ref any)) (result (ref any))
|
||||
(block (result (ref $t)) (br_on_cast_fail 1 (ref any) (ref $t) (local.get 0)))
|
||||
)
|
||||
(func (param (ref null any)) (result (ref null any))
|
||||
(block (result (ref $t)) (br_on_cast_fail 1 (ref null any) (ref $t) (local.get 0)))
|
||||
)
|
||||
(func (param (ref null any)) (result (ref null any))
|
||||
(block (result (ref null $t)) (br_on_cast_fail 1 (ref null any) (ref null $t) (local.get 0)))
|
||||
)
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (struct))
|
||||
(func (param (ref any)) (result (ref any))
|
||||
(block (result (ref $t)) (br_on_cast_fail 1 (ref null any) (ref null $t) (local.get 0)))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (struct))
|
||||
(func (param (ref any)) (result (ref any))
|
||||
(block (result (ref null $t)) (br_on_cast_fail 1 (ref any) (ref null $t) (local.get 0))) (ref.as_non_null)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (struct))
|
||||
(func (param (ref null any)) (result (ref any))
|
||||
(block (result (ref $t)) (br_on_cast_fail 1 (ref null any) (ref $t) (local.get 0)))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func (result anyref)
|
||||
(br_on_cast_fail 0 eqref anyref (unreachable))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func (result anyref)
|
||||
(br_on_cast_fail 0 structref arrayref (unreachable))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
208
tests/requirement-engineering/gc-aot/wasm-apps/call_ref.wast
Normal file
208
tests/requirement-engineering/gc-aot/wasm-apps/call_ref.wast
Normal file
|
@ -0,0 +1,208 @@
|
|||
(module
|
||||
(type $ii (func (param i32) (result i32)))
|
||||
|
||||
(func $apply (param $f (ref $ii)) (param $x i32) (result i32)
|
||||
(call_ref $ii (local.get $x) (local.get $f))
|
||||
)
|
||||
|
||||
(func $f (type $ii) (i32.mul (local.get 0) (local.get 0)))
|
||||
(func $g (type $ii) (i32.sub (i32.const 0) (local.get 0)))
|
||||
|
||||
(elem declare func $f $g)
|
||||
|
||||
(func (export "run") (param $x i32) (result i32)
|
||||
(local $rf (ref null $ii))
|
||||
(local $rg (ref null $ii))
|
||||
(local.set $rf (ref.func $f))
|
||||
(local.set $rg (ref.func $g))
|
||||
(call_ref $ii (call_ref $ii (local.get $x) (local.get $rf)) (local.get $rg))
|
||||
)
|
||||
|
||||
(func (export "null") (result i32)
|
||||
(call_ref $ii (i32.const 1) (ref.null $ii))
|
||||
)
|
||||
|
||||
;; Recursion
|
||||
|
||||
(type $ll (func (param i64) (result i64)))
|
||||
(type $lll (func (param i64 i64) (result i64)))
|
||||
|
||||
(elem declare func $fac)
|
||||
(global $fac (ref $ll) (ref.func $fac))
|
||||
|
||||
(func $fac (export "fac") (type $ll)
|
||||
(if (result i64) (i64.eqz (local.get 0))
|
||||
(then (i64.const 1))
|
||||
(else
|
||||
(i64.mul
|
||||
(local.get 0)
|
||||
(call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $fac))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(elem declare func $fac-acc)
|
||||
(global $fac-acc (ref $lll) (ref.func $fac-acc))
|
||||
|
||||
(func $fac-acc (export "fac-acc") (type $lll)
|
||||
(if (result i64) (i64.eqz (local.get 0))
|
||||
(then (local.get 1))
|
||||
(else
|
||||
(call_ref $lll
|
||||
(i64.sub (local.get 0) (i64.const 1))
|
||||
(i64.mul (local.get 0) (local.get 1))
|
||||
(global.get $fac-acc)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(elem declare func $fib)
|
||||
(global $fib (ref $ll) (ref.func $fib))
|
||||
|
||||
(func $fib (export "fib") (type $ll)
|
||||
(if (result i64) (i64.le_u (local.get 0) (i64.const 1))
|
||||
(then (i64.const 1))
|
||||
(else
|
||||
(i64.add
|
||||
(call_ref $ll (i64.sub (local.get 0) (i64.const 2)) (global.get $fib))
|
||||
(call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $fib))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(elem declare func $even $odd)
|
||||
(global $even (ref $ll) (ref.func $even))
|
||||
(global $odd (ref $ll) (ref.func $odd))
|
||||
|
||||
(func $even (export "even") (type $ll)
|
||||
(if (result i64) (i64.eqz (local.get 0))
|
||||
(then (i64.const 44))
|
||||
(else (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $odd)))
|
||||
)
|
||||
)
|
||||
(func $odd (export "odd") (type $ll)
|
||||
(if (result i64) (i64.eqz (local.get 0))
|
||||
(then (i64.const 99))
|
||||
(else (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $even)))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "run" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "run" (i32.const 3)) (i32.const -9))
|
||||
|
||||
(assert_trap (invoke "null") "null function")
|
||||
|
||||
(assert_return (invoke "fac" (i64.const 0)) (i64.const 1))
|
||||
(assert_return (invoke "fac" (i64.const 1)) (i64.const 1))
|
||||
(assert_return (invoke "fac" (i64.const 5)) (i64.const 120))
|
||||
(assert_return (invoke "fac" (i64.const 25)) (i64.const 7034535277573963776))
|
||||
(assert_return (invoke "fac-acc" (i64.const 0) (i64.const 1)) (i64.const 1))
|
||||
(assert_return (invoke "fac-acc" (i64.const 1) (i64.const 1)) (i64.const 1))
|
||||
(assert_return (invoke "fac-acc" (i64.const 5) (i64.const 1)) (i64.const 120))
|
||||
(assert_return
|
||||
(invoke "fac-acc" (i64.const 25) (i64.const 1))
|
||||
(i64.const 7034535277573963776)
|
||||
)
|
||||
|
||||
(assert_return (invoke "fib" (i64.const 0)) (i64.const 1))
|
||||
(assert_return (invoke "fib" (i64.const 1)) (i64.const 1))
|
||||
(assert_return (invoke "fib" (i64.const 2)) (i64.const 2))
|
||||
(assert_return (invoke "fib" (i64.const 5)) (i64.const 8))
|
||||
(assert_return (invoke "fib" (i64.const 20)) (i64.const 10946))
|
||||
|
||||
(assert_return (invoke "even" (i64.const 0)) (i64.const 44))
|
||||
(assert_return (invoke "even" (i64.const 1)) (i64.const 99))
|
||||
(assert_return (invoke "even" (i64.const 100)) (i64.const 44))
|
||||
(assert_return (invoke "even" (i64.const 77)) (i64.const 99))
|
||||
(assert_return (invoke "odd" (i64.const 0)) (i64.const 99))
|
||||
(assert_return (invoke "odd" (i64.const 1)) (i64.const 44))
|
||||
(assert_return (invoke "odd" (i64.const 200)) (i64.const 99))
|
||||
(assert_return (invoke "odd" (i64.const 77)) (i64.const 44))
|
||||
|
||||
|
||||
;; Unreachable typing.
|
||||
|
||||
(module
|
||||
(type $t (func))
|
||||
(func (export "unreachable") (result i32)
|
||||
(unreachable)
|
||||
(call_ref $t)
|
||||
)
|
||||
)
|
||||
(assert_trap (invoke "unreachable") "unreachable")
|
||||
|
||||
(module
|
||||
(elem declare func $f)
|
||||
(type $t (func (param i32) (result i32)))
|
||||
(func $f (param i32) (result i32) (local.get 0))
|
||||
|
||||
(func (export "unreachable") (result i32)
|
||||
(unreachable)
|
||||
(ref.func $f)
|
||||
(call_ref $t)
|
||||
)
|
||||
)
|
||||
(assert_trap (invoke "unreachable") "unreachable")
|
||||
|
||||
(module
|
||||
(elem declare func $f)
|
||||
(type $t (func (param i32) (result i32)))
|
||||
(func $f (param i32) (result i32) (local.get 0))
|
||||
|
||||
(func (export "unreachable") (result i32)
|
||||
(unreachable)
|
||||
(i32.const 0)
|
||||
(ref.func $f)
|
||||
(call_ref $t)
|
||||
(drop)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
(assert_trap (invoke "unreachable") "unreachable")
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(elem declare func $f)
|
||||
(type $t (func (param i32) (result i32)))
|
||||
(func $f (param i32) (result i32) (local.get 0))
|
||||
|
||||
(func (export "unreachable") (result i32)
|
||||
(unreachable)
|
||||
(i64.const 0)
|
||||
(ref.func $f)
|
||||
(call_ref $t)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(elem declare func $f)
|
||||
(type $t (func (param i32) (result i32)))
|
||||
(func $f (param i32) (result i32) (local.get 0))
|
||||
|
||||
(func (export "unreachable") (result i32)
|
||||
(unreachable)
|
||||
(ref.func $f)
|
||||
(call_ref $t)
|
||||
(drop)
|
||||
(i64.const 0)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (func))
|
||||
(func $f (param $r externref)
|
||||
(call_ref $t (local.get $r))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
54
tests/requirement-engineering/gc-aot/wasm-apps/extern.wast
Normal file
54
tests/requirement-engineering/gc-aot/wasm-apps/extern.wast
Normal file
|
@ -0,0 +1,54 @@
|
|||
(module
|
||||
(type $ft (func))
|
||||
(type $st (struct))
|
||||
(type $at (array i8))
|
||||
|
||||
(table 10 anyref)
|
||||
|
||||
(elem declare func $f)
|
||||
(func $f)
|
||||
|
||||
(func (export "init") (param $x externref)
|
||||
(table.set (i32.const 0) (ref.null any))
|
||||
(table.set (i32.const 1) (ref.i31 (i32.const 7)))
|
||||
(table.set (i32.const 2) (struct.new_default $st))
|
||||
(table.set (i32.const 3) (array.new_default $at (i32.const 0)))
|
||||
(table.set (i32.const 4) (any.convert_extern (local.get $x)))
|
||||
)
|
||||
|
||||
(func (export "internalize") (param externref) (result anyref)
|
||||
(any.convert_extern (local.get 0))
|
||||
)
|
||||
(func (export "externalize") (param anyref) (result externref)
|
||||
(extern.convert_any (local.get 0))
|
||||
)
|
||||
|
||||
(func (export "externalize-i") (param i32) (result externref)
|
||||
(extern.convert_any (table.get (local.get 0)))
|
||||
)
|
||||
(func (export "externalize-ii") (param i32) (result anyref)
|
||||
(any.convert_extern (extern.convert_any (table.get (local.get 0))))
|
||||
)
|
||||
)
|
||||
|
||||
(invoke "init" (ref.extern 0))
|
||||
|
||||
(assert_return (invoke "internalize" (ref.extern 1)) (ref.host 1))
|
||||
(assert_return (invoke "internalize" (ref.null extern)) (ref.null any))
|
||||
|
||||
(assert_return (invoke "externalize" (ref.host 2)) (ref.extern 2))
|
||||
(assert_return (invoke "externalize" (ref.null any)) (ref.null extern))
|
||||
|
||||
(assert_return (invoke "externalize-i" (i32.const 0)) (ref.null extern))
|
||||
(assert_return (invoke "externalize-i" (i32.const 1)) (ref.extern))
|
||||
(assert_return (invoke "externalize-i" (i32.const 2)) (ref.extern))
|
||||
(assert_return (invoke "externalize-i" (i32.const 3)) (ref.extern))
|
||||
(assert_return (invoke "externalize-i" (i32.const 4)) (ref.extern 0))
|
||||
(assert_return (invoke "externalize-i" (i32.const 5)) (ref.null extern))
|
||||
|
||||
(assert_return (invoke "externalize-ii" (i32.const 0)) (ref.null any))
|
||||
(assert_return (invoke "externalize-ii" (i32.const 1)) (ref.i31))
|
||||
(assert_return (invoke "externalize-ii" (i32.const 2)) (ref.struct))
|
||||
(assert_return (invoke "externalize-ii" (i32.const 3)) (ref.array))
|
||||
(assert_return (invoke "externalize-ii" (i32.const 4)) (ref.host 0))
|
||||
(assert_return (invoke "externalize-ii" (i32.const 5)) (ref.null any))
|
51
tests/requirement-engineering/gc-aot/wasm-apps/i31.wast
Normal file
51
tests/requirement-engineering/gc-aot/wasm-apps/i31.wast
Normal file
|
@ -0,0 +1,51 @@
|
|||
(module
|
||||
(func (export "new") (param $i i32) (result (ref i31))
|
||||
(ref.i31 (local.get $i))
|
||||
)
|
||||
|
||||
(func (export "get_u") (param $i i32) (result i32)
|
||||
(i31.get_u (ref.i31 (local.get $i)))
|
||||
)
|
||||
(func (export "get_s") (param $i i32) (result i32)
|
||||
(i31.get_s (ref.i31 (local.get $i)))
|
||||
)
|
||||
|
||||
(func (export "get_u-null") (result i32)
|
||||
(i31.get_u (ref.null i31))
|
||||
)
|
||||
(func (export "get_s-null") (result i32)
|
||||
(i31.get_u (ref.null i31))
|
||||
)
|
||||
|
||||
(global $i (ref i31) (ref.i31 (i32.const 2)))
|
||||
(global $m (mut (ref i31)) (ref.i31 (i32.const 3)))
|
||||
(func (export "get_globals") (result i32 i32)
|
||||
(i31.get_u (global.get $i))
|
||||
(i31.get_u (global.get $m))
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "new" (i32.const 1)) (ref.i31))
|
||||
|
||||
(assert_return (invoke "get_u" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "get_u" (i32.const 100)) (i32.const 100))
|
||||
(assert_return (invoke "get_u" (i32.const -1)) (i32.const 0x7fff_ffff))
|
||||
(assert_return (invoke "get_u" (i32.const 0x3fff_ffff)) (i32.const 0x3fff_ffff))
|
||||
(assert_return (invoke "get_u" (i32.const 0x4000_0000)) (i32.const 0x4000_0000))
|
||||
(assert_return (invoke "get_u" (i32.const 0x7fff_ffff)) (i32.const 0x7fff_ffff))
|
||||
(assert_return (invoke "get_u" (i32.const 0xaaaa_aaaa)) (i32.const 0x2aaa_aaaa))
|
||||
(assert_return (invoke "get_u" (i32.const 0xcaaa_aaaa)) (i32.const 0x4aaa_aaaa))
|
||||
|
||||
(assert_return (invoke "get_s" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "get_s" (i32.const 100)) (i32.const 100))
|
||||
(assert_return (invoke "get_s" (i32.const -1)) (i32.const -1))
|
||||
(assert_return (invoke "get_s" (i32.const 0x3fff_ffff)) (i32.const 0x3fff_ffff))
|
||||
(assert_return (invoke "get_s" (i32.const 0x4000_0000)) (i32.const -0x4000_0000))
|
||||
(assert_return (invoke "get_s" (i32.const 0x7fff_ffff)) (i32.const -1))
|
||||
(assert_return (invoke "get_s" (i32.const 0xaaaa_aaaa)) (i32.const 0x2aaa_aaaa))
|
||||
(assert_return (invoke "get_s" (i32.const 0xcaaa_aaaa)) (i32.const 0xcaaa_aaaa))
|
||||
|
||||
(assert_trap (invoke "get_u-null") "null i31 reference")
|
||||
(assert_trap (invoke "get_s-null") "null i31 reference")
|
||||
|
||||
(assert_return (invoke "get_globals") (i32.const 2) (i32.const 3))
|
362
tests/requirement-engineering/gc-aot/wasm-apps/local_set.wast
Normal file
362
tests/requirement-engineering/gc-aot/wasm-apps/local_set.wast
Normal file
|
@ -0,0 +1,362 @@
|
|||
;; Test `local.set` operator
|
||||
|
||||
(module
|
||||
;; Typing
|
||||
|
||||
(func (export "type-local-i32") (local i32) (local.set 0 (i32.const 0)))
|
||||
(func (export "type-local-i64") (local i64) (local.set 0 (i64.const 0)))
|
||||
(func (export "type-local-f32") (local f32) (local.set 0 (f32.const 0)))
|
||||
(func (export "type-local-f64") (local f64) (local.set 0 (f64.const 0)))
|
||||
|
||||
(func (export "type-param-i32") (param i32) (local.set 0 (i32.const 10)))
|
||||
(func (export "type-param-i64") (param i64) (local.set 0 (i64.const 11)))
|
||||
(func (export "type-param-f32") (param f32) (local.set 0 (f32.const 11.1)))
|
||||
(func (export "type-param-f64") (param f64) (local.set 0 (f64.const 12.2)))
|
||||
|
||||
(func (export "type-mixed") (param i64 f32 f64 i32 i32) (local f32 i64 i64 f64)
|
||||
(local.set 0 (i64.const 0))
|
||||
(local.set 1 (f32.const 0))
|
||||
(local.set 2 (f64.const 0))
|
||||
(local.set 3 (i32.const 0))
|
||||
(local.set 4 (i32.const 0))
|
||||
(local.set 5 (f32.const 0))
|
||||
(local.set 6 (i64.const 0))
|
||||
(local.set 7 (i64.const 0))
|
||||
(local.set 8 (f64.const 0))
|
||||
)
|
||||
|
||||
;; Writing
|
||||
|
||||
(func (export "write") (param i64 f32 f64 i32 i32) (result i64)
|
||||
(local f32 i64 i64 f64)
|
||||
(local.set 1 (f32.const -0.3))
|
||||
(local.set 3 (i32.const 40))
|
||||
(local.set 4 (i32.const -7))
|
||||
(local.set 5 (f32.const 5.5))
|
||||
(local.set 6 (i64.const 6))
|
||||
(local.set 8 (f64.const 8))
|
||||
(i64.trunc_f64_s
|
||||
(f64.add
|
||||
(f64.convert_i64_u (local.get 0))
|
||||
(f64.add
|
||||
(f64.promote_f32 (local.get 1))
|
||||
(f64.add
|
||||
(local.get 2)
|
||||
(f64.add
|
||||
(f64.convert_i32_u (local.get 3))
|
||||
(f64.add
|
||||
(f64.convert_i32_s (local.get 4))
|
||||
(f64.add
|
||||
(f64.promote_f32 (local.get 5))
|
||||
(f64.add
|
||||
(f64.convert_i64_u (local.get 6))
|
||||
(f64.add
|
||||
(f64.convert_i64_u (local.get 7))
|
||||
(local.get 8)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; As parameter of control constructs and instructions
|
||||
|
||||
(func (export "as-block-value") (param i32)
|
||||
(block (local.set 0 (i32.const 1)))
|
||||
)
|
||||
(func (export "as-loop-value") (param i32)
|
||||
(loop (local.set 0 (i32.const 3)))
|
||||
)
|
||||
|
||||
(func (export "as-br-value") (param i32)
|
||||
(block (br 0 (local.set 0 (i32.const 9))))
|
||||
)
|
||||
(func (export "as-br_if-value") (param i32)
|
||||
(block
|
||||
(br_if 0 (local.set 0 (i32.const 8)) (i32.const 1))
|
||||
)
|
||||
)
|
||||
(func (export "as-br_if-value-cond") (param i32)
|
||||
(block
|
||||
(br_if 0 (i32.const 6) (local.set 0 (i32.const 9)))
|
||||
)
|
||||
)
|
||||
(func (export "as-br_table-value") (param i32)
|
||||
(block
|
||||
(br_table 0 (local.set 0 (i32.const 10)) (i32.const 1))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "as-return-value") (param i32)
|
||||
(return (local.set 0 (i32.const 7)))
|
||||
)
|
||||
|
||||
(func (export "as-if-then") (param i32)
|
||||
(if (local.get 0) (then (local.set 0 (i32.const 3))))
|
||||
)
|
||||
(func (export "as-if-else") (param i32)
|
||||
(if (local.get 0) (then) (else (local.set 0 (i32.const 1))))
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "type-local-i32"))
|
||||
(assert_return (invoke "type-local-i64"))
|
||||
(assert_return (invoke "type-local-f32"))
|
||||
(assert_return (invoke "type-local-f64"))
|
||||
|
||||
(assert_return (invoke "type-param-i32" (i32.const 2)))
|
||||
(assert_return (invoke "type-param-i64" (i64.const 3)))
|
||||
(assert_return (invoke "type-param-f32" (f32.const 4.4)))
|
||||
(assert_return (invoke "type-param-f64" (f64.const 5.5)))
|
||||
|
||||
(assert_return (invoke "as-block-value" (i32.const 0)))
|
||||
(assert_return (invoke "as-loop-value" (i32.const 0)))
|
||||
|
||||
(assert_return (invoke "as-br-value" (i32.const 0)))
|
||||
(assert_return (invoke "as-br_if-value" (i32.const 0)))
|
||||
(assert_return (invoke "as-br_if-value-cond" (i32.const 0)))
|
||||
(assert_return (invoke "as-br_table-value" (i32.const 0)))
|
||||
|
||||
(assert_return (invoke "as-return-value" (i32.const 0)))
|
||||
|
||||
(assert_return (invoke "as-if-then" (i32.const 1)))
|
||||
(assert_return (invoke "as-if-else" (i32.const 0)))
|
||||
|
||||
(assert_return
|
||||
(invoke "type-mixed"
|
||||
(i64.const 1) (f32.const 2.2) (f64.const 3.3) (i32.const 4) (i32.const 5)
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return
|
||||
(invoke "write"
|
||||
(i64.const 1) (f32.const 2) (f64.const 3.3) (i32.const 4) (i32.const 5)
|
||||
)
|
||||
(i64.const 56)
|
||||
)
|
||||
|
||||
|
||||
;; Invalid typing of access to locals
|
||||
|
||||
|
||||
(assert_invalid
|
||||
(module (func $type-local-arg-void-vs-num (local i32) (local.set 0 (nop))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-local-arg-num-vs-num (local i32) (local.set 0 (f32.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-local-arg-num-vs-num (local f32) (local.set 0 (f64.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-local-arg-num-vs-num (local f64 i64) (local.set 1 (f64.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
|
||||
;; Invalid typing of access to parameters
|
||||
|
||||
|
||||
(assert_invalid
|
||||
(module (func $type-param-arg-void-vs-num (param i32) (local.set 0 (nop))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-param-arg-num-vs-num (param i32) (local.set 0 (f32.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-param-arg-num-vs-num (param f32) (local.set 0 (f64.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-param-arg-num-vs-num (param f64 i64) (local.set 1 (f64.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num (param i32)
|
||||
(local.set 0)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-block (param i32)
|
||||
(i32.const 0)
|
||||
(block (local.set 0))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-loop (param i32)
|
||||
(i32.const 0)
|
||||
(loop (local.set 0))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-then (param i32)
|
||||
(i32.const 0)
|
||||
(if (i32.const 1) (then (local.set 0)))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-else (param i32)
|
||||
(i32.const 0)
|
||||
(if (result i32) (i32.const 0) (then (i32.const 0)) (else (local.set 0)))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-br (param i32)
|
||||
(i32.const 0)
|
||||
(block (br 0 (local.set 0)))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-br_if (param i32)
|
||||
(i32.const 0)
|
||||
(block (br_if 0 (local.set 0)))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-br_table (param i32)
|
||||
(i32.const 0)
|
||||
(block (br_table 0 (local.set 0)))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-return (param i32)
|
||||
(return (local.set 0))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-select (param i32)
|
||||
(select (local.set 0) (i32.const 1) (i32.const 2))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-call (param i32)
|
||||
(call 1 (local.set 0))
|
||||
)
|
||||
(func (param i32) (result i32) (local.get 0))
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $f (param i32) (result i32) (local.get 0))
|
||||
(type $sig (func (param i32) (result i32)))
|
||||
(table funcref (elem $f))
|
||||
(func $type-param-arg-empty-vs-num-in-call_indirect (param i32)
|
||||
(block (result i32)
|
||||
(call_indirect (type $sig)
|
||||
(local.set 0) (i32.const 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
|
||||
;; Invalid typing of access to mixed args
|
||||
|
||||
(assert_invalid
|
||||
(module (func $type-mixed-arg-num-vs-num (param f32) (local i32) (local.set 1 (f32.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-mixed-arg-num-vs-num (param i64 i32) (local f32) (local.set 1 (f32.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-mixed-arg-num-vs-num (param i64) (local f64 i64) (local.set 1 (i64.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
|
||||
;; local.set should have no retval
|
||||
|
||||
(assert_invalid
|
||||
(module (func $type-empty-vs-i32 (param i32) (result i32) (local.set 0 (i32.const 1))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-empty-vs-i64 (param i64) (result i64) (local.set 0 (i64.const 1))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-empty-vs-f32 (param f32) (result f32) (local.set 0 (f32.const 1))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-empty-vs-f64 (param f64) (result f64) (local.set 0 (f64.const 1))))
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
|
||||
;; Invalid local index
|
||||
|
||||
(assert_invalid
|
||||
(module (func $unbound-local (local i32 i64) (local.set 3 (i32.const 0))))
|
||||
"unknown local"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $large-local (local i32 i64) (local.set 14324343 (i32.const 0))))
|
||||
"unknown local"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module (func $unbound-param (param i32 i64) (local.set 2 (i32.const 0))))
|
||||
"unknown local"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $large-param (param i32 i64) (local.set 714324343 (i32.const 0))))
|
||||
"unknown local"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module (func $unbound-mixed (param i32) (local i32 i64) (local.set 3 (i32.const 0))))
|
||||
"unknown local"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $large-mixed (param i64) (local i32 i64) (local.set 214324343 (i32.const 0))))
|
||||
"unknown local"
|
||||
)
|
||||
|
639
tests/requirement-engineering/gc-aot/wasm-apps/local_tee.wast
Normal file
639
tests/requirement-engineering/gc-aot/wasm-apps/local_tee.wast
Normal file
|
@ -0,0 +1,639 @@
|
|||
;; Test `local.tee` operator
|
||||
|
||||
(module
|
||||
;; Typing
|
||||
|
||||
(func (export "type-local-i32") (result i32) (local i32) (local.tee 0 (i32.const 0)))
|
||||
(func (export "type-local-i64") (result i64) (local i64) (local.tee 0 (i64.const 0)))
|
||||
(func (export "type-local-f32") (result f32) (local f32) (local.tee 0 (f32.const 0)))
|
||||
(func (export "type-local-f64") (result f64) (local f64) (local.tee 0 (f64.const 0)))
|
||||
|
||||
(func (export "type-param-i32") (param i32) (result i32) (local.tee 0 (i32.const 10)))
|
||||
(func (export "type-param-i64") (param i64) (result i64) (local.tee 0 (i64.const 11)))
|
||||
(func (export "type-param-f32") (param f32) (result f32) (local.tee 0 (f32.const 11.1)))
|
||||
(func (export "type-param-f64") (param f64) (result f64) (local.tee 0 (f64.const 12.2)))
|
||||
|
||||
(func (export "type-mixed") (param i64 f32 f64 i32 i32) (local f32 i64 i64 f64)
|
||||
(drop (i64.eqz (local.tee 0 (i64.const 0))))
|
||||
(drop (f32.neg (local.tee 1 (f32.const 0))))
|
||||
(drop (f64.neg (local.tee 2 (f64.const 0))))
|
||||
(drop (i32.eqz (local.tee 3 (i32.const 0))))
|
||||
(drop (i32.eqz (local.tee 4 (i32.const 0))))
|
||||
(drop (f32.neg (local.tee 5 (f32.const 0))))
|
||||
(drop (i64.eqz (local.tee 6 (i64.const 0))))
|
||||
(drop (i64.eqz (local.tee 7 (i64.const 0))))
|
||||
(drop (f64.neg (local.tee 8 (f64.const 0))))
|
||||
)
|
||||
|
||||
;; Writing
|
||||
|
||||
(func (export "write") (param i64 f32 f64 i32 i32) (result i64) (local f32 i64 i64 f64)
|
||||
(drop (local.tee 1 (f32.const -0.3)))
|
||||
(drop (local.tee 3 (i32.const 40)))
|
||||
(drop (local.tee 4 (i32.const -7)))
|
||||
(drop (local.tee 5 (f32.const 5.5)))
|
||||
(drop (local.tee 6 (i64.const 6)))
|
||||
(drop (local.tee 8 (f64.const 8)))
|
||||
(i64.trunc_f64_s
|
||||
(f64.add
|
||||
(f64.convert_i64_u (local.get 0))
|
||||
(f64.add
|
||||
(f64.promote_f32 (local.get 1))
|
||||
(f64.add
|
||||
(local.get 2)
|
||||
(f64.add
|
||||
(f64.convert_i32_u (local.get 3))
|
||||
(f64.add
|
||||
(f64.convert_i32_s (local.get 4))
|
||||
(f64.add
|
||||
(f64.promote_f32 (local.get 5))
|
||||
(f64.add
|
||||
(f64.convert_i64_u (local.get 6))
|
||||
(f64.add
|
||||
(f64.convert_i64_u (local.get 7))
|
||||
(local.get 8)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; Result
|
||||
|
||||
(func (export "result") (param i64 f32 f64 i32 i32) (result f64)
|
||||
(local f32 i64 i64 f64)
|
||||
(f64.add
|
||||
(f64.convert_i64_u (local.tee 0 (i64.const 1)))
|
||||
(f64.add
|
||||
(f64.promote_f32 (local.tee 1 (f32.const 2)))
|
||||
(f64.add
|
||||
(local.tee 2 (f64.const 3.3))
|
||||
(f64.add
|
||||
(f64.convert_i32_u (local.tee 3 (i32.const 4)))
|
||||
(f64.add
|
||||
(f64.convert_i32_s (local.tee 4 (i32.const 5)))
|
||||
(f64.add
|
||||
(f64.promote_f32 (local.tee 5 (f32.const 5.5)))
|
||||
(f64.add
|
||||
(f64.convert_i64_u (local.tee 6 (i64.const 6)))
|
||||
(f64.add
|
||||
(f64.convert_i64_u (local.tee 7 (i64.const 0)))
|
||||
(local.tee 8 (f64.const 8))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(func $dummy)
|
||||
|
||||
(func (export "as-block-first") (param i32) (result i32)
|
||||
(block (result i32) (local.tee 0 (i32.const 1)) (call $dummy))
|
||||
)
|
||||
(func (export "as-block-mid") (param i32) (result i32)
|
||||
(block (result i32) (call $dummy) (local.tee 0 (i32.const 1)) (call $dummy))
|
||||
)
|
||||
(func (export "as-block-last") (param i32) (result i32)
|
||||
(block (result i32) (call $dummy) (call $dummy) (local.tee 0 (i32.const 1)))
|
||||
)
|
||||
|
||||
(func (export "as-loop-first") (param i32) (result i32)
|
||||
(loop (result i32) (local.tee 0 (i32.const 3)) (call $dummy))
|
||||
)
|
||||
(func (export "as-loop-mid") (param i32) (result i32)
|
||||
(loop (result i32) (call $dummy) (local.tee 0 (i32.const 4)) (call $dummy))
|
||||
)
|
||||
(func (export "as-loop-last") (param i32) (result i32)
|
||||
(loop (result i32) (call $dummy) (call $dummy) (local.tee 0 (i32.const 5)))
|
||||
)
|
||||
|
||||
(func (export "as-br-value") (param i32) (result i32)
|
||||
(block (result i32) (br 0 (local.tee 0 (i32.const 9))))
|
||||
)
|
||||
|
||||
(func (export "as-br_if-cond") (param i32)
|
||||
(block (br_if 0 (local.tee 0 (i32.const 1))))
|
||||
)
|
||||
(func (export "as-br_if-value") (param i32) (result i32)
|
||||
(block (result i32)
|
||||
(drop (br_if 0 (local.tee 0 (i32.const 8)) (i32.const 1))) (i32.const 7)
|
||||
)
|
||||
)
|
||||
(func (export "as-br_if-value-cond") (param i32) (result i32)
|
||||
(block (result i32)
|
||||
(drop (br_if 0 (i32.const 6) (local.tee 0 (i32.const 9)))) (i32.const 7)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "as-br_table-index") (param i32)
|
||||
(block (br_table 0 0 0 (local.tee 0 (i32.const 0))))
|
||||
)
|
||||
(func (export "as-br_table-value") (param i32) (result i32)
|
||||
(block (result i32)
|
||||
(br_table 0 0 0 (local.tee 0 (i32.const 10)) (i32.const 1)) (i32.const 7)
|
||||
)
|
||||
)
|
||||
(func (export "as-br_table-value-index") (param i32) (result i32)
|
||||
(block (result i32)
|
||||
(br_table 0 0 (i32.const 6) (local.tee 0 (i32.const 11))) (i32.const 7)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "as-return-value") (param i32) (result i32)
|
||||
(return (local.tee 0 (i32.const 7)))
|
||||
)
|
||||
|
||||
(func (export "as-if-cond") (param i32) (result i32)
|
||||
(if (result i32) (local.tee 0 (i32.const 2))
|
||||
(then (i32.const 0)) (else (i32.const 1))
|
||||
)
|
||||
)
|
||||
(func (export "as-if-then") (param i32) (result i32)
|
||||
(if (result i32) (local.get 0)
|
||||
(then (local.tee 0 (i32.const 3))) (else (local.get 0))
|
||||
)
|
||||
)
|
||||
(func (export "as-if-else") (param i32) (result i32)
|
||||
(if (result i32) (local.get 0)
|
||||
(then (local.get 0)) (else (local.tee 0 (i32.const 4)))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "as-select-first") (param i32 i32) (result i32)
|
||||
(select (local.tee 0 (i32.const 5)) (local.get 0) (local.get 1))
|
||||
)
|
||||
(func (export "as-select-second") (param i32 i32) (result i32)
|
||||
(select (local.get 0) (local.tee 0 (i32.const 6)) (local.get 1))
|
||||
)
|
||||
(func (export "as-select-cond") (param i32) (result i32)
|
||||
(select (i32.const 0) (i32.const 1) (local.tee 0 (i32.const 7)))
|
||||
)
|
||||
|
||||
(func $f (param i32 i32 i32) (result i32) (i32.const -1))
|
||||
(func (export "as-call-first") (param i32) (result i32)
|
||||
(call $f (local.tee 0 (i32.const 12)) (i32.const 2) (i32.const 3))
|
||||
)
|
||||
(func (export "as-call-mid") (param i32) (result i32)
|
||||
(call $f (i32.const 1) (local.tee 0 (i32.const 13)) (i32.const 3))
|
||||
)
|
||||
(func (export "as-call-last") (param i32) (result i32)
|
||||
(call $f (i32.const 1) (i32.const 2) (local.tee 0 (i32.const 14)))
|
||||
)
|
||||
|
||||
(type $sig (func (param i32 i32 i32) (result i32)))
|
||||
(table funcref (elem $f))
|
||||
(func (export "as-call_indirect-first") (param i32) (result i32)
|
||||
(call_indirect (type $sig)
|
||||
(local.tee 0 (i32.const 1)) (i32.const 2) (i32.const 3) (i32.const 0)
|
||||
)
|
||||
)
|
||||
(func (export "as-call_indirect-mid") (param i32) (result i32)
|
||||
(call_indirect (type $sig)
|
||||
(i32.const 1) (local.tee 0 (i32.const 2)) (i32.const 3) (i32.const 0)
|
||||
)
|
||||
)
|
||||
(func (export "as-call_indirect-last") (param i32) (result i32)
|
||||
(call_indirect (type $sig)
|
||||
(i32.const 1) (i32.const 2) (local.tee 0 (i32.const 3)) (i32.const 0)
|
||||
)
|
||||
)
|
||||
(func (export "as-call_indirect-index") (param i32) (result i32)
|
||||
(call_indirect (type $sig)
|
||||
(i32.const 1) (i32.const 2) (i32.const 3) (local.tee 0 (i32.const 0))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "as-local.set-value") (local i32)
|
||||
(local.set 0 (local.tee 0 (i32.const 1)))
|
||||
)
|
||||
(func (export "as-local.tee-value") (param i32) (result i32)
|
||||
(local.tee 0 (local.tee 0 (i32.const 1)))
|
||||
)
|
||||
(global $g (mut i32) (i32.const 0))
|
||||
(func (export "as-global.set-value") (local i32)
|
||||
(global.set $g (local.tee 0 (i32.const 1)))
|
||||
)
|
||||
|
||||
(memory 1)
|
||||
(func (export "as-load-address") (param i32) (result i32)
|
||||
(i32.load (local.tee 0 (i32.const 1)))
|
||||
)
|
||||
(func (export "as-loadN-address") (param i32) (result i32)
|
||||
(i32.load8_s (local.tee 0 (i32.const 3)))
|
||||
)
|
||||
|
||||
(func (export "as-store-address") (param i32)
|
||||
(i32.store (local.tee 0 (i32.const 30)) (i32.const 7))
|
||||
)
|
||||
(func (export "as-store-value") (param i32)
|
||||
(i32.store (i32.const 2) (local.tee 0 (i32.const 1)))
|
||||
)
|
||||
|
||||
(func (export "as-storeN-address") (param i32)
|
||||
(i32.store8 (local.tee 0 (i32.const 1)) (i32.const 7))
|
||||
)
|
||||
(func (export "as-storeN-value") (param i32)
|
||||
(i32.store16 (i32.const 2) (local.tee 0 (i32.const 1)))
|
||||
)
|
||||
|
||||
(func (export "as-unary-operand") (param f32) (result f32)
|
||||
(f32.neg (local.tee 0 (f32.const nan:0x0f1e2)))
|
||||
)
|
||||
|
||||
(func (export "as-binary-left") (param i32) (result i32)
|
||||
(i32.add (local.tee 0 (i32.const 3)) (i32.const 10))
|
||||
)
|
||||
(func (export "as-binary-right") (param i32) (result i32)
|
||||
(i32.sub (i32.const 10) (local.tee 0 (i32.const 4)))
|
||||
)
|
||||
|
||||
(func (export "as-test-operand") (param i32) (result i32)
|
||||
(i32.eqz (local.tee 0 (i32.const 0)))
|
||||
)
|
||||
|
||||
(func (export "as-compare-left") (param i32) (result i32)
|
||||
(i32.le_s (local.tee 0 (i32.const 43)) (i32.const 10))
|
||||
)
|
||||
(func (export "as-compare-right") (param i32) (result i32)
|
||||
(i32.ne (i32.const 10) (local.tee 0 (i32.const 42)))
|
||||
)
|
||||
|
||||
(func (export "as-convert-operand") (param i64) (result i32)
|
||||
(i32.wrap_i64 (local.tee 0 (i64.const 41)))
|
||||
)
|
||||
|
||||
(func (export "as-memory.grow-size") (param i32) (result i32)
|
||||
(memory.grow (local.tee 0 (i32.const 40)))
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
(assert_return (invoke "type-local-i32") (i32.const 0))
|
||||
(assert_return (invoke "type-local-i64") (i64.const 0))
|
||||
(assert_return (invoke "type-local-f32") (f32.const 0))
|
||||
(assert_return (invoke "type-local-f64") (f64.const 0))
|
||||
|
||||
(assert_return (invoke "type-param-i32" (i32.const 2)) (i32.const 10))
|
||||
(assert_return (invoke "type-param-i64" (i64.const 3)) (i64.const 11))
|
||||
(assert_return (invoke "type-param-f32" (f32.const 4.4)) (f32.const 11.1))
|
||||
(assert_return (invoke "type-param-f64" (f64.const 5.5)) (f64.const 12.2))
|
||||
|
||||
(assert_return (invoke "as-block-first" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "as-block-mid" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "as-block-last" (i32.const 0)) (i32.const 1))
|
||||
|
||||
(assert_return (invoke "as-loop-first" (i32.const 0)) (i32.const 3))
|
||||
(assert_return (invoke "as-loop-mid" (i32.const 0)) (i32.const 4))
|
||||
(assert_return (invoke "as-loop-last" (i32.const 0)) (i32.const 5))
|
||||
|
||||
(assert_return (invoke "as-br-value" (i32.const 0)) (i32.const 9))
|
||||
|
||||
(assert_return (invoke "as-br_if-cond" (i32.const 0)))
|
||||
(assert_return (invoke "as-br_if-value" (i32.const 0)) (i32.const 8))
|
||||
(assert_return (invoke "as-br_if-value-cond" (i32.const 0)) (i32.const 6))
|
||||
|
||||
(assert_return (invoke "as-br_table-index" (i32.const 0)))
|
||||
(assert_return (invoke "as-br_table-value" (i32.const 0)) (i32.const 10))
|
||||
(assert_return (invoke "as-br_table-value-index" (i32.const 0)) (i32.const 6))
|
||||
|
||||
(assert_return (invoke "as-return-value" (i32.const 0)) (i32.const 7))
|
||||
|
||||
(assert_return (invoke "as-if-cond" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "as-if-then" (i32.const 1)) (i32.const 3))
|
||||
(assert_return (invoke "as-if-else" (i32.const 0)) (i32.const 4))
|
||||
|
||||
(assert_return (invoke "as-select-first" (i32.const 0) (i32.const 1)) (i32.const 5))
|
||||
(assert_return (invoke "as-select-second" (i32.const 0) (i32.const 0)) (i32.const 6))
|
||||
(assert_return (invoke "as-select-cond" (i32.const 0)) (i32.const 0))
|
||||
|
||||
(assert_return (invoke "as-call-first" (i32.const 0)) (i32.const -1))
|
||||
(assert_return (invoke "as-call-mid" (i32.const 0)) (i32.const -1))
|
||||
(assert_return (invoke "as-call-last" (i32.const 0)) (i32.const -1))
|
||||
|
||||
(assert_return (invoke "as-call_indirect-first" (i32.const 0)) (i32.const -1))
|
||||
(assert_return (invoke "as-call_indirect-mid" (i32.const 0)) (i32.const -1))
|
||||
(assert_return (invoke "as-call_indirect-last" (i32.const 0)) (i32.const -1))
|
||||
(assert_return (invoke "as-call_indirect-index" (i32.const 0)) (i32.const -1))
|
||||
|
||||
(assert_return (invoke "as-local.set-value"))
|
||||
(assert_return (invoke "as-local.tee-value" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "as-global.set-value"))
|
||||
|
||||
(assert_return (invoke "as-load-address" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "as-loadN-address" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "as-store-address" (i32.const 0)))
|
||||
(assert_return (invoke "as-store-value" (i32.const 0)))
|
||||
(assert_return (invoke "as-storeN-address" (i32.const 0)))
|
||||
(assert_return (invoke "as-storeN-value" (i32.const 0)))
|
||||
|
||||
(assert_return (invoke "as-unary-operand" (f32.const 0)) (f32.const -nan:0x0f1e2))
|
||||
(assert_return (invoke "as-binary-left" (i32.const 0)) (i32.const 13))
|
||||
(assert_return (invoke "as-binary-right" (i32.const 0)) (i32.const 6))
|
||||
(assert_return (invoke "as-test-operand" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "as-compare-left" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "as-compare-right" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "as-convert-operand" (i64.const 0)) (i32.const 41))
|
||||
(assert_return (invoke "as-memory.grow-size" (i32.const 0)) (i32.const 1))
|
||||
|
||||
(assert_return
|
||||
(invoke "type-mixed"
|
||||
(i64.const 1) (f32.const 2.2) (f64.const 3.3) (i32.const 4) (i32.const 5)
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return
|
||||
(invoke "write"
|
||||
(i64.const 1) (f32.const 2) (f64.const 3.3) (i32.const 4) (i32.const 5)
|
||||
)
|
||||
(i64.const 56)
|
||||
)
|
||||
|
||||
(assert_return
|
||||
(invoke "result"
|
||||
(i64.const -1) (f32.const -2) (f64.const -3.3) (i32.const -4) (i32.const -5)
|
||||
)
|
||||
(f64.const 34.8)
|
||||
)
|
||||
|
||||
|
||||
;; Invalid typing of access to locals
|
||||
|
||||
(assert_invalid
|
||||
(module (func $type-local-num-vs-num (result i64) (local i32) (local.tee 0 (i32.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-local-num-vs-num (local f32) (i32.eqz (local.tee 0 (f32.const 0)))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-local-num-vs-num (local f64 i64) (f64.neg (local.tee 1 (i64.const 0)))))
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module (func $type-local-arg-void-vs-num (local i32) (local.tee 0 (nop))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-local-arg-num-vs-num (local i32) (local.tee 0 (f32.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-local-arg-num-vs-num (local f32) (local.tee 0 (f64.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-local-arg-num-vs-num (local f64 i64) (local.tee 1 (f64.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
|
||||
;; Invalid typing of access to parameters
|
||||
|
||||
(assert_invalid
|
||||
(module (func $type-param-num-vs-num (param i32) (result i64) (local.get 0)))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-param-num-vs-num (param f32) (i32.eqz (local.get 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-param-num-vs-num (param f64 i64) (f64.neg (local.get 1))))
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module (func $type-param-arg-void-vs-num (param i32) (local.tee 0 (nop))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-param-arg-num-vs-num (param i32) (local.tee 0 (f32.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-param-arg-num-vs-num (param f32) (local.tee 0 (f64.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-param-arg-num-vs-num (param f64 i64) (local.tee 1 (f64.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num (param i32)
|
||||
(local.tee 0) (drop)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-block (param i32)
|
||||
(i32.const 0)
|
||||
(block (local.tee 0) (drop))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-loop (param i32)
|
||||
(i32.const 0)
|
||||
(loop (local.tee 0) (drop))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-then (param i32)
|
||||
(i32.const 0) (i32.const 0)
|
||||
(if (then (local.tee 0) (drop)))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-else (param i32)
|
||||
(i32.const 0) (i32.const 0)
|
||||
(if (result i32) (then (i32.const 0)) (else (local.tee 0))) (drop)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-br (param i32)
|
||||
(i32.const 0)
|
||||
(block (br 0 (local.tee 0)) (drop))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-br_if (param i32)
|
||||
(i32.const 0)
|
||||
(block (br_if 0 (local.tee 0) (i32.const 1)) (drop))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-br_table (param i32)
|
||||
(i32.const 0)
|
||||
(block (br_table 0 (local.tee 0)) (drop))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-return (param i32)
|
||||
(return (local.tee 0)) (drop)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-select (param i32)
|
||||
(select (local.tee 0) (i32.const 1) (i32.const 2)) (drop)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-call (param i32)
|
||||
(call 1 (local.tee 0)) (drop)
|
||||
)
|
||||
(func (param i32) (result i32) (local.get 0))
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $f (param i32) (result i32) (local.get 0))
|
||||
(type $sig (func (param i32) (result i32)))
|
||||
(table funcref (elem $f))
|
||||
(func $type-param-arg-empty-vs-num-in-call_indirect (param i32)
|
||||
(block (result i32)
|
||||
(call_indirect (type $sig)
|
||||
(local.tee 0) (i32.const 0)
|
||||
)
|
||||
(drop)
|
||||
)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-local.set (param i32)
|
||||
(local.set 0 (local.tee 0)) (local.get 0) (drop)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-param-arg-empty-vs-num-in-local.tee (param i32)
|
||||
(local.tee 0 (local.tee 0)) (drop)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(global $x (mut i32) (i32.const 0))
|
||||
(func $type-param-arg-empty-vs-num-in-global.set (param i32)
|
||||
(global.set $x (local.tee 0)) (global.get $x) (drop)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(memory 0)
|
||||
(func $type-param-arg-empty-vs-num-in-memory.grow (param i32)
|
||||
(memory.grow (local.tee 0)) (drop)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(memory 0)
|
||||
(func $type-param-arg-empty-vs-num-in-load (param i32)
|
||||
(i32.load (local.tee 0)) (drop)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(memory 1)
|
||||
(func $type-param-arg-empty-vs-num-in-store (param i32)
|
||||
(i32.store (local.tee 0) (i32.const 1))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module (func $type-mixed-arg-num-vs-num (param f32) (local i32) (local.tee 1 (f32.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-mixed-arg-num-vs-num (param i64 i32) (local f32) (local.tee 1 (f32.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-mixed-arg-num-vs-num (param i64) (local f64 i64) (local.tee 1 (i64.const 0))))
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
|
||||
;; Invalid local index
|
||||
|
||||
(assert_invalid
|
||||
(module (func $unbound-local (local i32 i64) (local.tee 3 (i32.const 0)) drop))
|
||||
"unknown local"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $large-local (local i32 i64) (local.tee 14324343 (i32.const 0)) drop))
|
||||
"unknown local"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module (func $unbound-param (param i32 i64) (local.tee 2 (i32.const 0)) drop))
|
||||
"unknown local"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $large-param (param i32 i64) (local.tee 714324343 (i32.const 0)) drop))
|
||||
"unknown local"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module (func $unbound-mixed (param i32) (local i32 i64) (local.tee 3 (i32.const 0)) drop))
|
||||
"unknown local"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $large-mixed (param i64) (local i32 i64) (local.tee 214324343 (i32.const 0)) drop))
|
||||
"unknown local"
|
||||
)
|
186
tests/requirement-engineering/gc-aot/wasm-apps/ref_cast.wast
Normal file
186
tests/requirement-engineering/gc-aot/wasm-apps/ref_cast.wast
Normal file
|
@ -0,0 +1,186 @@
|
|||
;; Abstract Types
|
||||
|
||||
(module
|
||||
(type $ft (func))
|
||||
(type $st (struct))
|
||||
(type $at (array i8))
|
||||
|
||||
(table 10 anyref)
|
||||
|
||||
(elem declare func $f)
|
||||
(func $f)
|
||||
|
||||
(func (export "init") (param $x externref)
|
||||
(table.set (i32.const 0) (ref.null any))
|
||||
(table.set (i32.const 1) (ref.i31 (i32.const 7)))
|
||||
(table.set (i32.const 2) (struct.new_default $st))
|
||||
(table.set (i32.const 3) (array.new_default $at (i32.const 0)))
|
||||
(table.set (i32.const 4) (any.convert_extern (local.get $x)))
|
||||
(table.set (i32.const 5) (ref.null i31))
|
||||
(table.set (i32.const 6) (ref.null struct))
|
||||
(table.set (i32.const 7) (ref.null none))
|
||||
)
|
||||
|
||||
(func (export "ref_cast_non_null") (param $i i32)
|
||||
(drop (ref.as_non_null (table.get (local.get $i))))
|
||||
(drop (ref.cast (ref null any) (table.get (local.get $i))))
|
||||
)
|
||||
(func (export "ref_cast_null") (param $i i32)
|
||||
(drop (ref.cast anyref (table.get (local.get $i))))
|
||||
(drop (ref.cast structref (table.get (local.get $i))))
|
||||
(drop (ref.cast arrayref (table.get (local.get $i))))
|
||||
(drop (ref.cast i31ref (table.get (local.get $i))))
|
||||
(drop (ref.cast nullref (table.get (local.get $i))))
|
||||
)
|
||||
(func (export "ref_cast_i31") (param $i i32)
|
||||
(drop (ref.cast (ref i31) (table.get (local.get $i))))
|
||||
(drop (ref.cast i31ref (table.get (local.get $i))))
|
||||
)
|
||||
(func (export "ref_cast_struct") (param $i i32)
|
||||
(drop (ref.cast (ref struct) (table.get (local.get $i))))
|
||||
(drop (ref.cast structref (table.get (local.get $i))))
|
||||
)
|
||||
(func (export "ref_cast_array") (param $i i32)
|
||||
(drop (ref.cast (ref array) (table.get (local.get $i))))
|
||||
(drop (ref.cast arrayref (table.get (local.get $i))))
|
||||
)
|
||||
)
|
||||
|
||||
(invoke "init" (ref.extern 0))
|
||||
|
||||
(assert_trap (invoke "ref_cast_non_null" (i32.const 0)) "null reference")
|
||||
(assert_return (invoke "ref_cast_non_null" (i32.const 1)))
|
||||
(assert_return (invoke "ref_cast_non_null" (i32.const 2)))
|
||||
(assert_return (invoke "ref_cast_non_null" (i32.const 3)))
|
||||
(assert_return (invoke "ref_cast_non_null" (i32.const 4)))
|
||||
(assert_trap (invoke "ref_cast_non_null" (i32.const 5)) "null reference")
|
||||
(assert_trap (invoke "ref_cast_non_null" (i32.const 6)) "null reference")
|
||||
(assert_trap (invoke "ref_cast_non_null" (i32.const 7)) "null reference")
|
||||
|
||||
(assert_return (invoke "ref_cast_null" (i32.const 0)))
|
||||
(assert_trap (invoke "ref_cast_null" (i32.const 1)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_null" (i32.const 2)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_null" (i32.const 3)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_null" (i32.const 4)) "cast failure")
|
||||
(assert_return (invoke "ref_cast_null" (i32.const 5)))
|
||||
(assert_return (invoke "ref_cast_null" (i32.const 6)))
|
||||
(assert_return (invoke "ref_cast_null" (i32.const 7)))
|
||||
|
||||
(assert_trap (invoke "ref_cast_i31" (i32.const 0)) "cast failure")
|
||||
(assert_return (invoke "ref_cast_i31" (i32.const 1)))
|
||||
(assert_trap (invoke "ref_cast_i31" (i32.const 2)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_i31" (i32.const 3)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_i31" (i32.const 4)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_i31" (i32.const 5)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_i31" (i32.const 6)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_i31" (i32.const 7)) "cast failure")
|
||||
|
||||
(assert_trap (invoke "ref_cast_struct" (i32.const 0)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_struct" (i32.const 1)) "cast failure")
|
||||
(assert_return (invoke "ref_cast_struct" (i32.const 2)))
|
||||
(assert_trap (invoke "ref_cast_struct" (i32.const 3)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_struct" (i32.const 4)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_struct" (i32.const 5)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_struct" (i32.const 6)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_struct" (i32.const 7)) "cast failure")
|
||||
|
||||
(assert_trap (invoke "ref_cast_array" (i32.const 0)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_array" (i32.const 1)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_array" (i32.const 2)) "cast failure")
|
||||
(assert_return (invoke "ref_cast_array" (i32.const 3)))
|
||||
(assert_trap (invoke "ref_cast_array" (i32.const 4)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_array" (i32.const 5)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_array" (i32.const 6)) "cast failure")
|
||||
(assert_trap (invoke "ref_cast_array" (i32.const 7)) "cast failure")
|
||||
|
||||
|
||||
;; Concrete Types
|
||||
|
||||
(module
|
||||
(type $t0 (sub (struct)))
|
||||
(type $t1 (sub $t0 (struct (field i32))))
|
||||
(type $t1' (sub $t0 (struct (field i32))))
|
||||
(type $t2 (sub $t1 (struct (field i32 i32))))
|
||||
(type $t2' (sub $t1' (struct (field i32 i32))))
|
||||
(type $t3 (sub $t0 (struct (field i32 i32))))
|
||||
(type $t0' (sub $t0 (struct)))
|
||||
(type $t4 (sub $t0' (struct (field i32 i32))))
|
||||
|
||||
(table 20 (ref null struct))
|
||||
|
||||
(func $init
|
||||
(table.set (i32.const 0) (struct.new_default $t0))
|
||||
(table.set (i32.const 10) (struct.new_default $t0))
|
||||
(table.set (i32.const 1) (struct.new_default $t1))
|
||||
(table.set (i32.const 11) (struct.new_default $t1'))
|
||||
(table.set (i32.const 2) (struct.new_default $t2))
|
||||
(table.set (i32.const 12) (struct.new_default $t2'))
|
||||
(table.set (i32.const 3) (struct.new_default $t3))
|
||||
(table.set (i32.const 4) (struct.new_default $t4))
|
||||
)
|
||||
|
||||
(func (export "test-sub")
|
||||
(call $init)
|
||||
|
||||
(drop (ref.cast (ref null $t0) (ref.null struct)))
|
||||
(drop (ref.cast (ref null $t0) (table.get (i32.const 0))))
|
||||
(drop (ref.cast (ref null $t0) (table.get (i32.const 1))))
|
||||
(drop (ref.cast (ref null $t0) (table.get (i32.const 2))))
|
||||
(drop (ref.cast (ref null $t0) (table.get (i32.const 3))))
|
||||
(drop (ref.cast (ref null $t0) (table.get (i32.const 4))))
|
||||
|
||||
(drop (ref.cast (ref null $t0) (ref.null struct)))
|
||||
(drop (ref.cast (ref null $t1) (table.get (i32.const 1))))
|
||||
(drop (ref.cast (ref null $t1) (table.get (i32.const 2))))
|
||||
|
||||
(drop (ref.cast (ref null $t0) (ref.null struct)))
|
||||
(drop (ref.cast (ref null $t2) (table.get (i32.const 2))))
|
||||
|
||||
(drop (ref.cast (ref null $t0) (ref.null struct)))
|
||||
(drop (ref.cast (ref null $t3) (table.get (i32.const 3))))
|
||||
|
||||
(drop (ref.cast (ref null $t4) (table.get (i32.const 4))))
|
||||
|
||||
(drop (ref.cast (ref $t0) (table.get (i32.const 0))))
|
||||
(drop (ref.cast (ref $t0) (table.get (i32.const 1))))
|
||||
(drop (ref.cast (ref $t0) (table.get (i32.const 2))))
|
||||
(drop (ref.cast (ref $t0) (table.get (i32.const 3))))
|
||||
(drop (ref.cast (ref $t0) (table.get (i32.const 4))))
|
||||
|
||||
(drop (ref.cast (ref $t1) (table.get (i32.const 1))))
|
||||
(drop (ref.cast (ref $t1) (table.get (i32.const 2))))
|
||||
|
||||
(drop (ref.cast (ref $t2) (table.get (i32.const 2))))
|
||||
|
||||
(drop (ref.cast (ref $t3) (table.get (i32.const 3))))
|
||||
|
||||
(drop (ref.cast (ref $t4) (table.get (i32.const 4))))
|
||||
)
|
||||
|
||||
(func (export "test-canon")
|
||||
(call $init)
|
||||
|
||||
(drop (ref.cast (ref $t0) (table.get (i32.const 0))))
|
||||
(drop (ref.cast (ref $t0) (table.get (i32.const 1))))
|
||||
(drop (ref.cast (ref $t0) (table.get (i32.const 2))))
|
||||
(drop (ref.cast (ref $t0) (table.get (i32.const 3))))
|
||||
(drop (ref.cast (ref $t0) (table.get (i32.const 4))))
|
||||
|
||||
(drop (ref.cast (ref $t0) (table.get (i32.const 10))))
|
||||
(drop (ref.cast (ref $t0) (table.get (i32.const 11))))
|
||||
(drop (ref.cast (ref $t0) (table.get (i32.const 12))))
|
||||
|
||||
(drop (ref.cast (ref $t1') (table.get (i32.const 1))))
|
||||
(drop (ref.cast (ref $t1') (table.get (i32.const 2))))
|
||||
|
||||
(drop (ref.cast (ref $t1) (table.get (i32.const 11))))
|
||||
(drop (ref.cast (ref $t1) (table.get (i32.const 12))))
|
||||
|
||||
(drop (ref.cast (ref $t2') (table.get (i32.const 2))))
|
||||
|
||||
(drop (ref.cast (ref $t2) (table.get (i32.const 12))))
|
||||
)
|
||||
)
|
||||
|
||||
(invoke "test-sub")
|
||||
(invoke "test-canon")
|
168
tests/requirement-engineering/gc-aot/wasm-apps/ref_eq.wast
Normal file
168
tests/requirement-engineering/gc-aot/wasm-apps/ref_eq.wast
Normal file
|
@ -0,0 +1,168 @@
|
|||
(module
|
||||
(type $st (sub (struct)))
|
||||
(type $st' (sub (struct (field i32))))
|
||||
(type $at (array i8))
|
||||
(type $st-sub1 (sub $st (struct)))
|
||||
(type $st-sub2 (sub $st (struct)))
|
||||
(type $st'-sub1 (sub $st' (struct (field i32))))
|
||||
(type $st'-sub2 (sub $st' (struct (field i32))))
|
||||
|
||||
(table 20 (ref null eq))
|
||||
|
||||
(func (export "init")
|
||||
(table.set (i32.const 0) (ref.null eq))
|
||||
(table.set (i32.const 1) (ref.null i31))
|
||||
(table.set (i32.const 2) (ref.i31 (i32.const 7)))
|
||||
(table.set (i32.const 3) (ref.i31 (i32.const 7)))
|
||||
(table.set (i32.const 4) (ref.i31 (i32.const 8)))
|
||||
(table.set (i32.const 5) (struct.new_default $st))
|
||||
(table.set (i32.const 6) (struct.new_default $st))
|
||||
(table.set (i32.const 7) (array.new_default $at (i32.const 0)))
|
||||
(table.set (i32.const 8) (array.new_default $at (i32.const 0)))
|
||||
)
|
||||
|
||||
(func (export "eq") (param $i i32) (param $j i32) (result i32)
|
||||
(ref.eq (table.get (local.get $i)) (table.get (local.get $j)))
|
||||
)
|
||||
)
|
||||
|
||||
(invoke "init")
|
||||
|
||||
(assert_return (invoke "eq" (i32.const 0) (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "eq" (i32.const 0) (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "eq" (i32.const 0) (i32.const 2)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 0) (i32.const 3)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 0) (i32.const 4)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 0) (i32.const 5)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 0) (i32.const 6)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 0) (i32.const 7)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 0) (i32.const 8)) (i32.const 0))
|
||||
|
||||
(assert_return (invoke "eq" (i32.const 1) (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "eq" (i32.const 1) (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "eq" (i32.const 1) (i32.const 2)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 1) (i32.const 3)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 1) (i32.const 4)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 1) (i32.const 5)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 1) (i32.const 6)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 1) (i32.const 7)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 1) (i32.const 8)) (i32.const 0))
|
||||
|
||||
(assert_return (invoke "eq" (i32.const 2) (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 2) (i32.const 1)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 2) (i32.const 2)) (i32.const 1))
|
||||
(assert_return (invoke "eq" (i32.const 2) (i32.const 3)) (i32.const 1))
|
||||
(assert_return (invoke "eq" (i32.const 2) (i32.const 4)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 2) (i32.const 5)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 2) (i32.const 6)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 2) (i32.const 7)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 2) (i32.const 8)) (i32.const 0))
|
||||
|
||||
(assert_return (invoke "eq" (i32.const 3) (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 3) (i32.const 1)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 3) (i32.const 2)) (i32.const 1))
|
||||
(assert_return (invoke "eq" (i32.const 3) (i32.const 3)) (i32.const 1))
|
||||
(assert_return (invoke "eq" (i32.const 3) (i32.const 4)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 3) (i32.const 5)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 3) (i32.const 6)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 3) (i32.const 7)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 3) (i32.const 8)) (i32.const 0))
|
||||
|
||||
(assert_return (invoke "eq" (i32.const 4) (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 4) (i32.const 1)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 4) (i32.const 2)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 4) (i32.const 3)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 4) (i32.const 4)) (i32.const 1))
|
||||
(assert_return (invoke "eq" (i32.const 4) (i32.const 5)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 4) (i32.const 6)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 4) (i32.const 7)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 4) (i32.const 8)) (i32.const 0))
|
||||
|
||||
(assert_return (invoke "eq" (i32.const 5) (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 5) (i32.const 1)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 5) (i32.const 2)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 5) (i32.const 3)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 5) (i32.const 4)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 5) (i32.const 5)) (i32.const 1))
|
||||
(assert_return (invoke "eq" (i32.const 5) (i32.const 6)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 5) (i32.const 7)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 5) (i32.const 8)) (i32.const 0))
|
||||
|
||||
(assert_return (invoke "eq" (i32.const 6) (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 6) (i32.const 1)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 6) (i32.const 2)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 6) (i32.const 3)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 6) (i32.const 4)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 6) (i32.const 5)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 6) (i32.const 6)) (i32.const 1))
|
||||
(assert_return (invoke "eq" (i32.const 6) (i32.const 7)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 6) (i32.const 8)) (i32.const 0))
|
||||
|
||||
(assert_return (invoke "eq" (i32.const 7) (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 7) (i32.const 1)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 7) (i32.const 2)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 7) (i32.const 3)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 7) (i32.const 4)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 7) (i32.const 5)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 7) (i32.const 6)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 7) (i32.const 7)) (i32.const 1))
|
||||
(assert_return (invoke "eq" (i32.const 7) (i32.const 8)) (i32.const 0))
|
||||
|
||||
(assert_return (invoke "eq" (i32.const 8) (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 8) (i32.const 1)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 8) (i32.const 2)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 8) (i32.const 3)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 8) (i32.const 4)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 8) (i32.const 5)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 8) (i32.const 6)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 8) (i32.const 7)) (i32.const 0))
|
||||
(assert_return (invoke "eq" (i32.const 8) (i32.const 8)) (i32.const 1))
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(func (export "eq") (param $r (ref any)) (result i32)
|
||||
(ref.eq (local.get $r) (local.get $r))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func (export "eq") (param $r (ref null any)) (result i32)
|
||||
(ref.eq (local.get $r) (local.get $r))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func (export "eq") (param $r (ref func)) (result i32)
|
||||
(ref.eq (local.get $r) (local.get $r))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func (export "eq") (param $r (ref null func)) (result i32)
|
||||
(ref.eq (local.get $r) (local.get $r))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func (export "eq") (param $r (ref extern)) (result i32)
|
||||
(ref.eq (local.get $r) (local.get $r))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func (export "eq") (param $r (ref null extern)) (result i32)
|
||||
(ref.eq (local.get $r) (local.get $r))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
331
tests/requirement-engineering/gc-aot/wasm-apps/ref_test.wast
Normal file
331
tests/requirement-engineering/gc-aot/wasm-apps/ref_test.wast
Normal file
|
@ -0,0 +1,331 @@
|
|||
;; Abstract Types
|
||||
|
||||
(module
|
||||
(type $ft (func))
|
||||
(type $st (struct))
|
||||
(type $at (array i8))
|
||||
|
||||
(table $ta 10 anyref)
|
||||
(table $tf 10 funcref)
|
||||
(table $te 10 externref)
|
||||
|
||||
(elem declare func $f)
|
||||
(func $f)
|
||||
|
||||
(func (export "init") (param $x externref)
|
||||
(table.set $ta (i32.const 0) (ref.null any))
|
||||
(table.set $ta (i32.const 1) (ref.null struct))
|
||||
(table.set $ta (i32.const 2) (ref.null none))
|
||||
(table.set $ta (i32.const 3) (ref.i31 (i32.const 7)))
|
||||
(table.set $ta (i32.const 4) (struct.new_default $st))
|
||||
(table.set $ta (i32.const 5) (array.new_default $at (i32.const 0)))
|
||||
(table.set $ta (i32.const 6) (any.convert_extern (local.get $x)))
|
||||
(table.set $ta (i32.const 7) (any.convert_extern (ref.null extern)))
|
||||
|
||||
(table.set $tf (i32.const 0) (ref.null nofunc))
|
||||
(table.set $tf (i32.const 1) (ref.null func))
|
||||
(table.set $tf (i32.const 2) (ref.func $f))
|
||||
|
||||
(table.set $te (i32.const 0) (ref.null noextern))
|
||||
(table.set $te (i32.const 1) (ref.null extern))
|
||||
(table.set $te (i32.const 2) (local.get $x))
|
||||
(table.set $te (i32.const 3) (extern.convert_any (ref.i31 (i32.const 8))))
|
||||
(table.set $te (i32.const 4) (extern.convert_any (struct.new_default $st)))
|
||||
(table.set $te (i32.const 5) (extern.convert_any (ref.null any)))
|
||||
)
|
||||
|
||||
(func (export "ref_test_null_data") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.is_null (table.get $ta (local.get $i)))
|
||||
(ref.test nullref (table.get $ta (local.get $i)))
|
||||
)
|
||||
)
|
||||
(func (export "ref_test_any") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.test (ref any) (table.get $ta (local.get $i)))
|
||||
(ref.test anyref (table.get $ta (local.get $i)))
|
||||
)
|
||||
)
|
||||
(func (export "ref_test_eq") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.test (ref eq) (table.get $ta (local.get $i)))
|
||||
(ref.test eqref (table.get $ta (local.get $i)))
|
||||
)
|
||||
)
|
||||
(func (export "ref_test_i31") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.test (ref i31) (table.get $ta (local.get $i)))
|
||||
(ref.test i31ref (table.get $ta (local.get $i)))
|
||||
)
|
||||
)
|
||||
(func (export "ref_test_struct") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.test (ref struct) (table.get $ta (local.get $i)))
|
||||
(ref.test structref (table.get $ta (local.get $i)))
|
||||
)
|
||||
)
|
||||
(func (export "ref_test_array") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.test (ref array) (table.get $ta (local.get $i)))
|
||||
(ref.test arrayref (table.get $ta (local.get $i)))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "ref_test_null_func") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.is_null (table.get $tf (local.get $i)))
|
||||
(ref.test (ref null nofunc) (table.get $tf (local.get $i)))
|
||||
)
|
||||
)
|
||||
(func (export "ref_test_func") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.test (ref func) (table.get $tf (local.get $i)))
|
||||
(ref.test funcref (table.get $tf (local.get $i)))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "ref_test_null_extern") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.is_null (table.get $te (local.get $i)))
|
||||
(ref.test (ref null noextern) (table.get $te (local.get $i)))
|
||||
)
|
||||
)
|
||||
(func (export "ref_test_extern") (param $i i32) (result i32)
|
||||
(i32.add
|
||||
(ref.test (ref extern) (table.get $te (local.get $i)))
|
||||
(ref.test externref (table.get $te (local.get $i)))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(invoke "init" (ref.extern 0))
|
||||
|
||||
(assert_return (invoke "ref_test_null_data" (i32.const 0)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_null_data" (i32.const 1)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_null_data" (i32.const 2)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_null_data" (i32.const 3)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_null_data" (i32.const 4)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_null_data" (i32.const 5)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_null_data" (i32.const 6)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_null_data" (i32.const 7)) (i32.const 2))
|
||||
|
||||
(assert_return (invoke "ref_test_any" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_any" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_any" (i32.const 2)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_any" (i32.const 3)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_any" (i32.const 4)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_any" (i32.const 5)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_any" (i32.const 6)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_any" (i32.const 7)) (i32.const 1))
|
||||
|
||||
(assert_return (invoke "ref_test_eq" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_eq" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_eq" (i32.const 2)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_eq" (i32.const 3)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_eq" (i32.const 4)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_eq" (i32.const 5)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_eq" (i32.const 6)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_eq" (i32.const 7)) (i32.const 1))
|
||||
|
||||
(assert_return (invoke "ref_test_i31" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_i31" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_i31" (i32.const 2)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_i31" (i32.const 3)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_i31" (i32.const 4)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_i31" (i32.const 5)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_i31" (i32.const 6)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_i31" (i32.const 7)) (i32.const 1))
|
||||
|
||||
(assert_return (invoke "ref_test_struct" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_struct" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_struct" (i32.const 2)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_struct" (i32.const 3)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_struct" (i32.const 4)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_struct" (i32.const 5)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_struct" (i32.const 6)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_struct" (i32.const 7)) (i32.const 1))
|
||||
|
||||
(assert_return (invoke "ref_test_array" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_array" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_array" (i32.const 2)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_array" (i32.const 3)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_array" (i32.const 4)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_array" (i32.const 5)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_array" (i32.const 6)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_array" (i32.const 7)) (i32.const 1))
|
||||
|
||||
(assert_return (invoke "ref_test_null_func" (i32.const 0)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_null_func" (i32.const 1)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_null_func" (i32.const 2)) (i32.const 0))
|
||||
|
||||
(assert_return (invoke "ref_test_func" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_func" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_func" (i32.const 2)) (i32.const 2))
|
||||
|
||||
(assert_return (invoke "ref_test_null_extern" (i32.const 0)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_null_extern" (i32.const 1)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_null_extern" (i32.const 2)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_null_extern" (i32.const 3)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_null_extern" (i32.const 4)) (i32.const 0))
|
||||
(assert_return (invoke "ref_test_null_extern" (i32.const 5)) (i32.const 2))
|
||||
|
||||
(assert_return (invoke "ref_test_extern" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_extern" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "ref_test_extern" (i32.const 2)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_extern" (i32.const 3)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_extern" (i32.const 4)) (i32.const 2))
|
||||
(assert_return (invoke "ref_test_extern" (i32.const 5)) (i32.const 1))
|
||||
|
||||
|
||||
;; Concrete Types
|
||||
|
||||
(module
|
||||
(type $t0 (sub (struct)))
|
||||
(type $t1 (sub $t0 (struct (field i32))))
|
||||
(type $t1' (sub $t0 (struct (field i32))))
|
||||
(type $t2 (sub $t1 (struct (field i32 i32))))
|
||||
(type $t2' (sub $t1' (struct (field i32 i32))))
|
||||
(type $t3 (sub $t0 (struct (field i32 i32))))
|
||||
(type $t0' (sub $t0 (struct)))
|
||||
(type $t4 (sub $t0' (struct (field i32 i32))))
|
||||
|
||||
(table 20 (ref null struct))
|
||||
|
||||
(func $init
|
||||
(table.set (i32.const 0) (struct.new_default $t0))
|
||||
(table.set (i32.const 10) (struct.new_default $t0))
|
||||
(table.set (i32.const 1) (struct.new_default $t1))
|
||||
(table.set (i32.const 11) (struct.new_default $t1'))
|
||||
(table.set (i32.const 2) (struct.new_default $t2))
|
||||
(table.set (i32.const 12) (struct.new_default $t2'))
|
||||
(table.set (i32.const 3) (struct.new_default $t3))
|
||||
(table.set (i32.const 4) (struct.new_default $t4))
|
||||
)
|
||||
|
||||
(func (export "test-sub")
|
||||
(call $init)
|
||||
(block $l
|
||||
;; must hold
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t0) (ref.null struct))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t0) (ref.null $t0))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t0) (ref.null $t1))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t0) (ref.null $t2))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t0) (ref.null $t3))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t0) (ref.null $t4))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t0) (table.get (i32.const 0)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t0) (table.get (i32.const 1)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t0) (table.get (i32.const 2)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t0) (table.get (i32.const 3)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t0) (table.get (i32.const 4)))))
|
||||
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t1) (ref.null struct))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t1) (ref.null $t0))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t1) (ref.null $t1))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t1) (ref.null $t2))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t1) (ref.null $t3))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t1) (ref.null $t4))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t1) (table.get (i32.const 1)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t1) (table.get (i32.const 2)))))
|
||||
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t2) (ref.null struct))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t2) (ref.null $t0))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t2) (ref.null $t1))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t2) (ref.null $t2))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t2) (ref.null $t3))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t2) (ref.null $t4))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t2) (table.get (i32.const 2)))))
|
||||
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t3) (ref.null struct))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t3) (ref.null $t0))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t3) (ref.null $t1))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t3) (ref.null $t2))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t3) (ref.null $t3))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t3) (ref.null $t4))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t3) (table.get (i32.const 3)))))
|
||||
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t4) (ref.null struct))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t4) (ref.null $t0))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t4) (ref.null $t1))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t4) (ref.null $t2))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t4) (ref.null $t3))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t4) (ref.null $t4))))
|
||||
(br_if $l (i32.eqz (ref.test (ref null $t4) (table.get (i32.const 4)))))
|
||||
|
||||
(br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 0)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 1)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 2)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 3)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 4)))))
|
||||
|
||||
(br_if $l (i32.eqz (ref.test (ref $t1) (table.get (i32.const 1)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref $t1) (table.get (i32.const 2)))))
|
||||
|
||||
(br_if $l (i32.eqz (ref.test (ref $t2) (table.get (i32.const 2)))))
|
||||
|
||||
(br_if $l (i32.eqz (ref.test (ref $t3) (table.get (i32.const 3)))))
|
||||
|
||||
(br_if $l (i32.eqz (ref.test (ref $t4) (table.get (i32.const 4)))))
|
||||
|
||||
;; must not hold
|
||||
(br_if $l (ref.test (ref $t0) (ref.null struct)))
|
||||
(br_if $l (ref.test (ref $t1) (ref.null struct)))
|
||||
(br_if $l (ref.test (ref $t2) (ref.null struct)))
|
||||
(br_if $l (ref.test (ref $t3) (ref.null struct)))
|
||||
(br_if $l (ref.test (ref $t4) (ref.null struct)))
|
||||
|
||||
(br_if $l (ref.test (ref $t1) (table.get (i32.const 0))))
|
||||
(br_if $l (ref.test (ref $t1) (table.get (i32.const 3))))
|
||||
(br_if $l (ref.test (ref $t1) (table.get (i32.const 4))))
|
||||
|
||||
(br_if $l (ref.test (ref $t2) (table.get (i32.const 0))))
|
||||
(br_if $l (ref.test (ref $t2) (table.get (i32.const 1))))
|
||||
(br_if $l (ref.test (ref $t2) (table.get (i32.const 3))))
|
||||
(br_if $l (ref.test (ref $t2) (table.get (i32.const 4))))
|
||||
|
||||
(br_if $l (ref.test (ref $t3) (table.get (i32.const 0))))
|
||||
(br_if $l (ref.test (ref $t3) (table.get (i32.const 1))))
|
||||
(br_if $l (ref.test (ref $t3) (table.get (i32.const 2))))
|
||||
(br_if $l (ref.test (ref $t3) (table.get (i32.const 4))))
|
||||
|
||||
(br_if $l (ref.test (ref $t4) (table.get (i32.const 0))))
|
||||
(br_if $l (ref.test (ref $t4) (table.get (i32.const 1))))
|
||||
(br_if $l (ref.test (ref $t4) (table.get (i32.const 2))))
|
||||
(br_if $l (ref.test (ref $t4) (table.get (i32.const 3))))
|
||||
|
||||
(return)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
|
||||
(func (export "test-canon")
|
||||
(call $init)
|
||||
(block $l
|
||||
(br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 0)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 1)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 2)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 3)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 4)))))
|
||||
|
||||
(br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 10)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 11)))))
|
||||
(br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 12)))))
|
||||
|
||||
;; Must have explicit sub relationship
|
||||
;; (br_if $l (i32.eqz (ref.test (ref $t1') (table.get (i32.const 1)))))
|
||||
;; (br_if $l (i32.eqz (ref.test (ref $t1') (table.get (i32.const 2)))))
|
||||
|
||||
;; (br_if $l (i32.eqz (ref.test (ref $t1) (table.get (i32.const 11)))))
|
||||
;; (br_if $l (i32.eqz (ref.test (ref $t1) (table.get (i32.const 12)))))
|
||||
|
||||
;; (br_if $l (i32.eqz (ref.test (ref $t2') (table.get (i32.const 2)))))
|
||||
|
||||
;; (br_if $l (i32.eqz (ref.test (ref $t2) (table.get (i32.const 12)))))
|
||||
|
||||
(return)
|
||||
)
|
||||
(unreachable)
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "test-sub"))
|
||||
(assert_return (invoke "test-canon"))
|
|
@ -0,0 +1,376 @@
|
|||
;; Test `return_call_ref` operator
|
||||
|
||||
(module
|
||||
;; Auxiliary definitions
|
||||
(type $proc (func))
|
||||
(type $-i32 (func (result i32)))
|
||||
(type $-i64 (func (result i64)))
|
||||
(type $-f32 (func (result f32)))
|
||||
(type $-f64 (func (result f64)))
|
||||
|
||||
(type $i32-i32 (func (param i32) (result i32)))
|
||||
(type $i64-i64 (func (param i64) (result i64)))
|
||||
(type $f32-f32 (func (param f32) (result f32)))
|
||||
(type $f64-f64 (func (param f64) (result f64)))
|
||||
|
||||
(type $f32-i32 (func (param f32 i32) (result i32)))
|
||||
(type $i32-i64 (func (param i32 i64) (result i64)))
|
||||
(type $f64-f32 (func (param f64 f32) (result f32)))
|
||||
(type $i64-f64 (func (param i64 f64) (result f64)))
|
||||
|
||||
(type $i64i64-i64 (func (param i64 i64) (result i64)))
|
||||
|
||||
(func $const-i32 (result i32) (i32.const 0x132))
|
||||
(func $const-i64 (result i64) (i64.const 0x164))
|
||||
(func $const-f32 (result f32) (f32.const 0xf32))
|
||||
(func $const-f64 (result f64) (f64.const 0xf64))
|
||||
|
||||
(func $id-i32 (param i32) (result i32) (local.get 0))
|
||||
(func $id-i64 (param i64) (result i64) (local.get 0))
|
||||
(func $id-f32 (param f32) (result f32) (local.get 0))
|
||||
(func $id-f64 (param f64) (result f64) (local.get 0))
|
||||
|
||||
(func $f32-i32 (param f32 i32) (result i32) (local.get 1))
|
||||
(func $i32-i64 (param i32 i64) (result i64) (local.get 1))
|
||||
(func $f64-f32 (param f64 f32) (result f32) (local.get 1))
|
||||
(func $i64-f64 (param i64 f64) (result f64) (local.get 1))
|
||||
|
||||
(global $const-i32 (ref $-i32) (ref.func $const-i32))
|
||||
(global $const-i64 (ref $-i64) (ref.func $const-i64))
|
||||
(global $const-f32 (ref $-f32) (ref.func $const-f32))
|
||||
(global $const-f64 (ref $-f64) (ref.func $const-f64))
|
||||
|
||||
(global $id-i32 (ref $i32-i32) (ref.func $id-i32))
|
||||
(global $id-i64 (ref $i64-i64) (ref.func $id-i64))
|
||||
(global $id-f32 (ref $f32-f32) (ref.func $id-f32))
|
||||
(global $id-f64 (ref $f64-f64) (ref.func $id-f64))
|
||||
|
||||
(global $f32-i32 (ref $f32-i32) (ref.func $f32-i32))
|
||||
(global $i32-i64 (ref $i32-i64) (ref.func $i32-i64))
|
||||
(global $f64-f32 (ref $f64-f32) (ref.func $f64-f32))
|
||||
(global $i64-f64 (ref $i64-f64) (ref.func $i64-f64))
|
||||
|
||||
(elem declare func
|
||||
$const-i32 $const-i64 $const-f32 $const-f64
|
||||
$id-i32 $id-i64 $id-f32 $id-f64
|
||||
$f32-i32 $i32-i64 $f64-f32 $i64-f64
|
||||
)
|
||||
|
||||
;; Typing
|
||||
|
||||
(func (export "type-i32") (result i32)
|
||||
(return_call_ref $-i32 (global.get $const-i32))
|
||||
)
|
||||
(func (export "type-i64") (result i64)
|
||||
(return_call_ref $-i64 (global.get $const-i64))
|
||||
)
|
||||
(func (export "type-f32") (result f32)
|
||||
(return_call_ref $-f32 (global.get $const-f32))
|
||||
)
|
||||
(func (export "type-f64") (result f64)
|
||||
(return_call_ref $-f64 (global.get $const-f64))
|
||||
)
|
||||
|
||||
(func (export "type-first-i32") (result i32)
|
||||
(return_call_ref $i32-i32 (i32.const 32) (global.get $id-i32))
|
||||
)
|
||||
(func (export "type-first-i64") (result i64)
|
||||
(return_call_ref $i64-i64 (i64.const 64) (global.get $id-i64))
|
||||
)
|
||||
(func (export "type-first-f32") (result f32)
|
||||
(return_call_ref $f32-f32 (f32.const 1.32) (global.get $id-f32))
|
||||
)
|
||||
(func (export "type-first-f64") (result f64)
|
||||
(return_call_ref $f64-f64 (f64.const 1.64) (global.get $id-f64))
|
||||
)
|
||||
|
||||
(func (export "type-second-i32") (result i32)
|
||||
(return_call_ref $f32-i32 (f32.const 32.1) (i32.const 32) (global.get $f32-i32))
|
||||
)
|
||||
(func (export "type-second-i64") (result i64)
|
||||
(return_call_ref $i32-i64 (i32.const 32) (i64.const 64) (global.get $i32-i64))
|
||||
)
|
||||
(func (export "type-second-f32") (result f32)
|
||||
(return_call_ref $f64-f32 (f64.const 64) (f32.const 32) (global.get $f64-f32))
|
||||
)
|
||||
(func (export "type-second-f64") (result f64)
|
||||
(return_call_ref $i64-f64 (i64.const 64) (f64.const 64.1) (global.get $i64-f64))
|
||||
)
|
||||
|
||||
;; Null
|
||||
|
||||
(func (export "null")
|
||||
(return_call_ref $proc (ref.null $proc))
|
||||
)
|
||||
|
||||
;; Recursion
|
||||
|
||||
(global $fac-acc (ref $i64i64-i64) (ref.func $fac-acc))
|
||||
|
||||
(elem declare func $fac-acc)
|
||||
(func $fac-acc (export "fac-acc") (param i64 i64) (result i64)
|
||||
(if (result i64) (i64.eqz (local.get 0))
|
||||
(then (local.get 1))
|
||||
(else
|
||||
(return_call_ref $i64i64-i64
|
||||
(i64.sub (local.get 0) (i64.const 1))
|
||||
(i64.mul (local.get 0) (local.get 1))
|
||||
(global.get $fac-acc)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(global $count (ref $i64-i64) (ref.func $count))
|
||||
|
||||
(elem declare func $count)
|
||||
(func $count (export "count") (param i64) (result i64)
|
||||
(if (result i64) (i64.eqz (local.get 0))
|
||||
(then (local.get 0))
|
||||
(else
|
||||
(return_call_ref $i64-i64
|
||||
(i64.sub (local.get 0) (i64.const 1))
|
||||
(global.get $count)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(global $even (ref $i64-i64) (ref.func $even))
|
||||
(global $odd (ref $i64-i64) (ref.func $odd))
|
||||
|
||||
(elem declare func $even)
|
||||
(func $even (export "even") (param i64) (result i64)
|
||||
(if (result i64) (i64.eqz (local.get 0))
|
||||
(then (i64.const 44))
|
||||
(else
|
||||
(return_call_ref $i64-i64
|
||||
(i64.sub (local.get 0) (i64.const 1))
|
||||
(global.get $odd)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(elem declare func $odd)
|
||||
(func $odd (export "odd") (param i64) (result i64)
|
||||
(if (result i64) (i64.eqz (local.get 0))
|
||||
(then (i64.const 99))
|
||||
(else
|
||||
(return_call_ref $i64-i64
|
||||
(i64.sub (local.get 0) (i64.const 1))
|
||||
(global.get $even)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "type-i32") (i32.const 0x132))
|
||||
(assert_return (invoke "type-i64") (i64.const 0x164))
|
||||
(assert_return (invoke "type-f32") (f32.const 0xf32))
|
||||
(assert_return (invoke "type-f64") (f64.const 0xf64))
|
||||
|
||||
(assert_return (invoke "type-first-i32") (i32.const 32))
|
||||
(assert_return (invoke "type-first-i64") (i64.const 64))
|
||||
(assert_return (invoke "type-first-f32") (f32.const 1.32))
|
||||
(assert_return (invoke "type-first-f64") (f64.const 1.64))
|
||||
|
||||
(assert_return (invoke "type-second-i32") (i32.const 32))
|
||||
(assert_return (invoke "type-second-i64") (i64.const 64))
|
||||
(assert_return (invoke "type-second-f32") (f32.const 32))
|
||||
(assert_return (invoke "type-second-f64") (f64.const 64.1))
|
||||
|
||||
(assert_trap (invoke "null") "null function")
|
||||
|
||||
(assert_return (invoke "fac-acc" (i64.const 0) (i64.const 1)) (i64.const 1))
|
||||
(assert_return (invoke "fac-acc" (i64.const 1) (i64.const 1)) (i64.const 1))
|
||||
(assert_return (invoke "fac-acc" (i64.const 5) (i64.const 1)) (i64.const 120))
|
||||
(assert_return
|
||||
(invoke "fac-acc" (i64.const 25) (i64.const 1))
|
||||
(i64.const 7034535277573963776)
|
||||
)
|
||||
|
||||
(assert_return (invoke "count" (i64.const 0)) (i64.const 0))
|
||||
(assert_return (invoke "count" (i64.const 1000)) (i64.const 0))
|
||||
(assert_return (invoke "count" (i64.const 1200)) (i64.const 0))
|
||||
|
||||
(assert_return (invoke "even" (i64.const 0)) (i64.const 44))
|
||||
(assert_return (invoke "even" (i64.const 1)) (i64.const 99))
|
||||
(assert_return (invoke "even" (i64.const 100)) (i64.const 44))
|
||||
(assert_return (invoke "even" (i64.const 77)) (i64.const 99))
|
||||
(assert_return (invoke "even" (i64.const 1200)) (i64.const 44))
|
||||
(assert_return (invoke "even" (i64.const 1201)) (i64.const 99))
|
||||
(assert_return (invoke "odd" (i64.const 0)) (i64.const 99))
|
||||
(assert_return (invoke "odd" (i64.const 1)) (i64.const 44))
|
||||
(assert_return (invoke "odd" (i64.const 200)) (i64.const 99))
|
||||
(assert_return (invoke "odd" (i64.const 77)) (i64.const 44))
|
||||
(assert_return (invoke "odd" (i64.const 1200)) (i64.const 99))
|
||||
(assert_return (invoke "odd" (i64.const 1119)) (i64.const 44))
|
||||
|
||||
|
||||
;; More typing
|
||||
|
||||
(module
|
||||
(type $t (func))
|
||||
(type $t1 (func (result (ref $t))))
|
||||
(type $t2 (func (result (ref null $t))))
|
||||
(type $t3 (func (result (ref func))))
|
||||
(type $t4 (func (result (ref null func))))
|
||||
(elem declare func $f11 $f22 $f33 $f44)
|
||||
(func $f11 (result (ref $t)) (return_call_ref $t1 (ref.func $f11)))
|
||||
(func $f21 (result (ref null $t)) (return_call_ref $t1 (ref.func $f11)))
|
||||
(func $f22 (result (ref null $t)) (return_call_ref $t2 (ref.func $f22)))
|
||||
(func $f31 (result (ref func)) (return_call_ref $t1 (ref.func $f11)))
|
||||
(func $f33 (result (ref func)) (return_call_ref $t3 (ref.func $f33)))
|
||||
(func $f41 (result (ref null func)) (return_call_ref $t1 (ref.func $f11)))
|
||||
(func $f42 (result (ref null func)) (return_call_ref $t2 (ref.func $f22)))
|
||||
(func $f43 (result (ref null func)) (return_call_ref $t3 (ref.func $f33)))
|
||||
(func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44)))
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (func))
|
||||
(type $t2 (func (result (ref null $t))))
|
||||
(elem declare func $f22)
|
||||
(func $f12 (result (ref $t)) (return_call_ref $t2 (ref.func $f22)))
|
||||
(func $f22 (result (ref null $t)) (return_call_ref $t2 (ref.func $f22)))
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (func))
|
||||
(type $t3 (func (result (ref func))))
|
||||
(elem declare func $f33)
|
||||
(func $f13 (result (ref $t)) (return_call_ref $t3 (ref.func $f33)))
|
||||
(func $f33 (result (ref func)) (return_call_ref $t3 (ref.func $f33)))
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (func))
|
||||
(type $t4 (func (result (ref null func))))
|
||||
(elem declare func $f44)
|
||||
(func $f14 (result (ref $t)) (return_call_ref $t4 (ref.func $f44)))
|
||||
(func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44)))
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (func))
|
||||
(type $t3 (func (result (ref func))))
|
||||
(elem declare func $f33)
|
||||
(func $f23 (result (ref null $t)) (return_call_ref $t3 (ref.func $f33)))
|
||||
(func $f33 (result (ref func)) (return_call_ref $t3 (ref.func $f33)))
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (func))
|
||||
(type $t4 (func (result (ref null func))))
|
||||
(elem declare func $f44)
|
||||
(func $f24 (result (ref null $t)) (return_call_ref $t4 (ref.func $f44)))
|
||||
(func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44)))
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t4 (func (result (ref null func))))
|
||||
(elem declare func $f44)
|
||||
(func $f34 (result (ref func)) (return_call_ref $t4 (ref.func $f44)))
|
||||
(func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44)))
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
|
||||
;; Unreachable typing.
|
||||
|
||||
(module
|
||||
(type $t (func (result i32)))
|
||||
(func (export "unreachable") (result i32)
|
||||
(unreachable)
|
||||
(return_call_ref $t)
|
||||
)
|
||||
)
|
||||
(assert_trap (invoke "unreachable") "unreachable")
|
||||
|
||||
(module
|
||||
(elem declare func $f)
|
||||
(type $t (func (param i32) (result i32)))
|
||||
(func $f (param i32) (result i32) (local.get 0))
|
||||
|
||||
(func (export "unreachable") (result i32)
|
||||
(unreachable)
|
||||
(ref.func $f)
|
||||
(return_call_ref $t)
|
||||
)
|
||||
)
|
||||
(assert_trap (invoke "unreachable") "unreachable")
|
||||
|
||||
(module
|
||||
(elem declare func $f)
|
||||
(type $t (func (param i32) (result i32)))
|
||||
(func $f (param i32) (result i32) (local.get 0))
|
||||
|
||||
(func (export "unreachable") (result i32)
|
||||
(unreachable)
|
||||
(i32.const 0)
|
||||
(ref.func $f)
|
||||
(return_call_ref $t)
|
||||
(i32.const 0)
|
||||
)
|
||||
)
|
||||
(assert_trap (invoke "unreachable") "unreachable")
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(elem declare func $f)
|
||||
(type $t (func (param i32) (result i32)))
|
||||
(func $f (param i32) (result i32) (local.get 0))
|
||||
|
||||
(func (export "unreachable") (result i32)
|
||||
(unreachable)
|
||||
(i64.const 0)
|
||||
(ref.func $f)
|
||||
(return_call_ref $t)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(elem declare func $f)
|
||||
(type $t (func (param i32) (result i32)))
|
||||
(func $f (param i32) (result i32) (local.get 0))
|
||||
|
||||
(func (export "unreachable") (result i32)
|
||||
(unreachable)
|
||||
(ref.func $f)
|
||||
(return_call_ref $t)
|
||||
(i64.const 0)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (func))
|
||||
(func $f (param $r externref)
|
||||
(return_call_ref $t (local.get $r))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
592
tests/requirement-engineering/gc-aot/wasm-apps/select.wast
Normal file
592
tests/requirement-engineering/gc-aot/wasm-apps/select.wast
Normal file
|
@ -0,0 +1,592 @@
|
|||
(module
|
||||
;; Auxiliary
|
||||
(func $dummy)
|
||||
(table $tab funcref (elem $dummy))
|
||||
(memory 1)
|
||||
|
||||
(func (export "select-i32") (param i32 i32 i32) (result i32)
|
||||
(select (local.get 0) (local.get 1) (local.get 2))
|
||||
)
|
||||
(func (export "select-i64") (param i64 i64 i32) (result i64)
|
||||
(select (local.get 0) (local.get 1) (local.get 2))
|
||||
)
|
||||
(func (export "select-f32") (param f32 f32 i32) (result f32)
|
||||
(select (local.get 0) (local.get 1) (local.get 2))
|
||||
)
|
||||
(func (export "select-f64") (param f64 f64 i32) (result f64)
|
||||
(select (local.get 0) (local.get 1) (local.get 2))
|
||||
)
|
||||
|
||||
(func (export "select-i32-t") (param i32 i32 i32) (result i32)
|
||||
(select (result i32) (local.get 0) (local.get 1) (local.get 2))
|
||||
)
|
||||
(func (export "select-i64-t") (param i64 i64 i32) (result i64)
|
||||
(select (result i64) (local.get 0) (local.get 1) (local.get 2))
|
||||
)
|
||||
(func (export "select-f32-t") (param f32 f32 i32) (result f32)
|
||||
(select (result f32) (local.get 0) (local.get 1) (local.get 2))
|
||||
)
|
||||
(func (export "select-f64-t") (param f64 f64 i32) (result f64)
|
||||
(select (result f64) (local.get 0) (local.get 1) (local.get 2))
|
||||
)
|
||||
(func (export "select-funcref") (param funcref funcref i32) (result funcref)
|
||||
(select (result funcref) (local.get 0) (local.get 1) (local.get 2))
|
||||
)
|
||||
(func (export "select-externref") (param externref externref i32) (result externref)
|
||||
(select (result externref) (local.get 0) (local.get 1) (local.get 2))
|
||||
)
|
||||
|
||||
(type $t (func))
|
||||
(func $tf) (elem declare func $tf)
|
||||
(func (export "join-funcnull") (param i32) (result (ref null func))
|
||||
(select (result (ref null func))
|
||||
(ref.func $tf)
|
||||
(ref.null func)
|
||||
(local.get 0)
|
||||
)
|
||||
)
|
||||
|
||||
;; Check that both sides of the select are evaluated
|
||||
(func (export "select-trap-left") (param $cond i32) (result i32)
|
||||
(select (unreachable) (i32.const 0) (local.get $cond))
|
||||
)
|
||||
(func (export "select-trap-right") (param $cond i32) (result i32)
|
||||
(select (i32.const 0) (unreachable) (local.get $cond))
|
||||
)
|
||||
|
||||
(func (export "select-unreached")
|
||||
(unreachable) (select)
|
||||
(unreachable) (i32.const 0) (select)
|
||||
(unreachable) (i32.const 0) (i32.const 0) (select)
|
||||
(unreachable) (i32.const 0) (i32.const 0) (i32.const 0) (select)
|
||||
(unreachable) (f32.const 0) (i32.const 0) (select)
|
||||
(unreachable)
|
||||
)
|
||||
|
||||
(func (export "select_unreached_result_1") (result i32)
|
||||
(unreachable) (i32.add (select))
|
||||
)
|
||||
|
||||
(func (export "select_unreached_result_2") (result i64)
|
||||
(unreachable) (i64.add (select (i64.const 0) (i32.const 0)))
|
||||
)
|
||||
|
||||
|
||||
;; As the argument of control constructs and instructions
|
||||
|
||||
(func (export "as-select-first") (param i32) (result i32)
|
||||
(select (select (i32.const 0) (i32.const 1) (local.get 0)) (i32.const 2) (i32.const 3))
|
||||
)
|
||||
(func (export "as-select-mid") (param i32) (result i32)
|
||||
(select (i32.const 2) (select (i32.const 0) (i32.const 1) (local.get 0)) (i32.const 3))
|
||||
)
|
||||
(func (export "as-select-last") (param i32) (result i32)
|
||||
(select (i32.const 2) (i32.const 3) (select (i32.const 0) (i32.const 1) (local.get 0)))
|
||||
)
|
||||
|
||||
(func (export "as-loop-first") (param i32) (result i32)
|
||||
(loop (result i32) (select (i32.const 2) (i32.const 3) (local.get 0)) (call $dummy) (call $dummy))
|
||||
)
|
||||
(func (export "as-loop-mid") (param i32) (result i32)
|
||||
(loop (result i32) (call $dummy) (select (i32.const 2) (i32.const 3) (local.get 0)) (call $dummy))
|
||||
)
|
||||
(func (export "as-loop-last") (param i32) (result i32)
|
||||
(loop (result i32) (call $dummy) (call $dummy) (select (i32.const 2) (i32.const 3) (local.get 0)))
|
||||
)
|
||||
|
||||
(func (export "as-if-condition") (param i32)
|
||||
(select (i32.const 2) (i32.const 3) (local.get 0)) (if (then (call $dummy)))
|
||||
)
|
||||
(func (export "as-if-then") (param i32) (result i32)
|
||||
(if (result i32) (i32.const 1) (then (select (i32.const 2) (i32.const 3) (local.get 0))) (else (i32.const 4)))
|
||||
)
|
||||
(func (export "as-if-else") (param i32) (result i32)
|
||||
(if (result i32) (i32.const 0) (then (i32.const 2)) (else (select (i32.const 2) (i32.const 3) (local.get 0))))
|
||||
)
|
||||
|
||||
(func (export "as-br_if-first") (param i32) (result i32)
|
||||
(block (result i32) (br_if 0 (select (i32.const 2) (i32.const 3) (local.get 0)) (i32.const 4)))
|
||||
)
|
||||
(func (export "as-br_if-last") (param i32) (result i32)
|
||||
(block (result i32) (br_if 0 (i32.const 2) (select (i32.const 2) (i32.const 3) (local.get 0))))
|
||||
)
|
||||
|
||||
(func (export "as-br_table-first") (param i32) (result i32)
|
||||
(block (result i32) (select (i32.const 2) (i32.const 3) (local.get 0)) (i32.const 2) (br_table 0 0))
|
||||
)
|
||||
(func (export "as-br_table-last") (param i32) (result i32)
|
||||
(block (result i32) (i32.const 2) (select (i32.const 2) (i32.const 3) (local.get 0)) (br_table 0 0))
|
||||
)
|
||||
|
||||
(func $func (param i32 i32) (result i32) (local.get 0))
|
||||
(type $check (func (param i32 i32) (result i32)))
|
||||
(table $t funcref (elem $func))
|
||||
(func (export "as-call_indirect-first") (param i32) (result i32)
|
||||
(block (result i32)
|
||||
(call_indirect $t (type $check)
|
||||
(select (i32.const 2) (i32.const 3) (local.get 0)) (i32.const 1) (i32.const 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func (export "as-call_indirect-mid") (param i32) (result i32)
|
||||
(block (result i32)
|
||||
(call_indirect $t (type $check)
|
||||
(i32.const 1) (select (i32.const 2) (i32.const 3) (local.get 0)) (i32.const 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(func (export "as-call_indirect-last") (param i32) (result i32)
|
||||
(block (result i32)
|
||||
(call_indirect $t (type $check)
|
||||
(i32.const 1) (i32.const 4) (select (i32.const 2) (i32.const 3) (local.get 0))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "as-store-first") (param i32)
|
||||
(select (i32.const 0) (i32.const 4) (local.get 0)) (i32.const 1) (i32.store)
|
||||
)
|
||||
(func (export "as-store-last") (param i32)
|
||||
(i32.const 8) (select (i32.const 1) (i32.const 2) (local.get 0)) (i32.store)
|
||||
)
|
||||
|
||||
(func (export "as-memory.grow-value") (param i32) (result i32)
|
||||
(memory.grow (select (i32.const 1) (i32.const 2) (local.get 0)))
|
||||
)
|
||||
|
||||
(func $f (param i32) (result i32) (local.get 0))
|
||||
|
||||
(func (export "as-call-value") (param i32) (result i32)
|
||||
(call $f (select (i32.const 1) (i32.const 2) (local.get 0)))
|
||||
)
|
||||
(func (export "as-return-value") (param i32) (result i32)
|
||||
(select (i32.const 1) (i32.const 2) (local.get 0)) (return)
|
||||
)
|
||||
(func (export "as-drop-operand") (param i32)
|
||||
(drop (select (i32.const 1) (i32.const 2) (local.get 0)))
|
||||
)
|
||||
(func (export "as-br-value") (param i32) (result i32)
|
||||
(block (result i32) (br 0 (select (i32.const 1) (i32.const 2) (local.get 0))))
|
||||
)
|
||||
(func (export "as-local.set-value") (param i32) (result i32)
|
||||
(local i32) (local.set 0 (select (i32.const 1) (i32.const 2) (local.get 0))) (local.get 0)
|
||||
)
|
||||
(func (export "as-local.tee-value") (param i32) (result i32)
|
||||
(local.tee 0 (select (i32.const 1) (i32.const 2) (local.get 0)))
|
||||
)
|
||||
(global $a (mut i32) (i32.const 10))
|
||||
(func (export "as-global.set-value") (param i32) (result i32)
|
||||
(global.set $a (select (i32.const 1) (i32.const 2) (local.get 0)))
|
||||
(global.get $a)
|
||||
)
|
||||
(func (export "as-load-operand") (param i32) (result i32)
|
||||
(i32.load (select (i32.const 0) (i32.const 4) (local.get 0)))
|
||||
)
|
||||
|
||||
(func (export "as-unary-operand") (param i32) (result i32)
|
||||
(i32.eqz (select (i32.const 0) (i32.const 1) (local.get 0)))
|
||||
)
|
||||
(func (export "as-binary-operand") (param i32) (result i32)
|
||||
(i32.mul
|
||||
(select (i32.const 1) (i32.const 2) (local.get 0))
|
||||
(select (i32.const 1) (i32.const 2) (local.get 0))
|
||||
)
|
||||
)
|
||||
(func (export "as-test-operand") (param i32) (result i32)
|
||||
(block (result i32)
|
||||
(i32.eqz (select (i32.const 0) (i32.const 1) (local.get 0)))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "as-compare-left") (param i32) (result i32)
|
||||
(block (result i32)
|
||||
(i32.le_s (select (i32.const 1) (i32.const 2) (local.get 0)) (i32.const 1))
|
||||
)
|
||||
)
|
||||
(func (export "as-compare-right") (param i32) (result i32)
|
||||
(block (result i32)
|
||||
(i32.ne (i32.const 1) (select (i32.const 0) (i32.const 1) (local.get 0)))
|
||||
)
|
||||
)
|
||||
|
||||
(func (export "as-convert-operand") (param i32) (result i32)
|
||||
(block (result i32)
|
||||
(i32.wrap_i64 (select (i64.const 1) (i64.const 0) (local.get 0)))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "select-i32" (i32.const 1) (i32.const 2) (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "select-i64" (i64.const 2) (i64.const 1) (i32.const 1)) (i64.const 2))
|
||||
(assert_return (invoke "select-f32" (f32.const 1) (f32.const 2) (i32.const 1)) (f32.const 1))
|
||||
(assert_return (invoke "select-f64" (f64.const 1) (f64.const 2) (i32.const 1)) (f64.const 1))
|
||||
|
||||
(assert_return (invoke "select-i32" (i32.const 1) (i32.const 2) (i32.const 0)) (i32.const 2))
|
||||
(assert_return (invoke "select-i32" (i32.const 2) (i32.const 1) (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "select-i64" (i64.const 2) (i64.const 1) (i32.const -1)) (i64.const 2))
|
||||
(assert_return (invoke "select-i64" (i64.const 2) (i64.const 1) (i32.const 0xf0f0f0f0)) (i64.const 2))
|
||||
|
||||
(assert_return (invoke "select-f32" (f32.const nan) (f32.const 1) (i32.const 1)) (f32.const nan))
|
||||
(assert_return (invoke "select-f32" (f32.const nan:0x20304) (f32.const 1) (i32.const 1)) (f32.const nan:0x20304))
|
||||
(assert_return (invoke "select-f32" (f32.const nan) (f32.const 1) (i32.const 0)) (f32.const 1))
|
||||
(assert_return (invoke "select-f32" (f32.const nan:0x20304) (f32.const 1) (i32.const 0)) (f32.const 1))
|
||||
(assert_return (invoke "select-f32" (f32.const 2) (f32.const nan) (i32.const 1)) (f32.const 2))
|
||||
(assert_return (invoke "select-f32" (f32.const 2) (f32.const nan:0x20304) (i32.const 1)) (f32.const 2))
|
||||
(assert_return (invoke "select-f32" (f32.const 2) (f32.const nan) (i32.const 0)) (f32.const nan))
|
||||
(assert_return (invoke "select-f32" (f32.const 2) (f32.const nan:0x20304) (i32.const 0)) (f32.const nan:0x20304))
|
||||
|
||||
(assert_return (invoke "select-f64" (f64.const nan) (f64.const 1) (i32.const 1)) (f64.const nan))
|
||||
(assert_return (invoke "select-f64" (f64.const nan:0x20304) (f64.const 1) (i32.const 1)) (f64.const nan:0x20304))
|
||||
(assert_return (invoke "select-f64" (f64.const nan) (f64.const 1) (i32.const 0)) (f64.const 1))
|
||||
(assert_return (invoke "select-f64" (f64.const nan:0x20304) (f64.const 1) (i32.const 0)) (f64.const 1))
|
||||
(assert_return (invoke "select-f64" (f64.const 2) (f64.const nan) (i32.const 1)) (f64.const 2))
|
||||
(assert_return (invoke "select-f64" (f64.const 2) (f64.const nan:0x20304) (i32.const 1)) (f64.const 2))
|
||||
(assert_return (invoke "select-f64" (f64.const 2) (f64.const nan) (i32.const 0)) (f64.const nan))
|
||||
(assert_return (invoke "select-f64" (f64.const 2) (f64.const nan:0x20304) (i32.const 0)) (f64.const nan:0x20304))
|
||||
|
||||
(assert_return (invoke "select-i32-t" (i32.const 1) (i32.const 2) (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "select-i64-t" (i64.const 2) (i64.const 1) (i32.const 1)) (i64.const 2))
|
||||
(assert_return (invoke "select-f32-t" (f32.const 1) (f32.const 2) (i32.const 1)) (f32.const 1))
|
||||
(assert_return (invoke "select-f64-t" (f64.const 1) (f64.const 2) (i32.const 1)) (f64.const 1))
|
||||
(assert_return (invoke "select-funcref" (ref.null func) (ref.null func) (i32.const 1)) (ref.null func))
|
||||
(assert_return (invoke "select-externref" (ref.extern 1) (ref.extern 2) (i32.const 1)) (ref.extern 1))
|
||||
|
||||
(assert_return (invoke "select-i32-t" (i32.const 1) (i32.const 2) (i32.const 0)) (i32.const 2))
|
||||
(assert_return (invoke "select-i32-t" (i32.const 2) (i32.const 1) (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "select-i64-t" (i64.const 2) (i64.const 1) (i32.const -1)) (i64.const 2))
|
||||
(assert_return (invoke "select-i64-t" (i64.const 2) (i64.const 1) (i32.const 0xf0f0f0f0)) (i64.const 2))
|
||||
(assert_return (invoke "select-externref" (ref.extern 1) (ref.extern 2) (i32.const 0)) (ref.extern 2))
|
||||
(assert_return (invoke "select-externref" (ref.extern 2) (ref.extern 1) (i32.const 0)) (ref.extern 1))
|
||||
|
||||
(assert_return (invoke "select-f32-t" (f32.const nan) (f32.const 1) (i32.const 1)) (f32.const nan))
|
||||
(assert_return (invoke "select-f32-t" (f32.const nan:0x20304) (f32.const 1) (i32.const 1)) (f32.const nan:0x20304))
|
||||
(assert_return (invoke "select-f32-t" (f32.const nan) (f32.const 1) (i32.const 0)) (f32.const 1))
|
||||
(assert_return (invoke "select-f32-t" (f32.const nan:0x20304) (f32.const 1) (i32.const 0)) (f32.const 1))
|
||||
(assert_return (invoke "select-f32-t" (f32.const 2) (f32.const nan) (i32.const 1)) (f32.const 2))
|
||||
(assert_return (invoke "select-f32-t" (f32.const 2) (f32.const nan:0x20304) (i32.const 1)) (f32.const 2))
|
||||
(assert_return (invoke "select-f32-t" (f32.const 2) (f32.const nan) (i32.const 0)) (f32.const nan))
|
||||
(assert_return (invoke "select-f32-t" (f32.const 2) (f32.const nan:0x20304) (i32.const 0)) (f32.const nan:0x20304))
|
||||
|
||||
(assert_return (invoke "select-f64-t" (f64.const nan) (f64.const 1) (i32.const 1)) (f64.const nan))
|
||||
(assert_return (invoke "select-f64-t" (f64.const nan:0x20304) (f64.const 1) (i32.const 1)) (f64.const nan:0x20304))
|
||||
(assert_return (invoke "select-f64-t" (f64.const nan) (f64.const 1) (i32.const 0)) (f64.const 1))
|
||||
(assert_return (invoke "select-f64-t" (f64.const nan:0x20304) (f64.const 1) (i32.const 0)) (f64.const 1))
|
||||
(assert_return (invoke "select-f64-t" (f64.const 2) (f64.const nan) (i32.const 1)) (f64.const 2))
|
||||
(assert_return (invoke "select-f64-t" (f64.const 2) (f64.const nan:0x20304) (i32.const 1)) (f64.const 2))
|
||||
(assert_return (invoke "select-f64-t" (f64.const 2) (f64.const nan) (i32.const 0)) (f64.const nan))
|
||||
(assert_return (invoke "select-f64-t" (f64.const 2) (f64.const nan:0x20304) (i32.const 0)) (f64.const nan:0x20304))
|
||||
|
||||
(assert_return (invoke "join-funcnull" (i32.const 1)) (ref.func))
|
||||
(assert_return (invoke "join-funcnull" (i32.const 0)) (ref.null func)) ;; we require type in expected results
|
||||
|
||||
(assert_trap (invoke "select-trap-left" (i32.const 1)) "unreachable")
|
||||
(assert_trap (invoke "select-trap-left" (i32.const 0)) "unreachable")
|
||||
(assert_trap (invoke "select-trap-right" (i32.const 1)) "unreachable")
|
||||
(assert_trap (invoke "select-trap-right" (i32.const 0)) "unreachable")
|
||||
|
||||
(assert_return (invoke "as-select-first" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "as-select-first" (i32.const 1)) (i32.const 0))
|
||||
(assert_return (invoke "as-select-mid" (i32.const 0)) (i32.const 2))
|
||||
(assert_return (invoke "as-select-mid" (i32.const 1)) (i32.const 2))
|
||||
(assert_return (invoke "as-select-last" (i32.const 0)) (i32.const 2))
|
||||
(assert_return (invoke "as-select-last" (i32.const 1)) (i32.const 3))
|
||||
|
||||
(assert_return (invoke "as-loop-first" (i32.const 0)) (i32.const 3))
|
||||
(assert_return (invoke "as-loop-first" (i32.const 1)) (i32.const 2))
|
||||
(assert_return (invoke "as-loop-mid" (i32.const 0)) (i32.const 3))
|
||||
(assert_return (invoke "as-loop-mid" (i32.const 1)) (i32.const 2))
|
||||
(assert_return (invoke "as-loop-last" (i32.const 0)) (i32.const 3))
|
||||
(assert_return (invoke "as-loop-last" (i32.const 1)) (i32.const 2))
|
||||
|
||||
(assert_return (invoke "as-if-condition" (i32.const 0)))
|
||||
(assert_return (invoke "as-if-condition" (i32.const 1)))
|
||||
(assert_return (invoke "as-if-then" (i32.const 0)) (i32.const 3))
|
||||
(assert_return (invoke "as-if-then" (i32.const 1)) (i32.const 2))
|
||||
(assert_return (invoke "as-if-else" (i32.const 0)) (i32.const 3))
|
||||
(assert_return (invoke "as-if-else" (i32.const 1)) (i32.const 2))
|
||||
|
||||
(assert_return (invoke "as-br_if-first" (i32.const 0)) (i32.const 3))
|
||||
(assert_return (invoke "as-br_if-first" (i32.const 1)) (i32.const 2))
|
||||
(assert_return (invoke "as-br_if-last" (i32.const 0)) (i32.const 2))
|
||||
(assert_return (invoke "as-br_if-last" (i32.const 1)) (i32.const 2))
|
||||
|
||||
(assert_return (invoke "as-br_table-first" (i32.const 0)) (i32.const 3))
|
||||
(assert_return (invoke "as-br_table-first" (i32.const 1)) (i32.const 2))
|
||||
(assert_return (invoke "as-br_table-last" (i32.const 0)) (i32.const 2))
|
||||
(assert_return (invoke "as-br_table-last" (i32.const 1)) (i32.const 2))
|
||||
|
||||
(assert_return (invoke "as-call_indirect-first" (i32.const 0)) (i32.const 3))
|
||||
(assert_return (invoke "as-call_indirect-first" (i32.const 1)) (i32.const 2))
|
||||
(assert_return (invoke "as-call_indirect-mid" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "as-call_indirect-mid" (i32.const 1)) (i32.const 1))
|
||||
(assert_trap (invoke "as-call_indirect-last" (i32.const 0)) "undefined element")
|
||||
(assert_trap (invoke "as-call_indirect-last" (i32.const 1)) "undefined element")
|
||||
|
||||
(assert_return (invoke "as-store-first" (i32.const 0)))
|
||||
(assert_return (invoke "as-store-first" (i32.const 1)))
|
||||
(assert_return (invoke "as-store-last" (i32.const 0)))
|
||||
(assert_return (invoke "as-store-last" (i32.const 1)))
|
||||
|
||||
(assert_return (invoke "as-memory.grow-value" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "as-memory.grow-value" (i32.const 1)) (i32.const 3))
|
||||
|
||||
(assert_return (invoke "as-call-value" (i32.const 0)) (i32.const 2))
|
||||
(assert_return (invoke "as-call-value" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "as-return-value" (i32.const 0)) (i32.const 2))
|
||||
(assert_return (invoke "as-return-value" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "as-drop-operand" (i32.const 0)))
|
||||
(assert_return (invoke "as-drop-operand" (i32.const 1)))
|
||||
(assert_return (invoke "as-br-value" (i32.const 0)) (i32.const 2))
|
||||
(assert_return (invoke "as-br-value" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "as-local.set-value" (i32.const 0)) (i32.const 2))
|
||||
(assert_return (invoke "as-local.set-value" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "as-local.tee-value" (i32.const 0)) (i32.const 2))
|
||||
(assert_return (invoke "as-local.tee-value" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "as-global.set-value" (i32.const 0)) (i32.const 2))
|
||||
(assert_return (invoke "as-global.set-value" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "as-load-operand" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "as-load-operand" (i32.const 1)) (i32.const 1))
|
||||
|
||||
(assert_return (invoke "as-unary-operand" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "as-unary-operand" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "as-binary-operand" (i32.const 0)) (i32.const 4))
|
||||
(assert_return (invoke "as-binary-operand" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "as-test-operand" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "as-test-operand" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "as-compare-left" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "as-compare-left" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "as-compare-right" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "as-compare-right" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "as-convert-operand" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "as-convert-operand" (i32.const 1)) (i32.const 1))
|
||||
|
||||
(assert_invalid
|
||||
(module (func $arity-0-implicit (select (nop) (nop) (i32.const 1))))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $arity-0 (select (result) (nop) (nop) (i32.const 1))))
|
||||
"invalid result arity"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $arity-2 (result i32 i32)
|
||||
(select (result i32 i32)
|
||||
(i32.const 0) (i32.const 0)
|
||||
(i32.const 0) (i32.const 0)
|
||||
(i32.const 1)
|
||||
)
|
||||
))
|
||||
"invalid result arity"
|
||||
)
|
||||
|
||||
|
||||
(assert_invalid
|
||||
(module (type $t (func))
|
||||
(func $type-ref-implicit (param $r (ref $t))
|
||||
(drop (select (local.get $r) (local.get $r) (i32.const 1)))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-funcref-implicit (param $r funcref)
|
||||
(drop (select (local.get $r) (local.get $r) (i32.const 1)))
|
||||
))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-externref-implicit (param $r externref)
|
||||
(drop (select (local.get $r) (local.get $r) (i32.const 1)))
|
||||
))
|
||||
"type mismatch"
|
||||
)
|
||||
(module (func $type-unreachable-ref-implicit
|
||||
(drop (ref.is_null (select (unreachable) (i32.const 1))))
|
||||
))
|
||||
|
||||
(assert_invalid
|
||||
(module (func $type-num-vs-num
|
||||
(drop (select (i32.const 1) (i64.const 1) (i32.const 1)))
|
||||
))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-num-vs-num
|
||||
(drop (select (i32.const 1) (f32.const 1.0) (i32.const 1)))
|
||||
))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-num-vs-num
|
||||
(drop (select (i32.const 1) (f64.const 1.0) (i32.const 1)))
|
||||
))
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module (func $type-num-vs-num (select (i32.const 1) (i64.const 1) (i32.const 1)) (drop)))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-num-vs-num (select (i32.const 1) (f32.const 1.0) (i32.const 1)) (drop)))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-num-vs-num (select (i32.const 1) (i64.const 1) (i32.const 1)) (drop)))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-num-vs-num (select (i32.const 1) (f32.const 1.0) (i32.const 1)) (drop)))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func $type-num-vs-num (select (i32.const 1) (f64.const 1.0) (i32.const 1)) (drop)))
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-1st-operand-empty
|
||||
(select) (drop)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-2nd-operand-empty
|
||||
(i32.const 0) (select) (drop)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-3rd-operand-empty
|
||||
(i32.const 0) (i32.const 0) (select) (drop)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-1st-operand-empty-in-block
|
||||
(i32.const 0) (i32.const 0) (i32.const 0)
|
||||
(block (select) (drop))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-2nd-operand-empty-in-block
|
||||
(i32.const 0) (i32.const 0)
|
||||
(block (i32.const 0) (select) (drop))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-3rd-operand-empty-in-block
|
||||
(i32.const 0)
|
||||
(block (i32.const 0) (i32.const 0) (select) (drop))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-1st-operand-empty-in-loop
|
||||
(i32.const 0) (i32.const 0) (i32.const 0)
|
||||
(loop (select) (drop))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-2nd-operand-empty-in-loop
|
||||
(i32.const 0) (i32.const 0)
|
||||
(loop (i32.const 0) (select) (drop))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-3rd-operand-empty-in-loop
|
||||
(i32.const 0)
|
||||
(loop (i32.const 0) (i32.const 0) (select) (drop))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-1st-operand-empty-in-then
|
||||
(i32.const 0) (i32.const 0) (i32.const 0)
|
||||
(if (then (select) (drop)))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-2nd-operand-empty-in-then
|
||||
(i32.const 0) (i32.const 0)
|
||||
(if (then (i32.const 0) (select) (drop)))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(func $type-3rd-operand-empty-in-then
|
||||
(i32.const 0)
|
||||
(if (then (i32.const 0) (i32.const 0) (select) (drop)))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
;; Third operand must be i32
|
||||
|
||||
(assert_invalid
|
||||
(module (func (select (i32.const 1) (i32.const 1) (i64.const 1)) (drop)))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func (select (i32.const 1) (i32.const 1) (f32.const 1)) (drop)))
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module (func (select (i32.const 1) (i32.const 1) (f64.const 1)) (drop)))
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
;; Result of select has type of first two operands
|
||||
|
||||
(assert_invalid
|
||||
(module (func (result i32) (select (i64.const 1) (i64.const 1) (i32.const 1))))
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
|
||||
;; Flat syntax
|
||||
|
||||
(module
|
||||
(table 1 funcref)
|
||||
(func (result i32) unreachable select)
|
||||
(func (result i32) unreachable select nop)
|
||||
(func (result i32) unreachable select (select))
|
||||
(func (result i32) unreachable select select)
|
||||
(func (result i32) unreachable select select select)
|
||||
(func (result i32) unreachable select (result i32))
|
||||
(func (result i32) unreachable select (result i32) (result))
|
||||
(func (result i32) unreachable select (result i32) (result) select)
|
||||
(func (result i32) unreachable select (result) (result i32) select (result i32))
|
||||
(func (result i32) unreachable select call_indirect)
|
||||
(func (result i32) unreachable select call_indirect select)
|
||||
)
|
229
tests/requirement-engineering/gc-aot/wasm-apps/struct.wast
Normal file
229
tests/requirement-engineering/gc-aot/wasm-apps/struct.wast
Normal file
|
@ -0,0 +1,229 @@
|
|||
;; Type syntax
|
||||
|
||||
(module
|
||||
(type (struct))
|
||||
(type (struct (field)))
|
||||
(type (struct (field i8)))
|
||||
(type (struct (field i8 i8 i8 i8)))
|
||||
(type (struct (field $x1 i32) (field $y1 i32)))
|
||||
(type (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
|
||||
(type (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
|
||||
(type (struct (field $x2 i32) (field f32 f64) (field $y2 i32)))
|
||||
)
|
||||
|
||||
|
||||
(assert_malformed
|
||||
(module quote
|
||||
"(type (struct (field $x i32) (field $x i32)))"
|
||||
)
|
||||
"duplicate field"
|
||||
)
|
||||
|
||||
|
||||
;; Binding structure
|
||||
|
||||
(module
|
||||
(rec
|
||||
(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"
|
||||
)
|
||||
|
||||
|
||||
;; Field names
|
||||
|
||||
(module
|
||||
(type (struct (field $x i32)))
|
||||
(type $t1 (struct (field i32) (field $x f32)))
|
||||
(type $t2 (struct (field i32 i32) (field $x i64)))
|
||||
|
||||
(func (param (ref 0)) (result i32) (struct.get 0 $x (local.get 0)))
|
||||
(func (param (ref $t1)) (result f32) (struct.get 1 $x (local.get 0)))
|
||||
(func (param (ref $t2)) (result i64) (struct.get $t2 $x (local.get 0)))
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type (struct (field $x i64)))
|
||||
(type $t (struct (field $x i32)))
|
||||
(func (param (ref 0)) (result i32) (struct.get 0 $x (local.get 0)))
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
|
||||
;; Basic instructions
|
||||
|
||||
(module
|
||||
(type $vec (struct (field f32) (field $y (mut f32)) (field $z f32)))
|
||||
|
||||
(global (ref $vec) (struct.new $vec (f32.const 1) (f32.const 2) (f32.const 3)))
|
||||
(global (ref $vec) (struct.new_default $vec))
|
||||
|
||||
(func (export "new") (result anyref)
|
||||
(struct.new_default $vec)
|
||||
)
|
||||
|
||||
(func $get_0_0 (param $v (ref $vec)) (result f32)
|
||||
(struct.get 0 0 (local.get $v))
|
||||
)
|
||||
(func (export "get_0_0") (result f32)
|
||||
(call $get_0_0 (struct.new_default $vec))
|
||||
)
|
||||
(func $get_vec_0 (param $v (ref $vec)) (result f32)
|
||||
(struct.get $vec 0 (local.get $v))
|
||||
)
|
||||
(func (export "get_vec_0") (result f32)
|
||||
(call $get_vec_0 (struct.new_default $vec))
|
||||
)
|
||||
(func $get_0_y (param $v (ref $vec)) (result f32)
|
||||
(struct.get 0 $y (local.get $v))
|
||||
)
|
||||
(func (export "get_0_y") (result f32)
|
||||
(call $get_0_y (struct.new_default $vec))
|
||||
)
|
||||
(func $get_vec_y (param $v (ref $vec)) (result f32)
|
||||
(struct.get $vec $y (local.get $v))
|
||||
)
|
||||
(func (export "get_vec_y") (result f32)
|
||||
(call $get_vec_y (struct.new_default $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 $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 $vec) (local.get $y))
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "new") (ref.struct))
|
||||
|
||||
(assert_return (invoke "get_0_0") (f32.const 0))
|
||||
(assert_return (invoke "get_vec_0") (f32.const 0))
|
||||
(assert_return (invoke "get_0_y") (f32.const 0))
|
||||
(assert_return (invoke "get_vec_y") (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 (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")
|
||||
|
||||
;; Packed field instructions
|
||||
|
||||
(module
|
||||
(type $s (struct (field i8) (field (mut i8)) (field i16) (field (mut i16))))
|
||||
|
||||
(global (export "g0") (ref $s) (struct.new $s (i32.const 0) (i32.const 1) (i32.const 2) (i32.const 3)))
|
||||
(global (export "g1") (ref $s) (struct.new $s (i32.const 254) (i32.const 255) (i32.const 65534) (i32.const 65535)))
|
||||
|
||||
(func (export "get_packed_g0_0") (result i32 i32)
|
||||
(struct.get_s 0 0 (global.get 0))
|
||||
(struct.get_u 0 0 (global.get 0))
|
||||
)
|
||||
|
||||
(func (export "get_packed_g1_0") (result i32 i32)
|
||||
(struct.get_s 0 0 (global.get 1))
|
||||
(struct.get_u 0 0 (global.get 1))
|
||||
)
|
||||
|
||||
(func (export "get_packed_g0_1") (result i32 i32)
|
||||
(struct.get_s 0 1 (global.get 0))
|
||||
(struct.get_u 0 1 (global.get 0))
|
||||
)
|
||||
|
||||
(func (export "get_packed_g1_1") (result i32 i32)
|
||||
(struct.get_s 0 1 (global.get 1))
|
||||
(struct.get_u 0 1 (global.get 1))
|
||||
)
|
||||
|
||||
(func (export "get_packed_g0_2") (result i32 i32)
|
||||
(struct.get_s 0 2 (global.get 0))
|
||||
(struct.get_u 0 2 (global.get 0))
|
||||
)
|
||||
|
||||
(func (export "get_packed_g1_2") (result i32 i32)
|
||||
(struct.get_s 0 2 (global.get 1))
|
||||
(struct.get_u 0 2 (global.get 1))
|
||||
)
|
||||
|
||||
(func (export "get_packed_g0_3") (result i32 i32)
|
||||
(struct.get_s 0 3 (global.get 0))
|
||||
(struct.get_u 0 3 (global.get 0))
|
||||
)
|
||||
|
||||
(func (export "get_packed_g1_3") (result i32 i32)
|
||||
(struct.get_s 0 3 (global.get 1))
|
||||
(struct.get_u 0 3 (global.get 1))
|
||||
)
|
||||
|
||||
(func (export "set_get_packed_g0_1") (param i32) (result i32 i32)
|
||||
(struct.set 0 1 (global.get 0) (local.get 0))
|
||||
(struct.get_s 0 1 (global.get 0))
|
||||
(struct.get_u 0 1 (global.get 0))
|
||||
)
|
||||
|
||||
(func (export "set_get_packed_g0_3") (param i32) (result i32 i32)
|
||||
(struct.set 0 3 (global.get 0) (local.get 0))
|
||||
(struct.get_s 0 3 (global.get 0))
|
||||
(struct.get_u 0 3 (global.get 0))
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "get_packed_g0_0") (i32.const 0) (i32.const 0))
|
||||
(assert_return (invoke "get_packed_g1_0") (i32.const -2) (i32.const 254))
|
||||
(assert_return (invoke "get_packed_g0_1") (i32.const 1) (i32.const 1))
|
||||
(assert_return (invoke "get_packed_g1_1") (i32.const -1) (i32.const 255))
|
||||
(assert_return (invoke "get_packed_g0_2") (i32.const 2) (i32.const 2))
|
||||
(assert_return (invoke "get_packed_g1_2") (i32.const -2) (i32.const 65534))
|
||||
(assert_return (invoke "get_packed_g0_3") (i32.const 3) (i32.const 3))
|
||||
(assert_return (invoke "get_packed_g1_3") (i32.const -1) (i32.const 65535))
|
||||
|
||||
(assert_return (invoke "set_get_packed_g0_1" (i32.const 257)) (i32.const 1) (i32.const 1))
|
||||
(assert_return (invoke "set_get_packed_g0_3" (i32.const 257)) (i32.const 257) (i32.const 257))
|
157
tests/requirement-engineering/gc-aot/wasm-apps/table_fill.wast
Normal file
157
tests/requirement-engineering/gc-aot/wasm-apps/table_fill.wast
Normal file
|
@ -0,0 +1,157 @@
|
|||
(module
|
||||
(table $t 10 externref)
|
||||
|
||||
(func (export "fill") (param $i i32) (param $r externref) (param $n i32)
|
||||
(table.fill $t (local.get $i) (local.get $r) (local.get $n))
|
||||
)
|
||||
|
||||
(func (export "fill-abbrev") (param $i i32) (param $r externref) (param $n i32)
|
||||
(table.fill (local.get $i) (local.get $r) (local.get $n))
|
||||
)
|
||||
|
||||
(func (export "get") (param $i i32) (result externref)
|
||||
(table.get $t (local.get $i))
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "get" (i32.const 1)) (ref.null extern))
|
||||
(assert_return (invoke "get" (i32.const 2)) (ref.null extern))
|
||||
(assert_return (invoke "get" (i32.const 3)) (ref.null extern))
|
||||
(assert_return (invoke "get" (i32.const 4)) (ref.null extern))
|
||||
(assert_return (invoke "get" (i32.const 5)) (ref.null extern))
|
||||
|
||||
(assert_return (invoke "fill" (i32.const 2) (ref.extern 1) (i32.const 3)))
|
||||
(assert_return (invoke "get" (i32.const 1)) (ref.null extern))
|
||||
(assert_return (invoke "get" (i32.const 2)) (ref.extern 1))
|
||||
(assert_return (invoke "get" (i32.const 3)) (ref.extern 1))
|
||||
(assert_return (invoke "get" (i32.const 4)) (ref.extern 1))
|
||||
(assert_return (invoke "get" (i32.const 5)) (ref.null extern))
|
||||
|
||||
(assert_return (invoke "fill" (i32.const 4) (ref.extern 2) (i32.const 2)))
|
||||
(assert_return (invoke "get" (i32.const 3)) (ref.extern 1))
|
||||
(assert_return (invoke "get" (i32.const 4)) (ref.extern 2))
|
||||
(assert_return (invoke "get" (i32.const 5)) (ref.extern 2))
|
||||
(assert_return (invoke "get" (i32.const 6)) (ref.null extern))
|
||||
|
||||
(assert_return (invoke "fill" (i32.const 4) (ref.extern 3) (i32.const 0)))
|
||||
(assert_return (invoke "get" (i32.const 3)) (ref.extern 1))
|
||||
(assert_return (invoke "get" (i32.const 4)) (ref.extern 2))
|
||||
(assert_return (invoke "get" (i32.const 5)) (ref.extern 2))
|
||||
|
||||
(assert_return (invoke "fill" (i32.const 8) (ref.extern 4) (i32.const 2)))
|
||||
(assert_return (invoke "get" (i32.const 7)) (ref.null extern))
|
||||
(assert_return (invoke "get" (i32.const 8)) (ref.extern 4))
|
||||
(assert_return (invoke "get" (i32.const 9)) (ref.extern 4))
|
||||
|
||||
(assert_return (invoke "fill-abbrev" (i32.const 9) (ref.null extern) (i32.const 1)))
|
||||
(assert_return (invoke "get" (i32.const 8)) (ref.extern 4))
|
||||
(assert_return (invoke "get" (i32.const 9)) (ref.null extern))
|
||||
|
||||
(assert_return (invoke "fill" (i32.const 10) (ref.extern 5) (i32.const 0)))
|
||||
(assert_return (invoke "get" (i32.const 9)) (ref.null extern))
|
||||
|
||||
(assert_trap
|
||||
(invoke "fill" (i32.const 8) (ref.extern 6) (i32.const 3))
|
||||
"out of bounds table access"
|
||||
)
|
||||
(assert_return (invoke "get" (i32.const 7)) (ref.null extern))
|
||||
(assert_return (invoke "get" (i32.const 8)) (ref.extern 4))
|
||||
(assert_return (invoke "get" (i32.const 9)) (ref.null extern))
|
||||
|
||||
(assert_trap
|
||||
(invoke "fill" (i32.const 11) (ref.null extern) (i32.const 0))
|
||||
"out of bounds table access"
|
||||
)
|
||||
|
||||
(assert_trap
|
||||
(invoke "fill" (i32.const 11) (ref.null extern) (i32.const 10))
|
||||
"out of bounds table access"
|
||||
)
|
||||
|
||||
|
||||
;; Type errors
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 10 externref)
|
||||
(func $type-index-value-length-empty-vs-i32-i32
|
||||
(table.fill $t)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 10 externref)
|
||||
(func $type-index-empty-vs-i32
|
||||
(table.fill $t (ref.null extern) (i32.const 1))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 10 externref)
|
||||
(func $type-value-empty-vs
|
||||
(table.fill $t (i32.const 1) (i32.const 1))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 10 externref)
|
||||
(func $type-length-empty-vs-i32
|
||||
(table.fill $t (i32.const 1) (ref.null extern))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 0 externref)
|
||||
(func $type-index-f32-vs-i32
|
||||
(table.fill $t (f32.const 1) (ref.null extern) (i32.const 1))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 0 funcref)
|
||||
(func $type-value-vs-funcref (param $r externref)
|
||||
(table.fill $t (i32.const 1) (local.get $r) (i32.const 1))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 0 externref)
|
||||
(func $type-length-f32-vs-i32
|
||||
(table.fill $t (i32.const 1) (ref.null extern) (f32.const 1))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t1 1 externref)
|
||||
(table $t2 1 funcref)
|
||||
(func $type-value-externref-vs-funcref-multi (param $r externref)
|
||||
(table.fill $t2 (i32.const 0) (local.get $r) (i32.const 1))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 1 externref)
|
||||
(func $type-result-empty-vs-num (result i32)
|
||||
(table.fill $t (i32.const 0) (ref.null extern) (i32.const 1))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
|
@ -0,0 +1,88 @@
|
|||
(module
|
||||
(table $t2 2 externref)
|
||||
(table $t3 3 funcref)
|
||||
(elem (table $t3) (i32.const 1) func $dummy)
|
||||
(func $dummy)
|
||||
|
||||
(func (export "init") (param $r externref)
|
||||
(table.set $t2 (i32.const 1) (local.get $r))
|
||||
(table.set $t3 (i32.const 2) (table.get $t3 (i32.const 1)))
|
||||
)
|
||||
|
||||
(func (export "get-externref") (param $i i32) (result externref)
|
||||
(table.get (local.get $i))
|
||||
)
|
||||
(func $f3 (export "get-funcref") (param $i i32) (result funcref)
|
||||
(table.get $t3 (local.get $i))
|
||||
)
|
||||
|
||||
(func (export "is_null-funcref") (param $i i32) (result i32)
|
||||
(ref.is_null (call $f3 (local.get $i)))
|
||||
)
|
||||
)
|
||||
|
||||
(invoke "init" (ref.extern 1))
|
||||
|
||||
(assert_return (invoke "get-externref" (i32.const 0)) (ref.null extern))
|
||||
(assert_return (invoke "get-externref" (i32.const 1)) (ref.extern 1))
|
||||
|
||||
(assert_return (invoke "get-funcref" (i32.const 0)) (ref.null func))
|
||||
(assert_return (invoke "is_null-funcref" (i32.const 1)) (i32.const 0))
|
||||
(assert_return (invoke "is_null-funcref" (i32.const 2)) (i32.const 0))
|
||||
|
||||
(assert_trap (invoke "get-externref" (i32.const 2)) "out of bounds table access")
|
||||
(assert_trap (invoke "get-funcref" (i32.const 3)) "out of bounds table access")
|
||||
(assert_trap (invoke "get-externref" (i32.const -1)) "out of bounds table access")
|
||||
(assert_trap (invoke "get-funcref" (i32.const -1)) "out of bounds table access")
|
||||
|
||||
|
||||
;; Type errors
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 10 externref)
|
||||
(func $type-index-empty-vs-i32 (result externref)
|
||||
(table.get $t)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 10 externref)
|
||||
(func $type-index-f32-vs-i32 (result externref)
|
||||
(table.get $t (f32.const 1))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 10 externref)
|
||||
(func $type-result-externref-vs-empty
|
||||
(table.get $t (i32.const 0))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 10 externref)
|
||||
(func $type-result-externref-vs-funcref (result funcref)
|
||||
(table.get $t (i32.const 1))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t1 1 funcref)
|
||||
(table $t2 1 externref)
|
||||
(func $type-result-externref-vs-funcref-multi (result funcref)
|
||||
(table.get $t2 (i32.const 0))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
176
tests/requirement-engineering/gc-aot/wasm-apps/table_grow.wast
Normal file
176
tests/requirement-engineering/gc-aot/wasm-apps/table_grow.wast
Normal file
|
@ -0,0 +1,176 @@
|
|||
(module
|
||||
(table $t 0 externref)
|
||||
|
||||
(func (export "get") (param $i i32) (result externref) (table.get $t (local.get $i)))
|
||||
(func (export "set") (param $i i32) (param $r externref) (table.set $t (local.get $i) (local.get $r)))
|
||||
|
||||
(func (export "grow") (param $sz i32) (param $init externref) (result i32)
|
||||
(table.grow $t (local.get $init) (local.get $sz))
|
||||
)
|
||||
(func (export "grow-abbrev") (param $sz i32) (param $init externref) (result i32)
|
||||
(table.grow (local.get $init) (local.get $sz))
|
||||
)
|
||||
(func (export "size") (result i32) (table.size $t))
|
||||
)
|
||||
|
||||
(assert_return (invoke "size") (i32.const 0))
|
||||
(assert_trap (invoke "set" (i32.const 0) (ref.extern 2)) "out of bounds table access")
|
||||
(assert_trap (invoke "get" (i32.const 0)) "out of bounds table access")
|
||||
|
||||
(assert_return (invoke "grow" (i32.const 1) (ref.null extern)) (i32.const 0))
|
||||
(assert_return (invoke "size") (i32.const 1))
|
||||
(assert_return (invoke "get" (i32.const 0)) (ref.null extern))
|
||||
(assert_return (invoke "set" (i32.const 0) (ref.extern 2)))
|
||||
(assert_return (invoke "get" (i32.const 0)) (ref.extern 2))
|
||||
(assert_trap (invoke "set" (i32.const 1) (ref.extern 2)) "out of bounds table access")
|
||||
(assert_trap (invoke "get" (i32.const 1)) "out of bounds table access")
|
||||
|
||||
(assert_return (invoke "grow-abbrev" (i32.const 4) (ref.extern 3)) (i32.const 1))
|
||||
(assert_return (invoke "size") (i32.const 5))
|
||||
(assert_return (invoke "get" (i32.const 0)) (ref.extern 2))
|
||||
(assert_return (invoke "set" (i32.const 0) (ref.extern 2)))
|
||||
(assert_return (invoke "get" (i32.const 0)) (ref.extern 2))
|
||||
(assert_return (invoke "get" (i32.const 1)) (ref.extern 3))
|
||||
(assert_return (invoke "get" (i32.const 4)) (ref.extern 3))
|
||||
(assert_return (invoke "set" (i32.const 4) (ref.extern 4)))
|
||||
(assert_return (invoke "get" (i32.const 4)) (ref.extern 4))
|
||||
(assert_trap (invoke "set" (i32.const 5) (ref.extern 2)) "out of bounds table access")
|
||||
(assert_trap (invoke "get" (i32.const 5)) "out of bounds table access")
|
||||
|
||||
|
||||
;; Reject growing to size outside i32 value range
|
||||
(module
|
||||
(table $t 0x10 funcref)
|
||||
(elem declare func $f)
|
||||
(func $f (export "grow") (result i32)
|
||||
(table.grow $t (ref.func $f) (i32.const 0xffff_fff0))
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "grow") (i32.const -1))
|
||||
|
||||
|
||||
(module
|
||||
(table $t 0 externref)
|
||||
(func (export "grow") (param i32) (result i32)
|
||||
(table.grow $t (ref.null extern) (local.get 0))
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "grow" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "grow" (i32.const 1)) (i32.const 0))
|
||||
(assert_return (invoke "grow" (i32.const 0)) (i32.const 1))
|
||||
(assert_return (invoke "grow" (i32.const 2)) (i32.const 1))
|
||||
(assert_return (invoke "grow" (i32.const 800)) (i32.const 3))
|
||||
|
||||
|
||||
(module
|
||||
(table $t 0 10 externref)
|
||||
(func (export "grow") (param i32) (result i32)
|
||||
(table.grow $t (ref.null extern) (local.get 0))
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "grow" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "grow" (i32.const 1)) (i32.const 0))
|
||||
(assert_return (invoke "grow" (i32.const 1)) (i32.const 1))
|
||||
(assert_return (invoke "grow" (i32.const 2)) (i32.const 2))
|
||||
(assert_return (invoke "grow" (i32.const 6)) (i32.const 4))
|
||||
(assert_return (invoke "grow" (i32.const 0)) (i32.const 10))
|
||||
(assert_return (invoke "grow" (i32.const 1)) (i32.const -1))
|
||||
(assert_return (invoke "grow" (i32.const 0x10000)) (i32.const -1))
|
||||
|
||||
|
||||
(module
|
||||
(table $t 10 funcref)
|
||||
(func (export "grow") (param i32) (result i32)
|
||||
(table.grow $t (ref.null func) (local.get 0))
|
||||
)
|
||||
(elem declare func 1)
|
||||
(func (export "check-table-null") (param i32 i32) (result funcref)
|
||||
(local funcref)
|
||||
(local.set 2 (ref.func 1))
|
||||
(block
|
||||
(loop
|
||||
(local.set 2 (table.get $t (local.get 0)))
|
||||
(br_if 1 (i32.eqz (ref.is_null (local.get 2))))
|
||||
(br_if 1 (i32.ge_u (local.get 0) (local.get 1)))
|
||||
(local.set 0 (i32.add (local.get 0) (i32.const 1)))
|
||||
(br_if 0 (i32.le_u (local.get 0) (local.get 1)))
|
||||
)
|
||||
)
|
||||
(local.get 2)
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "check-table-null" (i32.const 0) (i32.const 9)) (ref.null func))
|
||||
(assert_return (invoke "grow" (i32.const 10)) (i32.const 10))
|
||||
(assert_return (invoke "check-table-null" (i32.const 0) (i32.const 19)) (ref.null func))
|
||||
|
||||
|
||||
;; Type errors
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 0 externref)
|
||||
(func $type-init-size-empty-vs-i32-externref (result i32)
|
||||
(table.grow $t)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 0 externref)
|
||||
(func $type-size-empty-vs-i32 (result i32)
|
||||
(table.grow $t (ref.null extern))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 0 externref)
|
||||
(func $type-init-empty-vs-externref (result i32)
|
||||
(table.grow $t (i32.const 1))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 0 externref)
|
||||
(func $type-size-f32-vs-i32 (result i32)
|
||||
(table.grow $t (ref.null extern) (f32.const 1))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 0 funcref)
|
||||
(func $type-init-externref-vs-funcref (param $r externref) (result i32)
|
||||
(table.grow $t (local.get $r) (i32.const 1))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 1 externref)
|
||||
(func $type-result-i32-vs-empty
|
||||
(table.grow $t (ref.null extern) (i32.const 0))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 1 externref)
|
||||
(func $type-result-i32-vs-f32 (result f32)
|
||||
(table.grow $t (ref.null extern) (i32.const 0))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
2149
tests/requirement-engineering/gc-aot/wasm-apps/table_init.wast
Normal file
2149
tests/requirement-engineering/gc-aot/wasm-apps/table_init.wast
Normal file
File diff suppressed because it is too large
Load Diff
119
tests/requirement-engineering/gc-aot/wasm-apps/table_set.wast
Normal file
119
tests/requirement-engineering/gc-aot/wasm-apps/table_set.wast
Normal file
|
@ -0,0 +1,119 @@
|
|||
(module
|
||||
(table $t2 1 externref)
|
||||
(table $t3 2 funcref)
|
||||
(elem (table $t3) (i32.const 1) func $dummy)
|
||||
(func $dummy)
|
||||
|
||||
(func (export "get-externref") (param $i i32) (result externref)
|
||||
(table.get $t2 (local.get $i))
|
||||
)
|
||||
(func $f3 (export "get-funcref") (param $i i32) (result funcref)
|
||||
(table.get $t3 (local.get $i))
|
||||
)
|
||||
|
||||
(func (export "set-externref") (param $i i32) (param $r externref)
|
||||
(table.set (local.get $i) (local.get $r))
|
||||
)
|
||||
(func (export "set-funcref") (param $i i32) (param $r funcref)
|
||||
(table.set $t3 (local.get $i) (local.get $r))
|
||||
)
|
||||
(func (export "set-funcref-from") (param $i i32) (param $j i32)
|
||||
(table.set $t3 (local.get $i) (table.get $t3 (local.get $j)))
|
||||
)
|
||||
|
||||
(func (export "is_null-funcref") (param $i i32) (result i32)
|
||||
(ref.is_null (call $f3 (local.get $i)))
|
||||
)
|
||||
)
|
||||
|
||||
(assert_return (invoke "get-externref" (i32.const 0)) (ref.null extern))
|
||||
(assert_return (invoke "set-externref" (i32.const 0) (ref.extern 1)))
|
||||
(assert_return (invoke "get-externref" (i32.const 0)) (ref.extern 1))
|
||||
(assert_return (invoke "set-externref" (i32.const 0) (ref.null extern)))
|
||||
(assert_return (invoke "get-externref" (i32.const 0)) (ref.null extern))
|
||||
|
||||
(assert_return (invoke "get-funcref" (i32.const 0)) (ref.null func))
|
||||
(assert_return (invoke "set-funcref-from" (i32.const 0) (i32.const 1)))
|
||||
(assert_return (invoke "is_null-funcref" (i32.const 0)) (i32.const 0))
|
||||
(assert_return (invoke "set-funcref" (i32.const 0) (ref.null func)))
|
||||
(assert_return (invoke "get-funcref" (i32.const 0)) (ref.null func))
|
||||
|
||||
(assert_trap (invoke "set-externref" (i32.const 2) (ref.null extern)) "out of bounds table access")
|
||||
(assert_trap (invoke "set-funcref" (i32.const 3) (ref.null func)) "out of bounds table access")
|
||||
(assert_trap (invoke "set-externref" (i32.const -1) (ref.null extern)) "out of bounds table access")
|
||||
(assert_trap (invoke "set-funcref" (i32.const -1) (ref.null func)) "out of bounds table access")
|
||||
|
||||
(assert_trap (invoke "set-externref" (i32.const 2) (ref.extern 0)) "out of bounds table access")
|
||||
(assert_trap (invoke "set-funcref-from" (i32.const 3) (i32.const 1)) "out of bounds table access")
|
||||
(assert_trap (invoke "set-externref" (i32.const -1) (ref.extern 0)) "out of bounds table access")
|
||||
(assert_trap (invoke "set-funcref-from" (i32.const -1) (i32.const 1)) "out of bounds table access")
|
||||
|
||||
|
||||
;; Type errors
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 10 externref)
|
||||
(func $type-index-value-empty-vs-i32-externref
|
||||
(table.set $t)
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 10 externref)
|
||||
(func $type-index-empty-vs-i32
|
||||
(table.set $t (ref.null extern))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 10 externref)
|
||||
(func $type-value-empty-vs-externref
|
||||
(table.set $t (i32.const 1))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 10 externref)
|
||||
(func $type-size-f32-vs-i32
|
||||
(table.set $t (f32.const 1) (ref.null extern))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 10 funcref)
|
||||
(func $type-value-externref-vs-funcref (param $r externref)
|
||||
(table.set $t (i32.const 1) (local.get $r))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t1 1 externref)
|
||||
(table $t2 1 funcref)
|
||||
(func $type-value-externref-vs-funcref-multi (param $r externref)
|
||||
(table.set $t2 (i32.const 0) (local.get $r))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(table $t 10 externref)
|
||||
(func $type-result-empty-vs-num (result i32)
|
||||
(table.set $t (i32.const 0) (ref.null extern))
|
||||
)
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
|
@ -0,0 +1,804 @@
|
|||
;; Definitions
|
||||
|
||||
(module
|
||||
(type $e0 (sub (array i32)))
|
||||
(type $e1 (sub $e0 (array i32)))
|
||||
|
||||
(type $e2 (sub (array anyref)))
|
||||
(type $e3 (sub (array (ref null $e0))))
|
||||
(type $e4 (sub (array (ref $e1))))
|
||||
|
||||
(type $m1 (sub (array (mut i32))))
|
||||
(type $m2 (sub $m1 (array (mut i32))))
|
||||
)
|
||||
|
||||
(module
|
||||
(type $e0 (sub (struct)))
|
||||
(type $e1 (sub $e0 (struct)))
|
||||
(type $e2 (sub $e1 (struct (field i32))))
|
||||
(type $e3 (sub $e2 (struct (field i32 (ref null $e0)))))
|
||||
(type $e4 (sub $e3 (struct (field i32 (ref $e0) (mut i64)))))
|
||||
(type $e5 (sub $e4 (struct (field i32 (ref $e1) (mut i64)))))
|
||||
)
|
||||
|
||||
(module
|
||||
(type $s (sub (struct)))
|
||||
(type $s' (sub $s (struct)))
|
||||
|
||||
(type $f1 (sub (func (param (ref $s')) (result anyref))))
|
||||
(type $f2 (sub $f1 (func (param (ref $s)) (result (ref any)))))
|
||||
(type $f3 (sub $f2 (func (param (ref null $s)) (result (ref $s)))))
|
||||
(type $f4 (sub $f3 (func (param (ref null struct)) (result (ref $s')))))
|
||||
)
|
||||
|
||||
|
||||
;; Recursive definitions
|
||||
|
||||
(module
|
||||
(type $t (sub (struct (field anyref))))
|
||||
(rec (type $r (sub $t (struct (field (ref $r))))))
|
||||
(type $t' (sub $r (struct (field (ref $r) i32))))
|
||||
)
|
||||
|
||||
(module
|
||||
(rec
|
||||
(type $r1 (sub (struct (field i32 (ref $r1)))))
|
||||
)
|
||||
(rec
|
||||
(type $r2 (sub $r1 (struct (field i32 (ref $r3)))))
|
||||
(type $r3 (sub $r1 (struct (field i32 (ref $r2)))))
|
||||
)
|
||||
)
|
||||
|
||||
(module
|
||||
(rec
|
||||
(type $a1 (sub (struct (field i32 (ref $a2)))))
|
||||
(type $a2 (sub (struct (field i64 (ref $a1)))))
|
||||
)
|
||||
(rec
|
||||
(type $b1 (sub $a2 (struct (field i64 (ref $a1) i32))))
|
||||
(type $b2 (sub $a1 (struct (field i32 (ref $a2) i32))))
|
||||
(type $b3 (sub $a2 (struct (field i64 (ref $b2) i32))))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
;; Subsumption
|
||||
|
||||
(module
|
||||
(rec
|
||||
(type $t1 (sub (func (param i32 (ref $t3)))))
|
||||
(type $t2 (sub $t1 (func (param i32 (ref $t2)))))
|
||||
(type $t3 (sub $t2 (func (param i32 (ref $t1)))))
|
||||
)
|
||||
|
||||
(func $f1 (param $r (ref $t1))
|
||||
(call $f1 (local.get $r))
|
||||
)
|
||||
(func $f2 (param $r (ref $t2))
|
||||
(call $f1 (local.get $r))
|
||||
(call $f2 (local.get $r))
|
||||
)
|
||||
(func $f3 (param $r (ref $t3))
|
||||
(call $f1 (local.get $r))
|
||||
(call $f2 (local.get $r))
|
||||
(call $f3 (local.get $r))
|
||||
)
|
||||
)
|
||||
|
||||
(module
|
||||
(rec
|
||||
(type $t1 (sub (func (result i32 (ref $u1)))))
|
||||
(type $u1 (sub (func (result f32 (ref $t1)))))
|
||||
)
|
||||
|
||||
(rec
|
||||
(type $t2 (sub $t1 (func (result i32 (ref $u3)))))
|
||||
(type $u2 (sub $u1 (func (result f32 (ref $t3)))))
|
||||
(type $t3 (sub $t1 (func (result i32 (ref $u2)))))
|
||||
(type $u3 (sub $u1 (func (result f32 (ref $t2)))))
|
||||
)
|
||||
|
||||
(func $f1 (param $r (ref $t1))
|
||||
(call $f1 (local.get $r))
|
||||
)
|
||||
(func $f2 (param $r (ref $t2))
|
||||
(call $f1 (local.get $r))
|
||||
(call $f2 (local.get $r))
|
||||
)
|
||||
(func $f3 (param $r (ref $t3))
|
||||
(call $f1 (local.get $r))
|
||||
(call $f3 (local.get $r))
|
||||
)
|
||||
)
|
||||
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type (struct (field (ref $f1)))))
|
||||
(rec (type $f2 (sub (func))) (type (struct (field (ref $f2)))))
|
||||
(rec (type $g1 (sub $f1 (func))) (type (struct)))
|
||||
(rec (type $g2 (sub $f2 (func))) (type (struct)))
|
||||
(func $g (type $g2))
|
||||
(global (ref $g1) (ref.func $g))
|
||||
)
|
||||
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
||||
(rec (type $f2 (sub (func))) (type $s2 (sub (struct (field (ref $f2))))))
|
||||
(rec
|
||||
(type $g1 (sub $f1 (func)))
|
||||
(type (sub $s1 (struct (field (ref $f1) (ref $f1) (ref $f2) (ref $f2) (ref $g1)))))
|
||||
)
|
||||
(rec
|
||||
(type $g2 (sub $f2 (func)))
|
||||
(type (sub $s2 (struct (field (ref $f1) (ref $f2) (ref $f1) (ref $f2) (ref $g2)))))
|
||||
)
|
||||
(func $g (type $g2))
|
||||
(global (ref $g1) (ref.func $g))
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type (struct (field (ref $f1)))))
|
||||
(rec (type $f2 (sub (func))) (type (struct (field (ref $f1)))))
|
||||
(rec (type $g1 (sub $f1 (func))) (type (struct)))
|
||||
(rec (type $g2 (sub $f2 (func))) (type (struct)))
|
||||
(func $g (type $g2))
|
||||
(global (ref $g1) (ref.func $g))
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type (struct (field (ref $f1)))))
|
||||
(rec (type $f2 (sub (func))) (type (struct (field (ref $f2)))))
|
||||
(rec (type $g (sub $f1 (func))) (type (struct)))
|
||||
(func $g (type $g))
|
||||
(global (ref $f1) (ref.func $g))
|
||||
)
|
||||
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
||||
(rec (type $f2 (sub (func))) (type $s2 (sub (struct (field (ref $f2))))))
|
||||
(rec
|
||||
(type $g1 (sub $f1 (func)))
|
||||
(type (sub $s1 (struct (field (ref $f1) (ref $f1) (ref $f2) (ref $f2) (ref $g1)))))
|
||||
)
|
||||
(rec
|
||||
(type $g2 (sub $f2 (func)))
|
||||
(type (sub $s2 (struct (field (ref $f1) (ref $f2) (ref $f1) (ref $f2) (ref $g2)))))
|
||||
)
|
||||
(rec (type $h (sub $g2 (func))) (type (struct)))
|
||||
(func $h (type $h))
|
||||
(global (ref $f1) (ref.func $h))
|
||||
(global (ref $g1) (ref.func $h))
|
||||
)
|
||||
|
||||
|
||||
(module
|
||||
(rec (type $f11 (sub (func (result (ref func))))) (type $f12 (sub $f11 (func (result (ref $f11))))))
|
||||
(rec (type $f21 (sub (func (result (ref func))))) (type $f22 (sub $f21 (func (result (ref $f21))))))
|
||||
(func $f11 (type $f11) (unreachable))
|
||||
(func $f12 (type $f12) (unreachable))
|
||||
(global (ref $f11) (ref.func $f11))
|
||||
(global (ref $f21) (ref.func $f11))
|
||||
(global (ref $f12) (ref.func $f12))
|
||||
(global (ref $f22) (ref.func $f12))
|
||||
)
|
||||
|
||||
(module
|
||||
(rec (type $f11 (sub (func (result (ref func))))) (type $f12 (sub $f11 (func (result (ref $f11))))))
|
||||
(rec (type $f21 (sub (func (result (ref func))))) (type $f22 (sub $f21 (func (result (ref $f21))))))
|
||||
(rec (type $g11 (sub $f11 (func (result (ref func))))) (type $g12 (sub $g11 (func (result (ref $g11))))))
|
||||
(rec (type $g21 (sub $f21 (func (result (ref func))))) (type $g22 (sub $g21 (func (result (ref $g21))))))
|
||||
(func $g11 (type $g11) (unreachable))
|
||||
(func $g12 (type $g12) (unreachable))
|
||||
(global (ref $f11) (ref.func $g11))
|
||||
(global (ref $f21) (ref.func $g11))
|
||||
(global (ref $f11) (ref.func $g12))
|
||||
(global (ref $f21) (ref.func $g12))
|
||||
(global (ref $g11) (ref.func $g11))
|
||||
(global (ref $g21) (ref.func $g11))
|
||||
(global (ref $g12) (ref.func $g12))
|
||||
(global (ref $g22) (ref.func $g12))
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(rec (type $f11 (sub (func))) (type $f12 (sub $f11 (func))))
|
||||
(rec (type $f21 (sub (func))) (type $f22 (sub $f11 (func))))
|
||||
(func $f (type $f21))
|
||||
(global (ref $f11) (ref.func $f))
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(rec (type $f01 (sub (func))) (type $f02 (sub $f01 (func))))
|
||||
(rec (type $f11 (sub (func))) (type $f12 (sub $f01 (func))))
|
||||
(rec (type $f21 (sub (func))) (type $f22 (sub $f11 (func))))
|
||||
(func $f (type $f21))
|
||||
(global (ref $f11) (ref.func $f))
|
||||
)
|
||||
"type mismatch"
|
||||
)
|
||||
|
||||
|
||||
;; Runtime types
|
||||
|
||||
(module
|
||||
(type $t0 (sub (func (result (ref null func)))))
|
||||
(rec (type $t1 (sub $t0 (func (result (ref null $t1))))))
|
||||
(rec (type $t2 (sub $t1 (func (result (ref null $t2))))))
|
||||
|
||||
(func $f0 (type $t0) (ref.null func))
|
||||
(func $f1 (type $t1) (ref.null $t1))
|
||||
(func $f2 (type $t2) (ref.null $t2))
|
||||
(table funcref (elem $f0 $f1 $f2))
|
||||
|
||||
(func (export "run")
|
||||
(block (result (ref null func)) (call_indirect (type $t0) (i32.const 0)))
|
||||
(block (result (ref null func)) (call_indirect (type $t0) (i32.const 1)))
|
||||
(block (result (ref null func)) (call_indirect (type $t0) (i32.const 2)))
|
||||
(block (result (ref null $t1)) (call_indirect (type $t1) (i32.const 1)))
|
||||
(block (result (ref null $t1)) (call_indirect (type $t1) (i32.const 2)))
|
||||
(block (result (ref null $t2)) (call_indirect (type $t2) (i32.const 2)))
|
||||
|
||||
(block (result (ref null $t0)) (ref.cast (ref $t0) (table.get (i32.const 0))))
|
||||
(block (result (ref null $t0)) (ref.cast (ref $t0) (table.get (i32.const 1))))
|
||||
(block (result (ref null $t0)) (ref.cast (ref $t0) (table.get (i32.const 2))))
|
||||
(block (result (ref null $t1)) (ref.cast (ref $t1) (table.get (i32.const 1))))
|
||||
(block (result (ref null $t1)) (ref.cast (ref $t1) (table.get (i32.const 2))))
|
||||
(block (result (ref null $t2)) (ref.cast (ref $t2) (table.get (i32.const 2))))
|
||||
(br 0)
|
||||
)
|
||||
|
||||
(func (export "fail1")
|
||||
(block (result (ref null $t1)) (call_indirect (type $t1) (i32.const 0)))
|
||||
(br 0)
|
||||
)
|
||||
(func (export "fail2")
|
||||
(block (result (ref null $t1)) (call_indirect (type $t2) (i32.const 0)))
|
||||
(br 0)
|
||||
)
|
||||
(func (export "fail3")
|
||||
(block (result (ref null $t1)) (call_indirect (type $t2) (i32.const 1)))
|
||||
(br 0)
|
||||
)
|
||||
|
||||
(func (export "fail4")
|
||||
(ref.cast (ref $t1) (table.get (i32.const 0)))
|
||||
(br 0)
|
||||
)
|
||||
(func (export "fail5")
|
||||
(ref.cast (ref $t2) (table.get (i32.const 0)))
|
||||
(br 0)
|
||||
)
|
||||
(func (export "fail6")
|
||||
(ref.cast (ref $t2) (table.get (i32.const 1)))
|
||||
(br 0)
|
||||
)
|
||||
)
|
||||
(assert_return (invoke "run"))
|
||||
(assert_trap (invoke "fail1") "indirect call")
|
||||
(assert_trap (invoke "fail2") "indirect call")
|
||||
(assert_trap (invoke "fail3") "indirect call")
|
||||
(assert_trap (invoke "fail4") "cast")
|
||||
(assert_trap (invoke "fail5") "cast")
|
||||
(assert_trap (invoke "fail6") "cast")
|
||||
|
||||
(module
|
||||
(type $t1 (sub (func)))
|
||||
(type $t2 (sub final (func)))
|
||||
|
||||
(func $f1 (type $t1))
|
||||
(func $f2 (type $t2))
|
||||
(table funcref (elem $f1 $f2))
|
||||
|
||||
(func (export "fail1")
|
||||
(block (call_indirect (type $t1) (i32.const 1)))
|
||||
)
|
||||
(func (export "fail2")
|
||||
(block (call_indirect (type $t2) (i32.const 0)))
|
||||
)
|
||||
|
||||
(func (export "fail3")
|
||||
(ref.cast (ref $t1) (table.get (i32.const 1)))
|
||||
(drop)
|
||||
)
|
||||
(func (export "fail4")
|
||||
(ref.cast (ref $t2) (table.get (i32.const 0)))
|
||||
(drop)
|
||||
)
|
||||
)
|
||||
(assert_trap (invoke "fail1") "indirect call")
|
||||
(assert_trap (invoke "fail2") "indirect call")
|
||||
(assert_trap (invoke "fail3") "cast")
|
||||
(assert_trap (invoke "fail4") "cast")
|
||||
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type (struct (field (ref $f1)))))
|
||||
(rec (type $f2 (sub (func))) (type (struct (field (ref $f2)))))
|
||||
(rec (type $g1 (sub $f1 (func))) (type (struct)))
|
||||
(rec (type $g2 (sub $f2 (func))) (type (struct)))
|
||||
(func $g (type $g2)) (elem declare func $g)
|
||||
(func (export "run") (result i32)
|
||||
(ref.test (ref $g1) (ref.func $g))
|
||||
)
|
||||
)
|
||||
(assert_return (invoke "run") (i32.const 1))
|
||||
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
||||
(rec (type $f2 (sub (func))) (type $s2 (sub (struct (field (ref $f2))))))
|
||||
(rec
|
||||
(type $g1 (sub $f1 (func)))
|
||||
(type (sub $s1 (struct (field (ref $f1) (ref $f1) (ref $f2) (ref $f2) (ref $g1)))))
|
||||
)
|
||||
(rec
|
||||
(type $g2 (sub $f2 (func)))
|
||||
(type (sub $s2 (struct (field (ref $f1) (ref $f2) (ref $f1) (ref $f2) (ref $g2)))))
|
||||
)
|
||||
(func $g (type $g2)) (elem declare func $g)
|
||||
(func (export "run") (result i32)
|
||||
(ref.test (ref $g1) (ref.func $g))
|
||||
)
|
||||
)
|
||||
(assert_return (invoke "run") (i32.const 1))
|
||||
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type (struct (field (ref $f1)))))
|
||||
(rec (type $f2 (sub (func))) (type (struct (field (ref $f1)))))
|
||||
(rec (type $g1 (sub $f1 (func))) (type (struct)))
|
||||
(rec (type $g2 (sub $f2 (func))) (type (struct)))
|
||||
(func $g (type $g2)) (elem declare func $g)
|
||||
(func (export "run") (result i32)
|
||||
(ref.test (ref $g1) (ref.func $g))
|
||||
)
|
||||
)
|
||||
(assert_return (invoke "run") (i32.const 0))
|
||||
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type (struct (field (ref $f1)))))
|
||||
(rec (type $f2 (sub (func))) (type (struct (field (ref $f2)))))
|
||||
(rec (type $g (sub $f1 (func))) (type (struct)))
|
||||
(func $g (type $g)) (elem declare func $g)
|
||||
(func (export "run") (result i32)
|
||||
(ref.test (ref $f1) (ref.func $g))
|
||||
)
|
||||
)
|
||||
(assert_return (invoke "run") (i32.const 1))
|
||||
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
||||
(rec (type $f2 (sub (func))) (type $s2 (sub (struct (field (ref $f2))))))
|
||||
(rec
|
||||
(type $g1 (sub $f1 (func)))
|
||||
(type (sub $s1 (struct (field (ref $f1) (ref $f1) (ref $f2) (ref $f2) (ref $g1)))))
|
||||
)
|
||||
(rec
|
||||
(type $g2 (sub $f2 (func)))
|
||||
(type (sub $s2 (struct (field (ref $f1) (ref $f2) (ref $f1) (ref $f2) (ref $g2)))))
|
||||
)
|
||||
(rec (type $h (sub $g2 (func))) (type (struct)))
|
||||
(func $h (type $h)) (elem declare func $h)
|
||||
(func (export "run") (result i32 i32)
|
||||
(ref.test (ref $f1) (ref.func $h))
|
||||
(ref.test (ref $g1) (ref.func $h))
|
||||
)
|
||||
)
|
||||
(assert_return (invoke "run") (i32.const 1) (i32.const 1))
|
||||
|
||||
(module
|
||||
(rec (type $f11 (sub (func (result (ref func))))) (type $f12 (sub $f11 (func (result (ref $f11))))))
|
||||
(rec (type $f21 (sub (func (result (ref func))))) (type $f22 (sub $f21 (func (result (ref $f21))))))
|
||||
(func $f11 (type $f11) (unreachable)) (elem declare func $f11)
|
||||
(func $f12 (type $f12) (unreachable)) (elem declare func $f12)
|
||||
(func (export "run") (result i32 i32 i32 i32)
|
||||
(ref.test (ref $f11) (ref.func $f11))
|
||||
(ref.test (ref $f21) (ref.func $f11))
|
||||
(ref.test (ref $f12) (ref.func $f12))
|
||||
(ref.test (ref $f22) (ref.func $f12))
|
||||
)
|
||||
)
|
||||
(assert_return (invoke "run")
|
||||
(i32.const 1) (i32.const 1) (i32.const 1) (i32.const 1)
|
||||
)
|
||||
|
||||
(module
|
||||
(rec (type $f11 (sub (func (result (ref func))))) (type $f12 (sub $f11 (func (result (ref $f11))))))
|
||||
(rec (type $f21 (sub (func (result (ref func))))) (type $f22 (sub $f21 (func (result (ref $f21))))))
|
||||
(rec (type $g11 (sub $f11 (func (result (ref func))))) (type $g12 (sub $g11 (func (result (ref $g11))))))
|
||||
(rec (type $g21 (sub $f21 (func (result (ref func))))) (type $g22 (sub $g21 (func (result (ref $g21))))))
|
||||
(func $g11 (type $g11) (unreachable)) (elem declare func $g11)
|
||||
(func $g12 (type $g12) (unreachable)) (elem declare func $g12)
|
||||
(func (export "run") (result i32 i32 i32 i32 i32 i32 i32 i32)
|
||||
(ref.test (ref $f11) (ref.func $g11))
|
||||
(ref.test (ref $f21) (ref.func $g11))
|
||||
(ref.test (ref $f11) (ref.func $g12))
|
||||
(ref.test (ref $f21) (ref.func $g12))
|
||||
(ref.test (ref $g11) (ref.func $g11))
|
||||
(ref.test (ref $g21) (ref.func $g11))
|
||||
(ref.test (ref $g12) (ref.func $g12))
|
||||
(ref.test (ref $g22) (ref.func $g12))
|
||||
)
|
||||
)
|
||||
(assert_return (invoke "run")
|
||||
(i32.const 1) (i32.const 1) (i32.const 1) (i32.const 1)
|
||||
(i32.const 1) (i32.const 1) (i32.const 1) (i32.const 1)
|
||||
)
|
||||
|
||||
(module
|
||||
(rec (type $f11 (sub (func))) (type $f12 (sub $f11 (func))))
|
||||
(rec (type $f21 (sub (func))) (type $f22 (sub $f11 (func))))
|
||||
(func $f (type $f21)) (elem declare func $f)
|
||||
(func (export "run") (result i32)
|
||||
(ref.test (ref $f11) (ref.func $f))
|
||||
)
|
||||
)
|
||||
(assert_return (invoke "run") (i32.const 0))
|
||||
|
||||
(module
|
||||
(rec (type $f01 (sub (func))) (type $f02 (sub $f01 (func))))
|
||||
(rec (type $f11 (sub (func))) (type $f12 (sub $f01 (func))))
|
||||
(rec (type $f21 (sub (func))) (type $f22 (sub $f11 (func))))
|
||||
(func $f (type $f21)) (elem declare func $f)
|
||||
(func (export "run") (result i32)
|
||||
(ref.test (ref $f11) (ref.func $f))
|
||||
)
|
||||
)
|
||||
(assert_return (invoke "run") (i32.const 0))
|
||||
|
||||
|
||||
|
||||
;; Linking
|
||||
|
||||
(module
|
||||
(type $t0 (sub (func (result (ref null func)))))
|
||||
(rec (type $t1 (sub $t0 (func (result (ref null $t1))))))
|
||||
(rec (type $t2 (sub $t1 (func (result (ref null $t2))))))
|
||||
|
||||
(func (export "f0") (type $t0) (ref.null func))
|
||||
(func (export "f1") (type $t1) (ref.null $t1))
|
||||
(func (export "f2") (type $t2) (ref.null $t2))
|
||||
)
|
||||
(register "M")
|
||||
|
||||
(module
|
||||
(type $t0 (sub (func (result (ref null func)))))
|
||||
(rec (type $t1 (sub $t0 (func (result (ref null $t1))))))
|
||||
(rec (type $t2 (sub $t1 (func (result (ref null $t2))))))
|
||||
|
||||
(func (import "M" "f0") (type $t0))
|
||||
(func (import "M" "f1") (type $t0))
|
||||
(func (import "M" "f1") (type $t1))
|
||||
(func (import "M" "f2") (type $t0))
|
||||
(func (import "M" "f2") (type $t1))
|
||||
(func (import "M" "f2") (type $t2))
|
||||
)
|
||||
|
||||
(assert_unlinkable
|
||||
(module
|
||||
(type $t0 (sub (func (result (ref null func)))))
|
||||
(rec (type $t1 (sub $t0 (func (result (ref null $t1))))))
|
||||
(rec (type $t2 (sub $t1 (func (result (ref null $t2))))))
|
||||
(func (import "M" "f0") (type $t1))
|
||||
)
|
||||
"incompatible import type"
|
||||
)
|
||||
|
||||
(assert_unlinkable
|
||||
(module
|
||||
(type $t0 (sub (func (result (ref null func)))))
|
||||
(rec (type $t1 (sub $t0 (func (result (ref null $t1))))))
|
||||
(rec (type $t2 (sub $t1 (func (result (ref null $t2))))))
|
||||
(func (import "M" "f0") (type $t2))
|
||||
)
|
||||
"incompatible import type"
|
||||
)
|
||||
|
||||
(assert_unlinkable
|
||||
(module
|
||||
(type $t0 (sub (func (result (ref null func)))))
|
||||
(rec (type $t1 (sub $t0 (func (result (ref null $t1))))))
|
||||
(rec (type $t2 (sub $t1 (func (result (ref null $t2))))))
|
||||
(func (import "M" "f1") (type $t2))
|
||||
)
|
||||
"incompatible import type"
|
||||
)
|
||||
|
||||
(module
|
||||
(type $t1 (sub (func)))
|
||||
(type $t2 (sub final (func)))
|
||||
(func (export "f1") (type $t1))
|
||||
(func (export "f2") (type $t2))
|
||||
)
|
||||
(register "M2")
|
||||
|
||||
(assert_unlinkable
|
||||
(module
|
||||
(type $t1 (sub (func)))
|
||||
(type $t2 (sub final (func)))
|
||||
(func (import "M2" "f1") (type $t2))
|
||||
)
|
||||
"incompatible import type"
|
||||
)
|
||||
(assert_unlinkable
|
||||
(module
|
||||
(type $t1 (sub (func)))
|
||||
(type $t2 (sub final (func)))
|
||||
(func (import "M2" "f2") (type $t1))
|
||||
)
|
||||
"incompatible import type"
|
||||
)
|
||||
|
||||
|
||||
(module
|
||||
(rec (type $f2 (sub (func))) (type (struct (field (ref $f2)))))
|
||||
(rec (type $g2 (sub $f2 (func))) (type (struct)))
|
||||
(func (export "g") (type $g2))
|
||||
)
|
||||
(register "M3")
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type (struct (field (ref $f1)))))
|
||||
(rec (type $g1 (sub $f1 (func))) (type (struct)))
|
||||
(func (import "M3" "g") (type $g1))
|
||||
)
|
||||
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
||||
(rec (type $f2 (sub (func))) (type $s2 (sub (struct (field (ref $f2))))))
|
||||
(rec
|
||||
(type $g2 (sub $f2 (func)))
|
||||
(type (sub $s2 (struct (field (ref $f1) (ref $f2) (ref $f1) (ref $f2) (ref $g2)))))
|
||||
)
|
||||
(func (export "g") (type $g2))
|
||||
)
|
||||
(register "M4")
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
||||
(rec (type $f2 (sub (func))) (type $s2 (sub (struct (field (ref $f2))))))
|
||||
(rec
|
||||
(type $g1 (sub $f1 (func)))
|
||||
(type (sub $s1 (struct (field (ref $f1) (ref $f1) (ref $f2) (ref $f2) (ref $g1)))))
|
||||
)
|
||||
(func (import "M4" "g") (type $g1))
|
||||
)
|
||||
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type (struct (field (ref $f1)))))
|
||||
(rec (type $f2 (sub (func))) (type (struct (field (ref $f1)))))
|
||||
(rec (type $g2 (sub $f2 (func))) (type (struct)))
|
||||
(func (export "g") (type $g2))
|
||||
)
|
||||
(register "M5")
|
||||
(assert_unlinkable
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type (struct (field (ref $f1)))))
|
||||
(rec (type $g1 (sub $f1 (func))) (type (struct)))
|
||||
(func (import "M5" "g") (type $g1))
|
||||
)
|
||||
"incompatible import"
|
||||
)
|
||||
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type (struct (field (ref $f1)))))
|
||||
(rec (type $f2 (sub (func))) (type (struct (field (ref $f2)))))
|
||||
(rec (type $g (sub $f1 (func))) (type (struct)))
|
||||
(func (export "g") (type $g))
|
||||
)
|
||||
(register "M6")
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type (struct (field (ref $f1)))))
|
||||
(rec (type $f2 (sub (func))) (type (struct (field (ref $f2)))))
|
||||
(rec (type $g (sub $f1 (func))) (type (struct)))
|
||||
(func (import "M6" "g") (type $f1))
|
||||
)
|
||||
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
||||
(rec (type $f2 (sub (func))) (type $s2 (sub (struct (field (ref $f2))))))
|
||||
(rec
|
||||
(type $g2 (sub $f2 (func)))
|
||||
(type (sub $s2 (struct (field (ref $f1) (ref $f2) (ref $f1) (ref $f2) (ref $g2)))))
|
||||
)
|
||||
(rec (type $h (sub $g2 (func))) (type (struct)))
|
||||
(func (export "h") (type $h))
|
||||
)
|
||||
;; (register "M7")
|
||||
(module
|
||||
(rec (type $f1 (sub (func))) (type $s1 (sub (struct (field (ref $f1))))))
|
||||
(rec (type $f2 (sub (func))) (type $s2 (sub (struct (field (ref $f2))))))
|
||||
(rec
|
||||
(type $g1 (sub $f1 (func)))
|
||||
(type (sub $s1 (struct (field (ref $f1) (ref $f1) (ref $f2) (ref $f2) (ref $g1)))))
|
||||
)
|
||||
(rec (type $h (sub $g1 (func))) (type (struct)))
|
||||
(func (import "M7" "h") (type $f1))
|
||||
(func (import "M7" "h") (type $g1))
|
||||
)
|
||||
|
||||
|
||||
(module
|
||||
(rec (type $f11 (sub (func (result (ref func))))) (type $f12 (sub $f11 (func (result (ref $f11))))))
|
||||
(rec (type $f21 (sub (func (result (ref func))))) (type $f22 (sub $f21 (func (result (ref $f21))))))
|
||||
(func (export "f11") (type $f11) (unreachable))
|
||||
(func (export "f12") (type $f12) (unreachable))
|
||||
)
|
||||
(register "M8")
|
||||
(module
|
||||
(rec (type $f11 (sub (func (result (ref func))))) (type $f12 (sub $f11 (func (result (ref $f11))))))
|
||||
(rec (type $f21 (sub (func (result (ref func))))) (type $f22 (sub $f21 (func (result (ref $f21))))))
|
||||
(func (import "M8" "f11") (type $f11))
|
||||
(func (import "M8" "f11") (type $f21))
|
||||
(func (import "M8" "f12") (type $f12))
|
||||
(func (import "M8" "f12") (type $f22))
|
||||
)
|
||||
|
||||
(module
|
||||
(rec (type $f11 (sub (func (result (ref func))))) (type $f12 (sub $f11 (func (result (ref $f11))))))
|
||||
(rec (type $f21 (sub (func (result (ref func))))) (type $f22 (sub $f21 (func (result (ref $f21))))))
|
||||
(rec (type $g11 (sub $f11 (func (result (ref func))))) (type $g12 (sub $g11 (func (result (ref $g11))))))
|
||||
(rec (type $g21 (sub $f21 (func (result (ref func))))) (type $g22 (sub $g21 (func (result (ref $g21))))))
|
||||
(func (export "g11") (type $g11) (unreachable))
|
||||
(func (export "g12") (type $g12) (unreachable))
|
||||
)
|
||||
(register "M9")
|
||||
(module
|
||||
(rec (type $f11 (sub (func (result (ref func))))) (type $f12 (sub $f11 (func (result (ref $f11))))))
|
||||
(rec (type $f21 (sub (func (result (ref func))))) (type $f22 (sub $f21 (func (result (ref $f21))))))
|
||||
(rec (type $g11 (sub $f11 (func (result (ref func))))) (type $g12 (sub $g11 (func (result (ref $g11))))))
|
||||
(rec (type $g21 (sub $f21 (func (result (ref func))))) (type $g22 (sub $g21 (func (result (ref $g21))))))
|
||||
(func (import "M9" "g11") (type $f11))
|
||||
(func (import "M9" "g11") (type $f21))
|
||||
(func (import "M9" "g12") (type $f11))
|
||||
(func (import "M9" "g12") (type $f21))
|
||||
(func (import "M9" "g11") (type $g11))
|
||||
(func (import "M9" "g11") (type $g21))
|
||||
(func (import "M9" "g12") (type $g12))
|
||||
(func (import "M9" "g12") (type $g22))
|
||||
)
|
||||
|
||||
(module
|
||||
(rec (type $f11 (sub (func))) (type $f12 (sub $f11 (func))))
|
||||
(rec (type $f21 (sub (func))) (type $f22 (sub $f11 (func))))
|
||||
(func (export "f") (type $f21))
|
||||
)
|
||||
(register "M10")
|
||||
(assert_unlinkable
|
||||
(module
|
||||
(rec (type $f11 (sub (func))) (type $f12 (sub $f11 (func))))
|
||||
(func (import "M10" "f") (type $f11))
|
||||
)
|
||||
"incompatible import"
|
||||
)
|
||||
|
||||
(module
|
||||
(rec (type $f01 (sub (func))) (type $f02 (sub $f01 (func))))
|
||||
(rec (type $f11 (sub (func))) (type $f12 (sub $f01 (func))))
|
||||
(rec (type $f21 (sub (func))) (type $f22 (sub $f11 (func))))
|
||||
(func (export "f") (type $f21))
|
||||
)
|
||||
(register "M11")
|
||||
(assert_unlinkable
|
||||
(module
|
||||
(rec (type $f01 (sub (func))) (type $f02 (sub $f01 (func))))
|
||||
(rec (type $f11 (sub (func))) (type $f12 (sub $f01 (func))))
|
||||
(func (import "M11" "f") (type $f11))
|
||||
)
|
||||
"incompatible import"
|
||||
)
|
||||
|
||||
|
||||
|
||||
;; Finality violation
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (func))
|
||||
(type $s (sub $t (func)))
|
||||
)
|
||||
"sub type"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (struct))
|
||||
(type $s (sub $t (struct)))
|
||||
)
|
||||
"sub type"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (sub final (func)))
|
||||
(type $s (sub $t (func)))
|
||||
)
|
||||
"sub type"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $t (sub (func)))
|
||||
(type $s (sub final $t (func)))
|
||||
(type $u (sub $s (func)))
|
||||
)
|
||||
"sub type"
|
||||
)
|
||||
|
||||
|
||||
|
||||
;; Invalid subtyping definitions
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $a0 (sub (array i32)))
|
||||
(type $s0 (sub $a0 (struct)))
|
||||
)
|
||||
"sub type"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $f0 (sub (func (param i32) (result i32))))
|
||||
(type $s0 (sub $f0 (struct)))
|
||||
)
|
||||
"sub type"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $s0 (sub (struct)))
|
||||
(type $a0 (sub $s0 (array i32)))
|
||||
)
|
||||
"sub type"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $f0 (sub (func (param i32) (result i32))))
|
||||
(type $a0 (sub $f0 (array i32)))
|
||||
)
|
||||
"sub type"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $s0 (sub (struct)))
|
||||
(type $f0 (sub $s0 (func (param i32) (result i32))))
|
||||
)
|
||||
"sub type"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $a0 (sub (array i32)))
|
||||
(type $f0 (sub $a0 (func (param i32) (result i32))))
|
||||
)
|
||||
"sub type"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $a0 (sub (array i32)))
|
||||
(type $a1 (sub $a0 (array i64)))
|
||||
)
|
||||
"sub type"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $s0 (sub (struct (field i32))))
|
||||
(type $s1 (sub $s0 (struct (field i64))))
|
||||
)
|
||||
"sub type"
|
||||
)
|
||||
|
||||
(assert_invalid
|
||||
(module
|
||||
(type $f0 (sub (func)))
|
||||
(type $f1 (sub $f0 (func (param i32))))
|
||||
)
|
||||
"sub type"
|
||||
)
|
||||
|
215
tests/wamr-test-suites/requirement-engineering-test-script/run_requirement.py
Executable file
215
tests/wamr-test-suites/requirement-engineering-test-script/run_requirement.py
Executable file
|
@ -0,0 +1,215 @@
|
|||
#!/usr/bin/python3
|
||||
#
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
from typing import Dict, Tuple, List
|
||||
import importlib
|
||||
import inspect
|
||||
import csv
|
||||
|
||||
REQUIREMENT_TESTS_DIR = "../../requirement-engineering"
|
||||
SUBREQUIREMENT_DESCRIPTIONS = {}
|
||||
|
||||
|
||||
# To use this empty function to do signature check
|
||||
def expected_build_func_template(verbose: bool) -> None:
|
||||
pass
|
||||
|
||||
|
||||
# To use this empty function to do signature check
|
||||
# The actual implementation of the return value should has following information:
|
||||
#
|
||||
def expected_run_func_template(
|
||||
output_dir: str, subrequirement_ids: List[int]
|
||||
) -> Dict[int, Dict[Tuple[str, str], bool]]:
|
||||
pass
|
||||
|
||||
|
||||
def dynamic_import(requirement_dir: str):
|
||||
# Declare that we intend to modify the global variable
|
||||
global SUBREQUIREMENT_DESCRIPTIONS
|
||||
sys.path.append(requirement_dir)
|
||||
os.chdir(requirement_dir)
|
||||
|
||||
try:
|
||||
build_module = importlib.import_module("build")
|
||||
build_function = getattr(build_module, "build")
|
||||
except AttributeError:
|
||||
raise ImportError("'build' function not found in the specified build.py file.")
|
||||
|
||||
try:
|
||||
run_module = importlib.import_module("run")
|
||||
run_function = getattr(run_module, "run")
|
||||
SUBREQUIREMENT_DESCRIPTIONS = getattr(run_module, "SUBREQUIREMENT_DESCRIPTIONS")
|
||||
except AttributeError:
|
||||
raise ImportError(
|
||||
"'run' function or 'SUBREQUIREMENT_DESCRIPTIONS' not found in the specified run.py file."
|
||||
)
|
||||
|
||||
# Do signature check
|
||||
expected_signature = inspect.signature(expected_build_func_template)
|
||||
actual_signature = inspect.signature(build_function)
|
||||
assert (
|
||||
actual_signature == expected_signature
|
||||
), "The build function doesn't have the expected signature"
|
||||
|
||||
expected_signature = inspect.signature(expected_run_func_template)
|
||||
actual_signature = inspect.signature(run_function)
|
||||
assert (
|
||||
actual_signature == expected_signature
|
||||
), "The run function doesn't have the expected signature"
|
||||
|
||||
# Check if the variable is a dictionary
|
||||
if not isinstance(SUBREQUIREMENT_DESCRIPTIONS, dict):
|
||||
raise TypeError("SUBREQUIREMENT_DESCRIPTIONS is not a dictionary")
|
||||
|
||||
# Check the types of keys and values in the dictionary
|
||||
for key, value in SUBREQUIREMENT_DESCRIPTIONS.items():
|
||||
if not isinstance(key, int):
|
||||
raise TypeError("Key in SUBREQUIREMENT_DESCRIPTIONS is not an int")
|
||||
if not (
|
||||
isinstance(value, tuple)
|
||||
and len(value) == 2
|
||||
and all(isinstance(elem, str) for elem in value)
|
||||
):
|
||||
raise TypeError(
|
||||
"Value in SUBREQUIREMENT_DESCRIPTIONS is not a Tuple[str, str]"
|
||||
)
|
||||
|
||||
return build_function, run_function
|
||||
|
||||
|
||||
def cmd_line_summary(
|
||||
requirement_name: str, result_dict: dict, subrequirement_descriptions: dict
|
||||
):
|
||||
# command line summary
|
||||
total, total_pass_nums, total_fail_nums = 0, 0, 0
|
||||
print(f"\n============ Start: Summary of {requirement_name} test ============")
|
||||
for subrequirement_id in result_dict.keys():
|
||||
sub_total = len(result_dict[subrequirement_id])
|
||||
pass_nums = len(
|
||||
[_ for _, result in result_dict[subrequirement_id].items() if result]
|
||||
)
|
||||
fail_nums = len(
|
||||
[_ for _, result in result_dict[subrequirement_id].items() if not result]
|
||||
)
|
||||
issue_number, subrequirement_description = subrequirement_descriptions.get(
|
||||
subrequirement_id, ""
|
||||
)
|
||||
|
||||
print(f"\nTest Sub-requirement id: {subrequirement_id}")
|
||||
print(f"Issue Number: {issue_number}")
|
||||
print(f"Sub-requirement description: {subrequirement_description}")
|
||||
print(f"Number of test cases: {sub_total}")
|
||||
print(f"Pass: {pass_nums}")
|
||||
print(f"Fail: {fail_nums}\n")
|
||||
print(
|
||||
"----------------------------------------------------------------------------"
|
||||
)
|
||||
total += sub_total
|
||||
total_pass_nums += pass_nums
|
||||
total_fail_nums += fail_nums
|
||||
|
||||
print(f"\nTotal Number of test cases: {total}")
|
||||
print(f"Pass: {total_pass_nums}")
|
||||
print(f"Fail: {total_fail_nums}\n")
|
||||
|
||||
print(f"============= End: Summary of {requirement_name} test =============\n")
|
||||
|
||||
|
||||
def generate_report(output_filename: str, result_dict: dict):
|
||||
# create a list of column names
|
||||
column_names = [
|
||||
"subrequirement id",
|
||||
"issue number",
|
||||
"subrequirement description",
|
||||
"running mode",
|
||||
"test case name",
|
||||
"test case description",
|
||||
"test case executing result",
|
||||
]
|
||||
|
||||
# open the output file in write mode
|
||||
with open(output_filename + ".csv", "w") as output_file:
|
||||
# create a csv writer object
|
||||
csv_writer = csv.writer(output_file)
|
||||
# write the column names as the first row
|
||||
csv_writer.writerow(column_names)
|
||||
# loop through the result_dict
|
||||
for subrequirement_id, test_cases in result_dict.items():
|
||||
# get the subrequirement description from the subrequirement_descriptions dict
|
||||
issue_number, subrequirement_description = SUBREQUIREMENT_DESCRIPTIONS.get(
|
||||
subrequirement_id, ""
|
||||
)
|
||||
# loop through the test cases
|
||||
for test_case, result in test_cases.items():
|
||||
# unpack the test case name and description from the tuple
|
||||
test_case_name, test_case_description = test_case
|
||||
# convert the result to pass or fail
|
||||
result = "pass" if result else "fail"
|
||||
# create a list of values for the current row
|
||||
row_values = [
|
||||
subrequirement_id,
|
||||
issue_number,
|
||||
subrequirement_description,
|
||||
"AOT",
|
||||
test_case_name,
|
||||
test_case_description,
|
||||
result,
|
||||
]
|
||||
# write the row values to the output file
|
||||
csv_writer.writerow(row_values)
|
||||
|
||||
|
||||
def run_requirement(
|
||||
requirement_name: str, output_dir: str, subrequirement_ids: List[int]
|
||||
):
|
||||
requirement_dir = os.path.join(REQUIREMENT_TESTS_DIR, requirement_name)
|
||||
if not os.path.isdir(requirement_dir):
|
||||
print(f"No such requirement in directory {requirement_dir} exists")
|
||||
sys.exit(1)
|
||||
|
||||
output_path = os.path.join(output_dir, requirement_name)
|
||||
|
||||
build_requirement_func, run_requirement_func = dynamic_import(requirement_dir)
|
||||
|
||||
build_requirement_func(verbose=False)
|
||||
result_dict = run_requirement_func(output_path, subrequirement_ids)
|
||||
|
||||
cmd_line_summary(requirement_name, result_dict, SUBREQUIREMENT_DESCRIPTIONS)
|
||||
generate_report(output_path, result_dict)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Process command line options.")
|
||||
|
||||
# Define the '-o' option for output directory
|
||||
parser.add_argument(
|
||||
"-o", "--output_directory", required=True, help="Report output directory"
|
||||
)
|
||||
|
||||
# Define the '-r' option for requirement name
|
||||
parser.add_argument(
|
||||
"-r", "--requirement_name", required=True, help="Requirement name"
|
||||
)
|
||||
|
||||
# Define the subrequirement IDs as a list of integers
|
||||
parser.add_argument(
|
||||
"subrequirement_ids", nargs="*", type=int, help="Subrequirement IDs (optional)"
|
||||
)
|
||||
|
||||
# Parse the arguments
|
||||
args = parser.parse_args()
|
||||
|
||||
run_requirement(
|
||||
args.requirement_name, args.output_directory, list(args.subrequirement_ids)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -28,6 +28,7 @@ function help()
|
|||
echo "-e enable exception handling"
|
||||
echo "-x test SGX"
|
||||
echo "-w enable WASI threads"
|
||||
echo "-a test all runtimes in sightglass suite"
|
||||
echo "-b use the wabt binary release package instead of compiling from the source code"
|
||||
echo "-g build iwasm with debug version"
|
||||
echo "-v enable GC heap verification"
|
||||
|
@ -37,6 +38,10 @@ function help()
|
|||
echo "-C enable code coverage collect"
|
||||
echo "-j set the platform to test"
|
||||
echo "-T set sanitizer to use in tests(ubsan|tsan|asan)"
|
||||
echo "-r [requirement name] [N [N ...]] specify a requirement name followed by one or more"
|
||||
echo " subrequirement IDs, if no subrequirement is specificed,"
|
||||
echo " it will run all subrequirements. When this optin is used,"
|
||||
echo " only run requirement tests"
|
||||
}
|
||||
|
||||
OPT_PARSED=""
|
||||
|
@ -73,8 +78,11 @@ QEMU_FIRMWARE=""
|
|||
WASI_TESTSUITE_COMMIT="ee807fc551978490bf1c277059aabfa1e589a6c2"
|
||||
TARGET_LIST=("AARCH64" "AARCH64_VFP" "ARMV7" "ARMV7_VFP" "THUMBV7" "THUMBV7_VFP" \
|
||||
"RISCV32" "RISCV32_ILP32F" "RISCV32_ILP32D" "RISCV64" "RISCV64_LP64F" "RISCV64_LP64D")
|
||||
REQUIREMENT_NAME=""
|
||||
# Initialize an empty array for subrequirement IDs
|
||||
SUBREQUIREMENT_IDS=()
|
||||
|
||||
while getopts ":s:cabgvt:m:MCpSXexwWPGQF:j:T:" opt
|
||||
while getopts ":s:cabgvt:m:MCpSXexwWPGQF:j:T:r:" opt
|
||||
do
|
||||
OPT_PARSED="TRUE"
|
||||
case $opt in
|
||||
|
@ -192,6 +200,19 @@ do
|
|||
echo "sanitizer is " ${OPTARG}
|
||||
WAMR_BUILD_SANITIZER=${OPTARG}
|
||||
;;
|
||||
r)
|
||||
REQUIREMENT_NAME=$OPTARG
|
||||
# get next arg if there are multiple values after -r
|
||||
eval "nxarg=\${$((OPTIND))}"
|
||||
# loop until the next symbol '-' or the end of arguments
|
||||
while [[ "${nxarg}" =~ ^[0-9]+$ ]]; do
|
||||
SUBREQUIREMENT_IDS+=("$nxarg")
|
||||
OPTIND=$((OPTIND+1))
|
||||
eval "nxarg=\${$((OPTIND))}"
|
||||
done
|
||||
echo "Only Test requirement name: ${REQUIREMENT_NAME}"
|
||||
[[ ${#SUBREQUIREMENT_IDS[@]} -ne 0 ]] && echo "Choose subrequirement IDs: ${SUBREQUIREMENT_IDS[@]}"
|
||||
;;
|
||||
?)
|
||||
help
|
||||
exit 1
|
||||
|
@ -219,6 +240,7 @@ readonly REPORT_DIR=${WORK_DIR}/report/${DATE}
|
|||
mkdir -p ${REPORT_DIR}
|
||||
|
||||
readonly WAMR_DIR=${WORK_DIR}/../../..
|
||||
readonly REQUIREMENT_SCRIPT_DIR=${WORK_DIR}/../requirement-engineering-test-script
|
||||
|
||||
if [[ ${SGX_OPT} == "--sgx" ]];then
|
||||
readonly IWASM_LINUX_ROOT_DIR="${WAMR_DIR}/product-mini/platforms/linux-sgx"
|
||||
|
@ -442,17 +464,17 @@ function spec_test()
|
|||
popd
|
||||
if [ ! -d "exception-handling" ];then
|
||||
echo "exception-handling not exist, clone it from github"
|
||||
git clone -b master --single-branch https://github.com/WebAssembly/exception-handling
|
||||
git clone -b master --single-branch https://github.com/WebAssembly/exception-handling
|
||||
fi
|
||||
pushd exception-handling
|
||||
|
||||
# restore and clean everything
|
||||
git reset --hard 51c721661b671bb7dc4b3a3acb9e079b49778d36
|
||||
|
||||
|
||||
if [[ ${ENABLE_MULTI_MODULE} == 0 ]]; then
|
||||
git apply ../../spec-test-script/exception_handling.patch
|
||||
fi
|
||||
|
||||
|
||||
popd
|
||||
echo $(pwd)
|
||||
fi
|
||||
|
@ -731,6 +753,8 @@ function collect_standalone()
|
|||
./collect_coverage.sh "${CODE_COV_FILE}" "${STANDALONE_DIR}/test-running-modes/c-embed/build"
|
||||
echo "Collect code coverage of standalone test-ts2"
|
||||
./collect_coverage.sh "${CODE_COV_FILE}" "${STANDALONE_DIR}/test-ts2/build"
|
||||
echo "Collect code coverage of standalone test-module-malloc"
|
||||
./collect_coverage.sh "${CODE_COV_FILE}" "${STANDALONE_DIR}/test-module-malloc/build"
|
||||
|
||||
popd > /dev/null 2>&1
|
||||
fi
|
||||
|
@ -858,6 +882,13 @@ function collect_coverage()
|
|||
|
||||
function trigger()
|
||||
{
|
||||
# Check if REQUIREMENT_NAME is set, if set, only calling requirement test and early return
|
||||
if [[ -n $REQUIREMENT_NAME ]]; then
|
||||
python ${REQUIREMENT_SCRIPT_DIR}/run_requirement.py -o ${REPORT_DIR}/ -r "$REQUIREMENT_NAME" "${SUBREQUIREMENT_IDS[@]}"
|
||||
# early return with the python script exit status
|
||||
return $?
|
||||
fi
|
||||
|
||||
local EXTRA_COMPILE_FLAGS=""
|
||||
# default enabled features
|
||||
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_BULK_MEMORY=1"
|
||||
|
@ -907,6 +938,7 @@ function trigger()
|
|||
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_EXCE_HANDLING=1"
|
||||
EXTRA_COMPILE_FLAGS+=" -DWAMR_BUILD_TAIL_CALL=1"
|
||||
fi
|
||||
|
||||
echo "SANITIZER IS" $WAMR_BUILD_SANITIZER
|
||||
|
||||
if [[ "$WAMR_BUILD_SANITIZER" == "ubsan" ]]; then
|
||||
|
|
Loading…
Reference in New Issue
Block a user