feat: add a histrical wit-bindgen

This commit is contained in:
2023-01-01 00:25:48 +08:00
parent 01e8f5a959
commit aa50d63aec
419 changed files with 45283 additions and 1 deletions

View File

@@ -0,0 +1,123 @@
use anyhow::{bail, Context, Result};
use pretty_assertions::assert_eq;
use std::{fs, path::Path};
use wit_component::ComponentEncoder;
use wit_parser::Interface;
fn read_interface(path: &Path) -> Result<Interface> {
wit_parser::Interface::parse_file(&path)
.with_context(|| format!("failed to parse interface file `{}`", path.display()))
}
fn read_interfaces(dir: &Path, pattern: &str) -> Result<Vec<Interface>> {
glob::glob(dir.join(pattern).to_str().unwrap())?
.map(|p| {
let p = p?;
let mut i = read_interface(&p)?;
i.name = p
.file_stem()
.unwrap()
.to_str()
.unwrap()
.trim_start_matches("import-")
.trim_start_matches("export-")
.to_string();
Ok(i)
})
.collect::<Result<_>>()
}
/// Tests the encoding of components.
///
/// This test looks in the `components/` directory for test cases.
///
/// The expected input files for a test case are:
///
/// * [required] `module.wat` - contains the core module definition to be encoded
/// as a component.
/// * [optional] `default.wit` - represents the component's default interface.
/// * [optional] `export-<name>.wit` - represents an interface exported by the component.
/// * [optional] `import-<name>.wit` - represents an interface imported by the component.
///
/// And the output files are one of the following:
///
/// * `component.wat` - the expected encoded component in text format if the encoding
/// is expected to succeed.
/// * `error.txt` - the expected error message if the encoding is expected to fail.
///
/// The test encodes a component based on the input files. If the encoding succeeds,
/// it expects the output to match `component.wat`. If the encoding fails, it expects
/// the output to match `error.txt`.
///
/// Run the test with the environment variable `BLESS` set to update
/// either `component.wat` or `error.txt` depending on the outcome of the encoding.
#[test]
fn component_encoding() -> Result<()> {
for entry in fs::read_dir("tests/components")? {
let path = entry?.path();
if !path.is_dir() {
continue;
}
let test_case = path.file_stem().unwrap().to_str().unwrap();
let module_path = path.join("module.wat");
let interface_path = path.join("default.wit");
let component_path = path.join("component.wat");
let error_path = path.join("error.txt");
let module = wat::parse_file(&module_path)
.with_context(|| format!("expected file `{}`", module_path.display()))?;
let interface = interface_path
.is_file()
.then(|| read_interface(&interface_path))
.transpose()?;
let imports = read_interfaces(&path, "import-*.wit")?;
let exports = read_interfaces(&path, "export-*.wit")?;
let mut encoder = ComponentEncoder::default()
.module(&module)
.imports(&imports)
.exports(&exports)
.validate(true);
if let Some(interface) = &interface {
encoder = encoder.interface(interface);
}
let r = encoder.encode();
let (output, baseline_path) = if error_path.is_file() {
match r {
Ok(_) => bail!("encoding should fail for test case `{}`", test_case),
Err(e) => (e.to_string(), &error_path),
}
} else {
(
wasmprinter::print_bytes(
&r.with_context(|| format!("failed to encode for test case `{}`", test_case))?,
)
.with_context(|| {
format!(
"failed to print component bytes for test case `{}`",
test_case
)
})?,
&component_path,
)
};
if std::env::var_os("BLESS").is_some() {
fs::write(&baseline_path, output)?;
} else {
assert_eq!(
fs::read_to_string(&baseline_path)?.replace("\r\n", "\n"),
output,
"failed baseline comparison for test case `{}` ({})",
test_case,
baseline_path.display(),
);
}
}
Ok(())
}

View File

@@ -0,0 +1 @@
type mismatch for default interface function `a`: expected `[I32, I32] -> [I32]` but found `[] -> []`

View File

@@ -0,0 +1,3 @@
(module
(func (export "a") unreachable)
)

View File

@@ -0,0 +1 @@
module imports from an empty module name

View File

@@ -0,0 +1,3 @@
(module
(import "" "foo" (func))
)

View File

@@ -0,0 +1,4 @@
(component
(core module (;0;))
(core instance (;0;) (instantiate 0))
)

View File

@@ -0,0 +1 @@
type mismatch for function `a` from exported interface `foo`: expected `[I32, I32] -> [I32]` but found `[] -> []`

View File

@@ -0,0 +1,3 @@
(module
(func (export "foo#a") unreachable)
)

View File

@@ -0,0 +1,84 @@
(component
(type (;0;) (func))
(type (;1;) (func (param "a" s8) (param "b" s16) (param "c" s32) (param "d" s64) (result string)))
(type (;2;) (tuple s8 s16 s32 s64))
(type (;3;) (func (result 2)))
(type (;4;) (flags "a" "b" "c"))
(type (;5;) (func (param "x" 4)))
(type (;6;) (variant (case $c0 "a" unit) (case $c1 "b" string) (case $c2 "c" s64)))
(type (;7;) (func (param "x" string) (result 6)))
(type (;8;) (func (param "x" 6) (result string)))
(core module (;0;)
(type (;0;) (func (param i32 i32 i32 i32) (result i32)))
(type (;1;) (func))
(type (;2;) (func (param i32 i32 i32 i64) (result i32)))
(type (;3;) (func (result i32)))
(type (;4;) (func (param i32 i32) (result i32)))
(type (;5;) (func (param i32 i64 i32) (result i32)))
(type (;6;) (func (param i32)))
(func (;0;) (type 0) (param i32 i32 i32 i32) (result i32)
unreachable
)
(func (;1;) (type 1)
unreachable
)
(func (;2;) (type 2) (param i32 i32 i32 i64) (result i32)
unreachable
)
(func (;3;) (type 3) (result i32)
unreachable
)
(func (;4;) (type 1)
unreachable
)
(func (;5;) (type 4) (param i32 i32) (result i32)
unreachable
)
(func (;6;) (type 5) (param i32 i64 i32) (result i32)
unreachable
)
(func (;7;) (type 6) (param i32)
unreachable
)
(memory (;0;) 1)
(export "memory" (memory 0))
(export "canonical_abi_realloc" (func 0))
(export "a" (func 1))
(export "b" (func 2))
(export "c" (func 3))
(export "foo#a" (func 4))
(export "foo#b" (func 5))
(export "foo#c" (func 6))
(export "bar#a" (func 7))
)
(core instance (;0;) (instantiate 0))
(core alias export 0 "memory" (memory (;0;)))
(core alias export 0 "canonical_abi_realloc" (func (;0;)))
(core alias export 0 "a" (func (;1;)))
(core alias export 0 "b" (func (;2;)))
(core alias export 0 "c" (func (;3;)))
(func (;0;) (type 0) (canon lift (core func 1)))
(func (;1;) (type 1) (canon lift (core func 2) (memory 0) (realloc 0) string-encoding=utf8))
(func (;2;) (type 3) (canon lift (core func 3) (memory 0)))
(core alias export 0 "bar#a" (func (;4;)))
(func (;3;) (type 5) (canon lift (core func 4)))
(core alias export 0 "foo#a" (func (;5;)))
(core alias export 0 "foo#b" (func (;6;)))
(core alias export 0 "foo#c" (func (;7;)))
(func (;4;) (type 0) (canon lift (core func 5)))
(func (;5;) (type 7) (canon lift (core func 6) (memory 0) (realloc 0) string-encoding=utf8))
(func (;6;) (type 8) (canon lift (core func 7) (memory 0) (realloc 0) string-encoding=utf8))
(instance (;0;)
(export "a" (func 3))
)
(instance (;1;)
(export "a" (func 4))
(export "b" (func 5))
(export "c" (func 6))
)
(export "a" (func 0))
(export "b" (func 1))
(export "c" (func 2))
(export "bar" (instance 0))
(export "foo" (instance 1))
)

View File

@@ -0,0 +1,3 @@
a: func()
b: func(a: s8, b: s16, c: s32, d: s64) -> string
c: func() -> tuple<s8, s16, s32, s64>

View File

@@ -0,0 +1,7 @@
flags x {
a,
b,
c
}
a: func(x: x)

View File

@@ -0,0 +1,9 @@
variant x {
a,
b(string),
c(s64)
}
a: func()
b: func(x: string) -> x
c: func(x: x) -> string

View File

@@ -0,0 +1,11 @@
(module
(memory (export "memory") 1)
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32) unreachable)
(func (export "a") unreachable)
(func (export "b") (param i32 i32 i32 i64) (result i32) unreachable)
(func (export "c") (result i32) unreachable)
(func (export "foo#a") unreachable)
(func (export "foo#b") (param i32 i32) (result i32) unreachable)
(func (export "foo#c") (param i32 i64 i32) (result i32) unreachable)
(func (export "bar#a") (param i32) unreachable)
)

View File

