diff --git a/lib/interface-types/src/ast.rs b/lib/interface-types/src/ast.rs index 28c8682b113..63cb7789f54 100644 --- a/lib/interface-types/src/ast.rs +++ b/lib/interface-types/src/ast.rs @@ -37,6 +37,12 @@ pub enum Instruction<'input> { GetField(InterfaceType, u64), Const(InterfaceType, u64), FoldSeq(u64), + Add(InterfaceType), + MemToSeq(InterfaceType, &'input str), + Load(InterfaceType, &'input str), + SeqNew(InterfaceType), + ListPush, + RepeatWhile(u64, u64), } #[derive(PartialEq, Debug)] diff --git a/lib/interface-types/src/decoders/binary.rs b/lib/interface-types/src/decoders/binary.rs index f3cedc53b04..b86cdc303cf 100644 --- a/lib/interface-types/src/decoders/binary.rs +++ b/lib/interface-types/src/decoders/binary.rs @@ -193,6 +193,36 @@ fn instructions<'input, E: ParseError<&'input [u8]>>( (input, Instruction::FoldSeq(argument_0)) } + 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 => { + consume!((input, argument_0) = leb(input)?); + consume!((input, argument_1) = leb(input)?); + (input, Instruction::RepeatWhile(argument_0, argument_1)) + } + _ => return Err(Err::Error(make_error(input, ErrorKind::ParseTo))), }) } @@ -467,7 +497,7 @@ mod tests { #[test] fn test_instructions() { let input = &[ - 0x0e, // list of 14 items + 0x14, // list of 20 items 0x00, 0x01, // ArgumentGet(1) 0x01, 0x01, // Call(1) 0x02, 0x03, 0x61, 0x62, 0x63, // CallExport("abc") @@ -482,6 +512,12 @@ mod tests { 0x0c, 0xff, 0xff, 0x01, 0x02, // GetField(Int, 2) 0x0d, 0x7f, 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) + 0x13, // ListPush + 0x14, 0x01, 0x02, // RepeatWhile(1, 2) 0x0a, ]; let output = Ok(( @@ -501,6 +537,12 @@ mod tests { Instruction::GetField(InterfaceType::Int, 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::ListPush, + Instruction::RepeatWhile(1, 2), ], )); diff --git a/lib/interface-types/src/encoders/wat.rs b/lib/interface-types/src/encoders/wat.rs index eafca5713fe..41f73b473dc 100644 --- a/lib/interface-types/src/encoders/wat.rs +++ b/lib/interface-types/src/encoders/wat.rs @@ -44,6 +44,22 @@ impl<'input> From<&Instruction<'input>> for String { format!("const {} {}", String::from(interface_type), value) } Instruction::FoldSeq(import_index) => format!("fold-seq {}", import_index), + Instruction::Add(interface_type) => format!("add {}", String::from(interface_type)), + Instruction::MemToSeq(interface_type, memory) => format!( + r#"mem-to-seq {} "{}""#, + String::from(interface_type), + memory + ), + Instruction::Load(interface_type, memory) => { + format!(r#"load {} "{}""#, String::from(interface_type), memory) + } + Instruction::SeqNew(interface_type) => { + format!("seq.new {}", String::from(interface_type)) + } + Instruction::ListPush => "list.push".into(), + Instruction::RepeatWhile(condition_index, step_index) => { + format!("repeat-while {} {}", condition_index, step_index) + } } } } @@ -212,6 +228,12 @@ mod tests { (&Instruction::GetField(InterfaceType::Int, 7)).into(), (&Instruction::Const(InterfaceType::I32, 7)).into(), (&Instruction::FoldSeq(7)).into(), + (&Instruction::Add(InterfaceType::Int)).into(), + (&Instruction::MemToSeq(InterfaceType::Int, "foo")).into(), + (&Instruction::Load(InterfaceType::Int, "foo")).into(), + (&Instruction::SeqNew(InterfaceType::Int)).into(), + (&Instruction::ListPush).into(), + (&Instruction::RepeatWhile(1, 2)).into(), ]; let outputs = vec![ "arg.get 7", @@ -228,6 +250,12 @@ mod tests { "get-field Int 7", "const i32 7", "fold-seq 7", + "add Int", + r#"mem-to-seq Int "foo""#, + r#"load Int "foo""#, + "seq.new Int", + "list.push", + "repeat-while 1 2", ]; assert_eq!(inputs, outputs);