From 5249b243ee4d9b1349d9f93184a802faca20bb9a Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 31 Mar 2020 08:17:52 +0200 Subject: [PATCH] feat(interface-types) Encodes/decodes the `record.lift` instruction. --- src/decoders/binary.rs | 18 +++++++++++++++++- src/decoders/wat.rs | 9 +++++++++ src/encoders/binary.rs | 9 ++++++++- src/encoders/wat.rs | 5 ++++- src/interpreter/instructions/mod.rs | 6 ++++++ src/interpreter/mod.rs | 2 ++ 6 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/decoders/binary.rs b/src/decoders/binary.rs index 2ae47a9..35c324c 100644 --- a/src/decoders/binary.rs +++ b/src/decoders/binary.rs @@ -173,6 +173,7 @@ fn instruction<'input, E: ParseError<&'input [u8]>>( Ok(match opcode { 0x00 => { consume!((input, argument_0) = uleb(input)?); + ( input, Instruction::ArgumentGet { @@ -183,6 +184,7 @@ fn instruction<'input, E: ParseError<&'input [u8]>>( 0x01 => { consume!((input, argument_0) = uleb(input)?); + ( input, Instruction::CallCore { @@ -228,6 +230,7 @@ fn instruction<'input, E: ParseError<&'input [u8]>>( 0x23 => { consume!((input, argument_0) = uleb(input)?); + ( input, Instruction::StringLowerMemory { @@ -238,6 +241,17 @@ fn instruction<'input, E: ParseError<&'input [u8]>>( 0x24 => (input, Instruction::StringSize), + 0x25 => { + consume!((input, argument_0) = uleb(input)?); + + ( + input, + Instruction::RecordLift { + type_index: argument_0 as u32, + }, + ) + } + _ => return Err(Err::Error(make_error(input, ErrorKind::ParseTo))), }) } @@ -701,7 +715,7 @@ mod tests { #[test] fn test_instructions() { let input = &[ - 0x25, // list of 37 items + 0x26, // list of 38 items 0x00, 0x01, // ArgumentGet { index: 1 } 0x01, 0x01, // CallCore { function_index: 1 } 0x02, // S8FromI32 @@ -739,6 +753,7 @@ mod tests { 0x22, // StringLiftMemory 0x23, 0x01, // StringLowerMemory { allocator_index: 1 } 0x24, // StringSize + 0x25, 0x01, // RecordLift { type_index: 1 }, 0x0a, ]; let output = Ok(( @@ -781,6 +796,7 @@ mod tests { Instruction::StringLiftMemory, Instruction::StringLowerMemory { allocator_index: 1 }, Instruction::StringSize, + Instruction::RecordLift { type_index: 1 }, ], )); diff --git a/src/decoders/wat.rs b/src/decoders/wat.rs index fb81630..9abd840 100644 --- a/src/decoders/wat.rs +++ b/src/decoders/wat.rs @@ -65,6 +65,7 @@ mod keyword { custom_keyword!(string_lift_memory = "string.lift_memory"); custom_keyword!(string_lower_memory = "string.lower_memory"); custom_keyword!(string_size = "string.size"); + custom_keyword!(record_lift = "record.lift"); } impl Parse<'_> for InterfaceType { @@ -312,6 +313,12 @@ impl<'a> Parse<'a> for Instruction { parser.parse::()?; Ok(Instruction::StringSize) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::RecordLift { + type_index: parser.parse()?, + }) } else { Err(lookahead.error()) } @@ -756,6 +763,7 @@ mod tests { "string.lift_memory", "string.lower_memory 42", "string.size", + "record.lift 42", ]; let outputs = vec![ Instruction::ArgumentGet { index: 7 }, @@ -797,6 +805,7 @@ mod tests { allocator_index: 42, }, Instruction::StringSize, + Instruction::RecordLift { type_index: 42 }, ]; assert_eq!(inputs.len(), outputs.len()); diff --git a/src/encoders/binary.rs b/src/encoders/binary.rs index 2be2dad..439fe05 100644 --- a/src/encoders/binary.rs +++ b/src/encoders/binary.rs @@ -338,6 +338,11 @@ where } Instruction::StringSize => 0x24_u8.to_bytes(writer)?, + + Instruction::RecordLift { type_index } => { + 0x25_u8.to_bytes(writer)?; + (*type_index as u64).to_bytes(writer)? + } } Ok(()) @@ -683,9 +688,10 @@ mod tests { Instruction::StringLiftMemory, Instruction::StringLowerMemory { allocator_index: 1 }, Instruction::StringSize, + Instruction::RecordLift { type_index: 1 }, ], &[ - 0x25, // list of 37 items + 0x26, // list of 38 items 0x00, 0x01, // ArgumentGet { index: 1 } 0x01, 0x01, // CallCore { function_index: 1 } 0x02, // S8FromI32 @@ -723,6 +729,7 @@ mod tests { 0x22, // StringLiftMemory 0x23, 0x01, // StringLowerMemory { allocator_index: 1 } 0x24, // StringSize + 0x025, 0x01, // RecordLift { type_index: 1 } ] ); } diff --git a/src/encoders/wat.rs b/src/encoders/wat.rs index 772bf89..68d8cc1 100644 --- a/src/encoders/wat.rs +++ b/src/encoders/wat.rs @@ -136,9 +136,10 @@ impl ToString for &Instruction { Instruction::I64FromU64 => "i64.from_u64".into(), Instruction::StringLiftMemory => "string.lift_memory".into(), Instruction::StringLowerMemory { allocator_index } => { - format!(r#"string.lower_memory {}"#, allocator_index) + format!("string.lower_memory {}", allocator_index) } Instruction::StringSize => "string.size".into(), + Instruction::RecordLift { type_index } => format!("record.lift {}", type_index), } } } @@ -465,6 +466,7 @@ mod tests { }) .to_string(), (&Instruction::StringSize).to_string(), + (&Instruction::RecordLift { type_index: 42 }).to_string(), ]; let outputs = vec![ "arg.get 7", @@ -504,6 +506,7 @@ mod tests { "string.lift_memory", "string.lower_memory 42", "string.size", + "record.lift 42", ]; assert_eq!(inputs, outputs); diff --git a/src/interpreter/instructions/mod.rs b/src/interpreter/instructions/mod.rs index 42e2dad..383c596 100644 --- a/src/interpreter/instructions/mod.rs +++ b/src/interpreter/instructions/mod.rs @@ -135,6 +135,12 @@ pub enum Instruction { /// The `string.size` instruction. StringSize, + + /// The `record.lift` instruction. + RecordLift { + /// The type index of the record. + type_index: u32, + }, } /// Just a short helper to map the error of a cast from an diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 408d06c..7a553d7 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -234,6 +234,8 @@ where instructions::string_lower_memory(*allocator_index, *instruction) } Instruction::StringSize => instructions::string_size(*instruction), + + Instruction::RecordLift { type_index: _ } => todo!(), }) .collect();