Merge pull request #996 from alexcrichton/gc-tests

Add tests for the wasm-gc crate
This commit is contained in:
Alex Crichton 2018-10-31 10:03:35 -05:00 committed by GitHub
commit 0d5f514709
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 927 additions and 44 deletions

View File

@ -167,6 +167,16 @@ matrix:
script: cargo test -p ui-tests
if: branch = master
# wasm-gc tests work alright
- name: "test wasm-bindgen-gc crate"
install:
- git clone https://github.com/WebAssembly/wabt
- mkdir -p wabt/build
- (cd wabt/build && cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER=sccache -DCMAKE_CXX_COMPILER_ARG1=c++ -DBUILD_TESTS=OFF && cmake --build . -- -j4)
- export PATH=$PATH:`pwd`/wabt/build
script: cargo test -p wasm-bindgen-gc
if: branch = master
# Dist linux binary
- name: "dist: Linux (x86_64-unknown-linux-musl)"
env: JOB=dist-linux TARGET=x86_64-unknown-linux-musl

View File

@ -14,3 +14,14 @@ Support for removing unused items from a wasm executable
parity-wasm = "0.35.1"
log = "0.4"
rustc-demangle = "0.1.9"
[dev-dependencies]
rayon = "1.0.2"
tempfile = "3.0.4"
[lib]
doctest = false
[[test]]
name = 'all'
harness = false

View File

