From 09e57b7156423fca9e4ea07ba8acdd76385321a1 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 24 Feb 2020 15:37:03 +0100 Subject: [PATCH] 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. --- src/ast.rs | 42 ++++--- src/decoders/binary.rs | 196 +++++++++++++++++---------------- src/decoders/wat.rs | 138 ++++++++++++++--------- src/encoders/binary.rs | 120 ++++++++++---------- src/encoders/wat.rs | 85 +++++++------- src/interpreter/wasm/values.rs | 48 +++++--- 6 files changed, 357 insertions(+), 272 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index d0c8cab..1c80484 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -7,26 +7,29 @@ use std::str; /// Represents the types supported by WIT. #[derive(PartialEq, Debug)] pub enum InterfaceType { - /// An integer. - Int, + /// A 8-bits signed integer. + S8, - /// A float. - Float, + /// A 16-bits signed integer. + S16, - /// Opaque reference. - Any, + /// A 32-bits signed integer. + S32, - /// A string. - String, + /// A 64-bits signed integer. + S64, - /// A sequence. - Seq, + /// A 8-bits unsigned integer. + U8, - /// A 32-bits integer. - I32, + /// A 16-bits unsigned integer. + U16, - /// A 64-bits integer. - I64, + /// A 32-bits unsigned integer. + U32, + + /// A 64-bits unsigned integer. + U64, /// A 32-bits float. F32, @@ -34,8 +37,17 @@ pub enum InterfaceType { /// A 64-bits float. F64, + /// A stirng. + String, + /// An `any` reference. - AnyRef, + Anyref, + + /// A 32-bits integer (as defined in WebAssembly core). + I32, + + /// A 64-bits integer (as defiend in WebAssembly core). + I64, } /// Represents the kind of adapter. diff --git a/src/decoders/binary.rs b/src/decoders/binary.rs index 6beafc6..ffff812 100644 --- a/src/decoders/binary.rs +++ b/src/decoders/binary.rs @@ -8,21 +8,25 @@ use nom::{ use std::{convert::TryFrom, str}; /// Parse an `InterfaceType`. -impl TryFrom for InterfaceType { +impl TryFrom for InterfaceType { type Error = &'static str; - fn try_from(code: u64) -> Result { + fn try_from(code: u8) -> Result { Ok(match code { - 0x7fff => Self::Int, - 0x7ffe => Self::Float, - 0x7ffd => Self::Any, - 0x7ffc => Self::String, - 0x7ffb => Self::Seq, - 0x7f => Self::I32, - 0x7e => Self::I64, - 0x7d => Self::F32, - 0x7c => Self::F64, - 0x6f => Self::AnyRef, + 0 => Self::S8, + 1 => Self::S16, + 2 => Self::S32, + 3 => Self::S64, + 4 => Self::U8, + 5 => Self::U16, + 6 => Self::U32, + 7 => Self::U64, + 8 => Self::F32, + 9 => Self::F64, + 10 => Self::String, + 11 => Self::Anyref, + 12 => Self::I32, + 13 => Self::I64, _ => return Err("Unknown interface type code."), }) } @@ -133,7 +137,7 @@ fn ty<'input, E: ParseError<&'input [u8]>>( return Err(Err::Error(make_error(input, ErrorKind::Eof))); } - let (output, ty) = uleb(input)?; + let (output, ty) = byte(input)?; match InterfaceType::try_from(ty) { Ok(ty) => Ok((output, ty)), @@ -450,9 +454,9 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>( /// 0x02, // string of 2 bytes /// 0x61, 0x62, // "a", "b" /// 0x01, // list of 1 item -/// 0x7f, // I32 +/// 0x02, // S32 /// 0x01, // list of 1 item -/// 0x7f, // I32 +/// 0x02, // S32 /// 0x01, // 1 type /// 0x02, // string of 2 bytes /// 0x61, 0x62, // "a", "b" @@ -462,17 +466,17 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>( /// 0x01, // string of 1 byte /// 0x65, // "e" /// 0x02, // list of 2 items -/// 0x7f, // I32 -/// 0x7f, // I32 +/// 0x02, // S32 +/// 0x02, // S32 /// 0x01, // 1 import /// 0x01, // string of 1 byte /// 0x61, // "a" /// 0x01, // string of 1 byte /// 0x62, // "b" /// 0x01, // list of 1 item -/// 0x7f, // I32 +/// 0x02, // S32 /// 0x01, // list of 1 item -/// 0x7e, // I64 +/// 0x03, // S64 /// 0x01, // 1 adapter /// 0x00, // adapter kind: import /// 0x01, // string of 1 byte @@ -480,9 +484,9 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>( /// 0x01, // string of 1 byte /// 0x62, // "b" /// 0x01, // list of 1 item -/// 0x7f, // I32 +/// 0x02, // S32 /// 0x01, // list of 1 item -/// 0x7f, // I32 +/// 0x02, // S32 /// 0x01, // list of 1 item /// 0x00, 0x01, // ArgumentGet { index: 1 } /// 0x01, // 1 adapter @@ -494,25 +498,25 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>( /// Interfaces { /// exports: vec![Export { /// name: "ab", -/// input_types: vec![InterfaceType::I32], -/// output_types: vec![InterfaceType::I32], +/// input_types: vec![InterfaceType::S32], +/// output_types: vec![InterfaceType::S32], /// }], /// types: vec![Type::new( /// "ab", /// vec!["cd", "e"], -/// vec![InterfaceType::I32, InterfaceType::I32], +/// vec![InterfaceType::S32, InterfaceType::S32], /// )], /// imports: vec![Import { /// namespace: "a", /// name: "b", -/// input_types: vec![InterfaceType::I32], -/// output_types: vec![InterfaceType::I64], +/// input_types: vec![InterfaceType::S32], +/// output_types: vec![InterfaceType::S64], /// }], /// adapters: vec![Adapter::Import { /// namespace: "a", /// name: "b", -/// input_types: vec![InterfaceType::I32], -/// output_types: vec![InterfaceType::I32], +/// input_types: vec![InterfaceType::S32], +/// output_types: vec![InterfaceType::S32], /// instructions: vec![Instruction::ArgumentGet { index: 1 }], /// }], /// forwards: vec![Forward { name: "a" }], @@ -639,32 +643,40 @@ mod tests { #[test] fn test_ty() { let input = &[ - 0x0a, // list of 10 items - 0xff, 0xff, 0x01, // Int - 0xfe, 0xff, 0x01, // Float - 0xfd, 0xff, 0x01, // Any - 0xfc, 0xff, 0x01, // String - 0xfb, 0xff, 0x01, // Seq - 0x7f, // I32 - 0x7e, // I64 - 0x7d, // F32 - 0x7c, // F64 - 0x6f, // AnyRef + 0x0e, // list of 14 items + 0x00, // S8 + 0x01, // S16 + 0x02, // S32 + 0x03, // S64 + 0x04, // U8 + 0x05, // U16 + 0x06, // U32 + 0x07, // U64 + 0x08, // F32 + 0x09, // F64 + 0x0a, // String + 0x0b, // Anyref + 0x0c, // I32 + 0x0d, // I64 0x01, ]; let output = Ok(( &[0x01][..], vec![ - InterfaceType::Int, - InterfaceType::Float, - InterfaceType::Any, - InterfaceType::String, - InterfaceType::Seq, - InterfaceType::I32, - InterfaceType::I64, + InterfaceType::S8, + InterfaceType::S16, + InterfaceType::S32, + InterfaceType::S64, + InterfaceType::U8, + InterfaceType::U16, + InterfaceType::U32, + InterfaceType::U64, InterfaceType::F32, InterfaceType::F64, - InterfaceType::AnyRef, + InterfaceType::String, + InterfaceType::Anyref, + InterfaceType::I32, + InterfaceType::I64, ], )); @@ -680,19 +692,19 @@ mod tests { 0x02, 0x03, 0x61, 0x62, 0x63, // CallExport { export_name: "abc" } 0x03, // ReadUtf8 0x04, 0x03, 0x61, 0x62, 0x63, // WriteUtf8 { allocator_name: "abc" } - 0x05, 0xff, 0xff, 0x01, // AsWasm(Int) - 0x06, 0x7e, // AsInterface(I64) + 0x05, 0x00, // AsWasm(S8) + 0x06, 0x00, // AsInterface(S8) 0x07, // TableRefAdd 0x08, // TableRefGet 0x09, 0x01, // CallMethod(1) - 0x0a, 0x7f, // MakeRecord(I32) - 0x0c, 0xff, 0xff, 0x01, 0x02, // GetField(Int, 2) - 0x0d, 0x7f, 0x01, // Const(I32, 1) + 0x0a, 0x0c, // MakeRecord(I32) + 0x0c, 0x00, 0x02, // GetField(S8, 2) + 0x0d, 0x0c, 0x01, // Const(I32, 1) 0x0e, 0x01, // FoldSeq(1) - 0x0f, 0x7f, // Add(I32) - 0x10, 0x7f, 0x03, 0x61, 0x62, 0x63, // MemToSeq(I32, "abc") - 0x11, 0x7f, 0x03, 0x61, 0x62, 0x63, // Load(I32, "abc") - 0x12, 0x7f, // SeqNew(I32) + 0x0f, 0x00, // Add(I32) + 0x10, 0x00, 0x03, 0x61, 0x62, 0x63, // MemToSeq(S8, "abc") + 0x11, 0x00, 0x03, 0x61, 0x62, 0x63, // Load(S8, "abc") + 0x12, 0x00, // SeqNew(S8) 0x13, // ListPush 0x14, 0x01, 0x02, // RepeatUntil(1, 2) 0x0a, @@ -707,19 +719,19 @@ mod tests { Instruction::WriteUtf8 { allocator_name: "abc", }, - Instruction::AsWasm(InterfaceType::Int), - Instruction::AsInterface(InterfaceType::I64), + Instruction::AsWasm(InterfaceType::S8), + Instruction::AsInterface(InterfaceType::S8), Instruction::TableRefAdd, Instruction::TableRefGet, Instruction::CallMethod(1), Instruction::MakeRecord(InterfaceType::I32), - Instruction::GetField(InterfaceType::Int, 2), + Instruction::GetField(InterfaceType::S8, 2), Instruction::Const(InterfaceType::I32, 1), Instruction::FoldSeq(1), - Instruction::Add(InterfaceType::I32), - Instruction::MemToSeq(InterfaceType::I32, "abc"), - Instruction::Load(InterfaceType::I32, "abc"), - Instruction::SeqNew(InterfaceType::I32), + Instruction::Add(InterfaceType::S8), + Instruction::MemToSeq(InterfaceType::S8, "abc"), + Instruction::Load(InterfaceType::S8, "abc"), + Instruction::SeqNew(InterfaceType::S8), Instruction::ListPush, Instruction::RepeatUntil(1, 2), ], @@ -735,9 +747,9 @@ mod tests { 0x02, // string of 2 bytes 0x61, 0x62, // "a", "b" 0x01, // list of 1 item - 0x7f, // I32 + 0x00, // S8 0x01, // list of 1 item - 0x7f, // I32 + 0x00, // S8 0x02, // string of 2 bytes 0x63, 0x64, // "c", "d" 0x00, // list of 0 item @@ -748,8 +760,8 @@ mod tests { vec![ Export { name: "ab", - input_types: vec![InterfaceType::I32], - output_types: vec![InterfaceType::I32], + input_types: vec![InterfaceType::S8], + output_types: vec![InterfaceType::S8], }, Export { name: "cd", @@ -774,15 +786,15 @@ mod tests { 0x01, // string of 1 byte 0x65, // "e" 0x02, // list of 2 items - 0x7f, // I32 - 0x7f, // I32 + 0x02, // S32 + 0x02, // S32 ]; let output = Ok(( &[] as &[u8], vec![Type::new( "ab", vec!["cd", "e"], - vec![InterfaceType::I32, InterfaceType::I32], + vec![InterfaceType::S32, InterfaceType::S32], )], )); @@ -798,17 +810,17 @@ mod tests { 0x01, // string of 1 byte 0x62, // "b" 0x01, // list of 1 item - 0x7f, // I32 + 0x02, // S32 0x01, // list of 1 item - 0x7e, // I64 + 0x03, // S64 0x01, // string of 1 byte 0x63, // "c" 0x01, // string of 1 byte 0x64, // "d" 0x01, // list of 1 item - 0x7f, // I32 + 0x02, // S32 0x01, // list of 1 item - 0x7e, // I64 + 0x03, // S64 ]; let output = Ok(( &[] as &[u8], @@ -816,14 +828,14 @@ mod tests { Import { namespace: "a", name: "b", - input_types: vec![InterfaceType::I32], - output_types: vec![InterfaceType::I64], + input_types: vec![InterfaceType::S32], + output_types: vec![InterfaceType::S64], }, Import { namespace: "c", name: "d", - input_types: vec![InterfaceType::I32], - output_types: vec![InterfaceType::I64], + input_types: vec![InterfaceType::S32], + output_types: vec![InterfaceType::S64], }, ], )); @@ -841,27 +853,27 @@ mod tests { 0x01, // string of 1 byte 0x62, // "b" 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item 0x00, 0x01, // ArgumentGet { index: 1 } 0x01, // adapter kind: export 0x01, // string of 1 byte 0x63, // "c" 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item 0x00, 0x01, // ArgumentGet { index: 1 } 0x02, // adapter kind: helper function 0x01, // string of 1 byte 0x64, // "d" 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item 0x00, 0x01, // ArgumentGet { index: 1 } ]; @@ -917,9 +929,9 @@ mod tests { 0x02, // string of 2 bytes 0x61, 0x62, // "a", "b" 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // 1 type 0x02, // string of 2 bytes 0x61, 0x62, // "a", "b" @@ -929,17 +941,17 @@ mod tests { 0x01, // string of 1 byte 0x65, // "e" 0x02, // list of 2 items - 0x7f, // I32 - 0x7f, // I32 + 0x0c, // I32 + 0x0c, // I32 0x01, // 1 import 0x01, // string of 1 byte 0x61, // "a" 0x01, // string of 1 byte 0x62, // "b" 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item - 0x7e, // I64 + 0x0d, // I64 0x01, // 1 adapter 0x00, // adapter kind: import 0x01, // string of 1 byte @@ -947,9 +959,9 @@ mod tests { 0x01, // string of 1 byte 0x62, // "b" 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item 0x00, 0x01, // ArgumentGet { index: 1 } 0x01, // 1 adapter diff --git a/src/decoders/wat.rs b/src/decoders/wat.rs index 7ef1d54..e6b5215 100644 --- a/src/decoders/wat.rs +++ b/src/decoders/wat.rs @@ -18,11 +18,15 @@ mod keyword { custom_keyword!(forward); // New types. - custom_keyword!(int); - custom_keyword!(float); - custom_keyword!(any); + custom_keyword!(s8); + custom_keyword!(s16); + custom_keyword!(s32); + custom_keyword!(s64); + custom_keyword!(u8); + custom_keyword!(u16); + custom_keyword!(u32); + custom_keyword!(u64); custom_keyword!(string); - custom_keyword!(seq); // Instructions. custom_keyword!(argument_get = "arg.get"); @@ -47,39 +51,42 @@ mod keyword { custom_keyword!(repeat_until = "repeat-until"); } -/// Issue: Uppercased keyword aren't supported for the moment. impl Parse<'_> for InterfaceType { fn parse(parser: Parser<'_>) -> Result { let mut lookahead = parser.lookahead1(); - if lookahead.peek::() { - parser.parse::()?; + if lookahead.peek::() { + parser.parse::()?; - Ok(InterfaceType::Int) - } else if lookahead.peek::() { - parser.parse::()?; + Ok(InterfaceType::S8) + } else if lookahead.peek::() { + parser.parse::()?; - Ok(InterfaceType::Float) - } else if lookahead.peek::() { - parser.parse::()?; + Ok(InterfaceType::S16) + } else if lookahead.peek::() { + parser.parse::()?; - Ok(InterfaceType::Any) - } else if lookahead.peek::() { - parser.parse::()?; + Ok(InterfaceType::S32) + } else if lookahead.peek::() { + parser.parse::()?; - Ok(InterfaceType::String) - } else if lookahead.peek::() { - parser.parse::()?; + Ok(InterfaceType::S64) + } else if lookahead.peek::() { + parser.parse::()?; - Ok(InterfaceType::Seq) - } else if lookahead.peek::() { - parser.parse::()?; + Ok(InterfaceType::U8) + } else if lookahead.peek::() { + parser.parse::()?; - Ok(InterfaceType::I32) - } else if lookahead.peek::() { - parser.parse::()?; + Ok(InterfaceType::U16) + } else if lookahead.peek::() { + parser.parse::()?; - Ok(InterfaceType::I64) + Ok(InterfaceType::U32) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(InterfaceType::U64) } else if lookahead.peek::() { parser.parse::()?; @@ -88,10 +95,26 @@ impl Parse<'_> for InterfaceType { parser.parse::()?; Ok(InterfaceType::F64) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(InterfaceType::String) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(InterfaceType::String) } else if lookahead.peek::() { parser.parse::()?; - Ok(InterfaceType::AnyRef) + Ok(InterfaceType::Anyref) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(InterfaceType::I32) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(InterfaceType::I64) } else { Err(lookahead.error()) } @@ -464,16 +487,16 @@ impl<'a> Parse<'a> for Interfaces<'a> { /// (@interface export "bar") /// /// (@interface func $ns_foo (import "ns" "foo") -/// (result i32)) +/// (result i32)) /// /// (@interface func $ns_bar (import "ns" "bar")) /// /// (@interface adapt (import "ns" "foo") -/// (param i32) -/// arg.get 42) +/// (param i32) +/// arg.get 42) /// /// (@interface adapt (export "bar") -/// arg.get 42) +/// arg.get 42) /// /// (@interface forward (export "main"))"#, /// ) @@ -543,19 +566,24 @@ mod tests { #[test] fn test_interface_type() { let inputs = vec![ - "int", "float", "any", "string", "seq", "i32", "i64", "f32", "f64", "anyref", + "s8", "s16", "s32", "s64", "u8", "u16", "u32", "u64", "f32", "f64", "string", "anyref", + "i32", "i64", ]; let outputs = vec![ - InterfaceType::Int, - InterfaceType::Float, - InterfaceType::Any, - InterfaceType::String, - InterfaceType::Seq, - InterfaceType::I32, - InterfaceType::I64, + InterfaceType::S8, + InterfaceType::S16, + InterfaceType::S32, + InterfaceType::S64, + InterfaceType::U8, + InterfaceType::U16, + InterfaceType::U32, + InterfaceType::U64, InterfaceType::F32, InterfaceType::F64, - InterfaceType::AnyRef, + InterfaceType::String, + InterfaceType::Anyref, + InterfaceType::I32, + InterfaceType::I64, ]; assert_eq!(inputs.len(), outputs.len()); @@ -576,19 +604,19 @@ mod tests { r#"call-export "foo""#, "read-utf8", r#"write-utf8 "foo""#, - "as-wasm int", + "as-wasm s8", "as-interface anyref", "table-ref-add", "table-ref-get", "call-method 7", - "make-record int", - "get-field int 7", + "make-record s8", + "get-field i32 7", "const i32 7", "fold-seq 7", - "add int", - r#"mem-to-seq int "foo""#, - r#"load int "foo""#, - "seq.new int", + "add i32", + r#"mem-to-seq i32 "foo""#, + r#"load i32 "foo""#, + "seq.new i32", "list.push", "repeat-until 1 2", ]; @@ -600,19 +628,19 @@ mod tests { Instruction::WriteUtf8 { allocator_name: "foo", }, - Instruction::AsWasm(InterfaceType::Int), - Instruction::AsInterface(InterfaceType::AnyRef), + Instruction::AsWasm(InterfaceType::S8), + Instruction::AsInterface(InterfaceType::Anyref), Instruction::TableRefAdd, Instruction::TableRefGet, Instruction::CallMethod(7), - Instruction::MakeRecord(InterfaceType::Int), - Instruction::GetField(InterfaceType::Int, 7), + Instruction::MakeRecord(InterfaceType::S8), + Instruction::GetField(InterfaceType::I32, 7), Instruction::Const(InterfaceType::I32, 7), Instruction::FoldSeq(7), - Instruction::Add(InterfaceType::Int), - Instruction::MemToSeq(InterfaceType::Int, "foo"), - Instruction::Load(InterfaceType::Int, "foo"), - Instruction::SeqNew(InterfaceType::Int), + Instruction::Add(InterfaceType::I32), + Instruction::MemToSeq(InterfaceType::I32, "foo"), + Instruction::Load(InterfaceType::I32, "foo"), + Instruction::SeqNew(InterfaceType::I32), Instruction::ListPush, Instruction::RepeatUntil(1, 2), ]; diff --git a/src/encoders/binary.rs b/src/encoders/binary.rs index 9a61f8c..47cd12d 100644 --- a/src/encoders/binary.rs +++ b/src/encoders/binary.rs @@ -97,16 +97,20 @@ where { fn to_bytes(&self, writer: &mut W) -> io::Result<()> { match self { - InterfaceType::Int => 0x7fff_u64.to_bytes(writer), - InterfaceType::Float => 0x7ffe_u64.to_bytes(writer), - InterfaceType::Any => 0x7ffd_u64.to_bytes(writer), - InterfaceType::String => 0x7ffc_u64.to_bytes(writer), - InterfaceType::Seq => 0x7ffb_u64.to_bytes(writer), - InterfaceType::I32 => 0x7f_u64.to_bytes(writer), - InterfaceType::I64 => 0x7e_u64.to_bytes(writer), - InterfaceType::F32 => 0x7d_u64.to_bytes(writer), - InterfaceType::F64 => 0x7c_u64.to_bytes(writer), - InterfaceType::AnyRef => 0x6f_u64.to_bytes(writer), + InterfaceType::S8 => 0x00_u8.to_bytes(writer), + InterfaceType::S16 => 0x01_u8.to_bytes(writer), + InterfaceType::S32 => 0x02_u8.to_bytes(writer), + InterfaceType::S64 => 0x03_u8.to_bytes(writer), + InterfaceType::U8 => 0x04_u8.to_bytes(writer), + InterfaceType::U16 => 0x05_u8.to_bytes(writer), + InterfaceType::U32 => 0x06_u8.to_bytes(writer), + InterfaceType::U64 => 0x07_u8.to_bytes(writer), + InterfaceType::F32 => 0x08_u8.to_bytes(writer), + InterfaceType::F64 => 0x09_u8.to_bytes(writer), + InterfaceType::String => 0x0a_u8.to_bytes(writer), + InterfaceType::Anyref => 0x0b_u8.to_bytes(writer), + InterfaceType::I32 => 0x0c_u8.to_bytes(writer), + InterfaceType::I64 => 0x0d_u8.to_bytes(writer), } } } @@ -444,16 +448,20 @@ mod tests { #[test] fn test_interface_type() { - assert_to_bytes!(InterfaceType::Int, &[0xff, 0xff, 0x01]); - assert_to_bytes!(InterfaceType::Float, &[0xfe, 0xff, 0x01]); - assert_to_bytes!(InterfaceType::Any, &[0xfd, 0xff, 0x01]); - assert_to_bytes!(InterfaceType::String, &[0xfc, 0xff, 0x01]); - assert_to_bytes!(InterfaceType::Seq, &[0xfb, 0xff, 0x01]); - assert_to_bytes!(InterfaceType::I32, &[0x7f]); - assert_to_bytes!(InterfaceType::I64, &[0x7e]); - assert_to_bytes!(InterfaceType::F32, &[0x7d]); - assert_to_bytes!(InterfaceType::F64, &[0x7c]); - assert_to_bytes!(InterfaceType::AnyRef, &[0x6f]); + assert_to_bytes!(InterfaceType::S8, &[0x00]); + assert_to_bytes!(InterfaceType::S16, &[0x01]); + assert_to_bytes!(InterfaceType::S32, &[0x02]); + assert_to_bytes!(InterfaceType::S64, &[0x03]); + assert_to_bytes!(InterfaceType::U8, &[0x04]); + assert_to_bytes!(InterfaceType::U16, &[0x05]); + assert_to_bytes!(InterfaceType::U32, &[0x06]); + assert_to_bytes!(InterfaceType::U64, &[0x07]); + assert_to_bytes!(InterfaceType::F32, &[0x08]); + assert_to_bytes!(InterfaceType::F64, &[0x09]); + assert_to_bytes!(InterfaceType::String, &[0x0a]); + assert_to_bytes!(InterfaceType::Anyref, &[0x0b]); + assert_to_bytes!(InterfaceType::I32, &[0x0c]); + assert_to_bytes!(InterfaceType::I64, &[0x0d]); } #[test] @@ -477,10 +485,10 @@ mod tests { 0x62, // "b" 0x63, // "c" 0x02, // list of 2 items - 0x7f, // I32 - 0x7e, // I64 + 0x0c, // I32 + 0x0d, // I64 0x01, // list of 1 items - 0x7f, // I32 + 0x0c, // I32 ] ); } @@ -502,8 +510,8 @@ mod tests { 0x01, // string of length 1 0x63, // "c" 0x02, // list of 2 items - 0x7f, // I32 - 0x7e, // I64 + 0x0c, // I32 + 0x0d, // I64 ] ); } @@ -523,10 +531,10 @@ mod tests { 0x01, // string of length 1 0x62, // "b" 0x02, // list of 2 items - 0x7f, // I32 - 0x7e, // I64 + 0x0c, // I32 + 0x0d, // I64 0x01, // list of 1 items - 0x7f, // I32 + 0x0c, // I32 ] ); } @@ -548,10 +556,10 @@ mod tests { 0x01, // string of length 1 0x62, // "b" 0x02, // list of 2 items - 0x7f, // I32 - 0x7e, // I64 + 0x0c, // I32 + 0x0d, // I64 0x01, // list of 1 items - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item 0x00, 0x01, // ArgumentGet { index: 1 } ] @@ -572,10 +580,10 @@ mod tests { 0x01, // string of length 1 0x61, // "a" 0x02, // list of 2 items - 0x7f, // I32 - 0x7e, // I64 + 0x0c, // I32 + 0x0d, // I64 0x01, // list of 1 items - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item 0x00, 0x01, // ArgumentGet { index: 1 } ] @@ -596,10 +604,10 @@ mod tests { 0x01, // string of length 1 0x61, // "a" 0x02, // list of 2 items - 0x7f, // I32 - 0x7e, // I64 + 0x0c, // I32 + 0x0d, // I64 0x01, // list of 1 items - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item 0x00, 0x01, // ArgumentGet { index: 1 } ] @@ -652,9 +660,9 @@ mod tests { 0x02, // string of 2 bytes 0x61, 0x62, // "a", "b" 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // 1 type 0x02, // string of 2 bytes 0x61, 0x62, // "a", "b" @@ -664,17 +672,17 @@ mod tests { 0x01, // string of 1 byte 0x65, // "e" 0x02, // list of 2 items - 0x7f, // I32 - 0x7f, // I32 + 0x0c, // I32 + 0x0c, // I32 0x01, // 1 import 0x01, // string of 1 byte 0x61, // "a" 0x01, // string of 1 byte 0x62, // "b" 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item - 0x7e, // I64 + 0x0d, // I64 0x01, // 1 adapter 0x00, // adapter kind: import 0x01, // string of 1 byte @@ -682,9 +690,9 @@ mod tests { 0x01, // string of 1 byte 0x62, // "b" 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item - 0x7f, // I32 + 0x0c, // I32 0x01, // list of 1 item 0x00, 0x01, // ArgumentGet { index: 1 } 0x01, // 1 adapter @@ -705,13 +713,13 @@ mod tests { Instruction::WriteUtf8 { allocator_name: "abc", }, - Instruction::AsWasm(InterfaceType::Int), + Instruction::AsWasm(InterfaceType::I32), Instruction::AsInterface(InterfaceType::I64), Instruction::TableRefAdd, Instruction::TableRefGet, Instruction::CallMethod(1), Instruction::MakeRecord(InterfaceType::I32), - Instruction::GetField(InterfaceType::Int, 2), + Instruction::GetField(InterfaceType::I32, 2), Instruction::Const(InterfaceType::I32, 1), Instruction::FoldSeq(1), Instruction::Add(InterfaceType::I32), @@ -728,19 +736,19 @@ mod tests { 0x02, 0x03, 0x61, 0x62, 0x63, // CallExport { export_name: "abc" } 0x03, // ReadUtf8 0x04, 0x03, 0x61, 0x62, 0x63, // WriteUtf8 { allocator_name: "abc" } - 0x05, 0xff, 0xff, 0x01, // AsWasm(Int) - 0x06, 0x7e, // AsInterface(I64) + 0x05, 0x0c, // AsWasm(Int) + 0x06, 0x0d, // AsInterface(I64) 0x07, // TableRefAdd 0x08, // TableRefGet 0x09, 0x01, // CallMethod(1) - 0x0a, 0x7f, // MakeRecord(I32) - 0x0c, 0xff, 0xff, 0x01, 0x02, // GetField(Int, 2) - 0x0d, 0x7f, 0x01, // Const(I32, 1) + 0x0a, 0x0c, // MakeRecord(I32) + 0x0c, 0x0c, 0x02, // GetField(I32, 2) + 0x0d, 0x0c, 0x01, // Const(I32, 1) 0x0e, 0x01, // FoldSeq(1) - 0x0f, 0x7f, // Add(I32) - 0x10, 0x7f, 0x03, 0x61, 0x62, 0x63, // MemToSeq(I32, "abc") - 0x11, 0x7f, 0x03, 0x61, 0x62, 0x63, // Load(I32, "abc") - 0x12, 0x7f, // SeqNew(I32) + 0x0f, 0x0c, // Add(I32) + 0x10, 0x0c, 0x03, 0x61, 0x62, 0x63, // MemToSeq(I32, "abc") + 0x11, 0x0c, 0x03, 0x61, 0x62, 0x63, // Load(I32, "abc") + 0x12, 0x0c, // SeqNew(I32) 0x13, // ListPush 0x14, 0x01, 0x02, // RepeatUntil(1, 2) ] diff --git a/src/encoders/wat.rs b/src/encoders/wat.rs index 08813a2..3748829 100644 --- a/src/encoders/wat.rs +++ b/src/encoders/wat.rs @@ -98,16 +98,20 @@ use std::string::ToString; impl ToString for &InterfaceType { fn to_string(&self) -> String { match self { - InterfaceType::Int => "Int".into(), - InterfaceType::Float => "Float".into(), - InterfaceType::Any => "Any".into(), - InterfaceType::String => "String".into(), - InterfaceType::Seq => "Seq".into(), - InterfaceType::I32 => "i32".into(), - InterfaceType::I64 => "i64".into(), + InterfaceType::S8 => "s8".into(), + InterfaceType::S16 => "s16".into(), + InterfaceType::S32 => "s32".into(), + InterfaceType::S64 => "s64".into(), + InterfaceType::U8 => "u8".into(), + InterfaceType::U16 => "u16".into(), + InterfaceType::U32 => "u32".into(), + InterfaceType::U64 => "u64".into(), InterfaceType::F32 => "f32".into(), InterfaceType::F64 => "f64".into(), - InterfaceType::AnyRef => "anyref".into(), + InterfaceType::String => "string".into(), + InterfaceType::Anyref => "anyref".into(), + InterfaceType::I32 => "i32".into(), + InterfaceType::I64 => "i64".into(), } } } @@ -374,19 +378,24 @@ mod tests { #[test] fn test_interface_types() { let inputs: Vec = vec![ - (&InterfaceType::Int).to_string(), - (&InterfaceType::Float).to_string(), - (&InterfaceType::Any).to_string(), - (&InterfaceType::String).to_string(), - (&InterfaceType::Seq).to_string(), - (&InterfaceType::I32).to_string(), - (&InterfaceType::I64).to_string(), + (&InterfaceType::S8).to_string(), + (&InterfaceType::S16).to_string(), + (&InterfaceType::S32).to_string(), + (&InterfaceType::S64).to_string(), + (&InterfaceType::U8).to_string(), + (&InterfaceType::U16).to_string(), + (&InterfaceType::U32).to_string(), + (&InterfaceType::U64).to_string(), (&InterfaceType::F32).to_string(), (&InterfaceType::F64).to_string(), - (&InterfaceType::AnyRef).to_string(), + (&InterfaceType::String).to_string(), + (&InterfaceType::Anyref).to_string(), + (&InterfaceType::I32).to_string(), + (&InterfaceType::I64).to_string(), ]; let outputs = vec![ - "Int", "Float", "Any", "String", "Seq", "i32", "i64", "f32", "f64", "anyref", + "s8", "s16", "s32", "s64", "u8", "u16", "u32", "u64", "f32", "f64", "string", "anyref", + "i32", "i64", ]; assert_eq!(inputs, outputs); @@ -403,19 +412,19 @@ mod tests { allocator_name: "foo", }) .to_string(), - (&Instruction::AsWasm(InterfaceType::Int)).to_string(), - (&Instruction::AsInterface(InterfaceType::AnyRef)).to_string(), + (&Instruction::AsWasm(InterfaceType::I32)).to_string(), + (&Instruction::AsInterface(InterfaceType::I32)).to_string(), (&Instruction::TableRefAdd).to_string(), (&Instruction::TableRefGet).to_string(), (&Instruction::CallMethod(7)).to_string(), - (&Instruction::MakeRecord(InterfaceType::Int)).to_string(), - (&Instruction::GetField(InterfaceType::Int, 7)).to_string(), + (&Instruction::MakeRecord(InterfaceType::I32)).to_string(), + (&Instruction::GetField(InterfaceType::I32, 7)).to_string(), (&Instruction::Const(InterfaceType::I32, 7)).to_string(), (&Instruction::FoldSeq(7)).to_string(), - (&Instruction::Add(InterfaceType::Int)).to_string(), - (&Instruction::MemToSeq(InterfaceType::Int, "foo")).to_string(), - (&Instruction::Load(InterfaceType::Int, "foo")).to_string(), - (&Instruction::SeqNew(InterfaceType::Int)).to_string(), + (&Instruction::Add(InterfaceType::I32)).to_string(), + (&Instruction::MemToSeq(InterfaceType::I32, "foo")).to_string(), + (&Instruction::Load(InterfaceType::I32, "foo")).to_string(), + (&Instruction::SeqNew(InterfaceType::I32)).to_string(), (&Instruction::ListPush).to_string(), (&Instruction::RepeatUntil(1, 2)).to_string(), ]; @@ -425,19 +434,19 @@ mod tests { r#"call-export "foo""#, "read-utf8", r#"write-utf8 "foo""#, - "as-wasm Int", - "as-interface anyref", + "as-wasm i32", + "as-interface i32", "table-ref-add", "table-ref-get", "call-method 7", - "make-record Int", - "get-field Int 7", + "make-record i32", + "get-field i32 7", "const i32 7", "fold-seq 7", - "add Int", - r#"mem-to-seq Int "foo""#, - r#"load Int "foo""#, - "seq.new Int", + "add i32", + r#"mem-to-seq i32 "foo""#, + r#"load i32 "foo""#, + "seq.new i32", "list.push", "repeat-until 1 2", ]; @@ -493,7 +502,7 @@ mod tests { (&Import { namespace: "ns", name: "foo", - input_types: vec![InterfaceType::Int, InterfaceType::String], + input_types: vec![InterfaceType::I32, InterfaceType::String], output_types: vec![InterfaceType::String], }) .to_string(), @@ -521,12 +530,12 @@ mod tests { ]; let outputs = vec![ r#"(@interface func $ns_foo (import "ns" "foo") - (param Int String) - (result String))"#, + (param i32 string) + (result string))"#, r#"(@interface func $ns_foo (import "ns" "foo") - (param String))"#, + (param string))"#, r#"(@interface func $ns_foo (import "ns" "foo") - (result String))"#, + (result string))"#, r#"(@interface func $ns_foo (import "ns" "foo"))"#, ]; diff --git a/src/interpreter/wasm/values.rs b/src/interpreter/wasm/values.rs index f50763f..1e0976c 100644 --- a/src/interpreter/wasm/values.rs +++ b/src/interpreter/wasm/values.rs @@ -6,29 +6,39 @@ pub use crate::ast::InterfaceType; #[derive(Debug, Clone, PartialEq)] pub enum InterfaceValue { - Int(isize), - Float(f64), - Any(isize), - String(String), - // Seq(…), - I32(i32), - I64(i64), + S8(i8), + S16(i16), + S32(i32), + S64(i64), + U8(u8), + U16(u16), + U32(u32), + U64(u64), F32(f32), F64(f64), - // AnyRef(…), + String(String), + //Anyref(?), + I32(i32), + I64(i64), } impl From<&InterfaceValue> for InterfaceType { fn from(value: &InterfaceValue) -> Self { match value { - InterfaceValue::Int(_) => Self::Int, - InterfaceValue::Float(_) => Self::Float, - InterfaceValue::Any(_) => Self::Any, - InterfaceValue::String(_) => Self::String, - InterfaceValue::I32(_) => Self::I32, - InterfaceValue::I64(_) => Self::I64, + InterfaceValue::S8(_) => Self::S8, + InterfaceValue::S16(_) => Self::S16, + InterfaceValue::S32(_) => Self::S32, + InterfaceValue::S64(_) => Self::S64, + InterfaceValue::U8(_) => Self::U8, + InterfaceValue::U16(_) => Self::U16, + InterfaceValue::U32(_) => Self::U32, + InterfaceValue::U64(_) => Self::U64, InterfaceValue::F32(_) => Self::F32, InterfaceValue::F64(_) => Self::F64, + InterfaceValue::String(_) => Self::String, + //InterfaceValue::Anyref(_) => Self::Anyref, + InterfaceValue::I32(_) => Self::I32, + InterfaceValue::I64(_) => Self::I64, } } } @@ -60,8 +70,14 @@ macro_rules! from_x_for_interface_value { }; } +from_x_for_interface_value!(i8, S8); +from_x_for_interface_value!(i16, S16); +from_x_for_interface_value!(u8, U8); +from_x_for_interface_value!(u16, U16); +from_x_for_interface_value!(u32, U32); +from_x_for_interface_value!(u64, U64); +from_x_for_interface_value!(f32, F32); +from_x_for_interface_value!(f64, F64); from_x_for_interface_value!(String, String); from_x_for_interface_value!(i32, I32); from_x_for_interface_value!(i64, I64); -from_x_for_interface_value!(f32, F32); -from_x_for_interface_value!(f64, F64);