@@ -0,0 +1,108 @@
(component
(type (;0;) (func (param "x" u64) (param "y" string)))
(type (;1;)
(instance
(alias outer 1 0 (type (;0;)))
(export "a" (func (type 0)))
)
)
(type (;2;) (list u8))
(type (;3;) (func (param "x" 2) (result 2)))
(type (;4;)
(instance
(alias outer 1 3 (type (;0;)))
(export "baz" (func (type 0)))
)
)
(type (;5;) (func))
(type (;6;)
(instance
(alias outer 1 5 (type (;0;)))
(export "a" (func (type 0)))
)
)
(import "bar" (instance (;0;) (type 1)))
(import "baz" (instance (;1;) (type 4)))
(import "foo" (instance (;2;) (type 6)))
(core module (;0;)
(type (;0;) (func))
(type (;1;) (func (param i64 i32 i32)))
(type (;2;) (func (param i32 i32 i32)))
(type (;3;) (func (param i32 i32 i32 i32) (result i32)))
(import "foo" "a" (func (;0;) (type 0)))
(import "bar" "a" (func (;1;) (type 1)))
(import "baz" "baz" (func (;2;) (type 2)))
(func (;3;) (type 3) (param i32 i32 i32 i32) (result i32)
unreachable
)
(memory (;0;) 1)
(export "memory" (memory 0))
(export "canonical_abi_realloc" (func 3))
)
(core module (;1;)
(type (;0;) (func (param i64 i32 i32)))
(type (;1;) (func (param i32 i32 i32)))
(func (;0;) (type 0) (param i64 i32 i32)
local.get 0
local.get 1
local.get 2
i32.const 0
call_indirect (type 0)
)
(func (;1;) (type 1) (param i32 i32 i32)
local.get 0
local.get 1
local.get 2
i32.const 1
call_indirect (type 1)
)
(table (;0;) 2 2 funcref)
(export "0" (func 0))
(export "1" (func 1))
(export "$imports" (table 0))
)
(core module (;2;)
(type (;0;) (func (param i64 i32 i32)))
(type (;1;) (func (param i32 i32 i32)))
(import "" "0" (func (;0;) (type 0)))
(import "" "1" (func (;1;) (type 1)))
(import "" "$imports" (table (;0;) 2 2 funcref))
(elem (;0;) (i32.const 0) func 0 1)
)
(core instance (;0;) (instantiate 1))
(core alias export 0 "0" (func (;0;)))
(core alias export 0 "1" (func (;1;)))
(alias export 2 "a" (func (;0;)))
(core func (;2;) (canon lower (func 0)))
(core instance (;1;)
(export "a" (func 0))
)
(core instance (;2;)
(export "baz" (func 1))
)
(core instance (;3;)
(export "a" (func 2))
)
(core instance (;4;) (instantiate 0
(with "bar" (instance 1))
(with "baz" (instance 2))
(with "foo" (instance 3))
)
)
(core alias export 4 "memory" (memory (;0;)))
(core alias export 4 "canonical_abi_realloc" (func (;3;)))
(core alias export 0 "$imports" (table (;0;)))
(alias export 0 "a" (func (;1;)))
(alias export 1 "baz" (func (;2;)))
(core func (;4;) (canon lower (func 1) (memory 0) (realloc 3) string-encoding=utf8))
(core func (;5;) (canon lower (func 2) (memory 0) (realloc 3)))
(core instance (;5;)
(export "$imports" (table 0))
(export "0" (func 4))
(export "1" (func 5))
)
(core instance (;6;) (instantiate 2
(with "" (instance 5))
)
)
)

View File

@@ -0,0 +1 @@
baz: func(x: list<u8>) -> list<u8>

View File

@@ -0,0 +1,7 @@
(module
(import "foo" "a" (func))
(import "bar" "a" (func (param i64 i32 i32)))
(import "baz" "baz" (func (param i32 i32 i32)))
(memory (export "memory") 1)
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32) unreachable)
)

View File

@@ -0,0 +1,90 @@
(component
(type (;0;) (func (result string)))
(type (;1;)
(instance
(alias outer 1 0 (type (;0;)))
(export "a" (func (type 0)))
)
)
(type (;2;) (tuple string u32 string))
(type (;3;) (func (param "x" string) (result 2)))
(type (;4;) (func))
(import "foo" (instance (;0;) (type 1)))
(core module (;0;)
(type (;0;) (func (param i32)))
(type (;1;) (func (param i32 i32 i32 i32) (result i32)))
(type (;2;) (func (param i32 i32) (result i32)))
(type (;3;) (func))
(type (;4;) (func (result i32)))
(import "foo" "a" (func (;0;) (type 0)))
(func (;1;) (type 1) (param i32 i32 i32 i32) (result i32)
unreachable
)
(func (;2;) (type 2) (param i32 i32) (result i32)
unreachable
)
(func (;3;) (type 3)
unreachable
)
(func (;4;) (type 4) (result i32)
unreachable
)
(memory (;0;) 1)
(export "memory" (memory 0))
(export "canonical_abi_realloc" (func 1))
(export "a" (func 2))
(export "bar#a" (func 3))
(export "bar#b" (func 4))
)
(core module (;1;)
(type (;0;) (func (param i32)))
(func (;0;) (type 0) (param i32)
local.get 0
i32.const 0
call_indirect (type 0)
)
(table (;0;) 1 1 funcref)
(export "0" (func 0))
(export "$imports" (table 0))
)
(core module (;2;)
(type (;0;) (func (param i32)))
(import "" "0" (func (;0;) (type 0)))
(import "" "$imports" (table (;0;) 1 1 funcref))
(elem (;0;) (i32.const 0) func 0)
)
(core instance (;0;) (instantiate 1))
(core alias export 0 "0" (func (;0;)))
(core instance (;1;)
(export "a" (func 0))
)
(core instance (;2;) (instantiate 0
(with "foo" (instance 1))
)
)
(core alias export 2 "memory" (memory (;0;)))
(core alias export 2 "canonical_abi_realloc" (func (;1;)))
(core alias export 0 "$imports" (table (;0;)))
(alias export 0 "a" (func (;0;)))
(core func (;2;) (canon lower (func 0) (memory 0) (realloc 1) string-encoding=utf8))
(core instance (;3;)
(export "$imports" (table 0))
(export "0" (func 2))
)
(core instance (;4;) (instantiate 2
(with "" (instance 3))
)
)
(core alias export 2 "a" (func (;3;)))
(func (;1;) (type 3) (canon lift (core func 3) (memory 0) (realloc 1) string-encoding=utf8))
(core alias export 2 "bar#a" (func (;4;)))
(core alias export 2 "bar#b" (func (;5;)))
(func (;2;) (type 4) (canon lift (core func 4)))
(func (;3;) (type 0) (canon lift (core func 5) (memory 0) (realloc 1) string-encoding=utf8))
(instance (;1;)
(export "a" (func 2))
(export "b" (func 3))
)
(export "a" (func 1))
(export "bar" (instance 1))
)

View File

@@ -0,0 +1 @@
a: func(x: string) -> tuple<string, u32, string>

View File

@@ -0,0 +1,2 @@
a: func()
b: func() -> string

View File

@@ -0,0 +1,8 @@
(module
(import "foo" "a" (func (param i32)))
(memory (export "memory") 1)
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32) unreachable)
(func (export "a") (param i32 i32) (result i32) unreachable)
(func (export "bar#a") unreachable)
(func (export "bar#b") (result i32) unreachable)
)

View File

@@ -0,0 +1 @@
type mismatch for function `bar` on imported interface `foo`: expected `[I32, I32] -> []` but found `[] -> []`

View File

@@ -0,0 +1,3 @@
(module
(import "foo" "bar" (func))
)

View File