@ -29,6 +29,15 @@ impl BitSet {
}
}
pub fn remove(&mut self, i: &u32) {
let i = *i as usize;
let idx = i / BITS;
let bit = 1 << (i % BITS);
if let Some(slot) = self.bits.get_mut(idx) {
*slot &= !bit;
}
}
pub fn contains(&self, i: &u32) -> bool {
let i = *i as usize;
let idx = i / BITS;

View File

@ -51,17 +51,18 @@ impl Config {
}
fn run(config: &mut Config, module: &mut Module) {
let analysis = {
let mut analysis = {
let mut cx = LiveContext::new(&module);
cx.blacklist.insert("rust_eh_personality");
cx.blacklist.insert("__indirect_function_table");
cx.blacklist.insert("__heap_base");
cx.blacklist.insert("__data_end");
// always treat memory as a root
// Always treat memory as a root. In theory we could actually gc this
// away in some circumstances, but it's probably not worth the effort.
cx.add_memory(0);
// All exports are a root
// All non-blacklisted exports are roots
if let Some(section) = module.export_section() {
for (i, entry) in section.entries().iter().enumerate() {
if cx.blacklist.contains(entry.field()) {
@ -71,22 +72,7 @@ fn run(config: &mut Config, module: &mut Module) {
}
}
// Pessimistically assume all data and table segments are
// required
//
// TODO: this shouldn't assume this!
if let Some(section) = module.data_section() {
for entry in section.entries() {
cx.add_data_segment(entry);
}
}
if let Some(elements) = module.elements_section() {
for seg in elements.entries() {
cx.add_element_segment(seg);
}
}
// The start function is also a root
// ... and finally, the start function
if let Some(i) = module.start_section() {
cx.add_function(i);
}
@ -94,7 +80,7 @@ fn run(config: &mut Config, module: &mut Module) {
cx.analysis
};
let cx = RemapContext::new(&module, &analysis, config);
let cx = RemapContext::new(&module, &mut analysis, config);
for i in (0..module.sections().len()).rev() {
let retain = match module.sections_mut()[i] {
Section::Unparsed { .. } => {
@ -144,6 +130,8 @@ struct Analysis {
imports: BitSet,
exports: BitSet,
functions: BitSet,
elements: BitSet,
data_segments: BitSet,
imported_functions: u32,
imported_globals: u32,
imported_memories: u32,
@ -235,10 +223,12 @@ impl<'a> LiveContext<'a> {
// Add all element segments that initialize this table
if let Some(elements) = self.element_section {
for entry in elements.entries().iter().filter(|d| !d.passive()) {
if entry.index() == idx {
self.add_element_segment(entry);
}
let iter = elements.entries()
.iter()
.enumerate()
.filter(|(_, d)| !d.passive() && d.index() == idx);
for (i, _) in iter {
self.add_element_segment(i as u32);
}
}
@ -273,10 +263,12 @@ impl<'a> LiveContext<'a> {
// Add all data segments that initialize this memory
if let Some(data) = self.data_section {
for entry in data.entries().iter().filter(|d| !d.passive()) {
if entry.index() == idx {
self.add_data_segment(entry);
}
let iter = data.entries()
.iter()
.enumerate()
.filter(|(_, d)| !d.passive() && d.index() == idx);
for (i, _) in iter {
self.add_data_segment(i as u32);
}
}
@ -395,6 +387,16 @@ impl<'a> LiveContext<'a> {
}
Instruction::GetGlobal(i) |
Instruction::SetGlobal(i) => self.add_global(i),
Instruction::MemoryInit(i) |
Instruction::MemoryDrop(i) => {
self.add_memory(0);
self.add_data_segment(i);
}
Instruction::TableInit(i) |
Instruction::TableDrop(i) => {
self.add_table(0);
self.add_element_segment(i);
}
_ => {}
}
}
@ -431,20 +433,32 @@ impl<'a> LiveContext<'a> {
}
}
fn add_data_segment(&mut self, data: &DataSegment) {
if let Some(offset) = data.offset() {
self.add_memory(data.index());
self.add_init_expr(offset);
fn add_data_segment(&mut self, idx: u32) {
if !self.analysis.data_segments.insert(idx) {
return
}
let data = &self.data_section.unwrap().entries()[idx as usize];
if !data.passive() {
if let Some(offset) = data.offset() {
self.add_memory(data.index());
self.add_init_expr(offset);
}
}
}
fn add_element_segment(&mut self, seg: &ElementSegment) {
fn add_element_segment(&mut self, idx: u32) {
if !self.analysis.elements.insert(idx) {
return
}
let seg = &self.element_section.unwrap().entries()[idx as usize];
for member in seg.members() {
self.add_function(*member);
}
if let Some(offset) = seg.offset() {
self.add_table(seg.index());
self.add_init_expr(offset);
if !seg.passive() {
if let Some(offset) = seg.offset() {
self.add_table(seg.index());
self.add_init_expr(offset);
}
}
}
}
@ -457,10 +471,12 @@ struct RemapContext<'a> {
types: Vec<u32>,
tables: Vec<u32>,
memories: Vec<u32>,
elements: Vec<u32>,
data_segments: Vec<u32>,
}
impl<'a> RemapContext<'a> {
fn new(m: &Module, analysis: &'a Analysis, config: &'a Config) -> RemapContext<'a> {
fn new(m: &Module, analysis: &'a mut Analysis, config: &'a Config) -> RemapContext<'a> {
let mut nfunctions = 0;
let mut functions = Vec::new();
let mut nglobals = 0;
@ -478,6 +494,7 @@ impl<'a> RemapContext<'a> {
if analysis.types.contains(&(i as u32)) {
if let Some(prev) = map.get(&ty) {
types.push(*prev);
analysis.types.remove(&(i as u32));
continue
}
map.insert(ty, ntypes);
@ -530,8 +547,7 @@ impl<'a> RemapContext<'a> {
}
if let Some(s) = m.table_section() {
for i in 0..(s.entries().len() as u32) {
// TODO: should remove `|| true` here when this is better tested
if analysis.tables.contains(&(i + analysis.imported_tables)) || true {
if analysis.tables.contains(&(i + analysis.imported_tables)) {
tables.push(ntables);
ntables += 1;
} else {
@ -542,8 +558,7 @@ impl<'a> RemapContext<'a> {
}
if let Some(s) = m.memory_section() {
for i in 0..(s.entries().len() as u32) {
// TODO: should remove `|| true` here when this is better tested
if analysis.memories.contains(&(i + analysis.imported_memories)) || true {
if analysis.memories.contains(&(i + analysis.imported_memories)) {
memories.push(nmemories);
nmemories += 1;
} else {
@ -553,6 +568,34 @@ impl<'a> RemapContext<'a> {
}
}
let mut elements = Vec::new();
if let Some(s) = m.elements_section() {
let mut nelements = 0;
for i in 0..(s.entries().len() as u32) {
if analysis.elements.contains(&i) {
elements.push(nelements);
nelements += 1;
} else {
debug!("gc element segment {}", i);
elements.push(u32::max_value());
}
}
}
let mut data_segments = Vec::new();
if let Some(s) = m.data_section() {
let mut ndata_segments = 0;
for i in 0..(s.entries().len() as u32) {
if analysis.data_segments.contains(&i) {
data_segments.push(ndata_segments);
ndata_segments += 1;
} else {
debug!("gc data segment {}", i);
data_segments.push(u32::max_value());
}
}
}
RemapContext {
analysis,
functions,
@ -561,6 +604,8 @@ impl<'a> RemapContext<'a> {
tables,
types,
config,
elements,
data_segments,
}
}
@ -713,6 +758,7 @@ impl<'a> RemapContext<'a> {
}
fn remap_element_section(&self, s: &mut ElementSection) -> bool {
self.retain(&self.analysis.elements, s.entries_mut(), "element", 0);
for s in s.entries_mut() {
self.remap_element_segment(s);
}
@ -720,9 +766,11 @@ impl<'a> RemapContext<'a> {
}
fn remap_element_segment(&self, s: &mut ElementSegment) {
let mut i = s.index();
self.remap_table_idx(&mut i);
assert_eq!(s.index(), i);
if !s.passive() {
let mut i = s.index();
self.remap_table_idx(&mut i);
assert_eq!(s.index(), i);
}
for m in s.members_mut() {
self.remap_function_idx(m);
}
@ -763,6 +811,10 @@ impl<'a> RemapContext<'a> {
Instruction::CallIndirect(ref mut t, _) => self.remap_type_idx(t),
Instruction::GetGlobal(ref mut i) |
Instruction::SetGlobal(ref mut i) => self.remap_global_idx(i),
Instruction::TableInit(ref mut i) |
Instruction::TableDrop(ref mut i) => self.remap_element_idx(i),
Instruction::MemoryInit(ref mut i) |
Instruction::MemoryDrop(ref mut i) => self.remap_data_idx(i),
_ => {}
}
}
@ -775,6 +827,7 @@ impl<'a> RemapContext<'a> {
}
fn remap_data_section(&self, s: &mut DataSection) -> bool {
self.retain(&self.analysis.data_segments, s.entries_mut(), "data", 0);
for data in s.entries_mut() {
self.remap_data_segment(data);
}
@ -816,6 +869,16 @@ impl<'a> RemapContext<'a> {
assert!(*i != u32::max_value());
}
fn remap_element_idx(&self, i: &mut u32) {
*i = self.elements[*i as usize];
assert!(*i != u32::max_value());
}
fn remap_data_idx(&self, i: &mut u32) {
*i = self.data_segments[*i as usize];
assert!(*i != u32::max_value());
}
fn remap_name_section(&self, s: &mut NameSection) {
match *s {
NameSection::Module(_) => {}

148
crates/gc/tests/all.rs Normal file
View File

@ -0,0 +1,148 @@
extern crate parity_wasm;
extern crate rayon;
extern crate tempfile;
extern crate wasm_bindgen_gc;
use std::env;
use std::error::Error;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use rayon::prelude::*;
use parity_wasm::elements::Module;
use tempfile::NamedTempFile;
struct Test {
input: PathBuf,
}
fn main() {
let mut tests = Vec::new();
find_tests(&mut tests, "tests/wat".as_ref());
run_tests(&tests);
}
fn find_tests(tests: &mut Vec<Test>, path: &Path) {
for entry in path.read_dir().unwrap() {
let entry = entry.unwrap();
let path = entry.path();
if entry.file_type().unwrap().is_dir() {
find_tests(tests, &path);
continue
}
if path.extension().and_then(|s| s.to_str()) == Some("wat") {
tests.push(Test {
input: path,
});
}
}
}
fn run_tests(tests: &[Test]) {
println!("");
let results = tests.par_iter()
.map(|test| {
run_test(test).map_err(|e| (test, e.to_string()))
})
.collect::<Vec<_>>();
let mut bad = false;
for result in results {
let (test, err) = match result {
Ok(()) => continue,
Err(p) => p,
};
println!("fail: {} - {}", test.input.display(), err);
bad = true;
}
if bad {
std::process::exit(2);
}
println!("\nall good!");
}
fn run_test(test: &Test) -> Result<(), Box<Error>> {
println!("test {}", test.input.display());
let f = NamedTempFile::new()?;
let input = fs::read_to_string(&test.input)?;
let expected = extract_expected(&input);
let status = Command::new("wat2wasm")
.arg("--debug-names")
.arg("--enable-bulk-memory")
.arg(&test.input)
.arg("-o")
.arg(f.path())
.status()?;
if !status.success() {
return Err(io::Error::new(io::ErrorKind::Other, "failed to run wat2wasm").into())
}
let wasm = fs::read(f.path())?;
let mut module: Module = parity_wasm::deserialize_buffer(&wasm)?;
module = match module.parse_names() {
Ok(m) => m,
Err((_, m)) => m,
};
wasm_bindgen_gc::Config::new().run(&mut module);
let wasm = parity_wasm::serialize(module)?;
fs::write(f.path(), wasm)?;
let status = Command::new("wasm2wat")
.arg("--enable-bulk-memory")
.arg(&f.path())
.stderr(Stdio::inherit())
.output()?;
if !status.status.success() {
return Err(io::Error::new(io::ErrorKind::Other, "failed to run wasm2wat").into())
}
let actual = String::from_utf8(status.stdout)?;
let actual = actual.trim();
if env::var("BLESS_TESTS").is_ok() {
fs::write(&test.input, generate_blesssed(&input, &actual))?;
} else {
if actual != expected {
println!("{:?} {:?}", actual, expected);
return Err(io::Error::new(io::ErrorKind::Other,
"test failed").into())
}
}
Ok(())
}
fn extract_expected(input: &str) -> String {
input.lines()
.filter(|l| l.starts_with(";; "))
.skip_while(|l| !l.contains("STDOUT"))
.skip(1)
.take_while(|l| !l.contains("STDOUT"))
.map(|l| &l[3..])
.collect::<Vec<_>>()
.join("\n")
}
fn generate_blesssed(input: &str, actual: &str) -> String {
let mut input = input.lines()
.filter(|l| !l.starts_with(";;"))
.collect::<Vec<_>>()
.join("\n")
.trim()
.to_string();
input.push_str("\n\n");
input.push_str(";; STDOUT (update this section with `BLESS_TESTS=1` while running tests)\n");
for line in actual.lines() {
input.push_str(";; ");
input.push_str(line);
input.push_str("\n");
}
input.push_str(";; STDOUT\n");
return input
}

View File

@ -0,0 +1,11 @@
(module
(func $foo)
(export "foo" (func $foo))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (func $foo (type 0))
;; (export "foo" (func $foo)))
;; STDOUT

View File

@ -0,0 +1,16 @@
(module
(func $foo
call $bar
)
(func $bar)
(export "foo" (func $foo))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (func $foo (type 0)
;; call $bar)
;; (func $bar (type 0))
;; (export "foo" (func $foo)))
;; STDOUT

View File

@ -0,0 +1,21 @@
(module
(import "" "" (func (param i32)))
(func $foo
i32.const 0
call 0
)
(start $foo)
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func (param i32)))
;; (type (;1;) (func))
;; (import "" "" (func (;0;) (type 0)))
;; (func $foo (type 1)
;; i32.const 0
;; call 0)
;; (start 1))
;; STDOUT

View File

@ -0,0 +1,8 @@
(module
(import "" "a" (memory 0))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (import "" "a" (memory (;0;) 0)))
;; STDOUT

View File

@ -0,0 +1,10 @@
(module
(memory 0 1)
(data (i32.const 0) "foo")
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (memory (;0;) 0 1)
;; (data (;0;) (i32.const 0) "foo"))
;; STDOUT

View File

@ -0,0 +1,11 @@
(module
(global i32 (i32.const 0))
(export "foo" (global 0))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (global (;0;) i32 (i32.const 0))
;; (export "foo" (global 0)))
;; STDOUT

View File

@ -0,0 +1,8 @@
(module
(memory 0 17)
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (memory (;0;) 0 17))
;; STDOUT

View File

@ -0,0 +1,27 @@
(module
(memory 0 10)
(func $foo
i32.const 0
i32.const 0
i32.const 0
memory.init 0
)
(data passive "wut")
(start $foo)
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (func $foo (type 0)
;; i32.const 0
;; i32.const 0
;; i32.const 0
;; memory.init 0)
;; (memory (;0;) 0 10)
;; (start 0)
;; (data (;0;) passive "wut"))
;; STDOUT

View File

@ -0,0 +1,30 @@
(module
(import "" "" (table 0 1 anyfunc))
(func $foo
i32.const 0
i32.const 0
i32.const 0
table.init 0
)
(func $bar)
(elem passive $bar)
(start $foo)
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (import "" "" (table (;0;) 0 1 anyfunc))
;; (func $foo (type 0)
;; i32.const 0
;; i32.const 0
;; i32.const 0
;; table.init 0)
;; (func $bar (type 0))
;; (start 0)
;; (elem (;0;) passive $bar))
;; STDOUT

View File

@ -0,0 +1,23 @@
(module
(global (mut i32) (i32.const 0))
(start $foo)
(func $bar)
(func $foo
i32.const 1
set_global 0
)
(func $baz)
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (func $foo (type 0)
;; i32.const 1
;; set_global 0)
;; (global (;0;) (mut i32) (i32.const 0))
;; (start 0))
;; STDOUT

View File

@ -0,0 +1,14 @@
(module
(start $foo)
(func $bar)
(func $foo)
(func $baz)
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (func $foo (type 0))
;; (start 0))
;; STDOUT

View File

@ -0,0 +1,10 @@
(module
(table 0 17 anyfunc)
(export "foo" (table 0))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (table (;0;) 0 17 anyfunc)
;; (export "foo" (table 0)))
;; STDOUT

View File

@ -0,0 +1,17 @@
(module
(table 0 17 anyfunc)
(func $foo
i32.const 0
call_indirect)
(export "foo" (func $foo))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (func $foo (type 0)
;; i32.const 0
;; call_indirect (type 0))
;; (table (;0;) 0 17 anyfunc)
;; (export "foo" (func $foo)))
;; STDOUT

View File

@ -0,0 +1,39 @@
(module
(func $foo
(local i32 f32 i32 f64 i64 i32 f32 i64 i32 f32 f64)
get_local 0
get_local 1
get_local 2
get_local 3
get_local 4
get_local 5
get_local 6
get_local 7
get_local 8
get_local 9
get_local 10
unreachable
)
(export "foo" (func $foo))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (func $foo (type 0)
;; (local i32 i32 i32 i32 f32 f32 f32 f64 f64 i64 i64)
;; get_local 0
;; get_local 4
;; get_local 1
;; get_local 7
;; get_local 9
;; get_local 2
;; get_local 5
;; get_local 10
;; get_local 3
;; get_local 6
;; get_local 8
;; unreachable)
;; (export "foo" (func $foo)))
;; STDOUT

View File

@ -0,0 +1,16 @@
(module
(func $foo (result i32)
(local i32)
get_local 0
)
(export "foo" (func $foo))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func (result i32)))
;; (func $foo (type 0) (result i32)
;; (local i32)
;; get_local 0)
;; (export "foo" (func $foo)))
;; STDOUT

View File

@ -0,0 +1,18 @@
(module
(func $foo (param i32)
(local i32)
get_local 0
set_local 1
)
(export "foo" (func $foo))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func (param i32)))
;; (func $foo (type 0) (param i32)
;; (local i32)
;; get_local 0
;; set_local 1)
;; (export "foo" (func $foo)))
;; STDOUT

View File

@ -0,0 +1,18 @@
(module
(func $foo (param i32) (result i32)
(local i32)
get_local 0
tee_local 1
)
(export "foo" (func $foo))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func (param i32) (result i32)))
;; (func $foo (type 0) (param i32) (result i32)
;; (local i32)
;; get_local 0
;; tee_local 1)
;; (export "foo" (func $foo)))
;; STDOUT

View File

@ -0,0 +1,7 @@
(module
(func $foo)
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module)
;; STDOUT

View File

@ -0,0 +1,9 @@
(module
(global i32 (i32.const 0))
(export "__heap_base" (global 0))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module)
;; STDOUT

View File

@ -0,0 +1,26 @@
(module
(import "" "a" (func $i1))
(import "" "b" (func $i2))
(import "" "c" (func $i3))
(func $bar)
(func $foo
call $i1
call $i3)
(func $baz)
(export "foo" (func $foo))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (import "" "a" (func $i1 (type 0)))
;; (import "" "c" (func $i3 (type 0)))
;; (func $foo (type 0)
;; call $i1
;; call $i3)
;; (export "foo" (func $foo)))
;; STDOUT

View File

@ -0,0 +1,7 @@
(module
(import "" "" (global i32))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module)
;; STDOUT

View File

@ -0,0 +1,35 @@
(module
(import "" "a" (global i32))
(import "" "b" (global i32))
(import "" "c" (global i32))
(global i32 (i32.const 1))
(global i32 (i32.const 2))
(func $foo
get_global 0
drop
get_global 2
drop
get_global 4
drop
)
(export "foo" (func $foo))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (import "" "a" (global (;0;) i32))
;; (import "" "c" (global (;1;) i32))
;; (func $foo (type 0)
;; get_global 0
;; drop
;; get_global 1
;; drop
;; get_global 2
;; drop)
;; (global (;2;) i32 (i32.const 2))
;; (export "foo" (func $foo)))
;; STDOUT

View File

@ -0,0 +1,11 @@
(module
(import "" "" (table 0 1 anyfunc))
(func $foo)
(elem (i32.const 1) $foo)
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module)
;; STDOUT

View File

@ -0,0 +1,13 @@
(module
(func $foo
(local i32)
)
(export "foo" (func $foo))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (func $foo (type 0))
;; (export "foo" (func $foo)))
;; STDOUT

View File

@ -0,0 +1,18 @@
(module
(memory 0 10)
(func $foo
i32.const 0
i32.const 0
i32.const 0
memory.init 0
)
(data passive "wut")
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (memory (;0;) 0 10))
;; STDOUT

View File

@ -0,0 +1,7 @@
(module
(table 0 17 anyfunc)
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module)
;; STDOUT

View File

@ -0,0 +1,11 @@
(module
(import "" "" (table 0 1 anyfunc))
(func $foo)
(elem passive $foo)
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module)
;; STDOUT

View File

@ -0,0 +1,34 @@
(module
(type (func))
(type (func (param i32)))
(type (func (param i32)))
(type (func (result i32)))
(func $f1 (type 0))
(func $f2 (type 1))
(func $f3 (type 2))
(func $f4 (type 3)
i32.const 0
)
(export "a" (func $f1))
(export "b" (func $f2))
(export "c" (func $f3))
(export "d" (func $f4))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (type (;1;) (func (param i32)))
;; (type (;2;) (func (result i32)))
;; (func $f1 (type 0))
;; (func $f2 (type 1) (param i32))
;; (func $f3 (type 1) (param i32))
;; (func $f4 (type 2) (result i32)
;; i32.const 0)
;; (export "a" (func $f1))
;; (export "b" (func $f2))
;; (export "c" (func $f3))
;; (export "d" (func $f4)))
;; STDOUT

View File

@ -0,0 +1,29 @@
(module
(memory 0 10)
(func $foo
i32.const 0
i32.const 0
i32.const 0
memory.init 1
)
(data passive "wut")
(data passive "wut2")
(data passive "wut3")
(start $foo)
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (func $foo (type 0)
;; i32.const 0
;; i32.const 0
;; i32.const 0
;; memory.init 0)
;; (memory (;0;) 0 10)
;; (start 0)
;; (data (;0;) passive "wut2"))
;; STDOUT

View File

@ -0,0 +1,16 @@
(module
(func
call 2)
(func)
(func)
(export "foo" (func 0))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (func (;0;) (type 0)
;; call 1)
;; (func (;1;) (type 0))
;; (export "foo" (func 0)))
;; STDOUT

View File

@ -0,0 +1,16 @@
(module
(global i32 (i32.const 0))
(global i32 (i32.const 0))
(func (result i32)
get_global 1)
(export "foo" (func 0))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func (result i32)))
;; (func (;0;) (type 0) (result i32)
;; get_global 0)
;; (global (;0;) i32 (i32.const 0))
;; (export "foo" (func 0)))
;; STDOUT

View File

@ -0,0 +1,16 @@
(module
(func $foo (result i32)
(local i32 i32)
get_local 1
)
(export "foo" (func $foo))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func (result i32)))
;; (func $foo (type 0) (result i32)
;; (local i32)
;; get_local 0)
;; (export "foo" (func $foo)))
;; STDOUT

View File

@ -0,0 +1,32 @@
(module
(import "" "" (table 0 1 anyfunc))
(func $foo
i32.const 0
i32.const 0
i32.const 0
table.init 1
)
(func $bar)
(func $bar2)
(elem passive $bar)
(elem passive $bar2)
(start $foo)
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (import "" "" (table (;0;) 0 1 anyfunc))
;; (func $foo (type 0)
;; i32.const 0
;; i32.const 0
;; i32.const 0
;; table.init 0)
;; (func $bar2 (type 0))
;; (start 0)
;; (elem (;0;) passive $bar2))
;; STDOUT

View File

@ -0,0 +1,13 @@
(module
(type (func (result i32)))
(type (func))
(func (type 1))
(export "foo" (func 0))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (func (;0;) (type 0))
;; (export "foo" (func 0)))
;; STDOUT

View File

@ -0,0 +1,5 @@
(module)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module)
;; STDOUT

View File

@ -0,0 +1,15 @@
(module
(func $foo
i32.const 0
call_indirect
)
(func $bar)
(table 0 10 anyfunc)
(elem (i32.const 0) $bar)
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module)
;; STDOUT

View File

@ -0,0 +1,25 @@
(module
(func $foo
i32.const 0
call_indirect
)
(func $bar)
(table 0 10 anyfunc)
(elem (i32.const 0) $bar)
(export "foo" (func $foo))
)
;; STDOUT (update this section with `BLESS_TESTS=1` while running tests)
;; (module
;; (type (;0;) (func))
;; (func $foo (type 0)
;; i32.const 0
;; call_indirect (type 0))
;; (func $bar (type 0))
;; (table (;0;) 0 10 anyfunc)
;; (export "foo" (func $foo))
;; (elem (;0;) (i32.const 0) $bar))
;; STDOUT