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-10 16:39:06 +01:00
|
|
|
/// Parse an adapter kind.
|
2019-09-13 14:50:17 +02:00
|
|
|
impl TryFrom<u8> for AdapterKind {
|
|
|
|
type Error = &'static str;
|
|
|
|
|
|
|
|
fn try_from(code: u8) -> Result<Self, Self::Error> {
|
|
|
|
Ok(match code {
|
|
|
|
0x0 => Self::Import,
|
|
|
|
0x1 => Self::Export,
|
|
|
|
0x2 => Self::HelperFunction,
|
|
|
|
_ => return Err("Unknown adapter kind code."),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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 exports.
|
2019-09-13 14:26:49 +02:00
|
|
|
fn exports<'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<Export>, E> {
|
2020-02-13 13:36:18 +01:00
|
|
|
consume!((input, number_of_exports) = uleb(input)?);
|
2019-09-12 22:44:20 +02:00
|
|
|
|
2019-09-26 01:00:17 +02:00
|
|
|
let mut exports = Vec::with_capacity(number_of_exports as usize);
|
|
|
|
|
2019-09-12 22:44:20 +02:00
|
|
|
for _ in 0..number_of_exports {
|
|
|
|
consume!((input, export_name) = string(input)?);
|
|
|
|
consume!((input, export_input_types) = list(input, ty)?);
|
|
|
|
consume!((input, export_output_types) = list(input, ty)?);
|
|
|
|
|
|
|
|
exports.push(Export {
|
|
|
|
name: export_name,
|
|
|
|
input_types: export_input_types,
|
|
|
|
output_types: export_output_types,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok((input, exports))
|
|
|
|
}
|
|
|
|
|
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 {
|
|
|
|
consume!((input, type_name) = string(input)?);
|
|
|
|
consume!((input, type_fields) = list(input, string)?);
|
|
|
|
consume!((input, type_types) = list(input, ty)?);
|
|
|
|
|
2020-02-13 11:24:29 +01:00
|
|
|
types.push(Type::new(type_name, type_fields, type_types));
|
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 {
|
|
|
|
consume!((input, import_namespace) = string(input)?);
|
|
|
|
consume!((input, import_name) = string(input)?);
|
|
|
|
consume!((input, import_input_types) = list(input, ty)?);
|
|
|
|
consume!((input, import_output_types) = list(input, ty)?);
|
2019-09-12 22:44:20 +02:00
|
|
|
|
2020-02-10 15:41:10 +01:00
|
|
|
imports.push(Import {
|
|
|
|
namespace: import_namespace,
|
|
|
|
name: import_name,
|
|
|
|
input_types: import_input_types,
|
|
|
|
output_types: import_output_types,
|
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 {
|
|
|
|
consume!((input, adapter_kind) = byte(input)?);
|
|
|
|
let adapter_kind = AdapterKind::try_from(adapter_kind)
|
|
|
|
.map_err(|_| Err::Error(make_error(input, ErrorKind::ParseTo)))?;
|
|
|
|
|
|
|
|
match adapter_kind {
|
|
|
|
AdapterKind::Import => {
|
|
|
|
consume!((input, adapter_namespace) = string(input)?);
|
|
|
|
consume!((input, adapter_name) = string(input)?);
|
|
|
|
consume!((input, adapter_input_types) = list(input, ty)?);
|
|
|
|
consume!((input, adapter_output_types) = list(input, ty)?);
|
2020-02-10 16:39:06 +01:00
|
|
|
consume!((input, adapter_instructions) = list(input, instruction)?);
|
2019-09-12 22:44:20 +02:00
|
|
|
|
|
|
|
adapters.push(Adapter::Import {
|
|
|
|
namespace: adapter_namespace,
|
|
|
|
name: adapter_name,
|
|
|
|
input_types: adapter_input_types,
|
|
|
|
output_types: adapter_output_types,
|
|
|
|
instructions: adapter_instructions,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
AdapterKind::Export => {
|
|
|
|
consume!((input, adapter_name) = string(input)?);
|
|
|
|
consume!((input, adapter_input_types) = list(input, ty)?);
|
|
|
|
consume!((input, adapter_output_types) = list(input, ty)?);
|
2020-02-10 16:39:06 +01:00
|
|
|
consume!((input, adapter_instructions) = list(input, instruction)?);
|
2019-09-12 22:44:20 +02:00
|
|
|
|
|
|
|
adapters.push(Adapter::Export {
|
|
|
|
name: adapter_name,
|
|
|
|
input_types: adapter_input_types,
|
|
|
|
output_types: adapter_output_types,
|
|
|
|
instructions: adapter_instructions,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
AdapterKind::HelperFunction => {
|
|
|
|
consume!((input, adapter_name) = string(input)?);
|
|
|
|
consume!((input, adapter_input_types) = list(input, ty)?);
|
|
|
|
consume!((input, adapter_output_types) = list(input, ty)?);
|
2020-02-10 16:39:06 +01:00
|
|
|
consume!((input, adapter_instructions) = list(input, instruction)?);
|
2019-09-12 22:44:20 +02:00
|
|
|
|
|
|
|
adapters.push(Adapter::HelperFunction {
|
|
|
|
name: adapter_name,
|
|
|
|
input_types: adapter_input_types,
|
|
|
|
output_types: adapter_output_types,
|
|
|
|
instructions: adapter_instructions,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok((input, adapters))
|
|
|
|
}
|
|
|
|
|
2020-02-10 16:39:06 +01:00
|
|
|
/// Parse a list of forwarded exports.
|
2019-09-13 14:26:49 +02:00
|
|
|
fn forwards<'input, E: ParseError<&'input [u8]>>(
|
2020-02-13 13:54:26 +01:00
|
|
|
mut input: &'input [u8],
|
2019-09-12 22:44:20 +02:00
|
|
|
) -> IResult<&'input [u8], Vec<Forward>, E> {
|
2020-02-13 13:36:18 +01:00
|
|
|
consume!((input, number_of_forwards) = uleb(input)?);
|
2019-09-12 22:44:20 +02:00
|
|
|
|
2019-09-26 01:00:17 +02:00
|
|
|
let mut forwards = Vec::with_capacity(number_of_forwards as usize);
|
|
|
|
|
2019-09-12 22:44:20 +02:00
|
|
|
for _ in 0..number_of_forwards {
|
|
|
|
consume!((input, forward_name) = string(input)?);
|
|
|
|
|
|
|
|
forwards.push(Forward { name: forward_name });
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok((input, forwards))
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
consume!((input, exports) = exports(input)?);
|
|
|
|
consume!((input, types) = types(input)?);
|
|
|
|
consume!((input, imports) = imports(input)?);
|
|
|
|
consume!((input, adapters) = adapters(input)?);
|
|
|
|
consume!((input, forwards) = forwards(input)?);
|
|
|
|
|
|
|
|
Ok((
|
|
|
|
input,
|
|
|
|
Interfaces {
|
|
|
|
exports,
|
|
|
|
types,
|
|
|
|
imports,
|
|
|
|
adapters,
|
|
|
|
forwards,
|
|
|
|
},
|
|
|
|
))
|
|
|
|
}
|
|
|
|
|
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, // string of 2 bytes
|
|
|
|
/// 0x61, 0x62, // "a", "b"
|
|
|
|
/// 0x02, // list of 2 items
|
|
|
|
/// 0x02, // string of 2 bytes
|
|
|
|
/// 0x63, 0x64, // "c", "d"
|
|
|
|
/// 0x01, // string of 1 byte
|
|
|
|
/// 0x65, // "e"
|
|
|
|
/// 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-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 }
|
|
|
|
/// 0x01, // 1 adapter
|
|
|
|
/// 0x01, // string of 1 byte
|
|
|
|
/// 0x61, // "a"
|
|
|
|
/// ];
|
|
|
|
/// 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-13 11:24:29 +01:00
|
|
|
/// types: vec![Type::new(
|
|
|
|
/// "ab",
|
|
|
|
/// vec!["cd", "e"],
|
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
|
|
|
/// vec![InterfaceType::S32, InterfaceType::S32],
|
2020-02-13 11:24:29 +01:00
|
|
|
/// )],
|
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 }],
|
|
|
|
/// }],
|
|
|
|
/// forwards: vec![Forward { name: "a" }],
|
|
|
|
/// },
|
|
|
|
/// ));
|
|
|
|
///
|
|
|
|
/// 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, // string of 2 bytes
|
|
|
|
0x61, 0x62, // "a", "b"
|
|
|
|
0x02, // list of 2 items
|
|
|
|
0x02, // string of 2 bytes
|
|
|
|
0x63, 0x64, // "c", "d"
|
|
|
|
0x01, // string of 1 byte
|
|
|
|
0x65, // "e"
|
|
|
|
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
|
2019-09-13 14:24:03 +02:00
|
|
|
];
|
|
|
|
let output = Ok((
|
|
|
|
&[] as &[u8],
|
2020-02-13 11:24:29 +01:00
|
|
|
vec![Type::new(
|
|
|
|
"ab",
|
|
|
|
vec!["cd", "e"],
|
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
|
|
|
vec![InterfaceType::S32, InterfaceType::S32],
|
2020-02-13 11:24:29 +01:00
|
|
|
)],
|
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
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_adapters() {
|
|
|
|
let input = &[
|
|
|
|
0x03, // 3 adapters
|
|
|
|
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
|
|
|
0x02, // adapter kind: helper function
|
|
|
|
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
|
|
|
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
|
|
|
},
|
|
|
|
Adapter::HelperFunction {
|
|
|
|
name: "d",
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_forwards() {
|
|
|
|
let input = &[
|
|
|
|
0x02, // 2 adapters
|
|
|
|
0x01, // string of 1 byte
|
|
|
|
0x61, // "a"
|
|
|
|
0x02, // string of 2 bytes
|
|
|
|
0x62, 0x63, // "b", "c"
|
|
|
|
];
|
|
|
|
let output = Ok((
|
|
|
|
&[] as &[u8],
|
|
|
|
vec![Forward { name: "a" }, Forward { name: "bc" }],
|
|
|
|
));
|
|
|
|
|
|
|
|
assert_eq!(forwards::<()>(input), output);
|
|
|
|
}
|
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, // string of 2 bytes
|
|
|
|
0x61, 0x62, // "a", "b"
|
|
|
|
0x02, // list of 2 items
|
|
|
|
0x02, // string of 2 bytes
|
|
|
|
0x63, 0x64, // "c", "d"
|
|
|
|
0x01, // string of 1 byte
|
|
|
|
0x65, // "e"
|
|
|
|
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-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-10 16:39:34 +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
|
|
|
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, // list of 1 item
|
|
|
|
0x00, 0x01, // ArgumentGet { index: 1 }
|
|
|
|
0x01, // 1 adapter
|
|
|
|
0x01, // string of 1 byte
|
|
|
|
0x61, // "a"
|
|
|
|
];
|
|
|
|
let output = Ok((
|
|
|
|
&[] as &[u8],
|
|
|
|
Interfaces {
|
|
|
|
exports: vec![Export {
|
|
|
|
name: "ab",
|
|
|
|
input_types: vec![InterfaceType::I32],
|
|
|
|
output_types: vec![InterfaceType::I32],
|
|
|
|
}],
|
2020-02-13 11:24:29 +01:00
|
|
|
types: vec![Type::new(
|
|
|
|
"ab",
|
|
|
|
vec!["cd", "e"],
|
|
|
|
vec![InterfaceType::I32, InterfaceType::I32],
|
|
|
|
)],
|
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],
|
|
|
|
}],
|
|
|
|
adapters: vec![Adapter::Import {
|
|
|
|
namespace: "a",
|
|
|
|
name: "b",
|
|
|
|
input_types: vec![InterfaceType::I32],
|
|
|
|
output_types: vec![InterfaceType::I32],
|
|
|
|
instructions: vec![Instruction::ArgumentGet { index: 1 }],
|
|
|
|
}],
|
|
|
|
forwards: vec![Forward { name: "a" }],
|
|
|
|
},
|
|
|
|
));
|
|
|
|
|
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
|
|
|
}
|