diff --git a/src/host.rs b/src/host.rs index 6e2385a..4838dbb 100644 --- a/src/host.rs +++ b/src/host.rs @@ -1,6 +1,6 @@ use std::any::TypeId; use value::{RuntimeValue, TryInto}; -use {Error, Trap}; +use Trap; /// Safe wrapper for list of arguments. #[derive(Debug)] @@ -18,8 +18,8 @@ impl<'a> RuntimeArgs<'a> { /// # Errors /// /// Returns `Err` if cast is invalid or not enough arguments. - pub fn nth_checked(&self, idx: usize) -> Result where RuntimeValue: TryInto { - Ok(self.nth_value_checked(idx)?.try_into().map_err(|_| Error::Value("Invalid argument cast".to_owned()))?) + pub fn nth_checked(&self, idx: usize) -> Result where RuntimeValue: TryInto { + Ok(self.nth_value_checked(idx)?.try_into().map_err(|_| Trap::UnexpectedSignature)?) } /// Extract argument as a [`RuntimeValue`] by index `idx`. @@ -27,9 +27,9 @@ impl<'a> RuntimeArgs<'a> { /// # Errors /// /// Returns `Err` if this list has not enough arguments. - pub fn nth_value_checked(&self, idx: usize) -> Result { + pub fn nth_value_checked(&self, idx: usize) -> Result { if self.0.len() <= idx { - return Err(Error::Value("Invalid argument index".to_owned())); + return Err(Trap::UnexpectedSignature); } Ok(self.0[idx]) } @@ -39,7 +39,7 @@ impl<'a> RuntimeArgs<'a> { /// # Panics /// /// Panics if cast is invalid or not enough arguments. - pub fn nth(&self, idx: usize) -> T where RuntimeValue: TryInto { + pub fn nth(&self, idx: usize) -> T where RuntimeValue: TryInto { let value = self.nth_value_checked(idx).expect("Invalid argument index"); value.try_into().expect("Unexpected argument type") } diff --git a/src/lib.rs b/src/lib.rs index 4f925db..6f6595a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -105,7 +105,7 @@ use std::fmt; use std::error; use std::collections::HashMap; -/// Error type which can happen at execution time. +/// Error type which can thrown by wasm code or by host environment. /// /// Under some conditions, wasm execution may produce a `Trap`, which immediately aborts execution. /// Traps can't be handled by WebAssembly code, but are reported to the embedder. @@ -169,6 +169,12 @@ pub enum Trap { /// Extensive inlining might also be the cause of stack overflow. StackOverflow, + /// Unexpected signature provided. + /// + /// This can happen if [`FuncInstance`] was invoked + /// with mismatching signature. + UnexpectedSignature, + /// Error specified by the host. /// /// Typically returned from an implementation of [`Externals`]. diff --git a/src/runner.rs b/src/runner.rs index e6d7318..bf56dbe 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -370,8 +370,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { fn run_if(&mut self, context: &mut FunctionContext, labels: &HashMap, block_type: BlockType) -> Result { let condition: bool = context .value_stack_mut() - .pop_as() - .expect("Due to validation stack top should be I32"); + .pop_as(); let block_frame_type = if condition { BlockFrameType::IfTrue } else { let else_pos = labels[&context.position]; if !labels.contains_key(&else_pos) { @@ -404,9 +403,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_br_if(&mut self, context: &mut FunctionContext, label_idx: u32) -> Result { - let condition = context.value_stack_mut() - .pop_as() - .expect("Due to validation stack should contain value"); + let condition = context.value_stack_mut().pop_as(); if condition { Ok(InstructionOutcome::Branch(label_idx as usize)) } else { @@ -416,8 +413,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { fn run_br_table(&mut self, context: &mut FunctionContext, table: &[u32], default: u32) -> Result { let index: u32 = context.value_stack_mut() - .pop_as() - .expect("Due to validation stack should contain value"); + .pop_as(); Ok(InstructionOutcome::Branch(table.get(index as usize).cloned().unwrap_or(default) as usize)) } @@ -444,8 +440,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { ) -> Result { let table_func_idx: u32 = context .value_stack_mut() - .pop_as() - .expect("Due to validation stack top should be I32"); + .pop_as(); let table = context .module() .table_by_index(DEFAULT_TABLE_INDEX) @@ -546,8 +541,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { where RuntimeValue: From, T: LittleEndianConvert { let raw_address = context .value_stack_mut() - .pop_as() - .expect("Due to vaidation stack should contain value"); + .pop_as(); let address = effective_address( offset, @@ -568,8 +562,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { where T: ExtendInto, RuntimeValue: From, T: LittleEndianConvert { let raw_address = context .value_stack_mut() - .pop_as() - .expect("Due to vaidation stack should contain value"); + .pop_as(); let address = effective_address( offset, @@ -591,16 +584,14 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_store(&mut self, context: &mut FunctionContext, _align: u32, offset: u32) -> Result - where RuntimeValue: TryInto, T: LittleEndianConvert { + where RuntimeValue: TryInto, T: LittleEndianConvert { let stack_value = context .value_stack_mut() .pop_as::() - .expect("Due to vaidation stack should contain value") .into_little_endian(); let raw_address = context .value_stack_mut() - .pop_as::() - .expect("Due to validation stack should contain value"); + .pop_as::(); let address = effective_address( offset, @@ -622,7 +613,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { offset: u32, ) -> Result where - RuntimeValue: TryInto, + RuntimeValue: TryInto, T: WrapInto, U: LittleEndianConvert, { @@ -634,8 +625,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { let stack_value = stack_value.wrap_into().into_little_endian(); let raw_address = context .value_stack_mut() - .pop_as::() - .expect("Due to validation stack should contain value"); + .pop_as::(); let address = effective_address( offset, @@ -663,8 +653,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { fn run_grow_memory(&mut self, context: &mut FunctionContext) -> Result { let pages: u32 = context .value_stack_mut() - .pop_as() - .expect("Due to validation stack should contain value"); + .pop_as(); let m = context.module() .memory_by_index(DEFAULT_MEMORY_INDEX) .expect("Due to validation memory should exists"); @@ -687,7 +676,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { fn run_relop(&mut self, context: &mut FunctionContext, f: F) -> Result where - RuntimeValue: TryInto, + RuntimeValue: TryInto, F: FnOnce(T, T) -> bool, { let (left, right) = context @@ -704,78 +693,76 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_eqz(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: TryInto, T: PartialEq + Default { + where RuntimeValue: TryInto, T: PartialEq + Default { let v = context .value_stack_mut() - .pop_as::() - .expect("Due to vaidation stack should contain value"); + .pop_as::(); let v = RuntimeValue::I32(if v == Default::default() { 1 } else { 0 }); context.value_stack_mut().push(v)?; Ok(InstructionOutcome::RunNextInstruction) } fn run_eq(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: TryInto, T: PartialEq + where RuntimeValue: TryInto, T: PartialEq { self.run_relop(context, |left, right| left == right) } fn run_ne(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: TryInto, T: PartialEq { + where RuntimeValue: TryInto, T: PartialEq { self.run_relop(context, |left, right| left != right) } fn run_lt(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: TryInto, T: PartialOrd + Display { + where RuntimeValue: TryInto, T: PartialOrd + Display { self.run_relop(context, |left, right| left < right) } fn run_gt(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: TryInto, T: PartialOrd { + where RuntimeValue: TryInto, T: PartialOrd { self.run_relop(context, |left, right| left > right) } fn run_lte(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: TryInto, T: PartialOrd { + where RuntimeValue: TryInto, T: PartialOrd { self.run_relop(context, |left, right| left <= right) } fn run_gte(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: TryInto, T: PartialOrd { + where RuntimeValue: TryInto, T: PartialOrd { self.run_relop(context, |left, right| left >= right) } fn run_unop(&mut self, context: &mut FunctionContext, f: F) -> Result where F: FnOnce(T) -> U, - RuntimeValue: From + TryInto + RuntimeValue: From + TryInto { let v = context .value_stack_mut() - .pop_as::() - .map(|v| f(v)) - .expect("Due to vaidation stack should contain value"); + .pop_as::(); + let v = f(v); 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 { + 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 { + 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 { + 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 { + where RuntimeValue: From + TryInto, T: ArithmeticOps { let (left, right) = context .value_stack_mut() .pop_pair_as::() @@ -786,7 +773,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_sub(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: ArithmeticOps { + where RuntimeValue: From + TryInto, T: ArithmeticOps { let (left, right) = context .value_stack_mut() .pop_pair_as::() @@ -797,7 +784,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_mul(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: ArithmeticOps { + where RuntimeValue: From + TryInto, T: ArithmeticOps { let (left, right) = context .value_stack_mut() .pop_pair_as::() @@ -808,7 +795,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_div(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: TransmuteInto + Display, U: ArithmeticOps + TransmuteInto { + where RuntimeValue: From + TryInto, T: TransmuteInto + Display, U: ArithmeticOps + TransmuteInto { let (left, right) = context .value_stack_mut() .pop_pair_as::() @@ -821,7 +808,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_rem(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: TransmuteInto, U: Integer + TransmuteInto { + where RuntimeValue: From + TryInto, T: TransmuteInto, U: Integer + TransmuteInto { let (left, right) = context .value_stack_mut() .pop_pair_as::() @@ -834,7 +821,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_and(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From<::Output> + TryInto, T: ops::BitAnd { + where RuntimeValue: From<::Output> + TryInto, T: ops::BitAnd { let (left, right) = context .value_stack_mut() .pop_pair_as::() @@ -845,7 +832,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_or(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From<::Output> + TryInto, T: ops::BitOr { + where RuntimeValue: From<::Output> + TryInto, T: ops::BitOr { let (left, right) = context .value_stack_mut() .pop_pair_as::() @@ -856,7 +843,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_xor(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From<::Output> + TryInto, T: ops::BitXor { + where RuntimeValue: From<::Output> + TryInto, T: ops::BitXor { let (left, right) = context .value_stack_mut() .pop_pair_as::() @@ -867,7 +854,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_shl(&mut self, context: &mut FunctionContext, mask: T) -> Result - where RuntimeValue: From<>::Output> + TryInto, T: ops::Shl + ops::BitAnd { + where RuntimeValue: From<>::Output> + TryInto, T: ops::Shl + ops::BitAnd { let (left, right) = context .value_stack_mut() .pop_pair_as::() @@ -878,7 +865,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_shr(&mut self, context: &mut FunctionContext, mask: U) -> Result - where RuntimeValue: From + TryInto, T: TransmuteInto, U: ops::Shr + ops::BitAnd, >::Output: TransmuteInto { + where RuntimeValue: From + TryInto, T: TransmuteInto, U: ops::Shr + ops::BitAnd, >::Output: TransmuteInto { let (left, right) = context .value_stack_mut() .pop_pair_as::() @@ -891,7 +878,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_rotl(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Integer { + where RuntimeValue: From + TryInto, T: Integer { let (left, right) = context .value_stack_mut() .pop_pair_as::() @@ -902,7 +889,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_rotr(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Integer + where RuntimeValue: From + TryInto, T: Integer { let (left, right) = context .value_stack_mut() @@ -914,51 +901,51 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_abs(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Float + 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, + 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 + 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 + 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 + 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 + 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 + 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 + where RuntimeValue: From + TryInto, T: Float { let (left, right) = context .value_stack_mut() @@ -970,7 +957,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_max(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Float { + where RuntimeValue: From + TryInto, T: Float { let (left, right) = context .value_stack_mut() .pop_pair_as::() @@ -981,7 +968,7 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_copysign(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: Float { + where RuntimeValue: From + TryInto, T: Float { let (left, right) = context .value_stack_mut() .pop_pair_as::() @@ -992,16 +979,15 @@ impl<'a, E: Externals> Interpreter<'a, E> { } fn run_wrap(&mut self, context: &mut FunctionContext) -> Result - where RuntimeValue: From + TryInto, T: WrapInto { + 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, { + where RuntimeValue: From + TryInto, T: TryTruncateInto, U: TransmuteInto, { let v = context .value_stack_mut() - .pop_as::() - .expect("Due to vaidation stack should contain value"); + .pop_as::(); v.try_truncate_into() .map(|v| v.transmute_into()) @@ -1011,12 +997,11 @@ impl<'a, E: Externals> Interpreter<'a, E> { fn run_extend(&mut self, context: &mut FunctionContext) -> Result where - RuntimeValue: From + TryInto, T: ExtendInto, U: TransmuteInto + RuntimeValue: From + TryInto, T: ExtendInto, U: TransmuteInto { let v = context .value_stack_mut() - .pop_as::() - .expect("Due to vaidation stack should contain value"); + .pop_as::(); let v = v.extend_into().transmute_into(); context.value_stack_mut().push(v.into())?; @@ -1026,12 +1011,11 @@ impl<'a, E: Externals> Interpreter<'a, E> { fn run_reinterpret(&mut self, context: &mut FunctionContext) -> Result where - RuntimeValue: From, RuntimeValue: TryInto, T: TransmuteInto + RuntimeValue: From, RuntimeValue: TryInto, T: TransmuteInto { let v = context .value_stack_mut() - .pop_as::() - .expect("Due to vaidation stack should contain value"); + .pop_as::(); let v = v.transmute_into(); context.value_stack_mut().push(v.into())?; @@ -1263,22 +1247,22 @@ impl ValueStack { } } - fn pop_as(&mut self) -> Result + fn pop_as(&mut self) -> T where - RuntimeValue: TryInto, + RuntimeValue: TryInto, { let value = self.stack_with_limit .pop() .expect("Due to validation stack shouldn't be empty"); - TryInto::try_into(value) + TryInto::try_into(value).expect("Due to validation stack top's type should match") } fn pop_pair_as(&mut self) -> Result<(T, T), Error> where - RuntimeValue: TryInto, + RuntimeValue: TryInto, { - let right = self.pop_as()?; - let left = self.pop_as()?; + let right = self.pop_as(); + let left = self.pop_as(); Ok((left, right)) } diff --git a/src/value.rs b/src/value.rs index 4d1bdc6..608f7ba 100644 --- a/src/value.rs +++ b/src/value.rs @@ -1,9 +1,16 @@ use std::{i32, i64, u32, u64, f32}; use std::io; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; -use {Error, Trap}; +use {Trap}; use parity_wasm::elements::ValueType; +#[derive(Debug)] +pub enum Error { + UnexpectedType { + expected: ValueType, + }, + InvalidLittleEndianBuffer, +} /// Runtime value. #[derive(Copy, Clone, Debug, PartialEq)] @@ -180,7 +187,7 @@ impl TryInto for RuntimeValue { fn try_into(self) -> Result { match self { RuntimeValue::I32(val) => Ok(val != 0), - _ => Err(Error::Value("32-bit int value expected".to_owned())), + _ => Err(Error::UnexpectedType { expected: ValueType::I32 }), } } } @@ -189,7 +196,7 @@ impl TryInto for RuntimeValue { fn try_into(self) -> Result { match self { RuntimeValue::I32(val) => Ok(val), - _ => Err(Error::Value("32-bit int value expected".to_owned())), + _ => Err(Error::UnexpectedType { expected: ValueType::I32 }), } } } @@ -198,7 +205,7 @@ impl TryInto for RuntimeValue { fn try_into(self) -> Result { match self { RuntimeValue::I64(val) => Ok(val), - _ => Err(Error::Value("64-bit int value expected".to_owned())), + _ => Err(Error::UnexpectedType { expected: ValueType::I64 }), } } } @@ -207,7 +214,7 @@ impl TryInto for RuntimeValue { fn try_into(self) -> Result { match self { RuntimeValue::F32(val) => Ok(val), - _ => Err(Error::Value("32-bit float value expected".to_owned())), + _ => Err(Error::UnexpectedType { expected: ValueType::F32 }), } } } @@ -216,7 +223,7 @@ impl TryInto for RuntimeValue { fn try_into(self) -> Result { match self { RuntimeValue::F64(val) => Ok(val), - _ => Err(Error::Value("64-bit float value expected".to_owned())), + _ => Err(Error::UnexpectedType { expected: ValueType::F64 }), } } } @@ -225,7 +232,7 @@ impl TryInto for RuntimeValue { fn try_into(self) -> Result { match self { RuntimeValue::I32(val) => Ok(val as u32), - _ => Err(Error::Value("32-bit int value expected".to_owned())), + _ => Err(Error::UnexpectedType { expected: ValueType::I32 }), } } } @@ -234,7 +241,7 @@ impl TryInto for RuntimeValue { fn try_into(self) -> Result { match self { RuntimeValue::I64(val) => Ok(val as u64), - _ => Err(Error::Value("64-bit int value expected".to_owned())), + _ => Err(Error::UnexpectedType { expected: ValueType::I64 }), } } } @@ -379,7 +386,7 @@ impl LittleEndianConvert for i8 { fn from_little_endian(buffer: &[u8]) -> Result { buffer.get(0) .map(|v| *v as i8) - .ok_or_else(|| Error::Value("invalid little endian buffer".into())) + .ok_or_else(|| Error::InvalidLittleEndianBuffer) } } @@ -391,7 +398,7 @@ impl LittleEndianConvert for u8 { fn from_little_endian(buffer: &[u8]) -> Result { buffer.get(0) .cloned() - .ok_or_else(|| Error::Value("invalid little endian buffer".into())) + .ok_or_else(|| Error::InvalidLittleEndianBuffer) } } @@ -405,7 +412,7 @@ impl LittleEndianConvert for i16 { fn from_little_endian(buffer: &[u8]) -> Result { io::Cursor::new(buffer).read_i16::() - .map_err(|e| Error::Value(e.to_string())) + .map_err(|_| Error::InvalidLittleEndianBuffer) } } @@ -419,7 +426,7 @@ impl LittleEndianConvert for u16 { fn from_little_endian(buffer: &[u8]) -> Result { io::Cursor::new(buffer).read_u16::() - .map_err(|e| Error::Value(e.to_string())) + .map_err(|_| Error::InvalidLittleEndianBuffer) } } @@ -433,7 +440,7 @@ impl LittleEndianConvert for i32 { fn from_little_endian(buffer: &[u8]) -> Result { io::Cursor::new(buffer).read_i32::() - .map_err(|e| Error::Value(e.to_string())) + .map_err(|_| Error::InvalidLittleEndianBuffer) } } @@ -447,7 +454,7 @@ impl LittleEndianConvert for u32 { fn from_little_endian(buffer: &[u8]) -> Result { io::Cursor::new(buffer).read_u32::() - .map_err(|e| Error::Value(e.to_string())) + .map_err(|_| Error::InvalidLittleEndianBuffer) } } @@ -461,7 +468,7 @@ impl LittleEndianConvert for i64 { fn from_little_endian(buffer: &[u8]) -> Result { io::Cursor::new(buffer).read_i64::() - .map_err(|e| Error::Value(e.to_string())) + .map_err(|_| Error::InvalidLittleEndianBuffer) } } @@ -476,7 +483,7 @@ impl LittleEndianConvert for f32 { fn from_little_endian(buffer: &[u8]) -> Result { io::Cursor::new(buffer).read_u32::() .map(f32_from_bits) - .map_err(|e| Error::Value(e.to_string())) + .map_err(|_| Error::InvalidLittleEndianBuffer) } } @@ -491,7 +498,7 @@ impl LittleEndianConvert for f64 { fn from_little_endian(buffer: &[u8]) -> Result { io::Cursor::new(buffer).read_u64::() .map(f64_from_bits) - .map_err(|e| Error::Value(e.to_string())) + .map_err(|_| Error::InvalidLittleEndianBuffer) } }