feat(interface-types) Update interface types.

According to the last working notes, new interface types are s8, s16,
s32, s64, u8, u16, u32, u64, f32, f64, string, anyref, i32, and i64.

Their binary reprensentations are changing too, from 0x00 to 0x0d.
This commit is contained in:
Ivan Enderlin
2020-02-24 15:37:03 +01:00
parent ad04e07c67
commit ac68325cc9
6 changed files with 357 additions and 272 deletions

View File

@ -7,26 +7,29 @@ use std::str;
/// Represents the types supported by WIT.
#[derive(PartialEq, Debug)]
pub enum InterfaceType {
/// An integer.
Int,
/// A 8-bits signed integer.
S8,
/// A float.
Float,
/// A 16-bits signed integer.
S16,
/// Opaque reference.
Any,
/// A 32-bits signed integer.
S32,
/// A string.
String,
/// A 64-bits signed integer.
S64,
/// A sequence.
Seq,
/// A 8-bits unsigned integer.
U8,
/// A 32-bits integer.
I32,
/// A 16-bits unsigned integer.
U16,
/// A 64-bits integer.
I64,
/// A 32-bits unsigned integer.
U32,
/// A 64-bits unsigned integer.
U64,
/// A 32-bits float.
F32,
@ -34,8 +37,17 @@ pub enum InterfaceType {
/// A 64-bits float.
F64,
/// A stirng.
String,
/// An `any` reference.
AnyRef,
Anyref,
/// A 32-bits integer (as defined in WebAssembly core).
I32,
/// A 64-bits integer (as defiend in WebAssembly core).
I64,
}
/// Represents the kind of adapter.

View File

@ -8,21 +8,25 @@ use nom::{
use std::{convert::TryFrom, str};
/// Parse an `InterfaceType`.
impl TryFrom<u64> for InterfaceType {
impl TryFrom<u8> for InterfaceType {
type Error = &'static str;
fn try_from(code: u64) -> Result<Self, Self::Error> {
fn try_from(code: u8) -> Result<Self, Self::Error> {
Ok(match code {
0x7fff => Self::Int,
0x7ffe => Self::Float,
0x7ffd => Self::Any,
0x7ffc => Self::String,
0x7ffb => Self::Seq,
0x7f => Self::I32,
0x7e => Self::I64,
0x7d => Self::F32,
0x7c => Self::F64,
0x6f => Self::AnyRef,
0 => Self::S8,
1 => Self::S16,
2 => Self::S32,
3 => Self::S64,
4 => Self::U8,
5 => Self::U16,
6 => Self::U32,
7 => Self::U64,
8 => Self::F32,
9 => Self::F64,
10 => Self::String,
11 => Self::Anyref,
12 => Self::I32,
13 => Self::I64,
_ => return Err("Unknown interface type code."),
})
}
@ -133,7 +137,7 @@ fn ty<'input, E: ParseError<&'input [u8]>>(
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
}
let (output, ty) = uleb(input)?;
let (output, ty) = byte(input)?;
match InterfaceType::try_from(ty) {
Ok(ty) => Ok((output, ty)),
@ -450,9 +454,9 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>(
/// 0x02, // string of 2 bytes
/// 0x61, 0x62, // "a", "b"
/// 0x01, // list of 1 item
/// 0x7f, // I32
/// 0x02, // S32
/// 0x01, // list of 1 item
/// 0x7f, // I32
/// 0x02, // S32
/// 0x01, // 1 type
/// 0x02, // string of 2 bytes
/// 0x61, 0x62, // "a", "b"
@ -462,17 +466,17 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>(
/// 0x01, // string of 1 byte
/// 0x65, // "e"
/// 0x02, // list of 2 items
/// 0x7f, // I32
/// 0x7f, // I32
/// 0x02, // S32
/// 0x02, // S32
/// 0x01, // 1 import
/// 0x01, // string of 1 byte
/// 0x61, // "a"
/// 0x01, // string of 1 byte
/// 0x62, // "b"
/// 0x01, // list of 1 item
/// 0x7f, // I32
/// 0x02, // S32
/// 0x01, // list of 1 item
/// 0x7e, // I64
/// 0x03, // S64
/// 0x01, // 1 adapter
/// 0x00, // adapter kind: import
/// 0x01, // string of 1 byte
@ -480,9 +484,9 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>(
/// 0x01, // string of 1 byte
/// 0x62, // "b"
/// 0x01, // list of 1 item
/// 0x7f, // I32
/// 0x02, // S32
/// 0x01, // list of 1 item
/// 0x7f, // I32
/// 0x02, // S32
/// 0x01, // list of 1 item
/// 0x00, 0x01, // ArgumentGet { index: 1 }
/// 0x01, // 1 adapter
@ -494,25 +498,25 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>(
/// Interfaces {
/// exports: vec![Export {
/// name: "ab",
/// input_types: vec![InterfaceType::I32],
/// output_types: vec![InterfaceType::I32],
/// input_types: vec![InterfaceType::S32],
/// output_types: vec![InterfaceType::S32],
/// }],
/// types: vec![Type::new(
/// "ab",
/// vec!["cd", "e"],
/// vec![InterfaceType::I32, InterfaceType::I32],
/// vec![InterfaceType::S32, InterfaceType::S32],
/// )],
/// imports: vec![Import {
/// namespace: "a",
/// name: "b",
/// input_types: vec![InterfaceType::I32],
/// output_types: vec![InterfaceType::I64],
/// input_types: vec![InterfaceType::S32],
/// output_types: vec![InterfaceType::S64],
/// }],
/// adapters: vec![Adapter::Import {
/// namespace: "a",
/// name: "b",
/// input_types: vec![InterfaceType::I32],
/// output_types: vec![InterfaceType::I32],
/// input_types: vec![InterfaceType::S32],
/// output_types: vec![InterfaceType::S32],
/// instructions: vec![Instruction::ArgumentGet { index: 1 }],
/// }],
/// forwards: vec![Forward { name: "a" }],
@ -639,32 +643,40 @@ mod tests {
#[test]
fn test_ty() {
let input = &[
0x0a, // list of 10 items
0xff, 0xff, 0x01, // Int
0xfe, 0xff, 0x01, // Float
0xfd, 0xff, 0x01, // Any
0xfc, 0xff, 0x01, // String
0xfb, 0xff, 0x01, // Seq
0x7f, // I32
0x7e, // I64
0x7d, // F32
0x7c, // F64
0x6f, // AnyRef
0x0e, // list of 14 items
0x00, // S8
0x01, // S16
0x02, // S32
0x03, // S64
0x04, // U8
0x05, // U16
0x06, // U32
0x07, // U64
0x08, // F32
0x09, // F64
0x0a, // String
0x0b, // Anyref
0x0c, // I32
0x0d, // I64
0x01,
];
let output = Ok((
&[0x01][..],
vec![
InterfaceType::Int,
InterfaceType::Float,
InterfaceType::Any,
InterfaceType::String,
InterfaceType::Seq,
InterfaceType::I32,
InterfaceType::I64,
InterfaceType::S8,
InterfaceType::S16,
InterfaceType::S32,
InterfaceType::S64,
InterfaceType::U8,
InterfaceType::U16,
InterfaceType::U32,
InterfaceType::U64,
InterfaceType::F32,
InterfaceType::F64,
InterfaceType::AnyRef,
InterfaceType::String,
InterfaceType::Anyref,
InterfaceType::I32,
InterfaceType::I64,
],
));
@ -680,19 +692,19 @@ mod tests {
0x02, 0x03, 0x61, 0x62, 0x63, // CallExport { export_name: "abc" }
0x03, // ReadUtf8
0x04, 0x03, 0x61, 0x62, 0x63, // WriteUtf8 { allocator_name: "abc" }
0x05, 0xff, 0xff, 0x01, // AsWasm(Int)
0x06, 0x7e, // AsInterface(I64)
0x05, 0x00, // AsWasm(S8)
0x06, 0x00, // AsInterface(S8)
0x07, // TableRefAdd
0x08, // TableRefGet
0x09, 0x01, // CallMethod(1)
0x0a, 0x7f, // MakeRecord(I32)
0x0c, 0xff, 0xff, 0x01, 0x02, // GetField(Int, 2)
0x0d, 0x7f, 0x01, // Const(I32, 1)
0x0a, 0x0c, // MakeRecord(I32)
0x0c, 0x00, 0x02, // GetField(S8, 2)
0x0d, 0x0c, 0x01, // Const(I32, 1)
0x0e, 0x01, // FoldSeq(1)
0x0f, 0x7f, // Add(I32)
0x10, 0x7f, 0x03, 0x61, 0x62, 0x63, // MemToSeq(I32, "abc")
0x11, 0x7f, 0x03, 0x61, 0x62, 0x63, // Load(I32, "abc")
0x12, 0x7f, // SeqNew(I32)
0x0f, 0x00, // Add(I32)
0x10, 0x00, 0x03, 0x61, 0x62, 0x63, // MemToSeq(S8, "abc")
0x11, 0x00, 0x03, 0x61, 0x62, 0x63, // Load(S8, "abc")
0x12, 0x00, // SeqNew(S8)
0x13, // ListPush
0x14, 0x01, 0x02, // RepeatUntil(1, 2)
0x0a,
@ -707,19 +719,19 @@ mod tests {
Instruction::WriteUtf8 {
allocator_name: "abc",
},
Instruction::AsWasm(InterfaceType::Int),
Instruction::AsInterface(InterfaceType::I64),
Instruction::AsWasm(InterfaceType::S8),
Instruction::AsInterface(InterfaceType::S8),
Instruction::TableRefAdd,
Instruction::TableRefGet,
Instruction::CallMethod(1),
Instruction::MakeRecord(InterfaceType::I32),
Instruction::GetField(InterfaceType::Int, 2),
Instruction::GetField(InterfaceType::S8, 2),
Instruction::Const(InterfaceType::I32, 1),
Instruction::FoldSeq(1),
Instruction::Add(InterfaceType::I32),
Instruction::MemToSeq(InterfaceType::I32, "abc"),
Instruction::Load(InterfaceType::I32, "abc"),
Instruction::SeqNew(InterfaceType::I32),
Instruction::Add(InterfaceType::S8),
Instruction::MemToSeq(InterfaceType::S8, "abc"),
Instruction::Load(InterfaceType::S8, "abc"),
Instruction::SeqNew(InterfaceType::S8),
Instruction::ListPush,
Instruction::RepeatUntil(1, 2),
],
@ -735,9 +747,9 @@ mod tests {
0x02, // string of 2 bytes
0x61, 0x62, // "a", "b"
0x01, // list of 1 item
0x7f, // I32
0x00, // S8
0x01, // list of 1 item
0x7f, // I32
0x00, // S8
0x02, // string of 2 bytes
0x63, 0x64, // "c", "d"
0x00, // list of 0 item
@ -748,8 +760,8 @@ mod tests {
vec![
Export {
name: "ab",
input_types: vec![InterfaceType::I32],
output_types: vec![InterfaceType::I32],
input_types: vec![InterfaceType::S8],
output_types: vec![InterfaceType::S8],
},
Export {
name: "cd",
@ -774,15 +786,15 @@ mod tests {
0x01, // string of 1 byte
0x65, // "e"
0x02, // list of 2 items
0x7f, // I32
0x7f, // I32
0x02, // S32
0x02, // S32
];
let output = Ok((
&[] as &[u8],
vec![Type::new(
"ab",
vec!["cd", "e"],
vec![InterfaceType::I32, InterfaceType::I32],
vec![InterfaceType::S32, InterfaceType::S32],
)],
));
@ -798,17 +810,17 @@ mod tests {
0x01, // string of 1 byte
0x62, // "b"
0x01, // list of 1 item
0x7f, // I32
0x02, // S32
0x01, // list of 1 item
0x7e, // I64
0x03, // S64
0x01, // string of 1 byte
0x63, // "c"
0x01, // string of 1 byte
0x64, // "d"
0x01, // list of 1 item
0x7f, // I32
0x02, // S32
0x01, // list of 1 item
0x7e, // I64
0x03, // S64
];
let output = Ok((
&[] as &[u8],
@ -816,14 +828,14 @@ mod tests {
Import {
namespace: "a",
name: "b",
input_types: vec![InterfaceType::I32],
output_types: vec![InterfaceType::I64],
input_types: vec![InterfaceType::S32],
output_types: vec![InterfaceType::S64],
},
Import {
namespace: "c",
name: "d",
input_types: vec![InterfaceType::I32],
output_types: vec![InterfaceType::I64],
input_types: vec![InterfaceType::S32],
output_types: vec![InterfaceType::S64],
},
],
));
@ -841,27 +853,27 @@ mod tests {
0x01, // string of 1 byte
0x62, // "b"
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
0x01, // adapter kind: export
0x01, // string of 1 byte
0x63, // "c"
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
0x02, // adapter kind: helper function
0x01, // string of 1 byte
0x64, // "d"
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
];
@ -917,9 +929,9 @@ mod tests {
0x02, // string of 2 bytes
0x61, 0x62, // "a", "b"
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // 1 type
0x02, // string of 2 bytes
0x61, 0x62, // "a", "b"
@ -929,17 +941,17 @@ mod tests {
0x01, // string of 1 byte
0x65, // "e"
0x02, // list of 2 items
0x7f, // I32
0x7f, // I32
0x0c, // I32
0x0c, // I32
0x01, // 1 import
0x01, // string of 1 byte
0x61, // "a"
0x01, // string of 1 byte
0x62, // "b"
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x7e, // I64
0x0d, // I64
0x01, // 1 adapter
0x00, // adapter kind: import
0x01, // string of 1 byte
@ -947,9 +959,9 @@ mod tests {
0x01, // string of 1 byte
0x62, // "b"
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
0x01, // 1 adapter

View File

@ -18,11 +18,15 @@ mod keyword {
custom_keyword!(forward);
// New types.
custom_keyword!(int);
custom_keyword!(float);
custom_keyword!(any);
custom_keyword!(s8);
custom_keyword!(s16);
custom_keyword!(s32);
custom_keyword!(s64);
custom_keyword!(u8);
custom_keyword!(u16);
custom_keyword!(u32);
custom_keyword!(u64);
custom_keyword!(string);
custom_keyword!(seq);
// Instructions.
custom_keyword!(argument_get = "arg.get");
@ -47,39 +51,42 @@ mod keyword {
custom_keyword!(repeat_until = "repeat-until");
}
/// Issue: Uppercased keyword aren't supported for the moment.
impl Parse<'_> for InterfaceType {
fn parse(parser: Parser<'_>) -> Result<Self> {
let mut lookahead = parser.lookahead1();
if lookahead.peek::<keyword::int>() {
parser.parse::<keyword::int>()?;
if lookahead.peek::<keyword::s8>() {
parser.parse::<keyword::s8>()?;
Ok(InterfaceType::Int)
} else if lookahead.peek::<keyword::float>() {
parser.parse::<keyword::float>()?;
Ok(InterfaceType::S8)
} else if lookahead.peek::<keyword::s16>() {
parser.parse::<keyword::s16>()?;
Ok(InterfaceType::Float)
} else if lookahead.peek::<keyword::any>() {
parser.parse::<keyword::any>()?;
Ok(InterfaceType::S16)
} else if lookahead.peek::<keyword::s32>() {
parser.parse::<keyword::s32>()?;
Ok(InterfaceType::Any)
} else if lookahead.peek::<keyword::string>() {
parser.parse::<keyword::string>()?;
Ok(InterfaceType::S32)
} else if lookahead.peek::<keyword::s64>() {
parser.parse::<keyword::s64>()?;
Ok(InterfaceType::String)
} else if lookahead.peek::<keyword::seq>() {
parser.parse::<keyword::seq>()?;
Ok(InterfaceType::S64)
} else if lookahead.peek::<keyword::u8>() {
parser.parse::<keyword::u8>()?;
Ok(InterfaceType::Seq)
} else if lookahead.peek::<keyword::i32>() {
parser.parse::<keyword::i32>()?;
Ok(InterfaceType::U8)
} else if lookahead.peek::<keyword::u16>() {
parser.parse::<keyword::u16>()?;
Ok(InterfaceType::I32)
} else if lookahead.peek::<keyword::i64>() {
parser.parse::<keyword::i64>()?;
Ok(InterfaceType::U16)
} else if lookahead.peek::<keyword::u32>() {
parser.parse::<keyword::u32>()?;
Ok(InterfaceType::I64)
Ok(InterfaceType::U32)
} else if lookahead.peek::<keyword::u64>() {
parser.parse::<keyword::u64>()?;
Ok(InterfaceType::U64)
} else if lookahead.peek::<keyword::f32>() {
parser.parse::<keyword::f32>()?;
@ -88,10 +95,26 @@ impl Parse<'_> for InterfaceType {
parser.parse::<keyword::f64>()?;
Ok(InterfaceType::F64)
} else if lookahead.peek::<keyword::string>() {
parser.parse::<keyword::string>()?;
Ok(InterfaceType::String)
} else if lookahead.peek::<keyword::string>() {
parser.parse::<keyword::string>()?;
Ok(InterfaceType::String)
} else if lookahead.peek::<keyword::anyref>() {
parser.parse::<keyword::anyref>()?;
Ok(InterfaceType::AnyRef)
Ok(InterfaceType::Anyref)
} else if lookahead.peek::<keyword::i32>() {
parser.parse::<keyword::i32>()?;
Ok(InterfaceType::I32)
} else if lookahead.peek::<keyword::i64>() {
parser.parse::<keyword::i64>()?;
Ok(InterfaceType::I64)
} else {
Err(lookahead.error())
}
@ -464,16 +487,16 @@ impl<'a> Parse<'a> for Interfaces<'a> {
/// (@interface export "bar")
///
/// (@interface func $ns_foo (import "ns" "foo")
/// (result i32))
/// (result i32))
///
/// (@interface func $ns_bar (import "ns" "bar"))
///
/// (@interface adapt (import "ns" "foo")
/// (param i32)
/// arg.get 42)
/// (param i32)
/// arg.get 42)
///
/// (@interface adapt (export "bar")
/// arg.get 42)
/// arg.get 42)
///
/// (@interface forward (export "main"))"#,
/// )
@ -543,19 +566,24 @@ mod tests {
#[test]
fn test_interface_type() {
let inputs = vec![
"int", "float", "any", "string", "seq", "i32", "i64", "f32", "f64", "anyref",
"s8", "s16", "s32", "s64", "u8", "u16", "u32", "u64", "f32", "f64", "string", "anyref",
"i32", "i64",
];
let outputs = vec![
InterfaceType::Int,
InterfaceType::Float,
InterfaceType::Any,
InterfaceType::String,
InterfaceType::Seq,
InterfaceType::I32,
InterfaceType::I64,
InterfaceType::S8,
InterfaceType::S16,
InterfaceType::S32,
InterfaceType::S64,
InterfaceType::U8,
InterfaceType::U16,
InterfaceType::U32,
InterfaceType::U64,
InterfaceType::F32,
InterfaceType::F64,
InterfaceType::AnyRef,
InterfaceType::String,
InterfaceType::Anyref,
InterfaceType::I32,
InterfaceType::I64,
];
assert_eq!(inputs.len(), outputs.len());
@ -576,19 +604,19 @@ mod tests {
r#"call-export "foo""#,
"read-utf8",
r#"write-utf8 "foo""#,
"as-wasm int",
"as-wasm s8",
"as-interface anyref",
"table-ref-add",
"table-ref-get",
"call-method 7",
"make-record int",
"get-field int 7",
"make-record s8",
"get-field i32 7",
"const i32 7",
"fold-seq 7",
"add int",
r#"mem-to-seq int "foo""#,
r#"load int "foo""#,
"seq.new int",
"add i32",
r#"mem-to-seq i32 "foo""#,
r#"load i32 "foo""#,
"seq.new i32",
"list.push",
"repeat-until 1 2",
];
@ -600,19 +628,19 @@ mod tests {
Instruction::WriteUtf8 {
allocator_name: "foo",
},
Instruction::AsWasm(InterfaceType::Int),
Instruction::AsInterface(InterfaceType::AnyRef),
Instruction::AsWasm(InterfaceType::S8),
Instruction::AsInterface(InterfaceType::Anyref),
Instruction::TableRefAdd,
Instruction::TableRefGet,
Instruction::CallMethod(7),
Instruction::MakeRecord(InterfaceType::Int),
Instruction::GetField(InterfaceType::Int, 7),
Instruction::MakeRecord(InterfaceType::S8),
Instruction::GetField(InterfaceType::I32, 7),
Instruction::Const(InterfaceType::I32, 7),
Instruction::FoldSeq(7),
Instruction::Add(InterfaceType::Int),
Instruction::MemToSeq(InterfaceType::Int, "foo"),
Instruction::Load(InterfaceType::Int, "foo"),
Instruction::SeqNew(InterfaceType::Int),
Instruction::Add(InterfaceType::I32),
Instruction::MemToSeq(InterfaceType::I32, "foo"),
Instruction::Load(InterfaceType::I32, "foo"),
Instruction::SeqNew(InterfaceType::I32),
Instruction::ListPush,
Instruction::RepeatUntil(1, 2),
];

View File

@ -97,16 +97,20 @@ where
{
fn to_bytes(&self, writer: &mut W) -> io::Result<()> {
match self {
InterfaceType::Int => 0x7fff_u64.to_bytes(writer),
InterfaceType::Float => 0x7ffe_u64.to_bytes(writer),
InterfaceType::Any => 0x7ffd_u64.to_bytes(writer),
InterfaceType::String => 0x7ffc_u64.to_bytes(writer),
InterfaceType::Seq => 0x7ffb_u64.to_bytes(writer),
InterfaceType::I32 => 0x7f_u64.to_bytes(writer),
InterfaceType::I64 => 0x7e_u64.to_bytes(writer),
InterfaceType::F32 => 0x7d_u64.to_bytes(writer),
InterfaceType::F64 => 0x7c_u64.to_bytes(writer),
InterfaceType::AnyRef => 0x6f_u64.to_bytes(writer),
InterfaceType::S8 => 0x00_u8.to_bytes(writer),
InterfaceType::S16 => 0x01_u8.to_bytes(writer),
InterfaceType::S32 => 0x02_u8.to_bytes(writer),
InterfaceType::S64 => 0x03_u8.to_bytes(writer),
InterfaceType::U8 => 0x04_u8.to_bytes(writer),
InterfaceType::U16 => 0x05_u8.to_bytes(writer),
InterfaceType::U32 => 0x06_u8.to_bytes(writer),
InterfaceType::U64 => 0x07_u8.to_bytes(writer),
InterfaceType::F32 => 0x08_u8.to_bytes(writer),
InterfaceType::F64 => 0x09_u8.to_bytes(writer),
InterfaceType::String => 0x0a_u8.to_bytes(writer),
InterfaceType::Anyref => 0x0b_u8.to_bytes(writer),
InterfaceType::I32 => 0x0c_u8.to_bytes(writer),
InterfaceType::I64 => 0x0d_u8.to_bytes(writer),
}
}
}
@ -444,16 +448,20 @@ mod tests {
#[test]
fn test_interface_type() {
assert_to_bytes!(InterfaceType::Int, &[0xff, 0xff, 0x01]);
assert_to_bytes!(InterfaceType::Float, &[0xfe, 0xff, 0x01]);
assert_to_bytes!(InterfaceType::Any, &[0xfd, 0xff, 0x01]);
assert_to_bytes!(InterfaceType::String, &[0xfc, 0xff, 0x01]);
assert_to_bytes!(InterfaceType::Seq, &[0xfb, 0xff, 0x01]);
assert_to_bytes!(InterfaceType::I32, &[0x7f]);
assert_to_bytes!(InterfaceType::I64, &[0x7e]);
assert_to_bytes!(InterfaceType::F32, &[0x7d]);
assert_to_bytes!(InterfaceType::F64, &[0x7c]);
assert_to_bytes!(InterfaceType::AnyRef, &[0x6f]);
assert_to_bytes!(InterfaceType::S8, &[0x00]);
assert_to_bytes!(InterfaceType::S16, &[0x01]);
assert_to_bytes!(InterfaceType::S32, &[0x02]);
assert_to_bytes!(InterfaceType::S64, &[0x03]);
assert_to_bytes!(InterfaceType::U8, &[0x04]);
assert_to_bytes!(InterfaceType::U16, &[0x05]);
assert_to_bytes!(InterfaceType::U32, &[0x06]);
assert_to_bytes!(InterfaceType::U64, &[0x07]);
assert_to_bytes!(InterfaceType::F32, &[0x08]);
assert_to_bytes!(InterfaceType::F64, &[0x09]);
assert_to_bytes!(InterfaceType::String, &[0x0a]);
assert_to_bytes!(InterfaceType::Anyref, &[0x0b]);
assert_to_bytes!(InterfaceType::I32, &[0x0c]);
assert_to_bytes!(InterfaceType::I64, &[0x0d]);
}
#[test]
@ -477,10 +485,10 @@ mod tests {
0x62, // "b"
0x63, // "c"
0x02, // list of 2 items
0x7f, // I32
0x7e, // I64
0x0c, // I32
0x0d, // I64
0x01, // list of 1 items
0x7f, // I32
0x0c, // I32
]
);
}
@ -502,8 +510,8 @@ mod tests {
0x01, // string of length 1
0x63, // "c"
0x02, // list of 2 items
0x7f, // I32
0x7e, // I64
0x0c, // I32
0x0d, // I64
]
);
}
@ -523,10 +531,10 @@ mod tests {
0x01, // string of length 1
0x62, // "b"
0x02, // list of 2 items
0x7f, // I32
0x7e, // I64
0x0c, // I32
0x0d, // I64
0x01, // list of 1 items
0x7f, // I32
0x0c, // I32
]
);
}
@ -548,10 +556,10 @@ mod tests {
0x01, // string of length 1
0x62, // "b"
0x02, // list of 2 items
0x7f, // I32
0x7e, // I64
0x0c, // I32
0x0d, // I64
0x01, // list of 1 items
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
]
@ -572,10 +580,10 @@ mod tests {
0x01, // string of length 1
0x61, // "a"
0x02, // list of 2 items
0x7f, // I32
0x7e, // I64
0x0c, // I32
0x0d, // I64
0x01, // list of 1 items
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
]
@ -596,10 +604,10 @@ mod tests {
0x01, // string of length 1
0x61, // "a"
0x02, // list of 2 items
0x7f, // I32
0x7e, // I64
0x0c, // I32
0x0d, // I64
0x01, // list of 1 items
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
]
@ -652,9 +660,9 @@ mod tests {
0x02, // string of 2 bytes
0x61, 0x62, // "a", "b"
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // 1 type
0x02, // string of 2 bytes
0x61, 0x62, // "a", "b"
@ -664,17 +672,17 @@ mod tests {
0x01, // string of 1 byte
0x65, // "e"
0x02, // list of 2 items
0x7f, // I32
0x7f, // I32
0x0c, // I32
0x0c, // I32
0x01, // 1 import
0x01, // string of 1 byte
0x61, // "a"
0x01, // string of 1 byte
0x62, // "b"
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x7e, // I64
0x0d, // I64
0x01, // 1 adapter
0x00, // adapter kind: import
0x01, // string of 1 byte
@ -682,9 +690,9 @@ mod tests {
0x01, // string of 1 byte
0x62, // "b"
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x7f, // I32
0x0c, // I32
0x01, // list of 1 item
0x00, 0x01, // ArgumentGet { index: 1 }
0x01, // 1 adapter
@ -705,13 +713,13 @@ mod tests {
Instruction::WriteUtf8 {
allocator_name: "abc",
},
Instruction::AsWasm(InterfaceType::Int),
Instruction::AsWasm(InterfaceType::I32),
Instruction::AsInterface(InterfaceType::I64),
Instruction::TableRefAdd,
Instruction::TableRefGet,
Instruction::CallMethod(1),
Instruction::MakeRecord(InterfaceType::I32),
Instruction::GetField(InterfaceType::Int, 2),
Instruction::GetField(InterfaceType::I32, 2),
Instruction::Const(InterfaceType::I32, 1),
Instruction::FoldSeq(1),
Instruction::Add(InterfaceType::I32),
@ -728,19 +736,19 @@ mod tests {
0x02, 0x03, 0x61, 0x62, 0x63, // CallExport { export_name: "abc" }
0x03, // ReadUtf8
0x04, 0x03, 0x61, 0x62, 0x63, // WriteUtf8 { allocator_name: "abc" }
0x05, 0xff, 0xff, 0x01, // AsWasm(Int)
0x06, 0x7e, // AsInterface(I64)
0x05, 0x0c, // AsWasm(Int)
0x06, 0x0d, // AsInterface(I64)
0x07, // TableRefAdd
0x08, // TableRefGet
0x09, 0x01, // CallMethod(1)
0x0a, 0x7f, // MakeRecord(I32)
0x0c, 0xff, 0xff, 0x01, 0x02, // GetField(Int, 2)
0x0d, 0x7f, 0x01, // Const(I32, 1)
0x0a, 0x0c, // MakeRecord(I32)
0x0c, 0x0c, 0x02, // GetField(I32, 2)
0x0d, 0x0c, 0x01, // Const(I32, 1)
0x0e, 0x01, // FoldSeq(1)
0x0f, 0x7f, // Add(I32)
0x10, 0x7f, 0x03, 0x61, 0x62, 0x63, // MemToSeq(I32, "abc")
0x11, 0x7f, 0x03, 0x61, 0x62, 0x63, // Load(I32, "abc")
0x12, 0x7f, // SeqNew(I32)
0x0f, 0x0c, // Add(I32)
0x10, 0x0c, 0x03, 0x61, 0x62, 0x63, // MemToSeq(I32, "abc")
0x11, 0x0c, 0x03, 0x61, 0x62, 0x63, // Load(I32, "abc")
0x12, 0x0c, // SeqNew(I32)
0x13, // ListPush
0x14, 0x01, 0x02, // RepeatUntil(1, 2)
]

View File

@ -98,16 +98,20 @@ use std::string::ToString;
impl ToString for &InterfaceType {
fn to_string(&self) -> String {
match self {
InterfaceType::Int => "Int".into(),
InterfaceType::Float => "Float".into(),
InterfaceType::Any => "Any".into(),
InterfaceType::String => "String".into(),
InterfaceType::Seq => "Seq".into(),
InterfaceType::I32 => "i32".into(),
InterfaceType::I64 => "i64".into(),
InterfaceType::S8 => "s8".into(),
InterfaceType::S16 => "s16".into(),
InterfaceType::S32 => "s32".into(),
InterfaceType::S64 => "s64".into(),
InterfaceType::U8 => "u8".into(),
InterfaceType::U16 => "u16".into(),
InterfaceType::U32 => "u32".into(),
InterfaceType::U64 => "u64".into(),
InterfaceType::F32 => "f32".into(),
InterfaceType::F64 => "f64".into(),
InterfaceType::AnyRef => "anyref".into(),
InterfaceType::String => "string".into(),
InterfaceType::Anyref => "anyref".into(),
InterfaceType::I32 => "i32".into(),
InterfaceType::I64 => "i64".into(),
}
}
}
@ -374,19 +378,24 @@ mod tests {
#[test]
fn test_interface_types() {
let inputs: Vec<String> = vec![
(&InterfaceType::Int).to_string(),
(&InterfaceType::Float).to_string(),
(&InterfaceType::Any).to_string(),
(&InterfaceType::String).to_string(),
(&InterfaceType::Seq).to_string(),
(&InterfaceType::I32).to_string(),
(&InterfaceType::I64).to_string(),
(&InterfaceType::S8).to_string(),
(&InterfaceType::S16).to_string(),
(&InterfaceType::S32).to_string(),
(&InterfaceType::S64).to_string(),
(&InterfaceType::U8).to_string(),
(&InterfaceType::U16).to_string(),
(&InterfaceType::U32).to_string(),
(&InterfaceType::U64).to_string(),
(&InterfaceType::F32).to_string(),
(&InterfaceType::F64).to_string(),
(&InterfaceType::AnyRef).to_string(),
(&InterfaceType::String).to_string(),
(&InterfaceType::Anyref).to_string(),
(&InterfaceType::I32).to_string(),
(&InterfaceType::I64).to_string(),
];
let outputs = vec![
"Int", "Float", "Any", "String", "Seq", "i32", "i64", "f32", "f64", "anyref",
"s8", "s16", "s32", "s64", "u8", "u16", "u32", "u64", "f32", "f64", "string", "anyref",
"i32", "i64",
];
assert_eq!(inputs, outputs);
@ -403,19 +412,19 @@ mod tests {
allocator_name: "foo",
})
.to_string(),
(&Instruction::AsWasm(InterfaceType::Int)).to_string(),
(&Instruction::AsInterface(InterfaceType::AnyRef)).to_string(),
(&Instruction::AsWasm(InterfaceType::I32)).to_string(),
(&Instruction::AsInterface(InterfaceType::I32)).to_string(),
(&Instruction::TableRefAdd).to_string(),
(&Instruction::TableRefGet).to_string(),
(&Instruction::CallMethod(7)).to_string(),
(&Instruction::MakeRecord(InterfaceType::Int)).to_string(),
(&Instruction::GetField(InterfaceType::Int, 7)).to_string(),
(&Instruction::MakeRecord(InterfaceType::I32)).to_string(),
(&Instruction::GetField(InterfaceType::I32, 7)).to_string(),
(&Instruction::Const(InterfaceType::I32, 7)).to_string(),
(&Instruction::FoldSeq(7)).to_string(),
(&Instruction::Add(InterfaceType::Int)).to_string(),
(&Instruction::MemToSeq(InterfaceType::Int, "foo")).to_string(),
(&Instruction::Load(InterfaceType::Int, "foo")).to_string(),
(&Instruction::SeqNew(InterfaceType::Int)).to_string(),
(&Instruction::Add(InterfaceType::I32)).to_string(),
(&Instruction::MemToSeq(InterfaceType::I32, "foo")).to_string(),
(&Instruction::Load(InterfaceType::I32, "foo")).to_string(),
(&Instruction::SeqNew(InterfaceType::I32)).to_string(),
(&Instruction::ListPush).to_string(),
(&Instruction::RepeatUntil(1, 2)).to_string(),
];
@ -425,19 +434,19 @@ mod tests {
r#"call-export "foo""#,
"read-utf8",
r#"write-utf8 "foo""#,
"as-wasm Int",
"as-interface anyref",
"as-wasm i32",
"as-interface i32",
"table-ref-add",
"table-ref-get",
"call-method 7",
"make-record Int",
"get-field Int 7",
"make-record i32",
"get-field i32 7",
"const i32 7",
"fold-seq 7",
"add Int",
r#"mem-to-seq Int "foo""#,
r#"load Int "foo""#,
"seq.new Int",
"add i32",
r#"mem-to-seq i32 "foo""#,
r#"load i32 "foo""#,
"seq.new i32",
"list.push",
"repeat-until 1 2",
];
@ -493,7 +502,7 @@ mod tests {
(&Import {
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::Int, InterfaceType::String],
input_types: vec![InterfaceType::I32, InterfaceType::String],
output_types: vec![InterfaceType::String],
})
.to_string(),
@ -521,12 +530,12 @@ mod tests {
];
let outputs = vec![
r#"(@interface func $ns_foo (import "ns" "foo")
(param Int String)
(result String))"#,
(param i32 string)
(result string))"#,
r#"(@interface func $ns_foo (import "ns" "foo")
(param String))"#,
(param string))"#,
r#"(@interface func $ns_foo (import "ns" "foo")
(result String))"#,
(result string))"#,
r#"(@interface func $ns_foo (import "ns" "foo"))"#,
];

View File

@ -6,29 +6,39 @@ pub use crate::ast::InterfaceType;
#[derive(Debug, Clone, PartialEq)]
pub enum InterfaceValue {
Int(isize),
Float(f64),
Any(isize),
String(String),
// Seq(…),
I32(i32),
I64(i64),
S8(i8),
S16(i16),
S32(i32),
S64(i64),
U8(u8),
U16(u16),
U32(u32),
U64(u64),
F32(f32),
F64(f64),
// AnyRef(…),
String(String),
//Anyref(?),
I32(i32),
I64(i64),
}
impl From<&InterfaceValue> for InterfaceType {
fn from(value: &InterfaceValue) -> Self {
match value {
InterfaceValue::Int(_) => Self::Int,
InterfaceValue::Float(_) => Self::Float,
InterfaceValue::Any(_) => Self::Any,
InterfaceValue::String(_) => Self::String,
InterfaceValue::I32(_) => Self::I32,
InterfaceValue::I64(_) => Self::I64,
InterfaceValue::S8(_) => Self::S8,
InterfaceValue::S16(_) => Self::S16,
InterfaceValue::S32(_) => Self::S32,
InterfaceValue::S64(_) => Self::S64,
InterfaceValue::U8(_) => Self::U8,
InterfaceValue::U16(_) => Self::U16,
InterfaceValue::U32(_) => Self::U32,
InterfaceValue::U64(_) => Self::U64,
InterfaceValue::F32(_) => Self::F32,
InterfaceValue::F64(_) => Self::F64,
InterfaceValue::String(_) => Self::String,
//InterfaceValue::Anyref(_) => Self::Anyref,
InterfaceValue::I32(_) => Self::I32,
InterfaceValue::I64(_) => Self::I64,
}
}
}
@ -60,8 +70,14 @@ macro_rules! from_x_for_interface_value {
};
}
from_x_for_interface_value!(i8, S8);
from_x_for_interface_value!(i16, S16);
from_x_for_interface_value!(u8, U8);
from_x_for_interface_value!(u16, U16);
from_x_for_interface_value!(u32, U32);
from_x_for_interface_value!(u64, U64);
from_x_for_interface_value!(f32, F32);
from_x_for_interface_value!(f64, F64);
from_x_for_interface_value!(String, String);
from_x_for_interface_value!(i32, I32);
from_x_for_interface_value!(i64, I64);
from_x_for_interface_value!(f32, F32);
from_x_for_interface_value!(f64, F64);