diff --git a/crates/it-types/src/types.rs b/crates/it-types/src/types.rs index c3caced..362cd6f 100644 --- a/crates/it-types/src/types.rs +++ b/crates/it-types/src/types.rs @@ -101,7 +101,7 @@ impl Default for RecordType { impl ToString for &IType { fn to_string(&self) -> String { match &self { - IType::Boolean => "boolean".to_string(), + IType::Boolean => "bool".to_string(), IType::S8 => "s8".to_string(), IType::S16 => "s16".to_string(), IType::S32 => "s32".to_string(), diff --git a/wasmer-it/src/decoders/binary.rs b/wasmer-it/src/decoders/binary.rs index 9868d65..ef69dc8 100644 --- a/wasmer-it/src/decoders/binary.rs +++ b/wasmer-it/src/decoders/binary.rs @@ -357,6 +357,9 @@ fn instruction<'input, E: ParseError<&'input [u8]>>( 0x35 => (input, Instruction::Swap2), + 0x3E => (input, Instruction::BoolFromI32), + 0x3F => (input, Instruction::I32FromBool), + _ => return Err(Err::Error(make_error(input, ErrorKind::ParseTo))), }) } diff --git a/wasmer-it/src/decoders/wat.rs b/wasmer-it/src/decoders/wat.rs index b1fb492..9cbb8b1 100644 --- a/wasmer-it/src/decoders/wat.rs +++ b/wasmer-it/src/decoders/wat.rs @@ -39,6 +39,7 @@ mod keyword { // Instructions. custom_keyword!(argument_get = "arg.get"); custom_keyword!(call_core = "call-core"); + custom_keyword!(bool_from_i32 = "bool.from_i32"); custom_keyword!(s8_from_i32 = "s8.from_i32"); custom_keyword!(s8_from_i64 = "s8.from_i64"); custom_keyword!(s16_from_i32 = "s16.from_i32"); @@ -47,6 +48,7 @@ mod keyword { custom_keyword!(s32_from_i64 = "s32.from_i64"); custom_keyword!(s64_from_i32 = "s64.from_i32"); custom_keyword!(s64_from_i64 = "s64.from_i64"); + custom_keyword!(i32_from_bool = "i32.from_bool"); custom_keyword!(i32_from_s8 = "i32.from_s8"); custom_keyword!(i32_from_s16 = "i32.from_s16"); custom_keyword!(i32_from_s32 = "i32.from_s32"); diff --git a/wasmer-it/src/encoders/binary.rs b/wasmer-it/src/encoders/binary.rs index 7857dc6..4ca3a83 100644 --- a/wasmer-it/src/encoders/binary.rs +++ b/wasmer-it/src/encoders/binary.rs @@ -196,6 +196,7 @@ where (*function_index as u64).to_bytes(writer)?; } + Instruction::BoolFromI32 => 0x3E_u8.to_bytes(writer)?, Instruction::S8FromI32 => 0x02_u8.to_bytes(writer)?, Instruction::S8FromI64 => 0x03_u8.to_bytes(writer)?, Instruction::S16FromI32 => 0x04_u8.to_bytes(writer)?, @@ -204,6 +205,7 @@ where Instruction::S32FromI64 => 0x07_u8.to_bytes(writer)?, Instruction::S64FromI32 => 0x08_u8.to_bytes(writer)?, Instruction::S64FromI64 => 0x09_u8.to_bytes(writer)?, + Instruction::I32FromBool => 0x3F_u8.to_bytes(writer)?, Instruction::I32FromS8 => 0x0a_u8.to_bytes(writer)?, Instruction::I32FromS16 => 0x0b_u8.to_bytes(writer)?, Instruction::I32FromS32 => 0x0c_u8.to_bytes(writer)?, diff --git a/wasmer-it/src/encoders/wat.rs b/wasmer-it/src/encoders/wat.rs index ca71739..6a0f1eb 100644 --- a/wasmer-it/src/encoders/wat.rs +++ b/wasmer-it/src/encoders/wat.rs @@ -65,6 +65,7 @@ impl ToString for &Instruction { match self { Instruction::ArgumentGet { index } => format!("arg.get {}", index), Instruction::CallCore { function_index } => format!("call-core {}", function_index), + Instruction::BoolFromI32 => "bool.from_i32".into(), Instruction::S8FromI32 => "s8.from_i32".into(), Instruction::S8FromI64 => "s8.from_i64".into(), Instruction::S16FromI32 => "s16.from_i32".into(), @@ -73,6 +74,7 @@ impl ToString for &Instruction { Instruction::S32FromI64 => "s32.from_i64".into(), Instruction::S64FromI32 => "s64.from_i32".into(), Instruction::S64FromI64 => "s64.from_i64".into(), + Instruction::I32FromBool => "i32.from_bool".into(), Instruction::I32FromS8 => "i32.from_s8".into(), Instruction::I32FromS16 => "i32.from_s16".into(), Instruction::I32FromS32 => "i32.from_s32".into(), diff --git a/wasmer-it/src/interpreter/instructions/mod.rs b/wasmer-it/src/interpreter/instructions/mod.rs index f7f555d..b31193f 100644 --- a/wasmer-it/src/interpreter/instructions/mod.rs +++ b/wasmer-it/src/interpreter/instructions/mod.rs @@ -52,6 +52,9 @@ pub enum Instruction { function_index: u32, }, + /// The bool.from_i32` instruction. + BoolFromI32, + /// The `s8.from_i32` instruction. S8FromI32, @@ -76,6 +79,9 @@ pub enum Instruction { /// The `s64.from_i64` instruction. S64FromI64, + /// The i32.from_bool instruction. + I32FromBool, + /// The `i32.from_s8` instruction. I32FromS8, @@ -169,20 +175,6 @@ pub enum Instruction { value_type: IType, }, - /* - /// The `record.lift` instruction. - RecordLift { - /// The type index of the record. - type_index: u32, - }, - - /// The `record.lower` instruction. - RecordLower { - /// The type index of the record. - type_index: u32, - }, - - */ /// The `record.lift_memory` instruction. RecordLiftMemory { /// The type index of the record. diff --git a/wasmer-it/src/interpreter/instructions/numbers.rs b/wasmer-it/src/interpreter/instructions/numbers.rs index 30de571..b1dcc10 100644 --- a/wasmer-it/src/interpreter/instructions/numbers.rs +++ b/wasmer-it/src/interpreter/instructions/numbers.rs @@ -68,6 +68,7 @@ lowering_lifting!(s32_from_i32, "s32.from_i32", S32, I32); lowering_lifting!(s32_from_i64, "s32.from_i64", S32, I64); lowering_lifting!(s64_from_i32, "s64.from_i32", S64, I32); lowering_lifting!(s64_from_i64, "s64.from_i64", S64, I64); +lowering_lifting!(i32_from_bool, "i32.from_bool", I32, Boolean); lowering_lifting!(i32_from_s8, "i32.from_s8", I32, S8); lowering_lifting!(i32_from_s16, "i32.from_s16", I32, S16); lowering_lifting!(i32_from_s32, "i32.from_s32", I32, S32); @@ -93,6 +94,44 @@ lowering_lifting!(i64_from_u16, "i64.from_u16", I64, U16); lowering_lifting!(i64_from_u32, "i64.from_u32", I64, U32); lowering_lifting!(i64_from_u64, "i64.from_u64", I64, U64); +executable_instruction!( + bool_from_i32(instruction: Instruction) -> _ { + move |runtime| -> _ { + match runtime.stack.pop1() { + Some(IValue::I32(value)) => { + runtime + .stack + .push({ + let converted_value = IValue::Boolean(value == 1); + + log::trace!("bool.from_i32: converting {:?} to {:?}" , value, converted_value); + + converted_value + }) + } + Some(wrong_value) => { + return instr_error!( + instruction.clone(), + InstructionErrorKind::InvalidValueOnTheStack { + expected_type: IType::I32, + received_value: wrong_value, + } + ) + }, + + None => { + return instr_error!( + instruction.clone(), + InstructionErrorKind::StackIsTooSmall { needed: 1 } + ) + } + } + + Ok(()) + } + } +); + #[cfg(test)] mod tests { test_executable_instruction!( diff --git a/wasmer-it/src/interpreter/mod.rs b/wasmer-it/src/interpreter/mod.rs index 32befdd..b88fa20 100644 --- a/wasmer-it/src/interpreter/mod.rs +++ b/wasmer-it/src/interpreter/mod.rs @@ -200,6 +200,7 @@ where instructions::call_core(function_index, instruction) } + Instruction::BoolFromI32 => instructions::bool_from_i32(instruction), Instruction::S8FromI32 => instructions::s8_from_i32(instruction), Instruction::S8FromI64 => instructions::s8_from_i64(instruction), Instruction::S16FromI32 => instructions::s16_from_i32(instruction), @@ -208,6 +209,7 @@ where Instruction::S32FromI64 => instructions::s32_from_i64(instruction), Instruction::S64FromI32 => instructions::s64_from_i32(instruction), Instruction::S64FromI64 => instructions::s64_from_i64(instruction), + Instruction::I32FromBool => instructions::i32_from_bool(instruction), Instruction::I32FromS8 => instructions::i32_from_s8(instruction), Instruction::I32FromS16 => instructions::i32_from_s16(instruction), Instruction::I32FromS32 => instructions::i32_from_s32(instruction),