@@ -0,0 +1,141 @@
(component
(type (;0;) (func (param "x" string)))
(type (;1;) (record (field "a" u8)))
(type (;2;) (func (param "x" 1)))
(type (;3;)
(instance
(alias outer 1 0 (type (;0;)))
(export "bar1" (func (type 0)))
(alias outer 1 2 (type (;1;)))
(export "bar2" (func (type 1)))
)
)
(type (;4;) (list string))
(type (;5;) (func (param "x" 4)))
(type (;6;) (func))
(type (;7;) s8)
(type (;8;) (func (param "x" 7)))
(type (;9;)
(instance
(alias outer 1 5 (type (;0;)))
(export "baz1" (func (type 0)))
(alias outer 1 6 (type (;1;)))
(export "baz2" (func (type 1)))
(alias outer 1 8 (type (;2;)))
(export "baz3" (func (type 2)))
)
)
(type (;10;) (func (param "x" u8)))
(type (;11;) (func (param "x" float32)))
(type (;12;)
(instance
(alias outer 1 6 (type (;0;)))
(export "foo1" (func (type 0)))
(alias outer 1 10 (type (;1;)))
(export "foo2" (func (type 1)))
(alias outer 1 11 (type (;2;)))
(export "foo3" (func (type 2)))
)
)
(import "bar" (instance (;0;) (type 3)))
(import "baz" (instance (;1;) (type 9)))
(import "foo" (instance (;2;) (type 12)))
(core module (;0;)
(type (;0;) (func))
(type (;1;) (func (param i32)))
(type (;2;) (func (param f32)))
(type (;3;) (func (param i32 i32)))
(type (;4;) (func (param i32 i32 i32 i32) (result i32)))
(import "foo" "foo1" (func (;0;) (type 0)))
(import "foo" "foo2" (func (;1;) (type 1)))
(import "foo" "foo3" (func (;2;) (type 2)))
(import "bar" "bar1" (func (;3;) (type 3)))
(import "bar" "bar2" (func (;4;) (type 1)))
(import "baz" "baz1" (func (;5;) (type 3)))
(import "baz" "baz2" (func (;6;) (type 0)))
(import "baz" "baz3" (func (;7;) (type 1)))
(func (;8;) (type 4) (param i32 i32 i32 i32) (result i32)
unreachable
)
(memory (;0;) 1)
(export "memory" (memory 0))
(export "canonical_abi_realloc" (func 8))
)
(core module (;1;)
(type (;0;) (func (param i32 i32)))
(func (;0;) (type 0) (param i32 i32)
local.get 0
local.get 1
i32.const 0
call_indirect (type 0)
)
(func (;1;) (type 0) (param i32 i32)
local.get 0
local.get 1
i32.const 1
call_indirect (type 0)
)
(table (;0;) 2 2 funcref)
(export "0" (func 0))
(export "1" (func 1))
(export "$imports" (table 0))
)
(core module (;2;)
(type (;0;) (func (param i32 i32)))
(import "" "0" (func (;0;) (type 0)))
(import "" "1" (func (;1;) (type 0)))
(import "" "$imports" (table (;0;) 2 2 funcref))
(elem (;0;) (i32.const 0) func 0 1)
)
(core instance (;0;) (instantiate 1))
(core alias export 0 "0" (func (;0;)))
(alias export 0 "bar2" (func (;0;)))
(core func (;1;) (canon lower (func 0)))
(core alias export 0 "1" (func (;2;)))
(alias export 1 "baz2" (func (;1;)))
(alias export 1 "baz3" (func (;2;)))
(core func (;3;) (canon lower (func 1)))
(core func (;4;) (canon lower (func 2)))
(alias export 2 "foo1" (func (;3;)))
(alias export 2 "foo2" (func (;4;)))
(alias export 2 "foo3" (func (;5;)))
(core func (;5;) (canon lower (func 3)))
(core func (;6;) (canon lower (func 4)))
(core func (;7;) (canon lower (func 5)))
(core instance (;1;)
(export "bar1" (func 0))
(export "bar2" (func 1))
)
(core instance (;2;)
(export "baz1" (func 2))
(export "baz2" (func 3))
(export "baz3" (func 4))
)
(core instance (;3;)
(export "foo1" (func 5))
(export "foo2" (func 6))
(export "foo3" (func 7))
)
(core instance (;4;) (instantiate 0
(with "bar" (instance 1))
(with "baz" (instance 2))
(with "foo" (instance 3))
)
)
(core alias export 4 "memory" (memory (;0;)))
(core alias export 4 "canonical_abi_realloc" (func (;8;)))
(core alias export 0 "$imports" (table (;0;)))
(alias export 0 "bar1" (func (;6;)))
(alias export 1 "baz1" (func (;7;)))
(core func (;9;) (canon lower (func 6) (memory 0) (realloc 8) string-encoding=utf8))
(core func (;10;) (canon lower (func 7) (memory 0) (realloc 8) string-encoding=utf8))
(core instance (;5;)
(export "$imports" (table 0))
(export "0" (func 9))
(export "1" (func 10))
)
(core instance (;6;) (instantiate 2
(with "" (instance 5))
)
)
)

View File

@@ -0,0 +1,6 @@
record x {
a: u8
}
bar1: func(x: string)
bar2: func(x: x)

View File

@@ -0,0 +1,5 @@
type x = s8
baz1: func(x: list<string>)
baz2: func()
baz3: func(x: x)

View File

@@ -0,0 +1,3 @@
foo1: func()
foo2: func(x: u8)
foo3: func(x: float32)

View File

@@ -0,0 +1,12 @@
(module
(import "foo" "foo1" (func))
(import "foo" "foo2" (func (param i32)))
(import "foo" "foo3" (func (param f32)))
(import "bar" "bar1" (func (param i32 i32)))
(import "bar" "bar2" (func (param i32)))
(import "baz" "baz1" (func (param i32 i32)))
(import "baz" "baz2" (func))
(import "baz" "baz3" (func (param i32)))
(memory (export "memory") 1)
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32) unreachable)
)

View File

@@ -0,0 +1 @@
module is only allowed to import functions

View File

@@ -0,0 +1,3 @@
(module
(import "" "" (table 1 funcref))
)

View File

@@ -0,0 +1,161 @@
(component
(type (;0;) (func))
(type (;1;) (list string))
(type (;2;) (func (param "x" 1)))
(type (;3;) (record (field "s" string)))
(type (;4;) (func (param "x" 3)))
(type (;5;) (variant (case $c0 "s" string)))
(type (;6;) (func (param "x" 5)))
(type (;7;) (record (field "s" u32)))
(type (;8;) (func (param "x" 7)))
(type (;9;) (variant (case $c0 "s" u32)))
(type (;10;) (func (param "x" 9)))
(type (;11;) (list 3))
(type (;12;) (func (param "x" 11)))
(type (;13;) (list 5))
(type (;14;) (func (param "x" 13)))
(type (;15;) (list u32))
(type (;16;) (func (param "x" 15)))
(type (;17;) (func (param "x" u32)))
(type (;18;) (tuple u32 u32))
(type (;19;) (func (result 18)))
(type (;20;) (func (result string)))
(type (;21;) (func (result 15)))
(type (;22;) (func (result u32)))
(type (;23;) (func (result 5)))
(type (;24;) (list 9))
(type (;25;) (func (result 24)))
(export "r" (type 3))
(export "v" (type 5))
(export "r-no-string" (type 7))
(export "v-no-string" (type 9))
(core module (;0;)
(type (;0;) (func (param i32 i32 i32 i32) (result i32)))
(type (;1;) (func))
(type (;2;) (func (param i32 i32)))
(type (;3;) (func (param i32 i32 i32)))
(type (;4;) (func (param i32)))
(type (;5;) (func (result i32)))
(func (;0;) (type 0) (param i32 i32 i32 i32) (result i32)
unreachable
)
(func (;1;) (type 1)
unreachable
)
(func (;2;) (type 2) (param i32 i32)
unreachable
)
(func (;3;) (type 2) (param i32 i32)
unreachable
)
(func (;4;) (type 3) (param i32 i32 i32)
unreachable
)
(func (;5;) (type 4) (param i32)
unreachable
)
(func (;6;) (type 2) (param i32 i32)
unreachable
)
(func (;7;) (type 2) (param i32 i32)
unreachable
)
(func (;8;) (type 2) (param i32 i32)
unreachable
)
(func (;9;) (type 2) (param i32 i32)
unreachable
)
(func (;10;) (type 4) (param i32)
unreachable
)
(func (;11;) (type 5) (result i32)
unreachable
)
(func (;12;) (type 5) (result i32)
unreachable
)
(func (;13;) (type 5) (result i32)
unreachable
)
(func (;14;) (type 5) (result i32)
unreachable
)
(func (;15;) (type 5) (result i32)
unreachable
)
(func (;16;) (type 5) (result i32)
unreachable
)
(memory (;0;) 1)
(export "memory" (memory 0))
(export "canonical_abi_realloc" (func 0))
(export "a" (func 1))
(export "b" (func 2))
(export "c" (func 3))
(export "d" (func 4))
(export "e" (func 5))
(export "f" (func 6))
(export "g" (func 7))
(export "h" (func 8))
(export "i" (func 9))
(export "j" (func 10))
(export "k" (func 11))
(export "l" (func 12))
(export "m" (func 13))
(export "n" (func 14))
(export "o" (func 15))
(export "p" (func 16))
)
(core instance (;0;) (instantiate 0))
(core alias export 0 "memory" (memory (;0;)))
(core alias export 0 "canonical_abi_realloc" (func (;0;)))
(core alias export 0 "a" (func (;1;)))
(core alias export 0 "b" (func (;2;)))
(core alias export 0 "c" (func (;3;)))
(core alias export 0 "d" (func (;4;)))
(core alias export 0 "e" (func (;5;)))
(core alias export 0 "f" (func (;6;)))
(core alias export 0 "g" (func (;7;)))
(core alias export 0 "h" (func (;8;)))
(core alias export 0 "i" (func (;9;)))
(core alias export 0 "j" (func (;10;)))
(core alias export 0 "k" (func (;11;)))
(core alias export 0 "l" (func (;12;)))
(core alias export 0 "m" (func (;13;)))
(core alias export 0 "n" (func (;14;)))
(core alias export 0 "o" (func (;15;)))
(core alias export 0 "p" (func (;16;)))
(func (;0;) (type 0) (canon lift (core func 1)))
(func (;1;) (type 2) (canon lift (core func 2) (memory 0) (realloc 0) string-encoding=utf8))
(func (;2;) (type 4) (canon lift (core func 3) (memory 0) (realloc 0) string-encoding=utf8))
(func (;3;) (type 6) (canon lift (core func 4) (memory 0) (realloc 0) string-encoding=utf8))
(func (;4;) (type 8) (canon lift (core func 5)))
(func (;5;) (type 10) (canon lift (core func 6)))
(func (;6;) (type 12) (canon lift (core func 7) (memory 0) (realloc 0) string-encoding=utf8))
(func (;7;) (type 14) (canon lift (core func 8) (memory 0) (realloc 0) string-encoding=utf8))
(func (;8;) (type 16) (canon lift (core func 9) (memory 0) (realloc 0)))
(func (;9;) (type 17) (canon lift (core func 10)))
(func (;10;) (type 19) (canon lift (core func 11) (memory 0)))
(func (;11;) (type 20) (canon lift (core func 12) (memory 0) (realloc 0) string-encoding=utf8))
(func (;12;) (type 21) (canon lift (core func 13) (memory 0) (realloc 0)))
(func (;13;) (type 22) (canon lift (core func 14)))
(func (;14;) (type 23) (canon lift (core func 15) (memory 0) (realloc 0) string-encoding=utf8))
(func (;15;) (type 25) (canon lift (core func 16) (memory 0) (realloc 0)))
(export "a" (func 0))
(export "b" (func 1))
(export "c" (func 2))
(export "d" (func 3))
(export "e" (func 4))
(export "f" (func 5))
(export "g" (func 6))
(export "h" (func 7))
(export "i" (func 8))
(export "j" (func 9))
(export "k" (func 10))
(export "l" (func 11))
(export "m" (func 12))
(export "n" (func 13))
(export "o" (func 14))
(export "p" (func 15))
)

