summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry <mail@henrygressmann.de>2023-12-23 18:19:12 +0100
committerHenry <mail@henrygressmann.de>2023-12-23 18:19:12 +0100
commit154d5fe5311ede2be44036900ad7598fe5fc8664 (patch)
treee66a7e08e2108f4f85e308f2e60680be4447f9e1
parentac6b812d7555c7a84a3e8d12d64fdb34d8f536f2 (diff)
tests: improve test glue code
Signed-off-by: Henry <mail@henrygressmann.de>
-rw-r--r--Cargo.lock34
-rw-r--r--crates/tinywasm/Cargo.toml2
-rw-r--r--crates/tinywasm/tests/test-mvp.rs2
-rw-r--r--crates/tinywasm/tests/test-wast.rs21
-rw-r--r--crates/tinywasm/tests/testsuite/mod.rs2
-rw-r--r--crates/tinywasm/tests/testsuite/run.rs268
-rw-r--r--examples/wast/i32.wast985
7 files changed, 1163 insertions, 151 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 33ddaf4..fa98cc7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -71,7 +71,7 @@ dependencies = [
"argh_shared",
"proc-macro2",
"quote",
- "syn 2.0.41",
+ "syn 2.0.42",
]
[[package]]
@@ -241,7 +241,7 @@ dependencies = [
"eyre",
"indenter",
"once_cell",
- "owo-colors",
+ "owo-colors 3.5.0",
]
[[package]]
@@ -785,6 +785,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
[[package]]
+name = "owo-colors"
+version = "4.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f"
+
+[[package]]
name = "pathfinder_geometry"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -805,9 +811,9 @@ dependencies = [
[[package]]
name = "pkg-config"
-version = "0.3.27"
+version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
+checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a"
[[package]]
name = "plotters"
@@ -880,9 +886,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.70"
+version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
+checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8"
dependencies = [
"unicode-ident",
]
@@ -1029,7 +1035,7 @@ dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
- "syn 2.0.41",
+ "syn 2.0.42",
"walkdir",
]
@@ -1116,7 +1122,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.41",
+ "syn 2.0.42",
]
[[package]]
@@ -1166,9 +1172,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.41"
+version = "2.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269"
+checksum = "5b7d0a2c048d661a1a59fcd7355baa232f7ed34e0ee4df2eef3c1c1c0d3852d8"
dependencies = [
"proc-macro2",
"quote",
@@ -1207,7 +1213,7 @@ checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.41",
+ "syn 2.0.42",
]
[[package]]
@@ -1231,7 +1237,7 @@ version = "0.0.6-alpha.0"
dependencies = [
"eyre",
"log",
- "owo-colors",
+ "owo-colors 4.0.0",
"plotters",
"serde",
"serde_json",
@@ -1343,7 +1349,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
- "syn 2.0.41",
+ "syn 2.0.42",
"wasm-bindgen-shared",
]
@@ -1365,7 +1371,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.41",
+ "syn 2.0.42",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
diff --git a/crates/tinywasm/Cargo.toml b/crates/tinywasm/Cargo.toml
index 852c31c..86b65eb 100644
--- a/crates/tinywasm/Cargo.toml
+++ b/crates/tinywasm/Cargo.toml
@@ -20,7 +20,7 @@ tinywasm-types={version="0.0.6-alpha.0", path="../types", default-features=false
[dev-dependencies]
wasm-testsuite={path="../wasm-testsuite"}
wast={version="69.0"}
-owo-colors={version="3.5"}
+owo-colors={version="4.0"}
eyre={version="0.6"}
serde_json={version="1.0"}
serde={version="1.0", features=["derive"]}
diff --git a/crates/tinywasm/tests/test-mvp.rs b/crates/tinywasm/tests/test-mvp.rs
index eab372b..fdd043d 100644
--- a/crates/tinywasm/tests/test-mvp.rs
+++ b/crates/tinywasm/tests/test-mvp.rs
@@ -9,7 +9,7 @@ fn main() -> Result<()> {
fn test_mvp() -> Result<()> {
let mut test_suite = TestSuite::new();
- test_suite.run(wasm_testsuite::MVP_TESTS)?;
+ test_suite.run_spec_group(wasm_testsuite::MVP_TESTS)?;
test_suite.save_csv("./tests/generated/mvp.csv", env!("CARGO_PKG_VERSION"))?;
if test_suite.failed() {
diff --git a/crates/tinywasm/tests/test-wast.rs b/crates/tinywasm/tests/test-wast.rs
index 47e7d95..0770cb6 100644
--- a/crates/tinywasm/tests/test-wast.rs
+++ b/crates/tinywasm/tests/test-wast.rs
@@ -1,3 +1,5 @@
+use std::path::PathBuf;
+
use eyre::{bail, Result};
use testsuite::TestSuite;
@@ -9,8 +11,20 @@ fn main() -> Result<()> {
bail!("usage: cargo test-wast <wast-file>")
}
- let wast_file = &args[1];
- test_wast(wast_file)?;
+ // cwd for relative paths, absolute paths are kept as-is
+ let cwd = std::env::current_dir()?;
+
+ // if current dir is crates/tinywasm, then we want to go up 2 levels
+ let mut wast_file = if cwd.ends_with("crates/tinywasm") {
+ PathBuf::from("../../")
+ } else {
+ PathBuf::from("./")
+ };
+
+ wast_file.push(&args[1]);
+ let wast_file = cwd.join(wast_file);
+
+ test_wast(wast_file.to_str().expect("wast_file is not a valid path"))?;
Ok(())
}
@@ -19,7 +33,8 @@ fn test_wast(wast_file: &str) -> Result<()> {
println!("args: {:?}", args);
let mut test_suite = TestSuite::new();
- test_suite.run(&[wast_file])?;
+ println!("running wast file: {}", wast_file);
+ test_suite.run_paths(&[wast_file])?;
if test_suite.failed() {
eprintln!("\n\nfailed one or more tests:\n{:#?}", test_suite);
diff --git a/crates/tinywasm/tests/testsuite/mod.rs b/crates/tinywasm/tests/testsuite/mod.rs
index d5cde5f..2a9cf4e 100644
--- a/crates/tinywasm/tests/testsuite/mod.rs
+++ b/crates/tinywasm/tests/testsuite/mod.rs
@@ -1,3 +1,5 @@
+#![allow(dead_code)] // rust analyzer doesn't recognize that code is used by tests without harness
+
use eyre::Result;
use std::io::{BufRead, Seek, SeekFrom};
use std::{
diff --git a/crates/tinywasm/tests/testsuite/run.rs b/crates/tinywasm/tests/testsuite/run.rs
index 23c470c..afac117 100644
--- a/crates/tinywasm/tests/testsuite/run.rs
+++ b/crates/tinywasm/tests/testsuite/run.rs
@@ -7,165 +7,169 @@ use tinywasm_types::TinyWasmModule;
use wast::{lexer::Lexer, parser::ParseBuffer, Wast};
impl TestSuite {
- pub fn run(&mut self, tests: &[&str]) -> Result<()> {
+ pub fn run_paths(&mut self, tests: &[&str]) -> Result<()> {
tests.iter().for_each(|group| {
- let test_group = self.test_group(group);
+ let group_wast = std::fs::read(group).expect("failed to read test wast");
+ let group_wast = Cow::Owned(group_wast);
+ self.run_group(group, group_wast).expect("failed to run group");
+ });
- let wast = if group.starts_with("./") {
- let file = std::fs::read(group).expect("failed to read test wast");
- Cow::Owned(file)
- } else {
- wasm_testsuite::get_test_wast(group).expect("failed to get test wast")
- };
+ Ok(())
+ }
- let wast = std::str::from_utf8(&wast).expect("failed to convert wast to utf8");
+ pub fn run_spec_group(&mut self, tests: &[&str]) -> Result<()> {
+ tests.iter().for_each(|group| {
+ let group_wast = wasm_testsuite::get_test_wast(group).expect("failed to get test wast");
+ self.run_group(group, group_wast).expect("failed to run group");
+ });
- let mut lexer = Lexer::new(wast);
- // we need to allow confusing unicode characters since they are technically valid wasm
- lexer.allow_confusing_unicode(true);
+ Ok(())
+ }
- let buf = ParseBuffer::new_with_lexer(lexer).expect("failed to create parse buffer");
- let wast_data = wast::parser::parse::<Wast>(&buf).expect("failed to parse wat");
+ pub fn run_group(&mut self, group_name: &str, group_wast: Cow<'_, [u8]>) -> Result<()> {
+ let test_group = self.test_group(group_name);
+ let wast = std::str::from_utf8(&group_wast).expect("failed to convert wast to utf8");
- let mut last_module: Option<TinyWasmModule> = None;
- for (i, directive) in wast_data.directives.into_iter().enumerate() {
- let span = directive.span();
- use wast::WastDirective::*;
- let name = format!("{}-{}", group, i);
+ let mut lexer = Lexer::new(wast);
+ // we need to allow confusing unicode characters since they are technically valid wasm
+ lexer.allow_confusing_unicode(true);
- match directive {
- // TODO: needs to support more binary sections
- Wat(mut module) => {
- let result = catch_unwind_silent(move || parse_module_bytes(&module.encode().unwrap()))
- .map_err(|e| eyre!("failed to parse module: {:?}", e))
- .and_then(|res| res);
+ let buf = ParseBuffer::new_with_lexer(lexer).expect("failed to create parse buffer");
+ let wast_data = wast::parser::parse::<Wast>(&buf).expect("failed to parse wat");
- match &result {
- Err(_) => last_module = None,
- Ok(m) => last_module = Some(m.clone()),
- }
+ let mut last_module: Option<TinyWasmModule> = None;
+ for (i, directive) in wast_data.directives.into_iter().enumerate() {
+ let span = directive.span();
+ use wast::WastDirective::*;
+ let name = format!("{}-{}", group_name, i);
- test_group.add_result(&format!("{}-parse", name), span, result.map(|_| ()));
+ match directive {
+ Wat(mut module) => {
+ let result = catch_unwind_silent(move || parse_module_bytes(&module.encode().unwrap()))
+ .map_err(|e| eyre!("failed to parse module: {:?}", e))
+ .and_then(|res| res);
+
+ match &result {
+ Err(_) => last_module = None,
+ Ok(m) => last_module = Some(m.clone()),
}
- AssertMalformed {
- span,
- mut module,
- message: _,
- } => {
- let Ok(module) = module.encode() else {
- test_group.add_result(&format!("{}-malformed", name), span, Ok(()));
- continue;
- };
+ test_group.add_result(&format!("{}-parse", name), span, result.map(|_| ()));
+ }
- let res = catch_unwind_silent(|| parse_module_bytes(&module))
- .map_err(|e| eyre!("failed to parse module: {:?}", e))
- .and_then(|res| res);
+ AssertMalformed {
+ span,
+ mut module,
+ message: _,
+ } => {
+ let Ok(module) = module.encode() else {
+ test_group.add_result(&format!("{}-malformed", name), span, Ok(()));
+ continue;
+ };
- test_group.add_result(
- &format!("{}-malformed", name),
- span,
- match res {
- Ok(_) => Err(eyre!("expected module to be malformed")),
- Err(_) => Ok(()),
- },
- );
- }
+ let res = catch_unwind_silent(|| parse_module_bytes(&module))
+ .map_err(|e| eyre!("failed to parse module: {:?}", e))
+ .and_then(|res| res);
- AssertInvalid {
+ test_group.add_result(
+ &format!("{}-malformed", name),
span,
- mut module,
- message: _,
- } => {
- let res = catch_unwind_silent(move || parse_module_bytes(&module.encode().unwrap()))
- .map_err(|e| eyre!("failed to parse module: {:?}", e))
- .and_then(|res| res);
-
- test_group.add_result(
- &format!("{}-invalid", name),
- span,
- match res {
- Ok(_) => Err(eyre!("expected module to be invalid")),
- Err(_) => Ok(()),
- },
- );
- }
+ match res {
+ Ok(_) => Err(eyre!("expected module to be malformed")),
+ Err(_) => Ok(()),
+ },
+ );
+ }
- AssertTrap { exec, message: _, span } => {
- let res: Result<tinywasm::Result<()>, _> = catch_unwind_silent(|| {
- let (module, name) = match exec {
- wast::WastExecute::Wat(_wat) => unimplemented!("wat"),
- wast::WastExecute::Get { module: _, global: _ } => unimplemented!("get"),
- wast::WastExecute::Invoke(invoke) => (last_module.as_ref(), invoke.name),
- };
- exec_fn(module, name, &[]).map(|_| ())
- });
+ AssertInvalid {
+ span,
+ mut module,
+ message: _,
+ } => {
+ let res = catch_unwind_silent(move || parse_module_bytes(&module.encode().unwrap()))
+ .map_err(|e| eyre!("failed to parse module: {:?}", e))
+ .and_then(|res| res);
+ test_group.add_result(
+ &format!("{}-invalid", name),
+ span,
match res {
- Err(err) => test_group.add_result(
- &format!("{}-trap", name),
- span,
- Err(eyre!("test panicked: {:?}", err)),
- ),
- Ok(Err(tinywasm::Error::Trap(_))) => {
- test_group.add_result(&format!("{}-trap", name), span, Ok(()))
- }
- Ok(Err(err)) => test_group.add_result(
- &format!("{}-trap", name),
- span,
- Err(eyre!("expected trap, got error: {:?}", err)),
- ),
- Ok(Ok(())) => test_group.add_result(
- &format!("{}-trap", name),
- span,
- Err(eyre!("expected trap, got ok")),
- ),
+ Ok(_) => Err(eyre!("expected module to be invalid")),
+ Err(_) => Ok(()),
+ },
+ );
+ }
+
+ AssertTrap { exec, message: _, span } => {
+ let res: Result<tinywasm::Result<()>, _> = catch_unwind_silent(|| {
+ let (module, name) = match exec {
+ wast::WastExecute::Wat(_wat) => unimplemented!("wat"),
+ wast::WastExecute::Get { module: _, global: _ } => unimplemented!("get"),
+ wast::WastExecute::Invoke(invoke) => (last_module.as_ref(), invoke.name),
+ };
+ exec_fn(module, name, &[]).map(|_| ())
+ });
+
+ match res {
+ Err(err) => test_group.add_result(
+ &format!("{}-trap", name),
+ span,
+ Err(eyre!("test panicked: {:?}", err)),
+ ),
+ Ok(Err(tinywasm::Error::Trap(_))) => {
+ test_group.add_result(&format!("{}-trap", name), span, Ok(()))
+ }
+ Ok(Err(err)) => test_group.add_result(
+ &format!("{}-trap", name),
+ span,
+ Err(eyre!("expected trap, got error: {:?}", err)),
+ ),
+ Ok(Ok(())) => {
+ test_group.add_result(&format!("{}-trap", name), span, Err(eyre!("expected trap, got ok")))
}
}
+ }
- AssertReturn { span, exec, results } => {
- let res: Result<Result<()>, _> = catch_unwind_silent(|| {
- let invoke = match exec {
- wast::WastExecute::Wat(_) => unimplemented!("wat"),
- wast::WastExecute::Get { module: _, global: _ } => {
- return Err(eyre!("get not supported"))
- }
- wast::WastExecute::Invoke(invoke) => invoke,
- };
+ AssertReturn { span, exec, results } => {
+ let res: Result<Result<()>, _> = catch_unwind_silent(|| {
+ let invoke = match exec {
+ wast::WastExecute::Wat(_) => unimplemented!("wat"),
+ wast::WastExecute::Get { module: _, global: _ } => return Err(eyre!("get not supported")),
+ wast::WastExecute::Invoke(invoke) => invoke,
+ };
- let args = invoke
- .args
- .into_iter()
- .map(wastarg2tinywasmvalue)
- .collect::<Result<Vec<_>>>()?;
+ let args = invoke
+ .args
+ .into_iter()
+ .map(wastarg2tinywasmvalue)
+ .collect::<Result<Vec<_>>>()?;
- let outcomes = exec_fn(last_module.as_ref(), invoke.name, &args)?;
- let expected = results
- .into_iter()
- .map(wastret2tinywasmvalue)
- .collect::<Result<Vec<_>>>()?;
+ let outcomes = exec_fn(last_module.as_ref(), invoke.name, &args)?;
+ let expected = results
+ .into_iter()
+ .map(wastret2tinywasmvalue)
+ .collect::<Result<Vec<_>>>()?;
- if outcomes.len() != expected.len() {
- return Err(eyre!("expected {} results, got {}", expected.len(), outcomes.len()));
- }
- outcomes
- .iter()
- .zip(expected)
- .enumerate()
- .try_for_each(|(i, (outcome, exp))| {
- (outcome == &exp)
- .then_some(())
- .ok_or_else(|| eyre!("result {} did not match: {:?} != {:?}", i, outcome, exp))
- })
- });
+ if outcomes.len() != expected.len() {
+ return Err(eyre!("expected {} results, got {}", expected.len(), outcomes.len()));
+ }
+ outcomes
+ .iter()
+ .zip(expected)
+ .enumerate()
+ .try_for_each(|(i, (outcome, exp))| {
+ (outcome == &exp)
+ .then_some(())
+ .ok_or_else(|| eyre!("result {} did not match: {:?} != {:?}", i, outcome, exp))
+ })
+ });
- let res = res.map_err(|e| eyre!("test panicked: {:?}", e)).and_then(|r| r);
- test_group.add_result(&format!("{}-return", name), span, res);
- }
- _ => test_group.add_result(&format!("{}-unknown", name), span, Err(eyre!("unsupported directive"))),
+ let res = res.map_err(|e| eyre!("test panicked: {:?}", e)).and_then(|r| r);
+ test_group.add_result(&format!("{}-return", name), span, res);
}
+ _ => test_group.add_result(&format!("{}-unknown", name), span, Err(eyre!("unsupported directive"))),
}
- });
+ }
Ok(())
}
diff --git a/examples/wast/i32.wast b/examples/wast/i32.wast
new file mode 100644
index 0000000..2e8ab70
--- /dev/null
+++ b/examples/wast/i32.wast
@@ -0,0 +1,985 @@
+;; i32 operations
+
+(module
+ (func (export "add") (param $x i32) (param $y i32) (result i32) (i32.add (local.get $x) (local.get $y)))
+ (func (export "sub") (param $x i32) (param $y i32) (result i32) (i32.sub (local.get $x) (local.get $y)))
+ (func (export "mul") (param $x i32) (param $y i32) (result i32) (i32.mul (local.get $x) (local.get $y)))
+ (func (export "div_s") (param $x i32) (param $y i32) (result i32) (i32.div_s (local.get $x) (local.get $y)))
+ (func (export "div_u") (param $x i32) (param $y i32) (result i32) (i32.div_u (local.get $x) (local.get $y)))
+ (func (export "rem_s") (param $x i32) (param $y i32) (result i32) (i32.rem_s (local.get $x) (local.get $y)))
+ (func (export "rem_u") (param $x i32) (param $y i32) (result i32) (i32.rem_u (local.get $x) (local.get $y)))
+ (func (export "and") (param $x i32) (param $y i32) (result i32) (i32.and (local.get $x) (local.get $y)))
+ (func (export "or") (param $x i32) (param $y i32) (result i32) (i32.or (local.get $x) (local.get $y)))
+ (func (export "xor") (param $x i32) (param $y i32) (result i32) (i32.xor (local.get $x) (local.get $y)))
+ (func (export "shl") (param $x i32) (param $y i32) (result i32) (i32.shl (local.get $x) (local.get $y)))
+ (func (export "shr_s") (param $x i32) (param $y i32) (result i32) (i32.shr_s (local.get $x) (local.get $y)))
+ (func (export "shr_u") (param $x i32) (param $y i32) (result i32) (i32.shr_u (local.get $x) (local.get $y)))
+ (func (export "rotl") (param $x i32) (param $y i32) (result i32) (i32.rotl (local.get $x) (local.get $y)))
+ (func (export "rotr") (param $x i32) (param $y i32) (result i32) (i32.rotr (local.get $x) (local.get $y)))
+ (func (export "clz") (param $x i32) (result i32) (i32.clz (local.get $x)))
+ (func (export "ctz") (param $x i32) (result i32) (i32.ctz (local.get $x)))
+ (func (export "popcnt") (param $x i32) (result i32) (i32.popcnt (local.get $x)))
+ (func (export "extend8_s") (param $x i32) (result i32) (i32.extend8_s (local.get $x)))
+ (func (export "extend16_s") (param $x i32) (result i32) (i32.extend16_s (local.get $x)))
+ (func (export "eqz") (param $x i32) (result i32) (i32.eqz (local.get $x)))
+ (func (export "eq") (param $x i32) (param $y i32) (result i32) (i32.eq (local.get $x) (local.get $y)))
+ (func (export "ne") (param $x i32) (param $y i32) (result i32) (i32.ne (local.get $x) (local.get $y)))
+ (func (export "lt_s") (param $x i32) (param $y i32) (result i32) (i32.lt_s (local.get $x) (local.get $y)))
+ (func (export "lt_u") (param $x i32) (param $y i32) (result i32) (i32.lt_u (local.get $x) (local.get $y)))
+ (func (export "le_s") (param $x i32) (param $y i32) (result i32) (i32.le_s (local.get $x) (local.get $y)))
+ (func (export "le_u") (param $x i32) (param $y i32) (result i32) (i32.le_u (local.get $x) (local.get $y)))
+ (func (export "gt_s") (param $x i32) (param $y i32) (result i32) (i32.gt_s (local.get $x) (local.get $y)))
+ (func (export "gt_u") (param $x i32) (param $y i32) (result i32) (i32.gt_u (local.get $x) (local.get $y)))
+ (func (export "ge_s") (param $x i32) (param $y i32) (result i32) (i32.ge_s (local.get $x) (local.get $y)))
+ (func (export "ge_u") (param $x i32) (param $y i32) (result i32) (i32.ge_u (local.get $x) (local.get $y)))
+)
+
+(assert_return (invoke "add" (i32.const 1) (i32.const 1)) (i32.const 2))
+(assert_return (invoke "add" (i32.const 1) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "add" (i32.const -1) (i32.const -1)) (i32.const -2))
+(assert_return (invoke "add" (i32.const -1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "add" (i32.const 0x7fffffff) (i32.const 1)) (i32.const 0x80000000))
+(assert_return (invoke "add" (i32.const 0x80000000) (i32.const -1)) (i32.const 0x7fffffff))
+(assert_return (invoke "add" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "add" (i32.const 0x3fffffff) (i32.const 1)) (i32.const 0x40000000))
+
+(assert_return (invoke "sub" (i32.const 1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "sub" (i32.const 1) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "sub" (i32.const -1) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "sub" (i32.const 0x7fffffff) (i32.const -1)) (i32.const 0x80000000))
+(assert_return (invoke "sub" (i32.const 0x80000000) (i32.const 1)) (i32.const 0x7fffffff))
+(assert_return (invoke "sub" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "sub" (i32.const 0x3fffffff) (i32.const -1)) (i32.const 0x40000000))
+
+(assert_return (invoke "mul" (i32.const 1) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "mul" (i32.const 1) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "mul" (i32.const -1) (i32.const -1)) (i32.const 1))
+(assert_return (invoke "mul" (i32.const 0x10000000) (i32.const 4096)) (i32.const 0))
+(assert_return (invoke "mul" (i32.const 0x80000000) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "mul" (i32.const 0x80000000) (i32.const -1)) (i32.const 0x80000000))
+(assert_return (invoke "mul" (i32.const 0x7fffffff) (i32.const -1)) (i32.const 0x80000001))
+(assert_return (invoke "mul" (i32.const 0x01234567) (i32.const 0x76543210)) (i32.const 0x358e7470))
+(assert_return (invoke "mul" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 1))
+
+(assert_trap (invoke "div_s" (i32.const 1) (i32.const 0)) "integer divide by zero")
+(assert_trap (invoke "div_s" (i32.const 0) (i32.const 0)) "integer divide by zero")
+(assert_trap (invoke "div_s" (i32.const 0x80000000) (i32.const -1)) "integer overflow")
+(assert_trap (invoke "div_s" (i32.const 0x80000000) (i32.const 0)) "integer divide by zero")
+(assert_return (invoke "div_s" (i32.const 1) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "div_s" (i32.const 0) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "div_s" (i32.const 0) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "div_s" (i32.const -1) (i32.const -1)) (i32.const 1))
+(assert_return (invoke "div_s" (i32.const 0x80000000) (i32.const 2)) (i32.const 0xc0000000))
+(assert_return (invoke "div_s" (i32.const 0x80000001) (i32.const 1000)) (i32.const 0xffdf3b65))
+(assert_return (invoke "div_s" (i32.const 5) (i32.const 2)) (i32.const 2))
+(assert_return (invoke "div_s" (i32.const -5) (i32.const 2)) (i32.const -2))
+(assert_return (invoke "div_s" (i32.const 5) (i32.const -2)) (i32.const -2))
+(assert_return (invoke "div_s" (i32.const -5) (i32.const -2)) (i32.const 2))
+(assert_return (invoke "div_s" (i32.const 7) (i32.const 3)) (i32.const 2))
+(assert_return (invoke "div_s" (i32.const -7) (i32.const 3)) (i32.const -2))
+(assert_return (invoke "div_s" (i32.const 7) (i32.const -3)) (i32.const -2))
+(assert_return (invoke "div_s" (i32.const -7) (i32.const -3)) (i32.const 2))
+(assert_return (invoke "div_s" (i32.const 11) (i32.const 5)) (i32.const 2))
+(assert_return (invoke "div_s" (i32.const 17) (i32.const 7)) (i32.const 2))
+
+(assert_trap (invoke "div_u" (i32.const 1) (i32.const 0)) "integer divide by zero")
+(assert_trap (invoke "div_u" (i32.const 0) (i32.const 0)) "integer divide by zero")
+(assert_return (invoke "div_u" (i32.const 1) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "div_u" (i32.const 0) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "div_u" (i32.const -1) (i32.const -1)) (i32.const 1))
+(assert_return (invoke "div_u" (i32.const 0x80000000) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "div_u" (i32.const 0x80000000) (i32.const 2)) (i32.const 0x40000000))
+(assert_return (invoke "div_u" (i32.const 0x8ff00ff0) (i32.const 0x10001)) (i32.const 0x8fef))
+(assert_return (invoke "div_u" (i32.const 0x80000001) (i32.const 1000)) (i32.const 0x20c49b))
+(assert_return (invoke "div_u" (i32.const 5) (i32.const 2)) (i32.const 2))
+(assert_return (invoke "div_u" (i32.const -5) (i32.const 2)) (i32.const 0x7ffffffd))
+(assert_return (invoke "div_u" (i32.const 5) (i32.const -2)) (i32.const 0))
+(assert_return (invoke "div_u" (i32.const -5) (i32.const -2)) (i32.const 0))
+(assert_return (invoke "div_u" (i32.const 7) (i32.const 3)) (i32.const 2))
+(assert_return (invoke "div_u" (i32.const 11) (i32.const 5)) (i32.const 2))
+(assert_return (invoke "div_u" (i32.const 17) (i32.const 7)) (i32.const 2))
+
+(assert_trap (invoke "rem_s" (i32.const 1) (i32.const 0)) "integer divide by zero")
+(assert_trap (invoke "rem_s" (i32.const 0) (i32.const 0)) "integer divide by zero")
+(assert_return (invoke "rem_s" (i32.const 0x7fffffff) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "rem_s" (i32.const 1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "rem_s" (i32.const 0) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "rem_s" (i32.const 0) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "rem_s" (i32.const -1) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "rem_s" (i32.const 0x80000000) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "rem_s" (i32.const 0x80000000) (i32.const 2)) (i32.const 0))
+(assert_return (invoke "rem_s" (i32.const 0x80000001) (i32.const 1000)) (i32.const -647))
+(assert_return (invoke "rem_s" (i32.const 5) (i32.const 2)) (i32.const 1))
+(assert_return (invoke "rem_s" (i32.const -5) (i32.const 2)) (i32.const -1))
+(assert_return (invoke "rem_s" (i32.const 5) (i32.const -2)) (i32.const 1))
+(assert_return (invoke "rem_s" (i32.const -5) (i32.const -2)) (i32.const -1))
+(assert_return (invoke "rem_s" (i32.const 7) (i32.const 3)) (i32.const 1))
+(assert_return (invoke "rem_s" (i32.const -7) (i32.const 3)) (i32.const -1))
+(assert_return (invoke "rem_s" (i32.const 7) (i32.const -3)) (i32.const 1))
+(assert_return (invoke "rem_s" (i32.const -7) (i32.const -3)) (i32.const -1))
+(assert_return (invoke "rem_s" (i32.const 11) (i32.const 5)) (i32.const 1))
+(assert_return (invoke "rem_s" (i32.const 17) (i32.const 7)) (i32.const 3))
+
+(assert_trap (invoke "rem_u" (i32.const 1) (i32.const 0)) "integer divide by zero")
+(assert_trap (invoke "rem_u" (i32.const 0) (i32.const 0)) "integer divide by zero")
+(assert_return (invoke "rem_u" (i32.const 1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "rem_u" (i32.const 0) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "rem_u" (i32.const -1) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "rem_u" (i32.const 0x80000000) (i32.const -1)) (i32.const 0x80000000))
+(assert_return (invoke "rem_u" (i32.const 0x80000000) (i32.const 2)) (i32.const 0))
+(assert_return (invoke "rem_u" (i32.const 0x8ff00ff0) (i32.const 0x10001)) (i32.const 0x8001))
+(assert_return (invoke "rem_u" (i32.const 0x80000001) (i32.const 1000)) (i32.const 649))
+(assert_return (invoke "rem_u" (i32.const 5) (i32.const 2)) (i32.const 1))
+(assert_return (invoke "rem_u" (i32.const -5) (i32.const 2)) (i32.const 1))
+(assert_return (invoke "rem_u" (i32.const 5) (i32.const -2)) (i32.const 5))
+(assert_return (invoke "rem_u" (i32.const -5) (i32.const -2)) (i32.const -5))
+(assert_return (invoke "rem_u" (i32.const 7) (i32.const 3)) (i32.const 1))
+(assert_return (invoke "rem_u" (i32.const 11) (i32.const 5)) (i32.const 1))
+(assert_return (invoke "rem_u" (i32.const 17) (i32.const 7)) (i32.const 3))
+
+(assert_return (invoke "and" (i32.const 1) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "and" (i32.const 0) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "and" (i32.const 1) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "and" (i32.const 0) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "and" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "and" (i32.const 0x7fffffff) (i32.const -1)) (i32.const 0x7fffffff))
+(assert_return (invoke "and" (i32.const 0xf0f0ffff) (i32.const 0xfffff0f0)) (i32.const 0xf0f0f0f0))
+(assert_return (invoke "and" (i32.const 0xffffffff) (i32.const 0xffffffff)) (i32.const 0xffffffff))
+
+(assert_return (invoke "or" (i32.const 1) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "or" (i32.const 0) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "or" (i32.const 1) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "or" (i32.const 0) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "or" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const -1))
+(assert_return (invoke "or" (i32.const 0x80000000) (i32.const 0)) (i32.const 0x80000000))
+(assert_return (invoke "or" (i32.const 0xf0f0ffff) (i32.const 0xfffff0f0)) (i32.const 0xffffffff))
+(assert_return (invoke "or" (i32.const 0xffffffff) (i32.const 0xffffffff)) (i32.const 0xffffffff))
+
+(assert_return (invoke "xor" (i32.const 1) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "xor" (i32.const 0) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "xor" (i32.const 1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "xor" (i32.const 0) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "xor" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const -1))
+(assert_return (invoke "xor" (i32.const 0x80000000) (i32.const 0)) (i32.const 0x80000000))
+(assert_return (invoke "xor" (i32.const -1) (i32.const 0x80000000)) (i32.const 0x7fffffff))
+(assert_return (invoke "xor" (i32.const -1) (i32.const 0x7fffffff)) (i32.const 0x80000000))
+(assert_return (invoke "xor" (i32.const 0xf0f0ffff) (i32.const 0xfffff0f0)) (i32.const 0x0f0f0f0f))
+(assert_return (invoke "xor" (i32.const 0xffffffff) (i32.const 0xffffffff)) (i32.const 0))
+
+(assert_return (invoke "shl" (i32.const 1) (i32.const 1)) (i32.const 2))
+(assert_return (invoke "shl" (i32.const 1) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "shl" (i32.const 0x7fffffff) (i32.const 1)) (i32.const 0xfffffffe))
+(assert_return (invoke "shl" (i32.const 0xffffffff) (i32.const 1)) (i32.const 0xfffffffe))
+(assert_return (invoke "shl" (i32.const 0x80000000) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "shl" (i32.const 0x40000000) (i32.const 1)) (i32.const 0x80000000))
+(assert_return (invoke "shl" (i32.const 1) (i32.const 31)) (i32.const 0x80000000))
+(assert_return (invoke "shl" (i32.const 1) (i32.const 32)) (i32.const 1))
+(assert_return (invoke "shl" (i32.const 1) (i32.const 33)) (i32.const 2))
+(assert_return (invoke "shl" (i32.const 1) (i32.const -1)) (i32.const 0x80000000))
+(assert_return (invoke "shl" (i32.const 1) (i32.const 0x7fffffff)) (i32.const 0x80000000))
+
+(assert_return (invoke "shr_s" (i32.const 1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "shr_s" (i32.const 1) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "shr_s" (i32.const -1) (i32.const 1)) (i32.const -1))
+(assert_return (invoke "shr_s" (i32.const 0x7fffffff) (i32.const 1)) (i32.const 0x3fffffff))
+(assert_return (invoke "shr_s" (i32.const 0x80000000) (i32.const 1)) (i32.const 0xc0000000))
+(assert_return (invoke "shr_s" (i32.const 0x40000000) (i32.const 1)) (i32.const 0x20000000))
+(assert_return (invoke "shr_s" (i32.const 1) (i32.const 32)) (i32.const 1))
+(assert_return (invoke "shr_s" (i32.const 1) (i32.const 33)) (i32.const 0))
+(assert_return (invoke "shr_s" (i32.const 1) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "shr_s" (i32.const 1) (i32.const 0x7fffffff)) (i32.const 0))
+(assert_return (invoke "shr_s" (i32.const 1) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "shr_s" (i32.const 0x80000000) (i32.const 31)) (i32.const -1))
+(assert_return (invoke "shr_s" (i32.const -1) (i32.const 32)) (i32.const -1))
+(assert_return (invoke "shr_s" (i32.const -1) (i32.const 33)) (i32.const -1))
+(assert_return (invoke "shr_s" (i32.const -1) (i32.const -1)) (i32.const -1))
+(assert_return (invoke "shr_s" (i32.const -1) (i32.const 0x7fffffff)) (i32.const -1))
+(assert_return (invoke "shr_s" (i32.const -1) (i32.const 0x80000000)) (i32.const -1))
+
+(assert_return (invoke "shr_u" (i32.const 1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "shr_u" (i32.const 1) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "shr_u" (i32.const -1) (i32.const 1)) (i32.const 0x7fffffff))
+(assert_return (invoke "shr_u" (i32.const 0x7fffffff) (i32.const 1)) (i32.const 0x3fffffff))
+(assert_return (invoke "shr_u" (i32.const 0x80000000) (i32.const 1)) (i32.const 0x40000000))
+(assert_return (invoke "shr_u" (i32.const 0x40000000) (i32.const 1)) (i32.const 0x20000000))
+(assert_return (invoke "shr_u" (i32.const 1) (i32.const 32)) (i32.const 1))
+(assert_return (invoke "shr_u" (i32.const 1) (i32.const 33)) (i32.const 0))
+(assert_return (invoke "shr_u" (i32.const 1) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "shr_u" (i32.const 1) (i32.const 0x7fffffff)) (i32.const 0))
+(assert_return (invoke "shr_u" (i32.const 1) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "shr_u" (i32.const 0x80000000) (i32.const 31)) (i32.const 1))
+(assert_return (invoke "shr_u" (i32.const -1) (i32.const 32)) (i32.const -1))
+(assert_return (invoke "shr_u" (i32.const -1) (i32.const 33)) (i32.const 0x7fffffff))
+(assert_return (invoke "shr_u" (i32.const -1) (i32.const -1)) (i32.const 1))
+(assert_return (invoke "shr_u" (i32.const -1) (i32.const 0x7fffffff)) (i32.const 1))
+(assert_return (invoke "shr_u" (i32.const -1) (i32.const 0x80000000)) (i32.const -1))
+
+(assert_return (invoke "rotl" (i32.const 1) (i32.const 1)) (i32.const 2))
+(assert_return (invoke "rotl" (i32.const 1) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "rotl" (i32.const -1) (i32.const 1)) (i32.const -1))
+(assert_return (invoke "rotl" (i32.const 1) (i32.const 32)) (i32.const 1))
+(assert_return (invoke "rotl" (i32.const 0xabcd9876) (i32.const 1)) (i32.const 0x579b30ed))
+(assert_return (invoke "rotl" (i32.const 0xfe00dc00) (i32.const 4)) (i32.const 0xe00dc00f))
+(assert_return (invoke "rotl" (i32.const 0xb0c1d2e3) (i32.const 5)) (i32.const 0x183a5c76))
+(assert_return (invoke "rotl" (i32.const 0x00008000) (i32.const 37)) (i32.const 0x00100000))
+(assert_return (invoke "rotl" (i32.const 0xb0c1d2e3) (i32.const 0xff05)) (i32.const 0x183a5c76))
+(assert_return (invoke "rotl" (i32.const 0x769abcdf) (i32.const 0xffffffed)) (i32.const 0x579beed3))
+(assert_return (invoke "rotl" (i32.const 0x769abcdf) (i32.const 0x8000000d)) (i32.const 0x579beed3))
+(assert_return (invoke "rotl" (i32.const 1) (i32.const 31)) (i32.const 0x80000000))
+(assert_return (invoke "rotl" (i32.const 0x80000000) (i32.const 1)) (i32.const 1))
+
+(assert_return (invoke "rotr" (i32.const 1) (i32.const 1)) (i32.const 0x80000000))
+(assert_return (invoke "rotr" (i32.const 1) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "rotr" (i32.const -1) (i32.const 1)) (i32.const -1))
+(assert_return (invoke "rotr" (i32.const 1) (i32.const 32)) (i32.const 1))
+(assert_return (invoke "rotr" (i32.const 0xff00cc00) (i32.const 1)) (i32.const 0x7f806600))
+(assert_return (invoke "rotr" (i32.const 0x00080000) (i32.const 4)) (i32.const 0x00008000))
+(assert_return (invoke "rotr" (i32.const 0xb0c1d2e3) (i32.const 5)) (i32.const 0x1d860e97))
+(assert_return (invoke "rotr" (i32.const 0x00008000) (i32.const 37)) (i32.const 0x00000400))
+(assert_return (invoke "rotr" (i32.const 0xb0c1d2e3) (i32.const 0xff05)) (i32.const 0x1d860e97))
+(assert_return (invoke "rotr" (i32.const 0x769abcdf) (i32.const 0xffffffed)) (i32.const 0xe6fbb4d5))
+(assert_return (invoke "rotr" (i32.const 0x769abcdf) (i32.const 0x8000000d)) (i32.const 0xe6fbb4d5))
+(assert_return (invoke "rotr" (i32.const 1) (i32.const 31)) (i32.const 2))
+(assert_return (invoke "rotr" (i32.const 0x80000000) (i32.const 31)) (i32.const 1))
+
+(assert_return (invoke "clz" (i32.const 0xffffffff)) (i32.const 0))
+(assert_return (invoke "clz" (i32.const 0)) (i32.const 32))
+(assert_return (invoke "clz" (i32.const 0x00008000)) (i32.const 16))
+(assert_return (invoke "clz" (i32.const 0xff)) (i32.const 24))
+(assert_return (invoke "clz" (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "clz" (i32.const 1)) (i32.const 31))
+(assert_return (invoke "clz" (i32.const 2)) (i32.const 30))
+(assert_return (invoke "clz" (i32.const 0x7fffffff)) (i32.const 1))
+
+(assert_return (invoke "ctz" (i32.const -1)) (i32.const 0))
+(assert_return (invoke "ctz" (i32.const 0)) (i32.const 32))
+(assert_return (invoke "ctz" (i32.const 0x00008000)) (i32.const 15))
+(assert_return (invoke "ctz" (i32.const 0x00010000)) (i32.const 16))
+(assert_return (invoke "ctz" (i32.const 0x80000000)) (i32.const 31))
+(assert_return (invoke "ctz" (i32.const 0x7fffffff)) (i32.const 0))
+
+(assert_return (invoke "popcnt" (i32.const -1)) (i32.const 32))
+(assert_return (invoke "popcnt" (i32.const 0)) (i32.const 0))
+(assert_return (invoke "popcnt" (i32.const 0x00008000)) (i32.const 1))
+(assert_return (invoke "popcnt" (i32.const 0x80008000)) (i32.const 2))
+(assert_return (invoke "popcnt" (i32.const 0x7fffffff)) (i32.const 31))
+(assert_return (invoke "popcnt" (i32.const 0xAAAAAAAA)) (i32.const 16))
+(assert_return (invoke "popcnt" (i32.const 0x55555555)) (i32.const 16))
+(assert_return (invoke "popcnt" (i32.const 0xDEADBEEF)) (i32.const 24))
+
+(assert_return (invoke "extend8_s" (i32.const 0)) (i32.const 0))
+(assert_return (invoke "extend8_s" (i32.const 0x7f)) (i32.const 127))
+(assert_return (invoke "extend8_s" (i32.const 0x80)) (i32.const -128))
+(assert_return (invoke "extend8_s" (i32.const 0xff)) (i32.const -1))
+(assert_return (invoke "extend8_s" (i32.const 0x012345_00)) (i32.const 0))
+(assert_return (invoke "extend8_s" (i32.const 0xfedcba_80)) (i32.const -0x80))
+(assert_return (invoke "extend8_s" (i32.const -1)) (i32.const -1))
+
+(assert_return (invoke "extend16_s" (i32.const 0)) (i32.const 0))
+(assert_return (invoke "extend16_s" (i32.const 0x7fff)) (i32.const 32767))
+(assert_return (invoke "extend16_s" (i32.const 0x8000)) (i32.const -32768))
+(assert_return (invoke "extend16_s" (i32.const 0xffff)) (i32.const -1))
+(assert_return (invoke "extend16_s" (i32.const 0x0123_0000)) (i32.const 0))
+(assert_return (invoke "extend16_s" (i32.const 0xfedc_8000)) (i32.const -0x8000))
+(assert_return (invoke "extend16_s" (i32.const -1)) (i32.const -1))
+
+(assert_return (invoke "eqz" (i32.const 0)) (i32.const 1))
+(assert_return (invoke "eqz" (i32.const 1)) (i32.const 0))
+(assert_return (invoke "eqz" (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "eqz" (i32.const 0x7fffffff)) (i32.const 0))
+(assert_return (invoke "eqz" (i32.const 0xffffffff)) (i32.const 0))
+
+(assert_return (invoke "eq" (i32.const 0) (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 1)) (i32.const 0))
+(assert_return (invoke "eq" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "eq" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (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 0)) (i32.const 0))
+(assert_return (invoke "eq" (i32.const 0) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "eq" (i32.const 0x80000000) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "eq" (i32.const 0) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "eq" (i32.const 0x80000000) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "eq" (i32.const -1) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "eq" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 0))
+(assert_return (invoke "eq" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 0))
+
+(assert_return (invoke "ne" (i32.const 0) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "ne" (i32.const 1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "ne" (i32.const -1) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "ne" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "ne" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 0))
+(assert_return (invoke "ne" (i32.const -1) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "ne" (i32.const 1) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "ne" (i32.const 0) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "ne" (i32.const 0x80000000) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "ne" (i32.const 0) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "ne" (i32.const 0x80000000) (i32.const -1)) (i32.const 1))
+(assert_return (invoke "ne" (i32.const -1) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "ne" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 1))
+(assert_return (invoke "ne" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 1))
+
+(assert_return (invoke "lt_s" (i32.const 0) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "lt_s" (i32.const 1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "lt_s" (i32.const -1) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "lt_s" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "lt_s" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 0))
+(assert_return (invoke "lt_s" (i32.const -1) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "lt_s" (i32.const 1) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "lt_s" (i32.const 0) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "lt_s" (i32.const 0x80000000) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "lt_s" (i32.const 0) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "lt_s" (i32.const 0x80000000) (i32.const -1)) (i32.const 1))
+(assert_return (invoke "lt_s" (i32.const -1) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "lt_s" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 1))
+(assert_return (invoke "lt_s" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 0))
+
+(assert_return (invoke "lt_u" (i32.const 0) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "lt_u" (i32.const 1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "lt_u" (i32.const -1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "lt_u" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "lt_u" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 0))
+(assert_return (invoke "lt_u" (i32.const -1) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "lt_u" (i32.const 1) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "lt_u" (i32.const 0) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "lt_u" (i32.const 0x80000000) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "lt_u" (i32.const 0) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "lt_u" (i32.const 0x80000000) (i32.const -1)) (i32.const 1))
+(assert_return (invoke "lt_u" (i32.const -1) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "lt_u" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 0))
+(assert_return (invoke "lt_u" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 1))
+
+(assert_return (invoke "le_s" (i32.const 0) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "le_s" (i32.const 1) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "le_s" (i32.const -1) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "le_s" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "le_s" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 1))
+(assert_return (invoke "le_s" (i32.const -1) (i32.const -1)) (i32.const 1))
+(assert_return (invoke "le_s" (i32.const 1) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "le_s" (i32.const 0) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "le_s" (i32.const 0x80000000) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "le_s" (i32.const 0) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "le_s" (i32.const 0x80000000) (i32.const -1)) (i32.const 1))
+(assert_return (invoke "le_s" (i32.const -1) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "le_s" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 1))
+(assert_return (invoke "le_s" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 0))
+
+(assert_return (invoke "le_u" (i32.const 0) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "le_u" (i32.const 1) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "le_u" (i32.const -1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "le_u" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "le_u" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 1))
+(assert_return (invoke "le_u" (i32.const -1) (i32.const -1)) (i32.const 1))
+(assert_return (invoke "le_u" (i32.const 1) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "le_u" (i32.const 0) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "le_u" (i32.const 0x80000000) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "le_u" (i32.const 0) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "le_u" (i32.const 0x80000000) (i32.const -1)) (i32.const 1))
+(assert_return (invoke "le_u" (i32.const -1) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "le_u" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 0))
+(assert_return (invoke "le_u" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 1))
+
+(assert_return (invoke "gt_s" (i32.const 0) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "gt_s" (i32.const 1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "gt_s" (i32.const -1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "gt_s" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "gt_s" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 0))
+(assert_return (invoke "gt_s" (i32.const -1) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "gt_s" (i32.const 1) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "gt_s" (i32.const 0) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "gt_s" (i32.const 0x80000000) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "gt_s" (i32.const 0) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "gt_s" (i32.const 0x80000000) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "gt_s" (i32.const -1) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "gt_s" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 0))
+(assert_return (invoke "gt_s" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 1))
+
+(assert_return (invoke "gt_u" (i32.const 0) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "gt_u" (i32.const 1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "gt_u" (i32.const -1) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "gt_u" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "gt_u" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 0))
+(assert_return (invoke "gt_u" (i32.const -1) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "gt_u" (i32.const 1) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "gt_u" (i32.const 0) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "gt_u" (i32.const 0x80000000) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "gt_u" (i32.const 0) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "gt_u" (i32.const 0x80000000) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "gt_u" (i32.const -1) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "gt_u" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 1))
+(assert_return (invoke "gt_u" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 0))
+
+(assert_return (invoke "ge_s" (i32.const 0) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "ge_s" (i32.const 1) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "ge_s" (i32.const -1) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "ge_s" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "ge_s" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 1))
+(assert_return (invoke "ge_s" (i32.const -1) (i32.const -1)) (i32.const 1))
+(assert_return (invoke "ge_s" (i32.const 1) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "ge_s" (i32.const 0) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "ge_s" (i32.const 0x80000000) (i32.const 0)) (i32.const 0))
+(assert_return (invoke "ge_s" (i32.const 0) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "ge_s" (i32.const 0x80000000) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "ge_s" (i32.const -1) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "ge_s" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 0))
+(assert_return (invoke "ge_s" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 1))
+
+(assert_return (invoke "ge_u" (i32.const 0) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "ge_u" (i32.const 1) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "ge_u" (i32.const -1) (i32.const 1)) (i32.const 1))
+(assert_return (invoke "ge_u" (i32.const 0x80000000) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "ge_u" (i32.const 0x7fffffff) (i32.const 0x7fffffff)) (i32.const 1))
+(assert_return (invoke "ge_u" (i32.const -1) (i32.const -1)) (i32.const 1))
+(assert_return (invoke "ge_u" (i32.const 1) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "ge_u" (i32.const 0) (i32.const 1)) (i32.const 0))
+(assert_return (invoke "ge_u" (i32.const 0x80000000) (i32.const 0)) (i32.const 1))
+(assert_return (invoke "ge_u" (i32.const 0) (i32.const 0x80000000)) (i32.const 0))
+(assert_return (invoke "ge_u" (i32.const 0x80000000) (i32.const -1)) (i32.const 0))
+(assert_return (invoke "ge_u" (i32.const -1) (i32.const 0x80000000)) (i32.const 1))
+(assert_return (invoke "ge_u" (i32.const 0x80000000) (i32.const 0x7fffffff)) (i32.const 1))
+(assert_return (invoke "ge_u" (i32.const 0x7fffffff) (i32.const 0x80000000)) (i32.const 0))
+
+
+(assert_invalid
+ (module
+ (func $type-unary-operand-empty
+ (i32.eqz) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-unary-operand-empty-in-block
+ (i32.const 0)
+ (block (i32.eqz) (drop))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-unary-operand-empty-in-loop
+ (i32.const 0)
+ (loop (i32.eqz) (drop))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-unary-operand-empty-in-if
+ (i32.const 0) (i32.const 0)
+ (if (then (i32.eqz) (drop)))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-unary-operand-empty-in-else
+ (i32.const 0) (i32.const 0)
+ (if (result i32) (then (i32.const 0)) (else (i32.eqz))) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-unary-operand-empty-in-br
+ (i32.const 0)
+ (block (br 0 (i32.eqz)) (drop))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-unary-operand-empty-in-br_if
+ (i32.const 0)
+ (block (br_if 0 (i32.eqz) (i32.const 1)) (drop))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-unary-operand-empty-in-br_table
+ (i32.const 0)
+ (block (br_table 0 (i32.eqz)) (drop))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-unary-operand-empty-in-return
+ (return (i32.eqz)) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-unary-operand-empty-in-select
+ (select (i32.eqz) (i32.const 1) (i32.const 2)) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-unary-operand-empty-in-call
+ (call 1 (i32.eqz)) (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-unary-operand-empty-in-call_indirect
+ (block (result i32)
+ (call_indirect (type $sig)
+ (i32.eqz) (i32.const 0)
+ )
+ (drop)
+ )
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-unary-operand-empty-in-local.set
+ (local i32)
+ (local.set 0 (i32.eqz)) (local.get 0) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-unary-operand-empty-in-local.tee
+ (local i32)
+ (local.tee 0 (i32.eqz)) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (global $x (mut i32) (i32.const 0))
+ (func $type-unary-operand-empty-in-global.set
+ (global.set $x (i32.eqz)) (global.get $x) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (memory 0)
+ (func $type-unary-operand-empty-in-memory.grow
+ (memory.grow (i32.eqz)) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (memory 0)
+ (func $type-unary-operand-empty-in-load
+ (i32.load (i32.eqz)) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (memory 1)
+ (func $type-unary-operand-empty-in-store
+ (i32.store (i32.eqz) (i32.const 1))
+ )
+ )
+ "type mismatch"
+)
+
+(assert_invalid
+ (module
+ (func $type-binary-1st-operand-empty
+ (i32.add) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-2nd-operand-empty
+ (i32.const 0) (i32.add) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-1st-operand-empty-in-block
+ (i32.const 0) (i32.const 0)
+ (block (i32.add) (drop))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-2nd-operand-empty-in-block
+ (i32.const 0)
+ (block (i32.const 0) (i32.add) (drop))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-1st-operand-empty-in-loop
+ (i32.const 0) (i32.const 0)
+ (loop (i32.add) (drop))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-2nd-operand-empty-in-loop
+ (i32.const 0)
+ (loop (i32.const 0) (i32.add) (drop))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-1st-operand-empty-in-if
+ (i32.const 0) (i32.const 0) (i32.const 0)
+ (if (i32.add) (then (drop)))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-2nd-operand-empty-in-if
+ (i32.const 0) (i32.const 0)
+ (if (i32.const 0) (then (i32.add)) (else (drop)))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-1st-operand-empty-in-else
+ (i32.const 0) (i32.const 0) (i32.const 0)
+ (if (result i32) (then (i32.const 0)) (else (i32.add) (i32.const 0)))
+ (drop) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-2nd-operand-empty-in-else
+ (i32.const 0) (i32.const 0)
+ (if (result i32) (then (i32.const 0)) (else (i32.add)))
+ (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-1st-operand-empty-in-br
+ (i32.const 0) (i32.const 0)
+ (block (br 0 (i32.add)) (drop))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-2nd-operand-empty-in-br
+ (i32.const 0)
+ (block (br 0 (i32.const 0) (i32.add)) (drop))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-1st-operand-empty-in-br_if
+ (i32.const 0) (i32.const 0)
+ (block (br_if 0 (i32.add) (i32.const 1)) (drop))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-2nd-operand-empty-in-br_if
+ (i32.const 0)
+ (block (br_if 0 (i32.const 0) (i32.add) (i32.const 1)) (drop))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-1st-operand-empty-in-br_table
+ (i32.const 0) (i32.const 0)
+ (block (br_table 0 (i32.add)) (drop))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-2nd-operand-empty-in-br_table
+ (i32.const 0)
+ (block (br_table 0 (i32.const 0) (i32.add)) (drop))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-1st-operand-empty-in-return
+ (return (i32.add)) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-2nd-operand-empty-in-return
+ (return (i32.const 0) (i32.add)) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-1st-operand-empty-in-select
+ (select (i32.add) (i32.const 1) (i32.const 2)) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-2nd-operand-empty-in-select
+ (select (i32.const 0) (i32.add) (i32.const 1) (i32.const 2)) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-1st-operand-empty-in-call
+ (call 1 (i32.add)) (drop)
+ )
+ (func (param i32 i32) (result i32) (local.get 0))
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-2nd-operand-empty-in-call
+ (call 1 (i32.const 0) (i32.add)) (drop)
+ )
+ (func (param i32 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-binary-1st-operand-empty-in-call_indirect
+ (block (result i32)
+ (call_indirect (type $sig)
+ (i32.add) (i32.const 0)
+ )
+ (drop)
+ )
+ )
+ )
+ "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-binary-2nd-operand-empty-in-call_indirect
+ (block (result i32)
+ (call_indirect (type $sig)
+ (i32.const 0) (i32.add) (i32.const 0)
+ )
+ (drop)
+ )
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-1st-operand-empty-in-local.set
+ (local i32)
+ (local.set 0 (i32.add)) (local.get 0) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-2nd-operand-empty-in-local.set
+ (local i32)
+ (local.set 0 (i32.const 0) (i32.add)) (local.get 0) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-1st-operand-empty-in-local.tee
+ (local i32)
+ (local.tee 0 (i32.add)) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (func $type-binary-2nd-operand-empty-in-local.tee
+ (local i32)
+ (local.tee 0 (i32.const 0) (i32.add)) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (global $x (mut i32) (i32.const 0))
+ (func $type-binary-1st-operand-empty-in-global.set
+ (global.set $x (i32.add)) (global.get $x) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (global $x (mut i32) (i32.const 0))
+ (func $type-binary-2nd-operand-empty-in-global.set
+ (global.set $x (i32.const 0) (i32.add)) (global.get $x) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (memory 0)
+ (func $type-binary-1st-operand-empty-in-memory.grow
+ (memory.grow (i32.add)) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (memory 0)
+ (func $type-binary-2nd-operand-empty-in-memory.grow
+ (memory.grow (i32.const 0) (i32.add)) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (memory 0)
+ (func $type-binary-1st-operand-empty-in-load
+ (i32.load (i32.add)) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (memory 0)
+ (func $type-binary-2nd-operand-empty-in-load
+ (i32.load (i32.const 0) (i32.add)) (drop)
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (memory 1)
+ (func $type-binary-1st-operand-empty-in-store
+ (i32.store (i32.add) (i32.const 1))
+ )
+ )
+ "type mismatch"
+)
+(assert_invalid
+ (module
+ (memory 1)
+ (func $type-binary-2nd-operand-empty-in-store
+ (i32.store (i32.const 1) (i32.add) (i32.const 0))
+ )
+ )
+ "type mismatch"
+)
+
+
+;; Type check
+
+(assert_invalid (module (func (result i32) (i32.add (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.and (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.div_s (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.div_u (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.mul (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.or (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.rem_s (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.rem_u (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.rotl (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.rotr (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.shl (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.shr_s (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.shr_u (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.sub (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.xor (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.eqz (i64.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.clz (i64.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.ctz (i64.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.popcnt (i64.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.eq (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.ge_s (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.ge_u (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.gt_s (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.gt_u (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.le_s (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.le_u (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.lt_s (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.lt_u (i64.const 0) (f32.const 0)))) "type mismatch")
+(assert_invalid (module (func (result i32) (i32.ne (i64.const 0) (f32.const 0)))) "type mismatch")
+
+(assert_malformed
+ (module quote "(func (result i32) (i32.const nan:arithmetic))")
+ "unexpected token"
+)
+(assert_malformed
+ (module quote "(func (result i32) (i32.const nan:canonical))")
+ "unexpected token"
+)