2020-02-21 12:23:58 +01:00
|
|
|
//! Parse the WIT binary representation into an [AST](crate::ast).
|
2020-02-10 16:39:06 +01:00
|
|
|
|
2019-09-26 14:14:46 +02:00
|
|
|
use crate::{ast::*, interpreter::Instruction};
|
2019-09-12 22:44:20 +02:00
|
|
|
use nom::{
|
|
|
|
error::{make_error, ErrorKind, ParseError},
|
|
|
|
Err, IResult,
|
|
|
|
};
|
|
|
|
use std::{convert::TryFrom, str};
|
|
|
|
|
2020-02-10 16:39:06 +01:00
|
|
|
/// Parse an `InterfaceType`.
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
impl TryFrom<u8> for InterfaceType {
|
2019-09-13 14:50:17 +02:00
|
|
|
type Error = &'static str;
|
|
|
|
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
fn try_from(code: u8) -> Result<Self, Self::Error> {
|
2019-09-13 14:50:17 +02:00
|
|
|
Ok(match code {
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
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,
|
2019-09-13 14:50:17 +02:00
|
|
|
_ => return Err("Unknown interface type code."),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-24 18:12:01 +01:00
|
|
|
/// Parse an interface kind.
|
|
|
|
impl TryFrom<u8> for InterfaceKind {
|
2019-09-13 14:50:17 +02:00
|
|
|
type Error = &'static str;
|
|
|
|
|
|
|
|
fn try_from(code: u8) -> Result<Self, Self::Error> {
|
|
|
|
Ok(match code {
|
2020-02-24 18:12:01 +01:00
|
|
|
0x00 => Self::Type,
|
|
|
|
0x01 => Self::Import,
|
|
|
|
0x02 => Self::Adapter,
|
|
|
|
0x03 => Self::Export,
|
|
|
|
0x04 => Self::Implementation,
|
|
|
|
_ => return Err("Unknown interface kind code."),
|
2019-09-13 14:50:17 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-10 16:39:06 +01:00
|
|
|
/// Parse a byte.
|
2019-09-12 22:44:20 +02:00
|
|
|
fn byte<'input, E: ParseError<&'input [u8]>>(input: &'input [u8]) -> IResult<&'input [u8], u8, E> {
|
|
|
|
if input.is_empty() {
|
|
|
|
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok((&input[1..], input[0]))
|
|
|
|
}
|
|
|
|
|
2020-02-13 11:41:02 +01:00
|
|
|
/// Parse an unsigned Little Endian Based (LEB) with value no larger
|
|
|
|
/// than a 64-bits number. Read
|
2020-02-13 13:36:18 +01:00
|
|
|
/// [LEB128](https://en.wikipedia.org/wiki/LEB128) to learn more, or
|
|
|
|
/// the Variable Length Data Section from the [DWARF 4
|
|
|
|
/// standard](http://dwarfstd.org/doc/DWARF4.pdf).
|
|
|
|
fn uleb<'input, E: ParseError<&'input [u8]>>(input: &'input [u8]) -> IResult<&'input [u8], u64, E> {
|
2019-09-12 22:44:20 +02:00
|
|
|
if input.is_empty() {
|
|
|
|
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
|
|
|
|
}
|
|
|
|
|
2020-02-14 12:19:29 +01:00
|
|
|
let (output, bytes) = match input.iter().position(|&byte| byte & 0x80 == 0) {
|
2020-02-13 13:36:18 +01:00
|
|
|
Some(length) if length <= 8 => (&input[length + 1..], &input[..=length]),
|
|
|
|
Some(_) => return Err(Err::Error(make_error(input, ErrorKind::TooLarge))),
|
|
|
|
None => return Err(Err::Error(make_error(input, ErrorKind::Eof))),
|
2019-09-12 22:44:20 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
Ok((
|
|
|
|
output,
|
|
|
|
bytes
|
|
|
|
.iter()
|
|
|
|
.rev()
|
2019-09-20 12:02:11 +02:00
|
|
|
.fold(0, |acc, byte| (acc << 7) | u64::from(byte & 0x7f)),
|
2019-09-12 22:44:20 +02:00
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2020-02-10 16:39:06 +01:00
|
|
|
/// Parse a UTF-8 string.
|
2019-09-12 22:44:20 +02:00
|
|
|
fn string<'input, E: ParseError<&'input [u8]>>(
|
|
|
|
input: &'input [u8],
|
|
|
|
) -> IResult<&'input [u8], &'input str, E> {
|
|
|
|
if input.is_empty() {
|
|
|
|
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
|
|
|
|
}
|
|
|
|
|
|
|
|
let length = input[0] as usize;
|
|
|
|
let input = &input[1..];
|
|
|
|
|
|
|
|
if input.len() < length {
|
|
|
|
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
|
|
|
|
}
|
|
|
|
|
2020-02-13 13:52:23 +01:00
|
|
|
Ok((
|
|
|
|
&input[length..],
|
|
|
|
str::from_utf8(&input[..length])
|
|
|
|
.map_err(|_| Err::Error(make_error(input, ErrorKind::ParseTo)))?,
|
|
|
|
))
|
2019-09-12 22:44:20 +02:00
|
|
|
}
|
|
|
|
|
2020-02-10 16:39:06 +01:00
|
|
|
/// Parse a list, with a item parser.
|
2019-09-20 12:02:11 +02:00
|
|
|
#[allow(clippy::type_complexity)]
|
2019-09-12 22:44:20 +02:00
|
|
|
fn list<'input, I, E: ParseError<&'input [u8]>>(
|
|
|
|
input: &'input [u8],
|
|
|
|
item_parser: fn(&'input [u8]) -> IResult<&'input [u8], I, E>,
|
|
|
|
) -> IResult<&'input [u8], Vec<I>, E> {
|
|
|
|
if input.is_empty() {
|
|
|
|
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
|
|
|
|
}
|
|
|
|
|
|
|
|
let length = input[0] as usize;
|
|
|
|
let mut input = &input[1..];
|
|
|
|
|
|
|
|
if input.len() < length {
|
|
|
|
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
|
|
|
|
}
|
|
|
|
|
2019-09-26 01:00:17 +02:00
|
|
|
let mut items = Vec::with_capacity(length as usize);
|
2019-09-12 22:44:20 +02:00
|
|
|
|
|
|
|
for _ in 0..length {
|
|
|
|
consume!((input, item) = item_parser(input)?);
|
|
|
|
items.push(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok((input, items))
|
|
|
|
}
|
|
|
|
|
2020-02-10 16:39:06 +01:00
|
|
|
/// Parse a type.
|
2019-09-12 22:44:20 +02:00
|
|
|
fn ty<'input, E: ParseError<&'input [u8]>>(
|
|
|
|
input: &'input [u8],
|
|
|
|
) -> IResult<&'input [u8], InterfaceType, E> {
|
|
|
|
if input.is_empty() {
|
|
|
|
return Err(Err::Error(make_error(input, ErrorKind::Eof)));
|
|
|
|
}
|
|
|
|
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
let (output, ty) = byte(input)?;
|
2019-09-12 22:44:20 +02:00
|
|
|
|
|
|
|
match InterfaceType::try_from(ty) {
|
|
|
|
Ok(ty) => Ok((output, ty)),
|
|
|
|
Err(_) => Err(Err::Error(make_error(input, ErrorKind::ParseTo))),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-10 16:39:06 +01:00
|
|
|
/// Parse an instruction with its arguments.
|
|
|
|
fn instruction<'input, E: ParseError<&'input [u8]>>(
|
2019-09-12 22:44:20 +02:00
|
|
|
input: &'input [u8],
|
|
|
|
) -> IResult<&'input [u8], Instruction, E> {
|
|
|
|
let (mut input, opcode) = byte(input)?;
|
|
|
|
|
|
|
|
Ok(match opcode {
|
|
|
|
0x00 => {
|
2020-02-13 13:36:18 +01:00
|
|
|
consume!((input, argument_0) = uleb(input)?);
|
2019-09-25 23:29:08 +02:00
|
|
|
(input, Instruction::ArgumentGet { index: argument_0 })
|
2019-09-12 22:44:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
0x01 => {
|
2020-02-13 13:36:18 +01:00
|
|
|
consume!((input, argument_0) = uleb(input)?);
|
2019-09-25 23:29:08 +02:00
|
|
|
(
|
|
|
|
input,
|
|
|
|
Instruction::Call {
|
|
|
|
function_index: argument_0 as usize,
|
|
|
|
},
|
|
|
|
)
|
2019-09-12 22:44:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
0x02 => {
|
|
|
|
consume!((input, argument_0) = string(input)?);
|
2019-09-25 23:29:08 +02:00
|
|
|
(
|
|
|
|
input,
|
|
|
|
Instruction::CallExport {
|
|
|
|
export_name: argument_0,
|
|
|
|
},
|
|
|
|
)
|
2019-09-12 22:44:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
0x03 => (input, Instruction::ReadUtf8),
|
|
|
|
|
|
|
|
0x04 => {
|
|
|
|
consume!((input, argument_0) = string(input)?);
|
2019-09-25 23:29:08 +02:00
|
|
|
(
|
|
|
|
input,
|
|
|
|
Instruction::WriteUtf8 {
|
|
|
|
allocator_name: argument_0,
|
|
|
|
},
|
|
|
|
)
|
2019-09-12 22:44:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
0x05 => {
|
|
|
|
consume!((input, argument_0) = ty(input)?);
|
|
|
|
(input, Instruction::AsWasm(argument_0))
|
|
|
|
}
|
|
|
|
|
|
|
|
0x06 => {
|
|
|
|
consume!((input, argument_0) = ty(input)?);
|
|
|
|
(input, Instruction::AsInterface(argument_0))
|
|
|
|
}
|
|
|
|
|
|
|
|
0x07 => (input, Instruction::TableRefAdd),
|
|
|
|
|
|
|
|
0x08 => (input, Instruction::TableRefGet),
|
|
|
|
|
|
|
|
0x09 => {
|
2020-02-13 13:36:18 +01:00
|
|
|
consume!((input, argument_0) = uleb(input)?);
|
2019-09-12 22:44:20 +02:00
|
|
|
(input, Instruction::CallMethod(argument_0))
|
|
|
|
}
|
|
|
|
|
|
|
|
0x0a => {
|
|
|
|
consume!((input, argument_0) = ty(input)?);
|
|
|
|
(input, Instruction::MakeRecord(argument_0))
|
|
|
|
}
|
|
|
|
|
|
|
|
0x0c => {
|
2019-09-13 15:39:46 +02:00
|
|
|
consume!((input, argument_0) = ty(input)?);
|
2020-02-13 13:36:18 +01:00
|
|
|
consume!((input, argument_1) = uleb(input)?);
|
2019-09-12 22:44:20 +02:00
|
|
|
(input, Instruction::GetField(argument_0, argument_1))
|
|
|
|
}
|
|
|
|
|
|
|
|
0x0d => {
|
|
|
|
consume!((input, argument_0) = ty(input)?);
|
2020-02-13 13:36:18 +01:00
|
|
|
consume!((input, argument_1) = uleb(input)?);
|
2019-09-12 22:44:20 +02:00
|
|
|
(input, Instruction::Const(argument_0, argument_1))
|
|
|
|
}
|
|
|
|
|
|
|
|
0x0e => {
|
2020-02-13 13:36:18 +01:00
|
|
|
consume!((input, argument_0) = uleb(input)?);
|
2019-09-12 22:44:20 +02:00
|
|
|
(input, Instruction::FoldSeq(argument_0))
|
|
|
|
}
|
|
|
|
|
2019-09-18 17:09:18 +02:00
|
|
|
0x0f => {
|
|
|
|
consume!((input, argument_0) = ty(input)?);
|
|
|
|
(input, Instruction::Add(argument_0))
|
|
|
|
}
|
|
|
|
|
|
|
|
0x10 => {
|
|
|
|
consume!((input, argument_0) = ty(input)?);
|
|
|
|
consume!((input, argument_1) = string(input)?);
|
|
|
|
(input, Instruction::MemToSeq(argument_0, argument_1))
|
|
|
|
}
|
|
|
|
|
|
|
|
0x11 => {
|
|
|
|
consume!((input, argument_0) = ty(input)?);
|
|
|
|
consume!((input, argument_1) = string(input)?);
|
|
|
|
(input, Instruction::Load(argument_0, argument_1))
|
|
|
|
}
|
|
|
|
|
|
|
|
0x12 => {
|
|
|
|
consume!((input, argument_0) = ty(input)?);
|
|
|
|
(input, Instruction::SeqNew(argument_0))
|
|
|
|
}
|
|
|
|
|
|
|
|
0x13 => (input, Instruction::ListPush),
|
|
|
|
|
|
|
|
0x14 => {
|
2020-02-13 13:36:18 +01:00
|
|
|
consume!((input, argument_0) = uleb(input)?);
|
|
|
|
consume!((input, argument_1) = uleb(input)?);
|
2020-02-12 15:59:41 +01:00
|
|
|
(input, Instruction::RepeatUntil(argument_0, argument_1))
|
2019-09-18 17:09:18 +02:00
|
|
|
}
|
|
|
|
|
2019-09-12 22:44:20 +02:00
|
|
|
_ => return Err(Err::Error(make_error(input, ErrorKind::ParseTo))),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-02-10 16:39:06 +01:00
|
|
|
/// Parse a list of types.
|
2019-09-13 14:26:49 +02:00
|
|
|
fn types<'input, E: ParseError<&'input [u8]>>(
|
2020-02-13 13:56:30 +01:00
|
|
|
mut input: &'input [u8],
|
2019-09-12 22:44:20 +02:00
|
|
|
) -> IResult<&'input [u8], Vec<Type>, E> {
|
2020-02-13 13:36:18 +01:00
|
|
|
consume!((input, number_of_types) = uleb(input)?);
|
2019-09-12 22:44:20 +02:00
|
|
|
|
2019-09-26 01:00:17 +02:00
|
|
|
let mut types = Vec::with_capacity(number_of_types as usize);
|
|
|
|
|
2019-09-12 22:44:20 +02:00
|
|
|
for _ in 0..number_of_types {
|
2020-02-24 16:23:31 +01:00
|
|
|
consume!((input, inputs) = list(input, ty)?);
|
|
|
|
consume!((input, outputs) = list(input, ty)?);
|
2019-09-12 22:44:20 +02:00
|
|
|
|
2020-02-24 16:23:31 +01:00
|
|
|
types.push(Type { inputs, outputs });
|
2019-09-12 22:44:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok((input, types))
|
|
|
|
}
|
|
|
|
|
2020-02-10 16:39:06 +01:00
|
|
|
/// Parse a list of imports.
|
2020-02-10 15:41:10 +01:00
|
|
|
fn imports<'input, E: ParseError<&'input [u8]>>(
|
2020-02-13 13:56:30 +01:00
|
|
|
mut input: &'input [u8],
|
2020-02-10 15:41:10 +01:00
|
|
|
) -> IResult<&'input [u8], Vec<Import>, E> {
|
2020-02-13 13:36:18 +01:00
|
|
|
consume!((input, number_of_imports) = uleb(input)?);
|
2019-09-12 22:44:20 +02:00
|
|
|
|
2020-02-10 15:41:10 +01:00
|
|
|
let mut imports = Vec::with_capacity(number_of_imports as usize);
|
2019-09-26 01:00:17 +02:00
|
|
|
|
2020-02-10 15:41:10 +01:00
|
|
|
for _ in 0..number_of_imports {
|
2020-02-24 18:12:01 +01:00
|
|
|
consume!((input, namespace) = string(input)?);
|
|
|
|
consume!((input, name) = string(input)?);
|
|
|
|
consume!((input, signature_type) = uleb(input)?);
|
2019-09-12 22:44:20 +02:00
|
|
|
|
2020-02-10 15:41:10 +01:00
|
|
|
imports.push(Import {
|
2020-02-24 18:12:01 +01:00
|
|
|
namespace,
|
|
|
|
name,
|
|
|
|
signature_type: signature_type as u32,
|
2019-09-12 22:44:20 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-02-10 15:41:10 +01:00
|
|
|
Ok((input, imports))
|
2019-09-12 22:44:20 +02:00
|
|
|
}
|
|
|
|
|
2020-02-10 16:39:06 +01:00
|
|
|
/// Parse a list of adapters.
|
2019-09-13 14:26:49 +02:00
|
|
|
fn adapters<'input, E: ParseError<&'input [u8]>>(
|
2020-02-13 13:56:30 +01:00
|
|
|
mut input: &'input [u8],
|
2019-09-12 22:44:20 +02:00
|
|
|
) -> IResult<&'input [u8], Vec<Adapter>, E> {
|
2020-02-13 13:36:18 +01:00
|
|
|
consume!((input, number_of_adapters) = uleb(input)?);
|
2019-09-12 22:44:20 +02:00
|
|
|
|
2019-09-26 01:00:17 +02:00
|
|
|
let mut adapters = Vec::with_capacity(number_of_adapters as usize);
|
|
|
|
|
2019-09-12 22:44:20 +02:00
|
|
|
for _ in 0..number_of_adapters {
|
2020-02-24 18:12:01 +01:00
|
|
|
consume!((input, function_type) = uleb(input)?);
|
|
|
|
consume!((input, instructions) = list(input, instruction)?);
|
|
|
|
|
|
|
|
adapters.push(Adapter {
|
|
|
|
function_type: function_type as u32,
|
|
|
|
instructions,
|
|
|
|
});
|
2019-09-12 22:44:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Ok((input, adapters))
|
|
|
|
}
|
|
|
|
|
2020-02-24 18:12:01 +01:00
|
|
|
/// Parse a list of exports.
|
|
|
|
fn exports<'input, E: ParseError<&'input [u8]>>(
|
|
|
|
mut input: &'input [u8],
|
|
|
|
) -> IResult<&'input [u8], Vec<Export>, E> {
|
|
|
|
consume!((input, number_of_exports) = uleb(input)?);
|
|
|
|
|
|
|
|
let mut exports = Vec::with_capacity(number_of_exports as usize);
|
|
|
|
|
|
|
|
for _ in 0..number_of_exports {
|
|
|
|
consume!((input, name) = string(input)?);
|
|
|
|
consume!((input, function_type) = uleb(input)?);
|
|
|
|
|
|
|
|
exports.push(Export {
|
|
|
|
name,
|
|
|
|
function_type: function_type as u32,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok((input, exports))
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Parse a list of implementations.
|
|
|
|
fn implementations<'input, E: ParseError<&'input [u8]>>(
|
|
|
|
mut input: &'input [u8],
|
|
|
|
) -> IResult<&'input [u8], Vec<Implementation>, E> {
|
|
|
|
consume!((input, number_of_implementations) = uleb(input)?);
|
|
|
|
|
|
|
|
let mut implementations = Vec::with_capacity(number_of_implementations as usize);
|
|
|
|
|
|
|
|
for _ in 0..number_of_implementations {
|
|
|
|
consume!((input, core_function_type) = uleb(input)?);
|
|
|
|
consume!((input, adapter_function_type) = uleb(input)?);
|
|
|
|
|
|
|
|
implementations.push(Implementation {
|
|
|
|
core_function_type: core_function_type as u32,
|
|
|
|
adapter_function_type: adapter_function_type as u32,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok((input, implementations))
|
|
|
|
}
|
|
|
|
|
2020-02-17 13:52:00 +01:00
|
|
|
/// Parse complete interfaces.
|
|
|
|
fn interfaces<'input, E: ParseError<&'input [u8]>>(
|
|
|
|
bytes: &'input [u8],
|
|
|
|
) -> IResult<&'input [u8], Interfaces, E> {
|
|
|
|
let mut input = bytes;
|
|
|
|
|
2020-02-24 18:12:01 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
InterfaceKind::Import => {
|
|
|
|
consume!((input, mut new_imports) = imports(input)?);
|
|
|
|
all_imports.append(&mut new_imports);
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
}
|
|
|
|
}
|
2020-02-17 13:52:00 +01:00
|
|
|
|
|
|
|
Ok((
|
|
|
|
input,
|
|
|
|
Interfaces {
|
2020-02-24 18:12:01 +01:00
|
|
|
types: all_types,
|
|
|
|
imports: all_imports,
|
|
|
|
adapters: all_adapters,
|
|
|
|
exports: all_exports,
|
|
|
|
implementations: all_implementations,
|
2020-02-17 13:52:00 +01:00
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
2020-02-10 16:39:06 +01:00
|
|
|
/// Parse a sequence of bytes, expecting it to be a valid WIT binary
|
2020-02-21 12:23:58 +01:00
|
|
|
/// representation, into an [`Interfaces`](crate::ast::Interfaces)
|
|
|
|
/// structure.
|
2020-02-10 16:48:25 +01:00
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
///
|
|
|
|
/// ```rust
|
|
|
|
/// use wasmer_interface_types::{
|
|
|
|
/// ast::*,
|
|
|
|
/// decoders::binary::parse,
|
|
|
|
/// interpreter::Instruction,
|
|
|
|
/// };
|
|
|
|
///
|
|
|
|
/// # fn main() {
|
|
|
|
/// let input = &[
|
|
|
|
/// 0x01, // 1 export
|
|
|
|
/// 0x02, // string of 2 bytes
|
|
|
|
/// 0x61, 0x62, // "a", "b"
|
|
|
|
/// 0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
/// 0x02, // S32
|
2020-02-10 16:48:25 +01:00
|
|
|
/// 0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
/// 0x02, // S32
|
2020-02-10 16:48:25 +01:00
|
|
|
/// 0x01, // 1 type
|
|
|
|
/// 0x02, // list of 2 items
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
/// 0x02, // S32
|
|
|
|
/// 0x02, // S32
|
2020-02-24 16:23:31 +01:00
|
|
|
/// 0x01, // list of 1 item
|
|
|
|
/// 0x02, // S32
|
2020-02-10 16:48:25 +01:00
|
|
|
/// 0x01, // 1 import
|
|
|
|
/// 0x01, // string of 1 byte
|
|
|
|
/// 0x61, // "a"
|
|
|
|
/// 0x01, // string of 1 byte
|
|
|
|
/// 0x62, // "b"
|
|
|
|
/// 0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
/// 0x02, // S32
|
2020-02-10 16:48:25 +01:00
|
|
|
/// 0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
/// 0x03, // S64
|
2020-02-10 16:48:25 +01:00
|
|
|
/// 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
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
/// 0x02, // S32
|
2020-02-10 16:48:25 +01:00
|
|
|
/// 0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
/// 0x02, // S32
|
2020-02-10 16:48:25 +01:00
|
|
|
/// 0x01, // list of 1 item
|
|
|
|
/// 0x00, 0x01, // ArgumentGet { index: 1 }
|
|
|
|
/// ];
|
|
|
|
/// let output = Ok((
|
|
|
|
/// &[] as &[u8],
|
|
|
|
/// Interfaces {
|
|
|
|
/// exports: vec![Export {
|
|
|
|
/// name: "ab",
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
/// input_types: vec![InterfaceType::S32],
|
|
|
|
/// output_types: vec![InterfaceType::S32],
|
2020-02-10 16:48:25 +01:00
|
|
|
/// }],
|
2020-02-24 16:23:31 +01:00
|
|
|
/// types: vec![Type {
|
|
|
|
/// inputs: vec![InterfaceType::S32, InterfaceType::S32],
|
|
|
|
/// outputs: vec![InterfaceType::S32],
|
|
|
|
/// }],
|
2020-02-10 16:48:25 +01:00
|
|
|
/// imports: vec![Import {
|
|
|
|
/// namespace: "a",
|
|
|
|
/// name: "b",
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
/// input_types: vec![InterfaceType::S32],
|
|
|
|
/// output_types: vec![InterfaceType::S64],
|
2020-02-10 16:48:25 +01:00
|
|
|
/// }],
|
|
|
|
/// adapters: vec![Adapter::Import {
|
|
|
|
/// namespace: "a",
|
|
|
|
/// name: "b",
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
/// input_types: vec![InterfaceType::S32],
|
|
|
|
/// output_types: vec![InterfaceType::S32],
|
2020-02-10 16:48:25 +01:00
|
|
|
/// instructions: vec![Instruction::ArgumentGet { index: 1 }],
|
|
|
|
/// }],
|
|
|
|
/// },
|
|
|
|
/// ));
|
|
|
|
///
|
|
|
|
/// assert_eq!(parse::<()>(input), output);
|
|
|
|
/// # }
|
|
|
|
/// ```
|
2019-09-12 22:44:20 +02:00
|
|
|
pub fn parse<'input, E: ParseError<&'input [u8]>>(
|
|
|
|
bytes: &'input [u8],
|
|
|
|
) -> IResult<&'input [u8], Interfaces, E> {
|
2020-02-17 13:52:00 +01:00
|
|
|
interfaces(bytes)
|
2019-09-12 22:44:20 +02:00
|
|
|
}
|
2019-09-13 12:00:05 +02:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
2020-02-13 13:36:18 +01:00
|
|
|
use nom::{error, Err};
|
2019-09-13 12:00:05 +02:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_byte() {
|
|
|
|
let input = &[0x01, 0x02, 0x03];
|
|
|
|
let output = Ok((&[0x02, 0x03][..], 0x01u8));
|
|
|
|
|
|
|
|
assert_eq!(byte::<()>(input), output);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2020-02-13 13:36:18 +01:00
|
|
|
fn test_uleb_1_byte() {
|
2019-09-13 12:00:05 +02:00
|
|
|
let input = &[0x01, 0x02, 0x03];
|
|
|
|
let output = Ok((&[0x02, 0x03][..], 0x01u64));
|
|
|
|
|
2020-02-13 13:36:18 +01:00
|
|
|
assert_eq!(uleb::<()>(input), output);
|
2019-09-13 12:00:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2020-02-13 13:36:18 +01:00
|
|
|
fn test_uleb_3_bytes() {
|
2019-09-13 12:00:05 +02:00
|
|
|
let input = &[0xfc, 0xff, 0x01, 0x02];
|
|
|
|
let output = Ok((&[0x02][..], 0x7ffcu64));
|
|
|
|
|
2020-02-13 13:36:18 +01:00
|
|
|
assert_eq!(uleb::<()>(input), output);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Examples from Figure 22 of [DWARF 4
|
|
|
|
// standard](http://dwarfstd.org/doc/DWARF4.pdf).
|
|
|
|
#[test]
|
|
|
|
fn test_uleb_from_dwarf_standard() {
|
|
|
|
macro_rules! assert_uleb {
|
|
|
|
($to_parse:expr => $expected_result:expr) => {
|
|
|
|
assert_eq!(uleb::<()>($to_parse), Ok((&[][..], $expected_result)));
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_uleb!(&[2u8] => 2u64);
|
|
|
|
assert_uleb!(&[127u8] => 127u64);
|
|
|
|
assert_uleb!(&[0x80, 1u8] => 128u64);
|
|
|
|
assert_uleb!(&[1u8 | 0x80, 1] => 129u64);
|
|
|
|
assert_uleb!(&[2u8 | 0x80, 1] => 130u64);
|
|
|
|
assert_uleb!(&[57u8 | 0x80, 100] => 12857u64);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_uleb_eof() {
|
|
|
|
let input = &[0x80];
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
uleb::<(&[u8], error::ErrorKind)>(input),
|
|
|
|
Err(Err::Error((&input[..], error::ErrorKind::Eof))),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_uleb_overflow() {
|
|
|
|
let input = &[
|
|
|
|
0x01 | 0x80,
|
|
|
|
0x02 | 0x80,
|
|
|
|
0x03 | 0x80,
|
|
|
|
0x04 | 0x80,
|
|
|
|
0x05 | 0x80,
|
|
|
|
0x06 | 0x80,
|
|
|
|
0x07 | 0x80,
|
|
|
|
0x08 | 0x80,
|
|
|
|
0x09 | 0x80,
|
|
|
|
0x0a,
|
|
|
|
];
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
uleb::<(&[u8], error::ErrorKind)>(input),
|
|
|
|
Err(Err::Error((&input[..], error::ErrorKind::TooLarge))),
|
|
|
|
);
|
2019-09-13 12:00:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_string() {
|
|
|
|
let input = &[
|
|
|
|
0x03, // string of 3 bytes
|
|
|
|
0x61, // "a"
|
|
|
|
0x62, // "b"
|
|
|
|
0x63, // "c"
|
|
|
|
0x64, 0x65,
|
|
|
|
];
|
|
|
|
let output = Ok((&[0x64, 0x65][..], "abc"));
|
|
|
|
|
|
|
|
assert_eq!(string::<()>(input), output);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_list() {
|
|
|
|
let input = &[
|
|
|
|
0x02, // list of 2 items
|
|
|
|
0x01, // string of 1 byte
|
|
|
|
0x61, // "a"
|
|
|
|
0x02, // string of 2 bytes
|
|
|
|
0x62, // "b"
|
|
|
|
0x63, // "c"
|
|
|
|
0x07,
|
|
|
|
];
|
|
|
|
let output = Ok((&[0x07][..], vec!["a", "bc"]));
|
|
|
|
|
|
|
|
assert_eq!(list::<&str, ()>(input, string), output);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_ty() {
|
|
|
|
let input = &[
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
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
|
2019-09-13 12:00:05 +02:00
|
|
|
0x01,
|
|
|
|
];
|
|
|
|
let output = Ok((
|
|
|
|
&[0x01][..],
|
|
|
|
vec![
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
InterfaceType::S8,
|
|
|
|
InterfaceType::S16,
|
|
|
|
InterfaceType::S32,
|
|
|
|
InterfaceType::S64,
|
|
|
|
InterfaceType::U8,
|
|
|
|
InterfaceType::U16,
|
|
|
|
InterfaceType::U32,
|
|
|
|
InterfaceType::U64,
|
|
|
|
InterfaceType::F32,
|
|
|
|
InterfaceType::F64,
|
2019-09-13 12:00:05 +02:00
|
|
|
InterfaceType::String,
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
InterfaceType::Anyref,
|
2019-09-13 12:00:05 +02:00
|
|
|
InterfaceType::I32,
|
|
|
|
InterfaceType::I64,
|
|
|
|
],
|
|
|
|
));
|
|
|
|
|
|
|
|
assert_eq!(list::<InterfaceType, ()>(input, ty), output);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_instructions() {
|
|
|
|
let input = &[
|
2019-09-18 17:09:18 +02:00
|
|
|
0x14, // list of 20 items
|
2019-09-25 23:29:08 +02:00
|
|
|
0x00, 0x01, // ArgumentGet { index: 1 }
|
|
|
|
0x01, 0x01, // Call { function_index: 1 }
|
|
|
|
0x02, 0x03, 0x61, 0x62, 0x63, // CallExport { export_name: "abc" }
|
2019-09-13 12:00:05 +02:00
|
|
|
0x03, // ReadUtf8
|
2019-09-25 23:29:08 +02:00
|
|
|
0x04, 0x03, 0x61, 0x62, 0x63, // WriteUtf8 { allocator_name: "abc" }
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x05, 0x00, // AsWasm(S8)
|
|
|
|
0x06, 0x00, // AsInterface(S8)
|
2019-09-13 12:00:05 +02:00
|
|
|
0x07, // TableRefAdd
|
|
|
|
0x08, // TableRefGet
|
|
|
|
0x09, 0x01, // CallMethod(1)
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x0a, 0x0c, // MakeRecord(I32)
|
|
|
|
0x0c, 0x00, 0x02, // GetField(S8, 2)
|
|
|
|
0x0d, 0x0c, 0x01, // Const(I32, 1)
|
2019-09-13 12:00:05 +02:00
|
|
|
0x0e, 0x01, // FoldSeq(1)
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
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)
|
2019-09-18 17:09:18 +02:00
|
|
|
0x13, // ListPush
|
2020-02-12 15:59:41 +01:00
|
|
|
0x14, 0x01, 0x02, // RepeatUntil(1, 2)
|
2019-09-13 12:00:05 +02:00
|
|
|
0x0a,
|
|
|
|
];
|
|
|
|
let output = Ok((
|
|
|
|
&[0x0a][..],
|
|
|
|
vec![
|
2019-09-25 23:29:08 +02:00
|
|
|
Instruction::ArgumentGet { index: 1 },
|
|
|
|
Instruction::Call { function_index: 1 },
|
|
|
|
Instruction::CallExport { export_name: "abc" },
|
2019-09-13 12:00:05 +02:00
|
|
|
Instruction::ReadUtf8,
|
2019-09-25 23:29:08 +02:00
|
|
|
Instruction::WriteUtf8 {
|
|
|
|
allocator_name: "abc",
|
|
|
|
},
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
Instruction::AsWasm(InterfaceType::S8),
|
|
|
|
Instruction::AsInterface(InterfaceType::S8),
|
2019-09-13 12:00:05 +02:00
|
|
|
Instruction::TableRefAdd,
|
|
|
|
Instruction::TableRefGet,
|
|
|
|
Instruction::CallMethod(1),
|
|
|
|
Instruction::MakeRecord(InterfaceType::I32),
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
Instruction::GetField(InterfaceType::S8, 2),
|
2019-09-13 12:00:05 +02:00
|
|
|
Instruction::Const(InterfaceType::I32, 1),
|
|
|
|
Instruction::FoldSeq(1),
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
Instruction::Add(InterfaceType::S8),
|
|
|
|
Instruction::MemToSeq(InterfaceType::S8, "abc"),
|
|
|
|
Instruction::Load(InterfaceType::S8, "abc"),
|
|
|
|
Instruction::SeqNew(InterfaceType::S8),
|
2019-09-18 17:09:18 +02:00
|
|
|
Instruction::ListPush,
|
2020-02-12 15:59:41 +01:00
|
|
|
Instruction::RepeatUntil(1, 2),
|
2019-09-13 12:00:05 +02:00
|
|
|
],
|
|
|
|
));
|
|
|
|
|
2020-02-10 16:39:06 +01:00
|
|
|
assert_eq!(list::<Instruction, ()>(input, instruction), output);
|
2019-09-13 12:00:05 +02:00
|
|
|
}
|
2019-09-13 14:24:03 +02:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_exports() {
|
|
|
|
let input = &[
|
|
|
|
0x02, // 2 exports
|
|
|
|
0x02, // string of 2 bytes
|
|
|
|
0x61, 0x62, // "a", "b"
|
|
|
|
0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x00, // S8
|
2019-09-13 14:24:03 +02:00
|
|
|
0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x00, // S8
|
2019-09-13 14:24:03 +02:00
|
|
|
0x02, // string of 2 bytes
|
|
|
|
0x63, 0x64, // "c", "d"
|
|
|
|
0x00, // list of 0 item
|
|
|
|
0x00, // list of 0 item
|
|
|
|
];
|
|
|
|
let output = Ok((
|
|
|
|
&[] as &[u8],
|
|
|
|
vec![
|
|
|
|
Export {
|
|
|
|
name: "ab",
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
input_types: vec![InterfaceType::S8],
|
|
|
|
output_types: vec![InterfaceType::S8],
|
2019-09-13 14:24:03 +02:00
|
|
|
},
|
|
|
|
Export {
|
|
|
|
name: "cd",
|
|
|
|
input_types: vec![],
|
|
|
|
output_types: vec![],
|
|
|
|
},
|
|
|
|
],
|
|
|
|
));
|
|
|
|
|
|
|
|
assert_eq!(exports::<()>(input), output);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_types() {
|
|
|
|
let input = &[
|
|
|
|
0x01, // 1 type
|
|
|
|
0x02, // list of 2 items
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x02, // S32
|
|
|
|
0x02, // S32
|
2020-02-24 16:23:31 +01:00
|
|
|
0x01, // list of 2 items
|
|
|
|
0x02, // S32
|
2019-09-13 14:24:03 +02:00
|
|
|
];
|
|
|
|
let output = Ok((
|
|
|
|
&[] as &[u8],
|
2020-02-24 16:23:31 +01:00
|
|
|
vec![Type {
|
|
|
|
inputs: vec![InterfaceType::S32, InterfaceType::S32],
|
|
|
|
outputs: vec![InterfaceType::S32],
|
|
|
|
}],
|
2019-09-13 14:24:03 +02:00
|
|
|
));
|
|
|
|
|
|
|
|
assert_eq!(types::<()>(input), output);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2020-02-10 15:41:10 +01:00
|
|
|
fn test_imports() {
|
2019-09-13 14:24:03 +02:00
|
|
|
let input = &[
|
2020-02-10 15:41:10 +01:00
|
|
|
0x02, // 2 imports
|
2019-09-13 14:24:03 +02:00
|
|
|
0x01, // string of 1 byte
|
|
|
|
0x61, // "a"
|
|
|
|
0x01, // string of 1 byte
|
|
|
|
0x62, // "b"
|
|
|
|
0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x02, // S32
|
2019-09-13 14:24:03 +02:00
|
|
|
0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x03, // S64
|
2019-09-13 14:24:03 +02:00
|
|
|
0x01, // string of 1 byte
|
|
|
|
0x63, // "c"
|
|
|
|
0x01, // string of 1 byte
|
|
|
|
0x64, // "d"
|
|
|
|
0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x02, // S32
|
2019-09-13 14:24:03 +02:00
|
|
|
0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x03, // S64
|
2019-09-13 14:24:03 +02:00
|
|
|
];
|
|
|
|
let output = Ok((
|
|
|
|
&[] as &[u8],
|
|
|
|
vec![
|
2020-02-10 15:41:10 +01:00
|
|
|
Import {
|
2019-09-13 14:24:03 +02:00
|
|
|
namespace: "a",
|
|
|
|
name: "b",
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
input_types: vec![InterfaceType::S32],
|
|
|
|
output_types: vec![InterfaceType::S64],
|
2019-09-13 14:24:03 +02:00
|
|
|
},
|
2020-02-10 15:41:10 +01:00
|
|
|
Import {
|
2019-09-13 14:24:03 +02:00
|
|
|
namespace: "c",
|
|
|
|
name: "d",
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
input_types: vec![InterfaceType::S32],
|
|
|
|
output_types: vec![InterfaceType::S64],
|
2019-09-13 14:24:03 +02:00
|
|
|
},
|
|
|
|
],
|
|
|
|
));
|
|
|
|
|
2020-02-10 15:41:10 +01:00
|
|
|
assert_eq!(imports::<()>(input), output);
|
2019-09-13 14:24:03 +02:00
|
|
|
}
|
|
|
|
|
2020-02-24 18:12:01 +01:00
|
|
|
/*
|
2019-09-13 14:24:03 +02:00
|
|
|
#[test]
|
|
|
|
fn test_adapters() {
|
|
|
|
let input = &[
|
2020-02-24 15:49:03 +01:00
|
|
|
0x02, // 3 adapters
|
2019-09-13 14:24:03 +02:00
|
|
|
0x00, // adapter kind: import
|
|
|
|
0x01, // string of 1 byte
|
|
|
|
0x61, // "a"
|
|
|
|
0x01, // string of 1 byte
|
|
|
|
0x62, // "b"
|
|
|
|
0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x0c, // I32
|
2019-09-13 14:24:03 +02:00
|
|
|
0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x0c, // I32
|
2019-09-13 14:24:03 +02:00
|
|
|
0x01, // list of 1 item
|
2019-09-25 23:29:08 +02:00
|
|
|
0x00, 0x01, // ArgumentGet { index: 1 }
|
2019-09-13 14:24:03 +02:00
|
|
|
0x01, // adapter kind: export
|
|
|
|
0x01, // string of 1 byte
|
|
|
|
0x63, // "c"
|
|
|
|
0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x0c, // I32
|
2019-09-13 14:24:03 +02:00
|
|
|
0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x0c, // I32
|
2019-09-13 14:24:03 +02:00
|
|
|
0x01, // list of 1 item
|
2019-09-25 23:29:08 +02:00
|
|
|
0x00, 0x01, // ArgumentGet { index: 1 }
|
2019-09-13 14:24:03 +02:00
|
|
|
];
|
|
|
|
let output = Ok((
|
|
|
|
&[] as &[u8],
|
|
|
|
vec![
|
|
|
|
Adapter::Import {
|
|
|
|
namespace: "a",
|
|
|
|
name: "b",
|
|
|
|
input_types: vec![InterfaceType::I32],
|
|
|
|
output_types: vec![InterfaceType::I32],
|
2019-09-25 23:29:08 +02:00
|
|
|
instructions: vec![Instruction::ArgumentGet { index: 1 }],
|
2019-09-13 14:24:03 +02:00
|
|
|
},
|
|
|
|
Adapter::Export {
|
|
|
|
name: "c",
|
|
|
|
input_types: vec![InterfaceType::I32],
|
|
|
|
output_types: vec![InterfaceType::I32],
|
2019-09-25 23:29:08 +02:00
|
|
|
instructions: vec![Instruction::ArgumentGet { index: 1 }],
|
2019-09-13 14:24:03 +02:00
|
|
|
},
|
|
|
|
],
|
|
|
|
));
|
|
|
|
|
|
|
|
assert_eq!(adapters::<()>(input), output);
|
|
|
|
}
|
2020-02-24 18:12:01 +01:00
|
|
|
*/
|
2019-09-13 14:24:03 +02:00
|
|
|
|
2020-02-10 16:39:34 +01:00
|
|
|
#[test]
|
|
|
|
fn test_parse() {
|
|
|
|
let input = &[
|
|
|
|
0x01, // 1 export
|
|
|
|
0x02, // string of 2 bytes
|
|
|
|
0x61, 0x62, // "a", "b"
|
|
|
|
0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x0c, // I32
|
2020-02-10 16:39:34 +01:00
|
|
|
0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x0c, // I32
|
2020-02-10 16:39:34 +01:00
|
|
|
0x01, // 1 type
|
|
|
|
0x02, // list of 2 items
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x0c, // I32
|
|
|
|
0x0c, // I32
|
2020-02-24 16:23:31 +01:00
|
|
|
0x00, // list of 0 item
|
2020-02-10 16:39:34 +01:00
|
|
|
0x01, // 1 import
|
|
|
|
0x01, // string of 1 byte
|
|
|
|
0x61, // "a"
|
|
|
|
0x01, // string of 1 byte
|
|
|
|
0x62, // "b"
|
|
|
|
0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x0c, // I32
|
2020-02-10 16:39:34 +01:00
|
|
|
0x01, // list of 1 item
|
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.
2020-02-24 15:37:03 +01:00
|
|
|
0x0d, // I64
|
2020-02-24 18:12:01 +01:00
|
|
|
/*
|
|
|
|
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 }
|
|
|
|
*/
|
2020-02-10 16:39:34 +01:00
|
|
|
];
|
|
|
|
let output = Ok((
|
|
|
|
&[] as &[u8],
|
|
|
|
Interfaces {
|
|
|
|
exports: vec![Export {
|
|
|
|
name: "ab",
|
|
|
|
input_types: vec![InterfaceType::I32],
|
|
|
|
output_types: vec![InterfaceType::I32],
|
|
|
|
}],
|
2020-02-24 16:23:31 +01:00
|
|
|
types: vec![Type {
|
|
|
|
inputs: vec![InterfaceType::I32, InterfaceType::I32],
|
|
|
|
outputs: vec![],
|
|
|
|
}],
|
2020-02-10 16:39:34 +01:00
|
|
|
imports: vec![Import {
|
|
|
|
namespace: "a",
|
|
|
|
name: "b",
|
|
|
|
input_types: vec![InterfaceType::I32],
|
|
|
|
output_types: vec![InterfaceType::I64],
|
|
|
|
}],
|
2020-02-24 18:12:01 +01:00
|
|
|
adapters: vec![/*Adapter::Import {
|
2020-02-10 16:39:34 +01:00
|
|
|
namespace: "a",
|
|
|
|
name: "b",
|
|
|
|
input_types: vec![InterfaceType::I32],
|
|
|
|
output_types: vec![InterfaceType::I32],
|
|
|
|
instructions: vec![Instruction::ArgumentGet { index: 1 }],
|
2020-02-24 18:12:01 +01:00
|
|
|
}*/],
|
2020-02-10 16:39:34 +01:00
|
|
|
},
|
|
|
|
));
|
|
|
|
|
2020-02-17 13:52:00 +01:00
|
|
|
assert_eq!(interfaces::<()>(input), output);
|
2020-02-10 16:39:34 +01:00
|
|
|
}
|
2019-09-13 12:00:05 +02:00
|
|
|
}
|