View File

@@ -0,0 +1,32 @@
record r {
s: string
}
record r-no-string {
s: u32
}
variant v {
s(string)
}
variant v-no-string {
s(u32)
}
a: func()
b: func(x: list<string>)
c: func(x: r)
d: func(x: v)
e: func(x: r-no-string)
f: func(x: v-no-string)
g: func(x: list<r>)
h: func(x: list<v>)
i: func(x: list<u32>)
j: func(x: u32)
k: func() -> tuple<u32, u32>
l: func() -> string
m: func() -> list<u32>
n: func() -> u32
o: func() -> v
p: func() -> list<v-no-string>

View File

@@ -0,0 +1,20 @@
(module
(memory (export "memory") 1)
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32) unreachable)
(func (export "a") unreachable)
(func (export "b") (param i32 i32) unreachable)
(func (export "c") (param i32 i32) unreachable)
(func (export "d") (param i32 i32 i32) unreachable)
(func (export "e") (param i32) unreachable)
(func (export "f") (param i32 i32) unreachable)
(func (export "g") (param i32 i32) unreachable)
(func (export "h") (param i32 i32) unreachable)
(func (export "i") (param i32 i32) unreachable)
(func (export "j") (param i32) unreachable)
(func (export "k") (result i32) unreachable)
(func (export "l") (result i32) unreachable)
(func (export "m") (result i32) unreachable)
(func (export "n") (result i32) unreachable)
(func (export "o") (result i32) unreachable)
(func (export "p") (result i32) unreachable)
)

View File

@@ -0,0 +1,280 @@
(component
(type (;0;) (func))
(type (;1;) (list string))
(type (;2;) (func (param "x" 1)))
(type (;3;) (record (field "s" string)))
(type (;4;) (func (param "x" 3)))
(type (;5;) (variant (case $c0 "s" string)))
(type (;6;) (func (param "x" 5)))
(type (;7;) (record (field "s" u32)))
(type (;8;) (func (param "x" 7)))
(type (;9;) (variant (case $c0 "s" u32)))
(type (;10;) (func (param "x" 9)))
(type (;11;) (list 3))
(type (;12;) (func (param "x" 11)))
(type (;13;) (list 5))
(type (;14;) (func (param "x" 13)))
(type (;15;) (list u32))
(type (;16;) (func (param "x" 15)))
(type (;17;) (func (param "x" u32)))
(type (;18;) (tuple u32 u32))
(type (;19;) (func (result 18)))
(type (;20;) (func (result string)))
(type (;21;) (func (result 15)))
(type (;22;) (func (result u32)))
(type (;23;) (func (result 5)))
(type (;24;) (list 9))
(type (;25;) (func (result 24)))
(type (;26;)
(instance
(alias outer 1 0 (type (;0;)))
(export "a" (func (type 0)))
(alias outer 1 2 (type (;1;)))
(export "b" (func (type 1)))
(alias outer 1 4 (type (;2;)))
(export "c" (func (type 2)))
(alias outer 1 6 (type (;3;)))
(export "d" (func (type 3)))
(alias outer 1 8 (type (;4;)))
(export "e" (func (type 4)))
(alias outer 1 10 (type (;5;)))
(export "f" (func (type 5)))
(alias outer 1 12 (type (;6;)))
(export "g" (func (type 6)))
(alias outer 1 14 (type (;7;)))
(export "h" (func (type 7)))
(alias outer 1 16 (type (;8;)))
(export "i" (func (type 8)))
(alias outer 1 17 (type (;9;)))
(export "j" (func (type 9)))
(alias outer 1 19 (type (;10;)))
(export "k" (func (type 10)))
(alias outer 1 20 (type (;11;)))
(export "l" (func (type 11)))
(alias outer 1 21 (type (;12;)))
(export "m" (func (type 12)))
(alias outer 1 22 (type (;13;)))
(export "n" (func (type 13)))
(alias outer 1 23 (type (;14;)))
(export "o" (func (type 14)))
(alias outer 1 25 (type (;15;)))
(export "p" (func (type 15)))
)
)
(import "foo" (instance (;0;) (type 26)))
(core module (;0;)
(type (;0;) (func))
(type (;1;) (func (param i32 i32)))
(type (;2;) (func (param i32 i32 i32)))
(type (;3;) (func (param i32)))
(type (;4;) (func (result i32)))
(type (;5;) (func (param i32 i32 i32 i32) (result i32)))
(import "foo" "a" (func (;0;) (type 0)))
(import "foo" "b" (func (;1;) (type 1)))
(import "foo" "c" (func (;2;) (type 1)))
(import "foo" "d" (func (;3;) (type 2)))
(import "foo" "e" (func (;4;) (type 3)))
(import "foo" "f" (func (;5;) (type 1)))
(import "foo" "g" (func (;6;) (type 1)))
(import "foo" "h" (func (;7;) (type 1)))
(import "foo" "i" (func (;8;) (type 1)))
(import "foo" "j" (func (;9;) (type 3)))
(import "foo" "k" (func (;10;) (type 3)))
(import "foo" "l" (func (;11;) (type 3)))
(import "foo" "m" (func (;12;) (type 3)))
(import "foo" "n" (func (;13;) (type 4)))
(import "foo" "o" (func (;14;) (type 3)))
(import "foo" "p" (func (;15;) (type 3)))
(func (;16;) (type 5) (param i32 i32 i32 i32) (result i32)
unreachable
)
(memory (;0;) 1)
(export "memory" (memory 0))
(export "canonical_abi_realloc" (func 16))
)
(core module (;1;)
(type (;0;) (func (param i32 i32)))
(type (;1;) (func (param i32 i32 i32)))
(type (;2;) (func (param i32)))
(func (;0;) (type 0) (param i32 i32)
local.get 0
local.get 1
i32.const 0
call_indirect (type 0)
)
(func (;1;) (type 0) (param i32 i32)
local.get 0
local.get 1
i32.const 1
call_indirect (type 0)
)
(func (;2;) (type 1) (param i32 i32 i32)
local.get 0
local.get 1
local.get 2
i32.const 2
call_indirect (type 1)
)
(func (;3;) (type 0) (param i32 i32)
local.get 0
local.get 1
i32.const 3
call_indirect (type 0)
)
(func (;4;) (type 0) (param i32 i32)
local.get 0
local.get 1
i32.const 4
call_indirect (type 0)
)
(func (;5;) (type 0) (param i32 i32)
local.get 0
local.get 1
i32.const 5
call_indirect (type 0)
)
(func (;6;) (type 2) (param i32)
local.get 0
i32.const 6
call_indirect (type 2)
)
(func (;7;) (type 2) (param i32)
local.get 0
i32.const 7
call_indirect (type 2)
)
(func (;8;) (type 2) (param i32)
local.get 0
i32.const 8
call_indirect (type 2)
)
(func (;9;) (type 2) (param i32)
local.get 0
i32.const 9
call_indirect (type 2)
)
(func (;10;) (type 2) (param i32)
local.get 0
i32.const 10
call_indirect (type 2)
)
(table (;0;) 11 11 funcref)
(export "0" (func 0))
(export "1" (func 1))
(export "2" (func 2))
(export "3" (func 3))
(export "4" (func 4))
(export "5" (func 5))
(export "6" (func 6))
(export "7" (func 7))
(export "8" (func 8))
(export "9" (func 9))
(export "10" (func 10))
(export "$imports" (table 0))
)
(core module (;2;)
(type (;0;) (func (param i32 i32)))
(type (;1;) (func (param i32 i32 i32)))
(type (;2;) (func (param i32)))
(import "" "0" (func (;0;) (type 0)))
(import "" "1" (func (;1;) (type 0)))
(import "" "2" (func (;2;) (type 1)))
(import "" "3" (func (;3;) (type 0)))
(import "" "4" (func (;4;) (type 0)))
(import "" "5" (func (;5;) (type 0)))
(import "" "6" (func (;6;) (type 2)))
(import "" "7" (func (;7;) (type 2)))
(import "" "8" (func (;8;) (type 2)))
(import "" "9" (func (;9;) (type 2)))
(import "" "10" (func (;10;) (type 2)))
(import "" "$imports" (table (;0;) 11 11 funcref))
(elem (;0;) (i32.const 0) func 0 1 2 3 4 5 6 7 8 9 10)
)
(core instance (;0;) (instantiate 1))
(core alias export 0 "0" (func (;0;)))
(core alias export 0 "1" (func (;1;)))
(core alias export 0 "2" (func (;2;)))
(core alias export 0 "3" (func (;3;)))
(core alias export 0 "4" (func (;4;)))
(core alias export 0 "5" (func (;5;)))
(core alias export 0 "6" (func (;6;)))
(core alias export 0 "7" (func (;7;)))
(core alias export 0 "8" (func (;8;)))
(core alias export 0 "9" (func (;9;)))
(core alias export 0 "10" (func (;10;)))
(alias export 0 "a" (func (;0;)))
(alias export 0 "e" (func (;1;)))
(alias export 0 "f" (func (;2;)))
(alias export 0 "j" (func (;3;)))
(alias export 0 "n" (func (;4;)))
(core func (;11;) (canon lower (func 0)))
(core func (;12;) (canon lower (func 1)))
(core func (;13;) (canon lower (func 2)))
(core func (;14;) (canon lower (func 3)))
(core func (;15;) (canon lower (func 4)))
(core instance (;1;)
(export "b" (func 0))
(export "c" (func 1))
(export "d" (func 2))
(export "g" (func 3))
(export "h" (func 4))
(export "i" (func 5))
(export "k" (func 6))
(export "l" (func 7))
(export "m" (func 8))
(export "o" (func 9))
(export "p" (func 10))
(export "a" (func 11))
(export "e" (func 12))
(export "f" (func 13))
(export "j" (func 14))
(export "n" (func 15))
)
(core instance (;2;) (instantiate 0
(with "foo" (instance 1))
)
)
(core alias export 2 "memory" (memory (;0;)))
(core alias export 2 "canonical_abi_realloc" (func (;16;)))
(core alias export 0 "$imports" (table (;0;)))
(alias export 0 "b" (func (;5;)))
(alias export 0 "c" (func (;6;)))
(alias export 0 "d" (func (;7;)))
(alias export 0 "g" (func (;8;)))
(alias export 0 "h" (func (;9;)))
(alias export 0 "i" (func (;10;)))
(alias export 0 "k" (func (;11;)))
(alias export 0 "l" (func (;12;)))
(alias export 0 "m" (func (;13;)))
(alias export 0 "o" (func (;14;)))
(alias export 0 "p" (func (;15;)))
(core func (;17;) (canon lower (func 5) (memory 0) (realloc 16) string-encoding=utf8))
(core func (;18;) (canon lower (func 6) (memory 0) (realloc 16) string-encoding=utf8))
(core func (;19;) (canon lower (func 7) (memory 0) (realloc 16) string-encoding=utf8))
(core func (;20;) (canon lower (func 8) (memory 0) (realloc 16) string-encoding=utf8))
(core func (;21;) (canon lower (func 9) (memory 0) (realloc 16) string-encoding=utf8))
(core func (;22;) (canon lower (func 10) (memory 0) (realloc 16)))
(core func (;23;) (canon lower (func 11) (memory 0)))
(core func (;24;) (canon lower (func 12) (memory 0) (realloc 16) string-encoding=utf8))
(core func (;25;) (canon lower (func 13) (memory 0) (realloc 16)))
(core func (;26;) (canon lower (func 14) (memory 0) (realloc 16) string-encoding=utf8))
(core func (;27;) (canon lower (func 15) (memory 0) (realloc 16)))
(core instance (;3;)
(export "$imports" (table 0))
(export "0" (func 17))
(export "1" (func 18))
(export "2" (func 19))
(export "3" (func 20))
(export "4" (func 21))
(export "5" (func 22))
(export "6" (func 23))
(export "7" (func 24))
(export "8" (func 25))
(export "9" (func 26))
(export "10" (func 27))
)
(core instance (;4;) (instantiate 2
(with "" (instance 3))
)
)
)

