diff --git a/src/runner.rs b/src/runner.rs index c0ad5b3..a715254 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -743,303 +743,298 @@ impl<'a, E: Externals> Interpreter<'a, E> { self.run_relop(context, |left, right| left >= right) } - fn run_clz(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Integer { - context + fn run_unop(&mut self, context: &mut FunctionContext, f: F) -> Result + where + F: FnOnce(T) -> U, + RuntimeValue: From + TryInto + { + let v = context .value_stack_mut() .pop_as::() - .map(|v| v.leading_zeros()) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .map(|v| f(v)) + .expect("Due to vaidation stack should contain value"); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) + } + + fn run_clz(&mut self, context: &mut FunctionContext) -> Result + where RuntimeValue: From + TryInto, T: Integer { + self.run_unop(context, |v| v.leading_zeros()) } fn run_ctz(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Integer { - context - .value_stack_mut() - .pop_as::() - .map(|v| v.trailing_zeros()) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + where RuntimeValue: From + TryInto, T: Integer { + self.run_unop(context, |v| v.trailing_zeros()) } fn run_popcnt(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Integer { - context - .value_stack_mut() - .pop_as::() - .map(|v| v.count_ones()) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + where RuntimeValue: From + TryInto, T: Integer { + self.run_unop(context, |v| v.count_ones()) } fn run_add(&mut self, context: &mut FunctionContext) -> Result where RuntimeValue: From + TryInto, T: ArithmeticOps { - context + let (left, right) = context .value_stack_mut() .pop_pair_as::() - .map(|(left, right)| left.add(right)) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to validation stack should contain pair of values"); + let v = left.add(right); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) } fn run_sub(&mut self, context: &mut FunctionContext) -> Result where RuntimeValue: From + TryInto, T: ArithmeticOps { - context + let (left, right) = context .value_stack_mut() .pop_pair_as::() - .map(|(left, right)| left.sub(right)) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to validation stack should contain pair of values"); + let v = left.sub(right); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) } fn run_mul(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: ArithmeticOps { - context + where RuntimeValue: From + TryInto, T: ArithmeticOps { + let (left, right) = context .value_stack_mut() .pop_pair_as::() - .map(|(left, right)| left.mul(right)) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to validation stack should contain pair of values"); + let v = left.mul(right); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) } fn run_div(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: TransmuteInto + Display, U: ArithmeticOps + TransmuteInto { - context + where RuntimeValue: From + TryInto, T: TransmuteInto + Display, U: ArithmeticOps + TransmuteInto { + let (left, right) = context .value_stack_mut() .pop_pair_as::() - .map(|(left, right)| (left.transmute_into(), right.transmute_into())) - .map(|(left, right)| left.div(right).map_err(Error::Trap))? - .map(|v| v.transmute_into()) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to validation stack should contain pair of values"); + let (left, right) = (left.transmute_into(), right.transmute_into()); + let v = left.div(right).map_err(Error::Trap)?; + let v = v.transmute_into(); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) } fn run_rem(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: TransmuteInto, U: Integer + TransmuteInto { - context + where RuntimeValue: From + TryInto, T: TransmuteInto, U: Integer + TransmuteInto { + let (left, right) = context .value_stack_mut() .pop_pair_as::() - .map(|(left, right)| (left.transmute_into(), right.transmute_into())) - .map(|(left, right)| left.rem(right).map_err(Error::Trap))? - .map(|v| v.transmute_into()) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to validation stack should contain pair of values"); + let (left, right) = (left.transmute_into(), right.transmute_into()); + let v = left.rem(right).map_err(Error::Trap)?; + let v = v.transmute_into(); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) } fn run_and(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From<::Output> + TryInto, T: ops::BitAnd { - context + where RuntimeValue: From<::Output> + TryInto, T: ops::BitAnd { + let (left, right) = context .value_stack_mut() .pop_pair_as::() - .map(|(left, right)| left.bitand(right)) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to validation stack should contain pair of values"); + let v = left.bitand(right); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) } fn run_or(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From<::Output> + TryInto, T: ops::BitOr { - context + where RuntimeValue: From<::Output> + TryInto, T: ops::BitOr { + let (left, right) = context .value_stack_mut() .pop_pair_as::() - .map(|(left, right)| left.bitor(right)) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to validation stack should contain pair of values"); + let v = left.bitor(right); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) } fn run_xor(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From<::Output> + TryInto, T: ops::BitXor { - context + where RuntimeValue: From<::Output> + TryInto, T: ops::BitXor { + let (left, right) = context .value_stack_mut() .pop_pair_as::() - .map(|(left, right)| left.bitxor(right)) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to validation stack should contain pair of values"); + let v = left.bitxor(right); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) } fn run_shl(&mut self, context: &mut FunctionContext, mask: T) -> Result - where RuntimeValue: From<>::Output> + TryInto, T: ops::Shl + ops::BitAnd { - context + where RuntimeValue: From<>::Output> + TryInto, T: ops::Shl + ops::BitAnd { + let (left, right) = context .value_stack_mut() .pop_pair_as::() - .map(|(left, right)| left.shl(right & mask)) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to validation stack should contain pair of values"); + let v = left.shl(right & mask); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) } fn run_shr(&mut self, context: &mut FunctionContext, mask: U) -> Result - where RuntimeValue: From + TryInto, T: TransmuteInto, U: ops::Shr + ops::BitAnd, >::Output: TransmuteInto { - context + where RuntimeValue: From + TryInto, T: TransmuteInto, U: ops::Shr + ops::BitAnd, >::Output: TransmuteInto { + let (left, right) = context .value_stack_mut() .pop_pair_as::() - .map(|(left, right)| (left.transmute_into(), right.transmute_into())) - .map(|(left, right)| left.shr(right & mask)) - .map(|v| v.transmute_into()) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to validation stack should contain pair of values"); + let (left, right) = (left.transmute_into(), right.transmute_into()); + let v = left.shr(right & mask); + let v = v.transmute_into(); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) } fn run_rotl(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Integer { - context + where RuntimeValue: From + TryInto, T: Integer { + let (left, right) = context .value_stack_mut() .pop_pair_as::() - .map(|(left, right)| left.rotl(right)) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to validation stack should contain pair of values"); + let v = left.rotl(right); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) } fn run_rotr(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Integer { - context + where RuntimeValue: From + TryInto, T: Integer + { + let (left, right) = context .value_stack_mut() .pop_pair_as::() - .map(|(left, right)| left.rotr(right)) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to validation stack should contain pair of values"); + let v = left.rotr(right); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) } fn run_abs(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Float { - context - .value_stack_mut() - .pop_as::() - .map(|v| v.abs()) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + where RuntimeValue: From + TryInto, T: Float + { + self.run_unop(context, |v| v.abs()) } fn run_neg(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From<::Output> + TryInto, T: ops::Neg { - context - .value_stack_mut() - .pop_as::() - .map(|v| v.neg()) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + where + RuntimeValue: From<::Output> + TryInto, + T: ops::Neg + { + self.run_unop(context, |v| v.neg()) } fn run_ceil(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Float { - context - .value_stack_mut() - .pop_as::() - .map(|v| v.ceil()) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + where RuntimeValue: From + TryInto, T: Float + { + self.run_unop(context, |v| v.ceil()) } fn run_floor(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Float { - context - .value_stack_mut() - .pop_as::() - .map(|v| v.floor()) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + where RuntimeValue: From + TryInto, T: Float + { + self.run_unop(context, |v| v.floor()) } fn run_trunc(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Float { - context - .value_stack_mut() - .pop_as::() - .map(|v| v.trunc()) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + where RuntimeValue: From + TryInto, T: Float + { + self.run_unop(context, |v| v.trunc()) } fn run_nearest(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Float { - context - .value_stack_mut() - .pop_as::() - .map(|v| v.nearest()) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + where RuntimeValue: From + TryInto, T: Float + { + self.run_unop(context, |v| v.nearest()) } fn run_sqrt(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Float { - context - .value_stack_mut() - .pop_as::() - .map(|v| v.sqrt()) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + where RuntimeValue: From + TryInto, T: Float + { + self.run_unop(context, |v| v.sqrt()) } fn run_min(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Float { - context + where RuntimeValue: From + TryInto, T: Float + { + let (left, right) = context .value_stack_mut() .pop_pair_as::() - .map(|(left, right)| left.min(right)) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to validation stack should contain pair of values"); + let v = left.min(right); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) } fn run_max(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Float { - context + where RuntimeValue: From + TryInto, T: Float { + let (left, right) = context .value_stack_mut() .pop_pair_as::() - .map(|(left, right)| left.max(right)) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to validation stack should contain pair of values"); + let v = left.max(right); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) } fn run_copysign(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Float { - context + where RuntimeValue: From + TryInto, T: Float { + let (left, right) = context .value_stack_mut() .pop_pair_as::() - .map(|(left, right)| left.copysign(right)) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to validation stack should contain pair of values"); + let v = left.copysign(right); + context.value_stack_mut().push(v.into())?; + Ok(InstructionOutcome::RunNextInstruction) } fn run_wrap(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: WrapInto { - context - .value_stack_mut() - .pop_as::() - .map(|v| v.wrap_into()) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + where RuntimeValue: From + TryInto, T: WrapInto { + self.run_unop(context, |v| v.wrap_into()) } fn run_trunc_to_int(&mut self, context: &mut FunctionContext) -> Result where RuntimeValue: From + TryInto, T: TryTruncateInto, U: TransmuteInto, { - context + let v = context .value_stack_mut() .pop_as::() - .and_then(|v| v.try_truncate_into().map_err(Error::Trap)) + .expect("Due to vaidation stack should contain value"); + + v.try_truncate_into().map_err(Error::Trap) .map(|v| v.transmute_into()) .map(|v| context.value_stack_mut().push(v.into())) .map(|_| InstructionOutcome::RunNextInstruction) } fn run_extend(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: ExtendInto, U: TransmuteInto { - context + where + RuntimeValue: From + TryInto, T: ExtendInto, U: TransmuteInto + { + let v = context .value_stack_mut() .pop_as::() - .map_err(Error::into) - .map(|v| v.extend_into()) - .map(|v| v.transmute_into()) - .map(|v| context.value_stack_mut().push(v.into())) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to vaidation stack should contain value"); + + let v = v.extend_into().transmute_into(); + context.value_stack_mut().push(v.into())?; + + Ok(InstructionOutcome::RunNextInstruction) } fn run_reinterpret(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From, RuntimeValue: TryInto, T: TransmuteInto { - context + where + RuntimeValue: From, RuntimeValue: TryInto, T: TransmuteInto + { + let v = context .value_stack_mut() .pop_as::() - .map(TransmuteInto::transmute_into) - .and_then(|val| context.value_stack_mut().push(val.into()).map_err(Into::into)) - .map(|_| InstructionOutcome::RunNextInstruction) + .expect("Due to vaidation stack should contain value"); + + let v = v.transmute_into(); + context.value_stack_mut().push(v.into())?; + + Ok(InstructionOutcome::RunNextInstruction) } }