From c7bb9904f71c464bf968a39bcffbf5f2bfe8264e Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 2 Apr 2020 12:05:22 +0200 Subject: [PATCH] feat(interface-types) Encodes/decodes the `record.lower` instruction. --- src/decoders/binary.rs | 16 +++++++++++++--- src/decoders/wat.rs | 9 +++++++++ src/encoders/binary.rs | 10 +++++++--- src/encoders/wat.rs | 3 +++ src/interpreter/instructions/mod.rs | 6 ++++++ 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/decoders/binary.rs b/src/decoders/binary.rs index 35c324c..77e95a7 100644 --- a/src/decoders/binary.rs +++ b/src/decoders/binary.rs @@ -227,7 +227,6 @@ fn instruction<'input, E: ParseError<&'input [u8]>>( 0x21 => (input, Instruction::I64FromU64), 0x22 => (input, Instruction::StringLiftMemory), - 0x23 => { consume!((input, argument_0) = uleb(input)?); @@ -238,7 +237,6 @@ fn instruction<'input, E: ParseError<&'input [u8]>>( }, ) } - 0x24 => (input, Instruction::StringSize), 0x25 => { @@ -251,6 +249,16 @@ fn instruction<'input, E: ParseError<&'input [u8]>>( }, ) } + 0x26 => { + consume!((input, argument_0) = uleb(input)?); + + ( + input, + Instruction::RecordLower { + type_index: argument_0 as u32, + }, + ) + } _ => return Err(Err::Error(make_error(input, ErrorKind::ParseTo))), }) @@ -715,7 +723,7 @@ mod tests { #[test] fn test_instructions() { let input = &[ - 0x26, // list of 38 items + 0x27, // list of 39 items 0x00, 0x01, // ArgumentGet { index: 1 } 0x01, 0x01, // CallCore { function_index: 1 } 0x02, // S8FromI32 @@ -754,6 +762,7 @@ mod tests { 0x23, 0x01, // StringLowerMemory { allocator_index: 1 } 0x24, // StringSize 0x25, 0x01, // RecordLift { type_index: 1 }, + 0x26, 0x01, // RecordLower { type_index: 1 }, 0x0a, ]; let output = Ok(( @@ -797,6 +806,7 @@ mod tests { Instruction::StringLowerMemory { allocator_index: 1 }, Instruction::StringSize, Instruction::RecordLift { type_index: 1 }, + Instruction::RecordLower { type_index: 1 }, ], )); diff --git a/src/decoders/wat.rs b/src/decoders/wat.rs index 9abd840..39ea6f3 100644 --- a/src/decoders/wat.rs +++ b/src/decoders/wat.rs @@ -66,6 +66,7 @@ mod keyword { custom_keyword!(string_lower_memory = "string.lower_memory"); custom_keyword!(string_size = "string.size"); custom_keyword!(record_lift = "record.lift"); + custom_keyword!(record_lower = "record.lower"); } impl Parse<'_> for InterfaceType { @@ -319,6 +320,12 @@ impl<'a> Parse<'a> for Instruction { Ok(Instruction::RecordLift { type_index: parser.parse()?, }) + } else if lookahead.peek::() { + parser.parse::()?; + + Ok(Instruction::RecordLower { + type_index: parser.parse()?, + }) } else { Err(lookahead.error()) } @@ -764,6 +771,7 @@ mod tests { "string.lower_memory 42", "string.size", "record.lift 42", + "record.lower 42", ]; let outputs = vec![ Instruction::ArgumentGet { index: 7 }, @@ -806,6 +814,7 @@ mod tests { }, Instruction::StringSize, Instruction::RecordLift { type_index: 42 }, + Instruction::RecordLower { type_index: 42 }, ]; assert_eq!(inputs.len(), outputs.len()); diff --git a/src/encoders/binary.rs b/src/encoders/binary.rs index 439fe05..2370017 100644 --- a/src/encoders/binary.rs +++ b/src/encoders/binary.rs @@ -331,18 +331,20 @@ where Instruction::I64FromU64 => 0x21_u8.to_bytes(writer)?, Instruction::StringLiftMemory => 0x22_u8.to_bytes(writer)?, - Instruction::StringLowerMemory { allocator_index } => { 0x23_u8.to_bytes(writer)?; (*allocator_index as u64).to_bytes(writer)?; } - Instruction::StringSize => 0x24_u8.to_bytes(writer)?, Instruction::RecordLift { type_index } => { 0x25_u8.to_bytes(writer)?; (*type_index as u64).to_bytes(writer)? } + Instruction::RecordLower { type_index } => { + 0x26_u8.to_bytes(writer)?; + (*type_index as u64).to_bytes(writer)? + } } Ok(()) @@ -689,9 +691,10 @@ mod tests { Instruction::StringLowerMemory { allocator_index: 1 }, Instruction::StringSize, Instruction::RecordLift { type_index: 1 }, + Instruction::RecordLower { type_index: 1 }, ], &[ - 0x26, // list of 38 items + 0x27, // list of 39 items 0x00, 0x01, // ArgumentGet { index: 1 } 0x01, 0x01, // CallCore { function_index: 1 } 0x02, // S8FromI32 @@ -730,6 +733,7 @@ mod tests { 0x23, 0x01, // StringLowerMemory { allocator_index: 1 } 0x24, // StringSize 0x025, 0x01, // RecordLift { type_index: 1 } + 0x026, 0x01, // RecordLower { type_index: 1 } ] ); } diff --git a/src/encoders/wat.rs b/src/encoders/wat.rs index 68d8cc1..6ec680c 100644 --- a/src/encoders/wat.rs +++ b/src/encoders/wat.rs @@ -140,6 +140,7 @@ impl ToString for &Instruction { } Instruction::StringSize => "string.size".into(), Instruction::RecordLift { type_index } => format!("record.lift {}", type_index), + Instruction::RecordLower { type_index } => format!("record.lower {}", type_index), } } } @@ -467,6 +468,7 @@ mod tests { .to_string(), (&Instruction::StringSize).to_string(), (&Instruction::RecordLift { type_index: 42 }).to_string(), + (&Instruction::RecordLower { type_index: 42 }).to_string(), ]; let outputs = vec![ "arg.get 7", @@ -507,6 +509,7 @@ mod tests { "string.lower_memory 42", "string.size", "record.lift 42", + "record.lower 42", ]; assert_eq!(inputs, outputs); diff --git a/src/interpreter/instructions/mod.rs b/src/interpreter/instructions/mod.rs index 96657b5..5681620 100644 --- a/src/interpreter/instructions/mod.rs +++ b/src/interpreter/instructions/mod.rs @@ -143,6 +143,12 @@ pub enum Instruction { /// The type index of the record. type_index: u32, }, + + /// The `record.lower` instruction. + RecordLower { + /// The type index of the record. + type_index: u32, + }, } /// Just a short helper to map the error of a cast from an