View File

@@ -0,0 +1,32 @@
record r {
s: string
}
record r-no-string {
s: u32
}
variant v {
s(string)
}
variant v-no-string {
s(u32)
}
a: func()
b: func(x: list<string>)
c: func(x: r)
d: func(x: v)
e: func(x: r-no-string)
f: func(x: v-no-string)
g: func(x: list<r>)
h: func(x: list<v>)
i: func(x: list<u32>)
j: func(x: u32)
k: func() -> tuple<u32, u32>
l: func() -> string
m: func() -> list<u32>
n: func() -> u32
o: func() -> v
p: func() -> list<v-no-string>

View File

@@ -0,0 +1,20 @@
(module
(import "foo" "a" (func))
(import "foo" "b" (func (param i32 i32)))
(import "foo" "c" (func (param i32 i32)))
(import "foo" "d" (func (param i32 i32 i32)))
(import "foo" "e" (func (param i32)))
(import "foo" "f" (func (param i32 i32)))
(import "foo" "g" (func (param i32 i32)))
(import "foo" "h" (func (param i32 i32)))
(import "foo" "i" (func (param i32 i32)))
(import "foo" "j" (func (param i32)))
(import "foo" "k" (func (param i32)))
(import "foo" "l" (func (param i32)))
(import "foo" "m" (func (param i32)))
(import "foo" "n" (func (result i32)))
(import "foo" "o" (func (param i32)))
(import "foo" "p" (func (param i32)))
(memory (export "memory") 1)
(func (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32) unreachable)
)

View File

@@ -0,0 +1 @@
module does not export required function `a`

View File

@@ -0,0 +1 @@
module does not export required function `foo#a`

View File

@@ -0,0 +1 @@
import interface `foo` is missing function `bar` that is required by the module

View File

@@ -0,0 +1,3 @@
(module
(import "foo" "bar" (func))
)

View File

@@ -0,0 +1 @@
module requires an import interface named `foo`

View File

@@ -0,0 +1,3 @@
(module
(import "foo" "bar" (func))
)

View File

@@ -0,0 +1,52 @@
(component
(type (;0;) (func))
(type (;1;) (func (result string)))
(type (;2;) (func (param "x" string) (result string)))
(type (;3;) (list string))
(type (;4;) (func (param "x" 3)))
(export "x" (type 3))
(core module (;0;)
(type (;0;) (func (param i32 i32 i32 i32) (result i32)))
(type (;1;) (func))
(type (;2;) (func (result i32)))
(type (;3;) (func (param i32 i32) (result i32)))
(type (;4;) (func (param i32 i32)))
(func $canonical_abi_realloc (;0;) (type 0) (param i32 i32 i32 i32) (result i32)
unreachable
)
(func $a (;1;) (type 1)
unreachable
)
(func $b (;2;) (type 2) (result i32)
unreachable
)
(func $c (;3;) (type 3) (param i32 i32) (result i32)
unreachable
)
(func $d (;4;) (type 4) (param i32 i32)
unreachable
)
(memory $memory (;0;) 1)
(export "memory" (memory $memory))
(export "canonical_abi_realloc" (func $canonical_abi_realloc))
(export "a" (func $a))
(export "b" (func $b))
(export "c" (func $c))
(export "d" (func $d))
)
(core instance (;0;) (instantiate 0))
(core alias export 0 "memory" (memory (;0;)))
(core alias export 0 "canonical_abi_realloc" (func (;0;)))
(core alias export 0 "a" (func (;1;)))
(core alias export 0 "b" (func (;2;)))
(core alias export 0 "c" (func (;3;)))
(core alias export 0 "d" (func (;4;)))
(func (;0;) (type 0) (canon lift (core func 1)))
(func (;1;) (type 1) (canon lift (core func 2) (memory 0) (realloc 0) string-encoding=utf8))
(func (;2;) (type 2) (canon lift (core func 3) (memory 0) (realloc 0) string-encoding=utf8))
(func (;3;) (type 4) (canon lift (core func 4) (memory 0) (realloc 0) string-encoding=utf8))
(export "a" (func 0))
(export "b" (func 1))
(export "c" (func 2))
(export "d" (func 3))
)

