test(interface-types) Fix all tests based on previous commits.

This commit is contained in:
Ivan Enderlin 2020-02-26 15:32:14 +01:00
parent f9ef4a650b
commit d4c01e8ddc
6 changed files with 413 additions and 782 deletions

View File

@ -83,16 +83,6 @@ pub struct Export<'input> {
pub function_type: u32,
}
/// Represents an implementation.
#[derive(PartialEq, Debug)]
pub struct Implementation {
/// The core function type.
pub core_function_type: u32,
/// The adapter function type.
pub adapter_function_type: u32,
}
/// Represents an adapter.
#[derive(PartialEq, Debug)]
pub struct Adapter<'input> {
@ -103,6 +93,16 @@ pub struct Adapter<'input> {
pub instructions: Vec<Instruction<'input>>,
}
/// Represents an implementation.
#[derive(PartialEq, Debug)]
pub struct Implementation {
/// The core function type.
pub core_function_type: u32,
/// The adapter function type.
pub adapter_function_type: u32,
}
/// Represents the kind of interface.
#[derive(PartialEq, Debug)]
pub(crate) enum InterfaceKind {

View File

@ -376,41 +376,43 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>(
) -> IResult<&'input [u8], Interfaces, E> {
let mut input = bytes;
consume!((input, interface_kind) = byte(input)?);
let interface_kind = InterfaceKind::try_from(interface_kind)
.map_err(|_| Err::Error(make_error(input, ErrorKind::ParseTo)))?;
let mut all_types = vec![];
let mut all_imports = vec![];
let mut all_adapters = vec![];
let mut all_exports = vec![];
let mut all_implementations = vec![];
match interface_kind {
InterfaceKind::Type => {
consume!((input, mut new_types) = types(input)?);
all_types.append(&mut new_types);
}
while !input.is_empty() {
consume!((input, interface_kind) = byte(input)?);
InterfaceKind::Import => {
consume!((input, mut new_imports) = imports(input)?);
all_imports.append(&mut new_imports);
}
let interface_kind = InterfaceKind::try_from(interface_kind)
.map_err(|_| Err::Error(make_error(input, ErrorKind::ParseTo)))?;
InterfaceKind::Adapter => {
consume!((input, mut new_adapters) = adapters(input)?);
all_adapters.append(&mut new_adapters);
}
match interface_kind {
InterfaceKind::Type => {
consume!((input, mut new_types) = types(input)?);
all_types.append(&mut new_types);
}
InterfaceKind::Export => {
consume!((input, mut new_exports) = exports(input)?);
all_exports.append(&mut new_exports);
}
InterfaceKind::Import => {
consume!((input, mut new_imports) = imports(input)?);
all_imports.append(&mut new_imports);
}
InterfaceKind::Implementation => {
consume!((input, mut new_implementations) = implementations(input)?);
all_implementations.append(&mut new_implementations)
InterfaceKind::Adapter => {
consume!((input, mut new_adapters) = adapters(input)?);
all_adapters.append(&mut new_adapters);
}
InterfaceKind::Export => {
consume!((input, mut new_exports) = exports(input)?);
all_exports.append(&mut new_exports);
}
InterfaceKind::Implementation => {
consume!((input, mut new_implementations) = implementations(input)?);
all_implementations.append(&mut new_implementations)
}
}
}
@ -441,66 +443,62 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>(
///
/// # fn main() {
/// let input = &[
/// 0x00, // type section
/// 0x01, // 1 type
/// 0x01, // list of 1 item
/// 0x00, // S8
/// 0x01, // list of 1 item
/// 0x01, // S16
/// //
/// 0x01, // import section
/// 0x01, // 1 import
/// 0x02, // string of 2 bytes
/// 0x61, 0x62, // "a", "b"
/// 0x01, // string of 1 byte
/// 0x63, // "c"
/// 0x00, // signature type
/// //
/// 0x02, // adapter section
/// 0x01, // 1 adapter
/// 0x00, // function type
/// 0x01, // list of 1 item
/// 0x00, 0x01, // ArgumentGet { index: 1 }
/// //
/// 0x03, // export section
/// 0x01, // 1 export
/// 0x02, // string of 2 bytes
/// 0x61, 0x62, // "a", "b"
/// 0x01, // list of 1 item
/// 0x02, // S32
/// 0x01, // list of 1 item
/// 0x02, // S32
/// 0x01, // 1 type
/// 0x02, // list of 2 items
/// 0x02, // S32
/// 0x02, // S32
/// 0x01, // list of 1 item
/// 0x02, // S32
/// 0x01, // 1 import
/// 0x01, // string of 1 byte
/// 0x61, // "a"
/// 0x01, // string of 1 byte
/// 0x62, // "b"
/// 0x01, // list of 1 item
/// 0x02, // S32
/// 0x01, // list of 1 item
/// 0x03, // S64
/// 0x01, // 1 adapter
/// 0x00, // adapter kind: import
/// 0x01, // string of 1 byte
/// 0x61, // "a"
/// 0x01, // string of 1 byte
/// 0x62, // "b"
/// 0x01, // list of 1 item
/// 0x02, // S32
/// 0x01, // list of 1 item
/// 0x02, // S32
/// 0x01, // list of 1 item
/// 0x00, 0x01, // ArgumentGet { index: 1 }
/// 0x01, // function type
/// //
/// 0x04, // implementation section
/// 0x01, // 1 implementation
/// 0x02, // core function type
/// 0x03, // adapter function type
/// ];
/// let output = Ok((
/// &[] as &[u8],
/// Interfaces {
/// exports: vec![Export {
/// name: "ab",
/// input_types: vec![InterfaceType::S32],
/// output_types: vec![InterfaceType::S32],
/// }],
/// types: vec![Type {
/// inputs: vec![InterfaceType::S32, InterfaceType::S32],
/// outputs: vec![InterfaceType::S32],
/// inputs: vec![InterfaceType::S8],
/// outputs: vec![InterfaceType::S16],
/// }],
/// imports: vec![Import {
/// namespace: "a",
/// name: "b",
/// input_types: vec![InterfaceType::S32],
/// output_types: vec![InterfaceType::S64],
/// namespace: "ab",
/// name: "c",
/// signature_type: 0,
/// }],
/// adapters: vec![Adapter::Import {
/// namespace: "a",
/// name: "b",
/// input_types: vec![InterfaceType::S32],
/// output_types: vec![InterfaceType::S32],
/// adapters: vec![Adapter {
/// function_type: 0,
/// instructions: vec![Instruction::ArgumentGet { index: 1 }],
/// }],
/// exports: vec![Export {
/// name: "ab",
/// function_type: 1,
/// }],
/// implementations: vec![Implementation {
/// core_function_type: 2,
/// adapter_function_type: 3,
/// }],
/// },
/// ));
///
@ -727,27 +725,21 @@ mod tests {
0x02, // 2 exports
0x02, // string of 2 bytes
0x61, 0x62, // "a", "b"
0x01, // list of 1 item
0x00, // S8
0x01, // list of 1 item
0x00, // S8
0x01, // function type
0x02, // string of 2 bytes
0x63, 0x64, // "c", "d"
0x00, // list of 0 item
0x00, // list of 0 item
0x02, // function type
];
let output = Ok((
&[] as &[u8],
vec![
Export {
name: "ab",
input_types: vec![InterfaceType::S8],
output_types: vec![InterfaceType::S8],
function_type: 1,
},
Export {
name: "cd",
input_types: vec![],
output_types: vec![],
function_type: 2,
},
],
));
@ -784,18 +776,12 @@ mod tests {
0x61, // "a"
0x01, // string of 1 byte
0x62, // "b"
0x01, // list of 1 item
0x02, // S32
0x01, // list of 1 item
0x03, // S64
0x01, // signature type
0x01, // string of 1 byte
0x63, // "c"
0x01, // string of 1 byte
0x64, // "d"
0x01, // list of 1 item
0x02, // S32
0x01, // list of 1 item
0x03, // S64
0x02, // signature type
];
let output = Ok((
&[] as &[u8],
@ -803,14 +789,12 @@ mod tests {
Import {
namespace: "a",
name: "b",
input_types: vec![InterfaceType::S32],
output_types: vec![InterfaceType::S64],
signature_type: 1,
},
Import {
namespace: "c",
name: "d",
input_types: vec![InterfaceType::S32],
output_types: vec![InterfaceType::S64],
signature_type: 2,
},
],
));
@ -870,67 +854,62 @@ mod tests {
#[test]
fn test_parse() {
let input = &[
0x00, // type section
0x01, // 1 type
0x01, // list of 1 item
0x00, // S8
0x01, // list of 1 item
0x01, // S16
//
0x01, // import section
0x01, // 1 import
0x02, // string of 2 bytes
0x61, 0x62, // "a", "b"
0x01, // string of 1 byte
0x63, // "c"
0x00, // signature type
//
0x02, // adapter section
0x01, // 1 adapter
0x00, // function type
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
//
0x03, // export section
0x01, // 1 export
0x02, // string of 2 bytes
0x61, 0x62, // "a", "b"
0x01, // list of 1 item
0x0c, // I32
0x01, // list of 1 item
0x0c, // I32
0x01, // 1 type
0x02, // list of 2 items
0x0c, // I32
0x0c, // I32
0x00, // list of 0 item
0x01, // 1 import
0x01, // string of 1 byte
0x61, // "a"
0x01, // string of 1 byte
0x62, // "b"
0x01, // list of 1 item
0x0c, // I32
0x01, // list of 1 item
0x0d, // I64
/*
0x01, // 1 adapter
0x00, // adapter kind: import
0x01, // string of 1 byte
0x61, // "a"
0x01, // string of 1 byte
0x62, // "b"
0x01, // list of 1 item
0x0c, // I32
0x01, // list of 1 item
0x0c, // I32
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
*/
0x01, // function type
//
0x04, // implementation section
0x01, // 1 implementation
0x02, // core function type
0x03, // adapter function type
];
let output = Ok((
&[] as &[u8],
Interfaces {
exports: vec![Export {
name: "ab",
input_types: vec![InterfaceType::I32],
output_types: vec![InterfaceType::I32],
}],
types: vec![Type {
inputs: vec![InterfaceType::I32, InterfaceType::I32],
outputs: vec![],
inputs: vec![InterfaceType::S8],
outputs: vec![InterfaceType::S16],
}],
imports: vec![Import {
namespace: "a",
name: "b",
input_types: vec![InterfaceType::I32],
output_types: vec![InterfaceType::I64],
namespace: "ab",
name: "c",
signature_type: 0,
}],
adapters: vec![/*Adapter::Import {
namespace: "a",
name: "b",
input_types: vec![InterfaceType::I32],
output_types: vec![InterfaceType::I32],
adapters: vec![Adapter {
function_type: 0,
instructions: vec![Instruction::ArgumentGet { index: 1 }],
}*/],
}],
exports: vec![Export {
name: "ab",
function_type: 1,
}],
implementations: vec![Implementation {
core_function_type: 2,
adapter_function_type: 3,
}],
},
));

View File

@ -470,67 +470,39 @@ impl<'a> Parse<'a> for Interfaces<'a> {
///
/// # fn main() {
/// let input = Buffer::new(
/// r#"(@interface export "foo"
/// (param i32))
/// r#"(@interface type (func (param i32) (result s8)))
///
/// (@interface export "bar")
/// (@interface import "ns" "foo" (func (type 0)))
///
/// (@interface func $ns_foo (import "ns" "foo")
/// (result i32))
/// (@interface func (type 0) arg.get 42)
///
/// (@interface func $ns_bar (import "ns" "bar"))
/// (@interface export "bar" (func 0))
///
/// (@interface adapt (import "ns" "foo")
/// (param i32)
/// arg.get 42)
///
/// (@interface adapt (export "bar")
/// arg.get 42)"#,
/// (@interface implement (func 0) (func 1))"#,
/// )
/// .unwrap();
/// let output = Interfaces {
/// exports: vec![
/// Export {
/// name: "foo",
/// input_types: vec![InterfaceType::I32],
/// output_types: vec![],
/// },
/// Export {
/// name: "bar",
/// input_types: vec![],
/// output_types: vec![],
/// },
/// ],
/// types: vec![],
/// imports: vec![
/// Import {
/// namespace: "ns",
/// name: "foo",
/// input_types: vec![],
/// output_types: vec![InterfaceType::I32],
/// },
/// Import {
/// namespace: "ns",
/// name: "bar",
/// input_types: vec![],
/// output_types: vec![],
/// },
/// ],
/// adapters: vec![
/// Adapter::Import {
/// namespace: "ns",
/// name: "foo",
/// input_types: vec![InterfaceType::I32],
/// output_types: vec![],
/// instructions: vec![Instruction::ArgumentGet { index: 42 }],
/// },
/// Adapter::Export {
/// name: "bar",
/// input_types: vec![],
/// output_types: vec![],
/// instructions: vec![Instruction::ArgumentGet { index: 42 }],
/// },
/// ],
/// types: vec![Type {
/// inputs: vec![InterfaceType::I32],
/// outputs: vec![InterfaceType::S8],
/// }],
/// imports: vec![Import {
/// namespace: "ns",
/// name: "foo",
/// signature_type: 0,
/// }],
/// adapters: vec![Adapter {
/// function_type: 0,
/// instructions: vec![Instruction::ArgumentGet { index: 42 }],
/// }],
/// exports: vec![Export {
/// name: "bar",
/// function_type: 0,
/// }],
/// implementations: vec![Implementation {
/// core_function_type: 0,
/// adapter_function_type: 1,
/// }],
/// };
///
/// assert_eq!(parse(&input).unwrap(), output);
@ -685,48 +657,11 @@ mod tests {
}
#[test]
fn test_export_with_no_param_no_result() {
let input = buffer(r#"(@interface export "foo")"#);
fn test_export() {
let input = buffer(r#"(@interface export "foo" (func 0))"#);
let output = Interface::Export(Export {
name: "foo",
input_types: vec![],
output_types: vec![],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_export_with_some_param_no_result() {
let input = buffer(r#"(@interface export "foo" (param i32))"#);
let output = Interface::Export(Export {
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_export_with_no_param_some_result() {
let input = buffer(r#"(@interface export "foo" (result i32))"#);
let output = Interface::Export(Export {
name: "foo",
input_types: vec![],
output_types: vec![InterfaceType::I32],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_export_with_some_param_some_result() {
let input = buffer(r#"(@interface export "foo" (param string) (result i32 i32))"#);
let output = Interface::Export(Export {
name: "foo",
input_types: vec![InterfaceType::String],
output_types: vec![InterfaceType::I32, InterfaceType::I32],
function_type: 0,
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
@ -734,93 +669,44 @@ mod tests {
#[test]
fn test_export_escaped_name() {
let input = buffer(r#"(@interface export "fo\"o")"#);
let input = buffer(r#"(@interface export "fo\"o" (func 0))"#);
let output = Interface::Export(Export {
name: r#"fo"o"#,
input_types: vec![],
output_types: vec![],
function_type: 0,
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_import_with_no_param_no_result() {
let input = buffer(r#"(@interface func $ns_foo (import "ns" "foo"))"#);
fn test_import() {
let input = buffer(r#"(@interface import "ns" "foo" (func (type 0)))"#);
let output = Interface::Import(Import {
namespace: "ns",
name: "foo",
input_types: vec![],
output_types: vec![],
signature_type: 0,
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_import_with_some_param_no_result() {
let input = buffer(r#"(@interface func $ns_foo (import "ns" "foo") (param i32))"#);
let output = Interface::Import(Import {
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
fn test_adapter() {
let input = buffer(r#"(@interface func (type 0) arg.get 42)"#);
let output = Interface::Adapter(Adapter {
function_type: 0,
instructions: vec![Instruction::ArgumentGet { index: 42 }],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_import_with_no_param_some_result() {
let input = buffer(r#"(@interface func $ns_foo (import "ns" "foo") (result i32))"#);
let output = Interface::Import(Import {
namespace: "ns",
name: "foo",
input_types: vec![],
output_types: vec![InterfaceType::I32],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_import_with_some_param_some_result() {
let input = buffer(
r#"(@interface func $ns_foo (import "ns" "foo") (param string) (result i32 i32))"#,
);
let output = Interface::Import(Import {
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::String],
output_types: vec![InterfaceType::I32, InterfaceType::I32],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_adapter_import() {
let input =
buffer(r#"(@interface adapt (import "ns" "foo") (param i32 i32) (result i32))"#);
let output = Interface::Adapter(Adapter::Import {
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::I32, InterfaceType::I32],
output_types: vec![InterfaceType::I32],
instructions: vec![],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_adapter_export() {
let input = buffer(r#"(@interface adapt (export "foo") (param i32 i32) (result i32))"#);
let output = Interface::Adapter(Adapter::Export {
name: "foo",
input_types: vec![InterfaceType::I32, InterfaceType::I32],
output_types: vec![InterfaceType::I32],
instructions: vec![],
fn test_implementation() {
let input = buffer(r#"(@interface implement (func 0) (func 1))"#);
let output = Interface::Implementation(Implementation {
core_function_type: 0,
adapter_function_type: 1,
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
@ -829,66 +715,38 @@ mod tests {
#[test]
fn test_interfaces() {
let input = buffer(
r#"(@interface export "foo"
(param i32))
r#"(@interface type (func (param i32) (result s8)))
(@interface export "bar")
(@interface import "ns" "foo" (func (type 0)))
(@interface func $ns_foo (import "ns" "foo")
(result i32))
(@interface func (type 0) arg.get 42)
(@interface func $ns_bar (import "ns" "bar"))
(@interface export "bar" (func 0))
(@interface adapt (import "ns" "foo")
(param i32)
arg.get 42)
(@interface adapt (export "bar")
arg.get 42)"#,
(@interface implement (func 0) (func 1))"#,
);
let output = Interfaces {
exports: vec![
Export {
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
},
Export {
name: "bar",
input_types: vec![],
output_types: vec![],
},
],
types: vec![],
imports: vec![
Import {
namespace: "ns",
name: "foo",
input_types: vec![],
output_types: vec![InterfaceType::I32],
},
Import {
namespace: "ns",
name: "bar",
input_types: vec![],
output_types: vec![],
},
],
adapters: vec![
Adapter::Import {
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
instructions: vec![Instruction::ArgumentGet { index: 42 }],
},
Adapter::Export {
name: "bar",
input_types: vec![],
output_types: vec![],
instructions: vec![Instruction::ArgumentGet { index: 42 }],
},
],
types: vec![Type {
inputs: vec![InterfaceType::I32],
outputs: vec![InterfaceType::S8],
}],
imports: vec![Import {
namespace: "ns",
name: "foo",
signature_type: 0,
}],
adapters: vec![Adapter {
function_type: 0,
instructions: vec![Instruction::ArgumentGet { index: 42 }],
}],
exports: vec![Export {
name: "bar",
function_type: 0,
}],
implementations: vec![Implementation {
core_function_type: 0,
adapter_function_type: 1,
}],
};
assert_eq!(parser::parse::<Interfaces>(&input).unwrap(), output);

View File

@ -237,8 +237,6 @@ where
self.implementations.to_bytes(writer)?;
}
//self.adapters.to_bytes(writer)?;
Ok(())
}
}
@ -448,7 +446,7 @@ mod tests {
fn test_interface_kind() {
assert_to_bytes!(InterfaceKind::Type, &[0x00]);
assert_to_bytes!(InterfaceKind::Import, &[0x01]);
assert_to_bytes!(InterfaceKind::Function, &[0x02]);
assert_to_bytes!(InterfaceKind::Adapter, &[0x02]);
assert_to_bytes!(InterfaceKind::Export, &[0x03]);
assert_to_bytes!(InterfaceKind::Implementation, &[0x04]);
}
@ -458,19 +456,14 @@ mod tests {
assert_to_bytes!(
Export {
name: "abc",
input_types: vec![InterfaceType::I32, InterfaceType::I64],
output_types: vec![InterfaceType::I32]
function_type: 0,
},
&[
0x03, // string of length 3
0x61, // "a"
0x62, // "b"
0x63, // "c"
0x02, // list of 2 items
0x0c, // I32
0x0d, // I64
0x01, // list of 1 items
0x0c, // I32
0x00, // function type
]
);
}
@ -498,68 +491,27 @@ mod tests {
Import {
namespace: "a",
name: "b",
input_types: vec![InterfaceType::I32, InterfaceType::I64],
output_types: vec![InterfaceType::I32],
signature_type: 0,
},
&[
0x01, // string of length 1
0x61, // "a"
0x01, // string of length 1
0x62, // "b"
0x02, // list of 2 items
0x0c, // I32
0x0d, // I64
0x01, // list of 1 items
0x0c, // I32
0x00, // signature typr
]
);
}
#[test]
fn test_adapter_import() {
fn test_adapter() {
assert_to_bytes!(
Adapter::Import {
namespace: "a",
name: "b",
input_types: vec![InterfaceType::I32, InterfaceType::I64],
output_types: vec![InterfaceType::I32],
Adapter {
function_type: 0,
instructions: vec![Instruction::ArgumentGet { index: 1 }],
},
&[
0x01, // InterfaceKind::Import
0x01, // string of length 1
0x61, // "a"
0x01, // string of length 1
0x62, // "b"
0x02, // list of 2 items
0x0c, // I32
0x0d, // I64
0x01, // list of 1 items
0x0c, // I32
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
]
);
}
#[test]
fn test_adapter_export() {
assert_to_bytes!(
Adapter::Export {
name: "a",
input_types: vec![InterfaceType::I32, InterfaceType::I64],
output_types: vec![InterfaceType::I32],
instructions: vec![Instruction::ArgumentGet { index: 1 }],
},
&[
0x03, // InterfaceKind::Export
0x01, // string of length 1
0x61, // "a"
0x02, // list of 2 items
0x0c, // I32
0x0d, // I64
0x01, // list of 1 items
0x0c, // I32
0x00, // function type
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
]
@ -570,64 +522,60 @@ mod tests {
fn test_interfaces() {
assert_to_bytes!(
Interfaces {
exports: vec![Export {
name: "ab",
input_types: vec![InterfaceType::I32],
output_types: vec![InterfaceType::I32],
}],
types: vec![Type {
inputs: vec![InterfaceType::I32, InterfaceType::I32],
outputs: vec![InterfaceType::S32],
inputs: vec![InterfaceType::S8],
outputs: vec![InterfaceType::S16],
}],
imports: vec![Import {
namespace: "a",
name: "b",
input_types: vec![InterfaceType::I32],
output_types: vec![InterfaceType::I64],
namespace: "ab",
name: "c",
signature_type: 0,
}],
adapters: vec![Adapter::Import {
namespace: "a",
name: "b",
input_types: vec![InterfaceType::I32],
output_types: vec![InterfaceType::I32],
adapters: vec![Adapter {
function_type: 0,
instructions: vec![Instruction::ArgumentGet { index: 1 }],
}],
exports: vec![Export {
name: "ab",
function_type: 1,
}],
implementations: vec![Implementation {
core_function_type: 2,
adapter_function_type: 3,
}],
},
&[
0x00, // type section
0x01, // 1 type
0x01, // list of 1 item
0x00, // S8
0x01, // list of 1 item
0x01, // S16
//
0x01, // import section
0x01, // 1 import
0x02, // string of 2 bytes
0x61, 0x62, // "a", "b"
0x01, // string of 1 byte
0x63, // "c"
0x00, // signature type
//
0x02, // adapter section
0x01, // 1 adapter
0x00, // function type
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
//
0x03, // export section
0x01, // 1 export
0x02, // string of 2 bytes
0x61, 0x62, // "a", "b"
0x01, // list of 1 item
0x0c, // I32
0x01, // list of 1 item
0x0c, // I32
0x01, // 1 type
0x02, // list of 2 items
0x0c, // I32
0x0c, // I32
0x01, // list of 1 item
0x02, // S32
0x01, // 1 import
0x01, // string of 1 byte
0x61, // "a"
0x01, // string of 1 byte
0x62, // "b"
0x01, // list of 1 item
0x0c, // I32
0x01, // list of 1 item
0x0d, // I64
0x01, // 1 adapter
0x00, // adapter kind: import
0x01, // string of 1 byte
0x61, // "a"
0x01, // string of 1 byte
0x62, // "b"
0x01, // list of 1 item
0x0c, // I32
0x01, // list of 1 item
0x0c, // I32
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
0x01, // function type
//
0x04, // implementation section
0x01, // 1 implementation
0x02, // core function type
0x03, // adapter function type
]
);
}

View File

@ -11,74 +11,46 @@
//!
//! # fn main() {
//! let input: String = (&Interfaces {
//! exports: vec![
//! Export {
//! name: "foo",
//! input_types: vec![InterfaceType::I32],
//! output_types: vec![],
//! },
//! Export {
//! name: "bar",
//! input_types: vec![],
//! output_types: vec![],
//! },
//! ],
//! types: vec![],
//! imports: vec![
//! Import {
//! namespace: "ns",
//! name: "foo",
//! input_types: vec![],
//! output_types: vec![InterfaceType::I32],
//! },
//! Import {
//! namespace: "ns",
//! name: "bar",
//! input_types: vec![],
//! output_types: vec![],
//! },
//! ],
//! adapters: vec![
//! Adapter::Import {
//! namespace: "ns",
//! name: "foo",
//! input_types: vec![InterfaceType::I32],
//! output_types: vec![],
//! instructions: vec![Instruction::ArgumentGet { index: 42 }],
//! },
//! Adapter::Export {
//! name: "bar",
//! input_types: vec![],
//! output_types: vec![],
//! instructions: vec![Instruction::ArgumentGet { index: 42 }],
//! },
//! ],
//! types: vec![Type {
//! inputs: vec![InterfaceType::I32],
//! outputs: vec![InterfaceType::S8],
//! }],
//! imports: vec![Import {
//! namespace: "ns",
//! name: "foo",
//! signature_type: 0,
//! }],
//! adapters: vec![Adapter {
//! function_type: 0,
//! instructions: vec![Instruction::ArgumentGet { index: 42 }],
//! }],
//! exports: vec![Export {
//! name: "bar",
//! function_type: 0,
//! }],
//! implementations: vec![Implementation {
//! core_function_type: 0,
//! adapter_function_type: 1,
//! }],
//! })
//! .to_string();
//! let output = r#";; Interfaces
//!
//! ;; Interface, Export foo
//! (@interface export "foo"
//! (param i32))
//!
//! ;; Interface, Export bar
//! (@interface export "bar")
//!
//! ;; Interface, Import ns.foo
//! (@interface func $ns_foo (import "ns" "foo")
//! (result i32))
//!
//! ;; Interface, Import ns.bar
//! (@interface func $ns_bar (import "ns" "bar"))
//!
//! ;; Interface, Adapter ns.foo
//! (@interface adapt (import "ns" "foo")
//! let output = r#";; Types
//! (@interface type (func
//! (param i32)
//! (result s8)))
//!
//! ;; Imports
//! (@interface import "ns" "foo" (func (type 0)))
//!
//! ;; Adapters
//! (@interface func (type 0)
//! arg.get 42)
//!
//! ;; Interface, Adapter bar
//! (@interface adapt (export "bar")
//! arg.get 42)"#;
//! ;; Exports
//! (@interface export "bar" (func 0))
//!
//! ;; Implementations
//! (@interface implement (func 0) (func 1))"#;
//!
//! assert_eq!(input, output);
//! # }
@ -261,12 +233,13 @@ impl<'input> ToString for &Implementation {
/// Encode an `Interfaces` into a string.
impl<'input> ToString for &Interfaces<'input> {
fn to_string(&self) -> String {
let mut output = String::from(";; Interfaces");
let mut output = String::new();
let types = self
.types
.iter()
.fold(String::new(), |mut accumulator, ty| {
accumulator.push('\n');
accumulator.push_str(&ty.to_string());
accumulator
});
@ -275,6 +248,7 @@ impl<'input> ToString for &Interfaces<'input> {
.imports
.iter()
.fold(String::new(), |mut accumulator, import| {
accumulator.push('\n');
accumulator.push_str(&import.to_string());
accumulator
});
@ -283,6 +257,7 @@ impl<'input> ToString for &Interfaces<'input> {
.adapters
.iter()
.fold(String::new(), |mut accumulator, adapter| {
accumulator.push('\n');
accumulator.push_str(&adapter.to_string());
accumulator
});
@ -291,6 +266,7 @@ impl<'input> ToString for &Interfaces<'input> {
.exports
.iter()
.fold(String::new(), |mut accumulator, export| {
accumulator.push('\n');
accumulator.push_str(&export.to_string());
accumulator
});
@ -299,15 +275,49 @@ impl<'input> ToString for &Interfaces<'input> {
self.implementations
.iter()
.fold(String::new(), |mut accumulator, implementation| {
accumulator.push('\n');
accumulator.push_str(&implementation.to_string());
accumulator
});
output.push_str(&types);
output.push_str(&imports);
output.push_str(&adapters);
output.push_str(&exports);
output.push_str(&implementations);
let separator = |output: &mut String| {
if !output.is_empty() {
output.push_str("\n\n");
}
};
if !types.is_empty() {
output.push_str(";; Types");
output.push_str(&types);
}
separator(&mut output);
if !imports.is_empty() {
output.push_str(";; Imports");
output.push_str(&imports);
}
separator(&mut output);
if !adapters.is_empty() {
output.push_str(";; Adapters");
output.push_str(&adapters);
}
separator(&mut output);
if !exports.is_empty() {
output.push_str(";; Exports");
output.push_str(&exports);
}
separator(&mut output);
if !implementations.is_empty() {
output.push_str(";; Implementations");
output.push_str(&implementations);
}
output
}
@ -436,254 +446,85 @@ mod tests {
#[test]
fn test_exports() {
let inputs: Vec<String> = vec![
(&Export {
name: "foo",
input_types: vec![InterfaceType::I32, InterfaceType::F32],
output_types: vec![InterfaceType::I32],
})
.to_string(),
(&Export {
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
})
.to_string(),
(&Export {
name: "foo",
input_types: vec![],
output_types: vec![InterfaceType::I32],
})
.to_string(),
(&Export {
name: "foo",
input_types: vec![],
output_types: vec![],
})
.to_string(),
];
let outputs = vec![
r#"(@interface export "foo"
(param i32 f32)
(result i32))"#,
r#"(@interface export "foo"
(param i32))"#,
r#"(@interface export "foo"
(result i32))"#,
r#"(@interface export "foo")"#,
];
let input = (&Export {
name: "foo",
function_type: 0,
})
.to_string();
let output = r#"(@interface export "foo" (func 0))"#;
assert_eq!(inputs, outputs);
assert_eq!(input, output);
}
#[test]
fn test_imports() {
let inputs: Vec<String> = vec![
(&Import {
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::I32, InterfaceType::String],
output_types: vec![InterfaceType::String],
})
.to_string(),
(&Import {
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::String],
output_types: vec![],
})
.to_string(),
(&Import {
namespace: "ns",
name: "foo",
input_types: vec![],
output_types: vec![InterfaceType::String],
})
.to_string(),
(&Import {
namespace: "ns",
name: "foo",
input_types: vec![],
output_types: vec![],
})
.to_string(),
];
let outputs = vec![
r#"(@interface func $ns_foo (import "ns" "foo")
(param i32 string)
(result string))"#,
r#"(@interface func $ns_foo (import "ns" "foo")
(param string))"#,
r#"(@interface func $ns_foo (import "ns" "foo")
(result string))"#,
r#"(@interface func $ns_foo (import "ns" "foo"))"#,
];
let input = (&Import {
namespace: "ns",
name: "foo",
signature_type: 0,
})
.to_string();
let output = r#"(@interface import "ns" "foo" (func (type 0)))"#;
assert_eq!(inputs, outputs);
assert_eq!(input, output);
}
#[test]
fn test_adapters() {
let inputs: Vec<String> = vec![
(&Adapter::Import {
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::I32, InterfaceType::F32],
output_types: vec![InterfaceType::I32],
instructions: vec![
Instruction::ArgumentGet { index: 0 },
Instruction::WriteUtf8 {
allocator_name: "hello",
},
Instruction::CallExport { export_name: "f" },
],
})
.to_string(),
(&Adapter::Import {
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
instructions: vec![Instruction::CallExport { export_name: "f" }],
})
.to_string(),
(&Adapter::Import {
namespace: "ns",
name: "foo",
input_types: vec![],
output_types: vec![InterfaceType::I32],
instructions: vec![Instruction::CallExport { export_name: "f" }],
})
.to_string(),
(&Adapter::Export {
name: "foo",
input_types: vec![InterfaceType::I32, InterfaceType::F32],
output_types: vec![InterfaceType::I32],
instructions: vec![
Instruction::ArgumentGet { index: 0 },
Instruction::WriteUtf8 {
allocator_name: "hello",
},
Instruction::CallExport { export_name: "f" },
],
})
.to_string(),
(&Adapter::Export {
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
instructions: vec![Instruction::CallExport { export_name: "f" }],
})
.to_string(),
(&Adapter::Export {
name: "foo",
input_types: vec![],
output_types: vec![InterfaceType::I32],
instructions: vec![Instruction::CallExport { export_name: "f" }],
})
.to_string(),
];
let outputs = vec![
r#"(@interface adapt (import "ns" "foo")
(param i32 f32)
(result i32)
arg.get 0
write-utf8 "hello"
call-export "f")"#,
r#"(@interface adapt (import "ns" "foo")
(param i32)
call-export "f")"#,
r#"(@interface adapt (import "ns" "foo")
(result i32)
call-export "f")"#,
r#"(@interface adapt (export "foo")
(param i32 f32)
(result i32)
arg.get 0
write-utf8 "hello"
call-export "f")"#,
r#"(@interface adapt (export "foo")
(param i32)
call-export "f")"#,
r#"(@interface adapt (export "foo")
(result i32)
call-export "f")"#,
];
fn test_adapter() {
let input = (&Adapter {
function_type: 0,
instructions: vec![Instruction::ArgumentGet { index: 42 }],
})
.to_string();
let output = r#"(@interface func (type 0)
arg.get 42)"#;
assert_eq!(inputs, outputs);
assert_eq!(input, output);
}
#[test]
fn test_interfaces() {
let input: String = (&Interfaces {
exports: vec![
Export {
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
},
Export {
name: "bar",
input_types: vec![],
output_types: vec![],
},
],
types: vec![],
imports: vec![
Import {
namespace: "ns",
name: "foo",
input_types: vec![],
output_types: vec![InterfaceType::I32],
},
Import {
namespace: "ns",
name: "bar",
input_types: vec![],
output_types: vec![],
},
],
adapters: vec![
Adapter::Import {
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
instructions: vec![Instruction::ArgumentGet { index: 42 }],
},
Adapter::Export {
name: "bar",
input_types: vec![],
output_types: vec![],
instructions: vec![Instruction::ArgumentGet { index: 42 }],
},
],
types: vec![Type {
inputs: vec![InterfaceType::I32],
outputs: vec![InterfaceType::S8],
}],
imports: vec![Import {
namespace: "ns",
name: "foo",
signature_type: 0,
}],
adapters: vec![Adapter {
function_type: 0,
instructions: vec![Instruction::ArgumentGet { index: 42 }],
}],
exports: vec![Export {
name: "bar",
function_type: 0,
}],
implementations: vec![Implementation {
core_function_type: 0,
adapter_function_type: 1,
}],
})
.to_string();
let output = r#";; Interfaces
;; Interface, Export foo
(@interface export "foo"
(param i32))
;; Interface, Export bar
(@interface export "bar")
;; Interface, Import ns.foo
(@interface func $ns_foo (import "ns" "foo")
(result i32))
;; Interface, Import ns.bar
(@interface func $ns_bar (import "ns" "bar"))
;; Interface, Adapter ns.foo
(@interface adapt (import "ns" "foo")
let output = r#";; Types
(@interface type (func
(param i32)
(result s8)))
;; Imports
(@interface import "ns" "foo" (func (type 0)))
;; Adapters
(@interface func (type 0)
arg.get 42)
;; Interface, Adapter bar
(@interface adapt (export "bar")
arg.get 42)"#;
;; Exports
(@interface export "bar" (func 0))
;; Implementations
(@interface implement (func 0) (func 1))"#;
assert_eq!(input, output);
}

View File

@ -6,28 +6,33 @@ use wasmer_interface_types::{
#[test]
fn test_binary_encoding_decoding_roundtrip() {
let original_ast = Interfaces {
exports: vec![Export {
name: "ab",
input_types: vec![InterfaceType::I32],
output_types: vec![InterfaceType::I32],
}],
types: vec![Type {
inputs: vec![InterfaceType::I32, InterfaceType::I32],
outputs: vec![InterfaceType::S32],
}],
types: vec![
Type {
inputs: vec![],
outputs: vec![],
},
Type {
inputs: vec![InterfaceType::I32, InterfaceType::I32],
outputs: vec![InterfaceType::S32],
},
],
imports: vec![Import {
namespace: "a",
name: "b",
input_types: vec![InterfaceType::I32],
output_types: vec![InterfaceType::I64],
signature_type: 0,
}],
adapters: vec![Adapter::Import {
namespace: "a",
name: "b",
input_types: vec![InterfaceType::I32],
output_types: vec![InterfaceType::I32],
adapters: vec![Adapter {
function_type: 0,
instructions: vec![Instruction::ArgumentGet { index: 1 }],
}],
exports: vec![Export {
name: "ab",
function_type: 1,
}],
implementations: vec![Implementation {
core_function_type: 0,
adapter_function_type: 0,
}],
};
let mut binary = vec![];