View File

@@ -0,0 +1,6 @@
type x = list<string>
a: func()
b: func() -> string
c: func(x: string) -> string
d: func(x: x)

View File

@@ -0,0 +1,8 @@
(module
(memory $memory (export "memory") 1)
(func $canonical_abi_realloc (export "canonical_abi_realloc") (param i32 i32 i32 i32) (result i32) unreachable)
(func $a (export "a") unreachable)
(func $b (export "b") (result i32) unreachable)
(func $c (export "c") (param i32 i32) (result i32) unreachable)
(func $d (export "d") (param i32 i32) unreachable)
)

View File

@@ -0,0 +1,60 @@
use anyhow::{Context, Result};
use pretty_assertions::assert_eq;
use std::fs;
use wit_component::InterfaceEncoder;
use wit_parser::Interface;
/// Tests the encoding of individual interface files.
///
/// This test looks in the `interfaces/` directory for test cases.
///
/// Each test case is a directory containing a `<testcase>.wit` file
/// and an expected `<testcase>.wat` file.
///
/// The test encodes the wit file, prints the resulting component, and
/// compares the output to the wat file.
///
/// Run the test with the environment variable `BLESS` set to update
/// the wat baseline file.
#[test]
fn interface_encoding() -> Result<()> {
for entry in fs::read_dir("tests/interfaces")? {
let path = entry?.path();
if !path.is_dir() {
continue;
}
let test_case = path.file_stem().unwrap().to_str().unwrap();
let wit_path = path.join(test_case).with_extension("wit");
let interface = Interface::parse_file(&wit_path)?;
let encoder = InterfaceEncoder::new(&interface).validate(true);
let bytes = encoder.encode().with_context(|| {
format!(
"failed to encode a component from interface `{}` for test case `{}`",
wit_path.display(),
test_case,
)
})?;
let output = wasmprinter::print_bytes(&bytes)?;
let wat_path = wit_path.with_extension("wat");
if std::env::var_os("BLESS").is_some() {
fs::write(&wat_path, output)?;
} else {
assert_eq!(
fs::read_to_string(&wat_path)?.replace("\r\n", "\n"),
output,
"encoding of wit file `{}` did not match the expected wat file `{}` for test case `{}`",
wit_path.display(),
wat_path.display(),
test_case
);
}
}
Ok(())
}

View File

@@ -0,0 +1,30 @@
(component
(type (;0;) (flags "b0"))
(type (;1;) (func (param "x" 0) (result 0)))
(type (;2;) (flags "b0" "b1"))
(type (;3;) (func (param "x" 2) (result 2)))
(type (;4;) (flags "b0" "b1" "b2" "b3"))
(type (;5;) (func (param "x" 4) (result 4)))
(type (;6;) (flags "b0" "b1" "b2" "b3" "b4" "b5" "b6" "b7"))
(type (;7;) (func (param "x" 6) (result 6)))
(type (;8;) (flags "b0" "b1" "b2" "b3" "b4" "b5" "b6" "b7" "b8" "b9" "b10" "b11" "b12" "b13" "b14" "b15"))
(type (;9;) (func (param "x" 8) (result 8)))
(type (;10;) (flags "b0" "b1" "b2" "b3" "b4" "b5" "b6" "b7" "b8" "b9" "b10" "b11" "b12" "b13" "b14" "b15" "b16" "b17" "b18" "b19" "b20" "b21" "b22" "b23" "b24" "b25" "b26" "b27" "b28" "b29" "b30" "b31"))
(type (;11;) (func (param "x" 10) (result 10)))
(type (;12;) (flags "b0" "b1" "b2" "b3" "b4" "b5" "b6" "b7" "b8" "b9" "b10" "b11" "b12" "b13" "b14" "b15" "b16" "b17" "b18" "b19" "b20" "b21" "b22" "b23" "b24" "b25" "b26" "b27" "b28" "b29" "b30" "b31" "b32" "b33" "b34" "b35" "b36" "b37" "b38" "b39" "b40" "b41" "b42" "b43" "b44" "b45" "b46" "b47" "b48" "b49" "b50" "b51" "b52" "b53" "b54" "b55" "b56" "b57" "b58" "b59" "b60" "b61" "b62" "b63"))
(type (;13;) (func (param "x" 12) (result 12)))
(export "flag1" (type 0))
(export "roundtrip-flag1" (type 1))
(export "flag2" (type 2))
(export "roundtrip-flag2" (type 3))
(export "flag4" (type 4))
(export "roundtrip-flag4" (type 5))
(export "flag8" (type 6))
(export "roundtrip-flag8" (type 7))
(export "flag16" (type 8))
(export "roundtrip-flag16" (type 9))
(export "flag32" (type 10))
(export "roundtrip-flag32" (type 11))
(export "flag64" (type 12))
(export "roundtrip-flag64" (type 13))
)

View File

@@ -0,0 +1,162 @@
flags flag1 {
b0,
}
flags flag2 {
b0,
b1,
}
flags flag4 {
b0,
b1,
b2,
b3,
}
flags flag8 {
b0,
b1,
b2,
b3,
b4,
b5,
b6,
b7,
}
flags flag16 {
b0,
b1,
b2,
b3,
b4,
b5,
b6,
b7,
b8,
b9,
b10,
b11,
b12,
b13,
b14,
b15,
}
flags flag32 {
b0,
b1,
b2,
b3,
b4,
b5,
b6,
b7,
b8,
b9,
b10,
b11,
b12,
b13,
b14,
b15,
b16,
b17,
b18,
b19,
b20,
b21,
b22,
b23,
b24,
b25,
b26,
b27,
b28,
b29,
b30,
b31,
}
flags flag64 {
b0,
b1,
b2,
b3,
b4,
b5,
b6,
b7,
b8,
b9,
b10,
b11,
b12,
b13,
b14,
b15,
b16,
b17,
b18,
b19,
b20,
b21,
b22,
b23,
b24,
b25,
b26,
b27,
b28,
b29,
b30,
b31,
b32,
b33,
b34,
b35,
b36,
b37,
b38,
b39,
b40,
b41,
b42,
b43,
b44,
b45,
b46,
b47,
b48,
b49,
b50,
b51,
b52,
b53,
b54,
b55,
b56,
b57,
b58,
b59,
b60,
b61,
b62,
b63,
}
roundtrip-flag1: func(x: flag1) -> flag1
roundtrip-flag2: func(x: flag2) -> flag2
roundtrip-flag4: func(x: flag4) -> flag4
roundtrip-flag8: func(x: flag8) -> flag8
roundtrip-flag16: func(x: flag16) -> flag16
roundtrip-flag32: func(x: flag32) -> flag32
roundtrip-flag64: func(x: flag64) -> flag64

View File

@@ -0,0 +1,10 @@
(component
(type (;0;) (func (param "x" float32)))
(type (;1;) (func (param "x" float64)))
(type (;2;) (func (result float32)))
(type (;3;) (func (result float64)))
(export "float32-param" (type 0))
(export "float64-param" (type 1))
(export "float32-result" (type 2))
(export "float64-result" (type 3))
)

View File

@@ -0,0 +1,8 @@
float32-param: func(x: float32)
float64-param: func(x: float64)
float32-result: func() -> float32
float64-result: func() -> float64

View File

@@ -0,0 +1,40 @@
(component
(type (;0;) (func (param "x" u8)))
(type (;1;) (func (param "x" s8)))
(type (;2;) (func (param "x" u16)))
(type (;3;) (func (param "x" s16)))
(type (;4;) (func (param "x" u32)))
(type (;5;) (func (param "x" s32)))
(type (;6;) (func (param "x" u64)))
(type (;7;) (func (param "x" s64)))
(type (;8;) (func (param "p1" u8) (param "p2" s8) (param "p3" u16) (param "p4" s16) (param "p5" u32) (param "p6" s32) (param "p7" u64) (param "p8" s64)))
(type (;9;) (func (result u8)))
(type (;10;) (func (result s8)))
(type (;11;) (func (result u16)))
(type (;12;) (func (result s16)))
(type (;13;) (func (result u32)))
(type (;14;) (func (result s32)))
(type (;15;) (func (result u64)))
(type (;16;) (func (result s64)))
(type (;17;) (tuple s64 u8))
(type (;18;) (func (result 17)))
(export "a1" (type 0))
(export "a2" (type 1))
(export "a3" (type 2))
(export "a4" (type 3))
(export "a5" (type 4))
(export "a6" (type 5))
(export "a7" (type 6))
(export "a8" (type 7))
(export "a9" (type 8))
(export "r1" (type 9))
(export "r2" (type 10))
(export "r3" (type 11))
(export "r4" (type 12))
(export "r5" (type 13))
(export "r6" (type 14))
(export "r7" (type 15))
(export "r8" (type 16))
(export "pair-ret" (type 18))
(export "multi-ret" (type 18))
)

View File

@@ -0,0 +1,38 @@
a1: func(x: u8)
a2: func(x: s8)
a3: func(x: u16)
a4: func(x: s16)
a5: func(x: u32)
a6: func(x: s32)
a7: func(x: u64)
a8: func(x: s64)
a9: func(p1: u8, p2: s8, p3: u16, p4: s16, p5: u32, p6: s32, p7: u64, p8: s64)
r1: func() -> u8
r2: func() -> s8
r3: func() -> u16
r4: func() -> s16
r5: func() -> u32
r6: func() -> s32
r7: func() -> u64
r8: func() -> s64
pair-ret: func() -> tuple<s64, u8>
multi-ret: func() -> tuple<s64, u8>

View File

@@ -0,0 +1,92 @@
(component
(type (;0;) (list u8))
(type (;1;) (func (param "x" 0)))
(type (;2;) (list u16))
(type (;3;) (func (param "x" 2)))
(type (;4;) (list u32))
(type (;5;) (func (param "x" 4)))
(type (;6;) (list u64))
(type (;7;) (func (param "x" 6)))
(type (;8;) (list s8))
(type (;9;) (func (param "x" 8)))
(type (;10;) (list s16))
(type (;11;) (func (param "x" 10)))
(type (;12;) (list s32))
(type (;13;) (func (param "x" 12)))
(type (;14;) (list s64))
(type (;15;) (func (param "x" 14)))
(type (;16;) (list float32))
(type (;17;) (func (param "x" 16)))
(type (;18;) (list float64))
(type (;19;) (func (param "x" 18)))
(type (;20;) (func (result 0)))
(type (;21;) (func (result 2)))
(type (;22;) (func (result 4)))
(type (;23;) (func (result 6)))
(type (;24;) (func (result 8)))
(type (;25;) (func (result 10)))
(type (;26;) (func (result 12)))
(type (;27;) (func (result 14)))
(type (;28;) (func (result 16)))
(type (;29;) (func (result 18)))
(type (;30;) (tuple u8 s8))
(type (;31;) (list 30))
(type (;32;) (tuple s64 u32))
(type (;33;) (list 32))
(type (;34;) (func (param "x" 31) (result 33)))
(type (;35;) (list string))
(type (;36;) (func (param "a" 35)))
(type (;37;) (func (result 35)))
(type (;38;) (tuple u8 string))
(type (;39;) (list 38))
(type (;40;) (tuple string u8))
(type (;41;) (list 40))
(type (;42;) (func (param "x" 39) (result 41)))
(type (;43;) (func (param "x" 35) (result 35)))
(type (;44;) (record (field "a1" u32) (field "a2" u64) (field "a3" s32) (field "a4" s64) (field "b" string) (field "c" 0)))
(type (;45;) (record (field "x" string) (field "y" 44) (field "c1" u32) (field "c2" u64) (field "c3" s32) (field "c4" s64)))
(type (;46;) (list 45))
(type (;47;) (list 44))
(type (;48;) (func (param "x" 46) (result 47)))
(type (;49;) (variant (case $c0 "a" unit) (case $c1 "b" u32) (case $c2 "c" string)))
(type (;50;) (list 49))
(type (;51;) (variant (case $c0 "a" string) (case $c1 "b" unit) (case $c2 "c" u32) (case $c3 "d" 50)))
(type (;52;) (list 51))
(type (;53;) (func (param "x" 52) (result 50)))
(type (;54;) (tuple string u8 s8 u16 s16 u32 s32 u64 s64 float32 float64 char))
(type (;55;) (list 54))
(type (;56;) (func (param "a" 55) (result 55)))
(export "list-u8-param" (type 1))
(export "list-u16-param" (type 3))
(export "list-u32-param" (type 5))
(export "list-u64-param" (type 7))
(export "list-s8-param" (type 9))
(export "list-s16-param" (type 11))
(export "list-s32-param" (type 13))
(export "list-s64-param" (type 15))
(export "list-float32-param" (type 17))
(export "list-float64-param" (type 19))
(export "list-u8-ret" (type 20))
(export "list-u16-ret" (type 21))
(export "list-u32-ret" (type 22))
(export "list-u64-ret" (type 23))
(export "list-s8-ret" (type 24))
(export "list-s16-ret" (type 25))
(export "list-s32-ret" (type 26))
(export "list-s64-ret" (type 27))
(export "list-float32-ret" (type 28))
(export "list-float64-ret" (type 29))
(export "tuple-list" (type 34))
(export "string-list-arg" (type 36))
(export "string-list-ret" (type 37))
(export "tuple-string-list" (type 42))
(export "string-list" (type 43))
(export "other-record" (type 44))
(export "some-record" (type 45))
(export "record-list" (type 48))
(export "other-variant" (type 49))
(export "some-variant" (type 51))
(export "variant-list" (type 53))
(export "load-store-all-sizes" (type 55))
(export "load-store-everything" (type 56))
)

View File

@@ -0,0 +1,89 @@
record other-record {
a1: u32,
a2: u64,
a3: s32,
a4: s64,
b: string,
c: list<u8>,
}
record some-record {
x: string,
y: other-record,
c1: u32,
c2: u64,
c3: s32,
c4: s64,
}
variant other-variant {
a,
b(u32),
c(string),
}
variant some-variant {
a(string),
b,
c(u32),
d(list<other-variant>),
}
type load-store-all-sizes = list<tuple<string, u8, s8, u16, s16, u32, s32, u64, s64, float32, float64, char>>
list-u8-param: func(x: list<u8>)
list-u16-param: func(x: list<u16>)
list-u32-param: func(x: list<u32>)
list-u64-param: func(x: list<u64>)
list-s8-param: func(x: list<s8>)
list-s16-param: func(x: list<s16>)
list-s32-param: func(x: list<s32>)
list-s64-param: func(x: list<s64>)
list-float32-param: func(x: list<float32>)
list-float64-param: func(x: list<float64>)
list-u8-ret: func() -> list<u8>
list-u16-ret: func() -> list<u16>
list-u32-ret: func() -> list<u32>
list-u64-ret: func() -> list<u64>
list-s8-ret: func() -> list<s8>
list-s16-ret: func() -> list<s16>
list-s32-ret: func() -> list<s32>
list-s64-ret: func() -> list<s64>
list-float32-ret: func() -> list<float32>
list-float64-ret: func() -> list<float64>
tuple-list: func(x: list<tuple<u8, s8>>) -> list<tuple<s64, u32>>
string-list-arg: func(a: list<string>)
string-list-ret: func() -> list<string>
tuple-string-list: func(x: list<tuple<u8, string>>) -> list<tuple<string, u8>>
string-list: func(x: list<string>) -> list<string>
record-list: func(x: list<some-record>) -> list<other-record>
variant-list: func(x: list<some-variant>) -> list<other-variant>
load-store-everything: func(a: load-store-all-sizes) -> load-store-all-sizes

View File

@@ -0,0 +1,37 @@
(component
(type (;0;) (tuple char u32))
(type (;1;) (func (param "x" 0)))
(type (;2;) (func (result 0)))
(type (;3;) (record))
(type (;4;) (func (param "x" 3)))
(type (;5;) (func (result 3)))
(type (;6;) (record (field "a" u32) (field "b" u32)))
(type (;7;) (func (param "x" 6)))
(type (;8;) (func (result 6)))
(type (;9;) (flags "a" "b" "c" "d" "e" "f" "g" "h" "i"))
(type (;10;) (func (param "x" 9)))
(type (;11;) (func (result 9)))
(type (;12;) (record (field "a" 6) (field "b" u32) (field "c" 3) (field "d" string) (field "e" 9)))
(type (;13;) (func (param "x" 12)))
(type (;14;) (func (result 12)))
(type (;15;) s32)
(type (;16;) (tuple 15))
(type (;17;) (func (param "e" 16) (result s32)))
(export "tuple-arg" (type 1))
(export "tuple-result" (type 2))
(export "empty" (type 3))
(export "empty-arg" (type 4))
(export "empty-result" (type 5))
(export "scalars" (type 6))
(export "scalar-arg" (type 7))
(export "scalar-result" (type 8))
(export "really-flags" (type 9))
(export "flags-arg" (type 10))
(export "flags-result" (type 11))
(export "aggregates" (type 12))
(export "aggregate-arg" (type 13))
(export "aggregate-result" (type 14))
(export "int-typedef" (type 15))
(export "tuple-typedef2" (type 16))
(export "typedef-inout" (type 17))
)

View File

@@ -0,0 +1,54 @@
record empty {
}
record scalars {
a: u32,
b: u32,
}
flags really-flags {
a,
b,
c,
d,
e,
f,
g,
h,
i,
}
record aggregates {
a: scalars,
b: u32,
c: empty,
d: string,
e: really-flags,
}
type int-typedef = s32
type tuple-typedef2 = tuple<int-typedef>
tuple-arg: func(x: tuple<char, u32>)
tuple-result: func() -> tuple<char, u32>
empty-arg: func(x: empty)
empty-result: func() -> empty
scalar-arg: func(x: scalars)
scalar-result: func() -> scalars
flags-arg: func(x: really-flags)
flags-result: func() -> really-flags
aggregate-arg: func(x: aggregates)
aggregate-result: func() -> aggregates
typedef-inout: func(e: tuple-typedef2) -> s32

View File

@@ -0,0 +1,92 @@
(component
(type (;0;) (enum "a"))
(type (;1;) (func (param "x" 0)))
(type (;2;) (func (result 0)))
(type (;3;) (union u32 float32))
(type (;4;) (func (param "x" 3)))
(type (;5;) (func (result 3)))
(type (;6;) (record))
(type (;7;) (variant (case $c0 "a" unit) (case $c1 "b" 3) (case $c2 "c" 0) (case $c3 "d" string) (case $c4 "e" 6) (case $c5 "f" unit) (case $c6 "g" u32)))
(type (;8;) (func (param "x" 7)))
(type (;9;) (func (result 7)))
(type (;10;) (func (param "x" bool)))
(type (;11;) (func (result bool)))
(type (;12;) (option bool))
(type (;13;) (tuple))
(type (;14;) (option 13))
(type (;15;) (option u32))
(type (;16;) (option 0))
(type (;17;) (option float32))
(type (;18;) (option 3))
(type (;19;) (option 12))
(type (;20;) (func (param "a" 12) (param "b" 14) (param "c" 15) (param "d" 16) (param "e" 17) (param "f" 18) (param "g" 19)))
(type (;21;) (tuple 12 14 15 16 17 18 19))
(type (;22;) (func (result 21)))
(type (;23;) (variant (case $c0 "a" s32) (case $c1 "b" float32)))
(type (;24;) (variant (case $c0 "a" float64) (case $c1 "b" float32)))
(type (;25;) (variant (case $c0 "a" float64) (case $c1 "b" u64)))
(type (;26;) (variant (case $c0 "a" u32) (case $c1 "b" s64)))
(type (;27;) (variant (case $c0 "a" float32) (case $c1 "b" s64)))
(type (;28;) (tuple float32 u32))
(type (;29;) (tuple u32 u32))
(type (;30;) (variant (case $c0 "a" 28) (case $c1 "b" 29)))
(type (;31;) (tuple 23 24 25 26 27 30))
(type (;32;) (func (param "a" 23) (param "b" 24) (param "c" 25) (param "d" 26) (param "e" 27) (param "f" 30) (result 31)))
(type (;33;) (expected unit unit))
(type (;34;) (expected unit 0))
(type (;35;) (expected 0 unit))
(type (;36;) (expected 13 13))
(type (;37;) (expected u32 7))
(type (;38;) (list u8))
(type (;39;) (expected string 38))
(type (;40;) (func (param "a" 33) (param "b" 34) (param "c" 35) (param "d" 36) (param "e" 37) (param "f" 39)))
(type (;41;) (tuple 33 34 35 36 37 39))
(type (;42;) (func (result 41)))
(type (;43;) (enum "bad1" "bad2"))
(type (;44;) (expected s32 43))
(type (;45;) (func (result 44)))
(type (;46;) (expected unit 43))
(type (;47;) (func (result 46)))
(type (;48;) (expected 43 43))
(type (;49;) (func (result 48)))
(type (;50;) (tuple s32 u32))
(type (;51;) (expected 50 43))
(type (;52;) (func (result 51)))
(type (;53;) (option s32))
(type (;54;) (func (result 53)))
(type (;55;) (option 43))
(type (;56;) (func (result 55)))
(type (;57;) (expected u32 s32))
(type (;58;) (func (result 57)))
(export "e1" (type 0))
(export "e1-arg" (type 1))
(export "e1-result" (type 2))
(export "u1" (type 3))
(export "u1-arg" (type 4))
(export "u1-result" (type 5))
(export "empty" (type 6))
(export "v1" (type 7))
(export "v1-arg" (type 8))
(export "v1-result" (type 9))
(export "bool-arg" (type 10))
(export "bool-result" (type 11))
(export "option-arg" (type 20))
(export "option-result" (type 22))
(export "casts1" (type 23))
(export "casts2" (type 24))
(export "casts3" (type 25))
(export "casts4" (type 26))
(export "casts5" (type 27))
(export "casts6" (type 30))
(export "casts" (type 32))
(export "expected-arg" (type 40))
(export "expected-result" (type 42))
(export "my-errno" (type 43))
(export "return-expected-sugar" (type 45))
(export "return-expected-sugar2" (type 47))
(export "return-expected-sugar3" (type 49))
(export "return-expected-sugar4" (type 52))
(export "return-option-sugar" (type 54))
(export "return-option-sugar2" (type 56))
(export "expected-simple" (type 58))
)

View File

@@ -0,0 +1,97 @@
enum e1 {
a,
}
union u1 {
u32,
float32,
}
record empty {
}
variant v1 {
a,
b(u1),
c(e1),
d(string),
e(empty),
f,
g(u32),
}
variant casts1 {
a(s32),
b(float32),
}
variant casts2 {
a(float64),
b(float32),
}
variant casts3 {
a(float64),
b(u64),
}
variant casts4 {
a(u32),
b(s64),
}
variant casts5 {
a(float32),
b(s64),
}
variant casts6 {
a(tuple<float32, u32>),
b(tuple<u32, u32>),
}
enum my-errno {
bad1,
bad2,
}
e1-arg: func(x: e1)
e1-result: func() -> e1
u1-arg: func(x: u1)
u1-result: func() -> u1
v1-arg: func(x: v1)
v1-result: func() -> v1
bool-arg: func(x: bool)
bool-result: func() -> bool
option-arg: func(a: option<bool>, b: option<tuple<>>, c: option<u32>, d: option<e1>, e: option<float32>, f: option<u1>, g: option<option<bool>>)
option-result: func() -> tuple<option<bool>, option<tuple<>>, option<u32>, option<e1>, option<float32>, option<u1>, option<option<bool>>>
casts: func(a: casts1, b: casts2, c: casts3, d: casts4, e: casts5, f: casts6) -> tuple<casts1, casts2, casts3, casts4, casts5, casts6>
expected-arg: func(a: expected<unit, unit>, b: expected<unit, e1>, c: expected<e1, unit>, d: expected<tuple<>, tuple<>>, e: expected<u32, v1>, f: expected<string, list<u8>>)
expected-result: func() -> tuple<expected<unit, unit>, expected<unit, e1>, expected<e1, unit>, expected<tuple<>, tuple<>>, expected<u32, v1>, expected<string, list<u8>>>
return-expected-sugar: func() -> expected<s32, my-errno>
return-expected-sugar2: func() -> expected<unit, my-errno>
return-expected-sugar3: func() -> expected<my-errno, my-errno>
return-expected-sugar4: func() -> expected<tuple<s32, u32>, my-errno>
return-option-sugar: func() -> option<s32>
return-option-sugar2: func() -> option<my-errno>
expected-simple: func() -> expected<u32, s32>

View File

@@ -0,0 +1,63 @@
use anyhow::{Context, Result};
use pretty_assertions::assert_eq;
use std::fs;
use wit_component::{decode_interface_component, InterfaceEncoder, InterfacePrinter};
use wit_parser::Interface;
/// Tests the the roundtrip encoding of individual interface files.
///
/// This test looks in the `interfaces/` directory for test cases.
///
/// Each test case is a directory containing a `<testcase>.wit` file.
///
/// The test encodes the wit file, decodes the resulting bytes, and
/// compares the generated interface definition to the original interface
/// definition.
///
/// Run the test with the environment variable `BLESS` set to update
/// the wit file based on the decoded output.
#[test]
fn roundtrip_interfaces() -> Result<()> {
for entry in fs::read_dir("tests/interfaces")? {
let path = entry?.path();
if !path.is_dir() {
continue;
}
let test_case = path.file_stem().unwrap().to_str().unwrap();
let wit_path = path.join(test_case).with_extension("wit");
let interface = Interface::parse_file(&wit_path).context("failed to parse `wit` file")?;
let encoder = InterfaceEncoder::new(&interface).validate(true);
let bytes = encoder.encode().with_context(|| {
format!(
"failed to encode a component from interface `{}` for test case `{}`",
path.display(),
test_case,
)
})?;
let interface = decode_interface_component(&bytes).context("failed to decode bytes")?;
let mut printer = InterfacePrinter::default();
let output = printer
.print(&interface)
.context("failed to print interface")?;
if std::env::var_os("BLESS").is_some() {
fs::write(&wit_path, output)?;
} else {
assert_eq!(
fs::read_to_string(&wit_path)?.replace("\r\n", "\n"),
output,
"encoding of wit file `{}` did not match the the decoded interface for test case `{}`",
wit_path.display(),
test_case,
);
}
}
Ok(())
}