From 37f3365c3d981f6e4212a7c5a3c48fd5000c4b29 Mon Sep 17 00:00:00 2001 From: Robin Freyler Date: Wed, 26 Oct 2022 10:50:32 +0200 Subject: [PATCH] Cleanup some test code (#540) * add convenience write_slice function * remove commented out code * rename some bindings in FuncType::new * cleanup FuncType display tests * rename assert_func_type -> assert_display * add FuncType constructor unit tests * add doc comment about cloning FuncTypes * move write_slice function down in file --- crates/wasmi/src/func_type.rs | 202 +++++++++++++++++++++++----------- 1 file changed, 138 insertions(+), 64 deletions(-) diff --git a/crates/wasmi/src/func_type.rs b/crates/wasmi/src/func_type.rs index fe0d7a6db4..aeda43195e 100644 --- a/crates/wasmi/src/func_type.rs +++ b/crates/wasmi/src/func_type.rs @@ -3,6 +3,10 @@ use alloc::{sync::Arc, vec::Vec}; use core::fmt::{self, Display}; /// A function type representing a function's parameter and result types. +/// +/// # Note +/// +/// Can be cloned cheaply. #[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq)] pub struct FuncType { /// The number of function parameters. @@ -23,12 +27,7 @@ impl Display for FuncType { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "fn(")?; let (params, results) = self.params_results(); - if let Some((first, rest)) = params.split_first() { - write!(f, "{first}")?; - for param in rest { - write!(f, ", {param}")?; - } - } + write_slice(f, params, ",")?; write!(f, ")")?; if let Some((first, rest)) = results.split_first() { write!(f, " -> ")?; @@ -47,19 +46,33 @@ impl Display for FuncType { } } +/// Writes the elements of a `slice` separated by the `separator`. +fn write_slice(f: &mut fmt::Formatter, slice: &[T], separator: &str) -> fmt::Result +where + T: Display, +{ + if let Some((first, rest)) = slice.split_first() { + write!(f, "{first}")?; + for param in rest { + write!(f, "{separator} {param}")?; + } + } + Ok(()) +} + impl FuncType { - /// Creates a new function signature. - pub fn new(inputs: I, outputs: O) -> Self + /// Creates a new [`FuncType`]. + pub fn new(params: P, results: R) -> Self where - I: IntoIterator, - O: IntoIterator, + P: IntoIterator, + R: IntoIterator, { - let mut inputs_outputs = inputs.into_iter().collect::>(); - let len_inputs = inputs_outputs.len(); - inputs_outputs.extend(outputs); + let mut params_results = params.into_iter().collect::>(); + let len_params = params_results.len(); + params_results.extend(results); Self { - params_results: inputs_outputs.into(), - len_params: len_inputs, + params_results: params_results.into(), + len_params, } } @@ -68,10 +81,6 @@ impl FuncType { &self.params_results[..self.len_params] } - // pub fn into_params(self) -> impl ExactSizeIterator + 'static { - // self.params_results[..self.len_params].iter().copied() - // } - /// Returns the result types of the function type. pub fn results(&self) -> &[ValueType] { &self.params_results[self.len_params..] @@ -86,72 +95,137 @@ impl FuncType { #[cfg(test)] mod tests { use super::*; + use core::borrow::Borrow; + + #[test] + fn new_empty_works() { + let ft = FuncType::new([], []); + assert!(ft.params().is_empty()); + assert!(ft.results().is_empty()); + assert_eq!(ft.params(), ft.params_results().0); + assert_eq!(ft.results(), ft.params_results().1); + } + + #[test] + fn new_works() { + let types = [ + &[ValueType::I32][..], + &[ValueType::I64][..], + &[ValueType::F32][..], + &[ValueType::F64][..], + &[ValueType::I32, ValueType::I32][..], + &[ValueType::I32, ValueType::I32, ValueType::I32][..], + &[ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ][..], + &[ + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ValueType::I32, + ][..], + &[ + ValueType::I32, + ValueType::I64, + ValueType::F32, + ValueType::F64, + ][..], + ]; + for params in types { + for results in types { + let ft = FuncType::new(params.iter().copied(), results.iter().copied()); + assert_eq!(ft.params(), params); + assert_eq!(ft.results(), results); + assert_eq!(ft.params(), ft.params_results().0); + assert_eq!(ft.results(), ft.params_results().1); + } + } + } + + fn assert_display(func_type: impl Borrow, expected: &str) { + assert_eq!(format!("{}", func_type.borrow()), String::from(expected),); + } #[test] fn display_0in_0out() { - let func_type = FuncType::new([], []); - assert_eq!(format!("{func_type}"), String::from("fn()"),); + assert_display(FuncType::new([], []), "fn()"); + } + + #[test] + fn display_1in_0out() { + assert_display(FuncType::new([ValueType::I32], []), "fn(i32)"); + } + + #[test] + fn display_0in_1out() { + assert_display(FuncType::new([], [ValueType::I32]), "fn() -> i32"); } #[test] fn display_1in_1out() { - let func_type = FuncType::new([ValueType::I32], [ValueType::I32]); - assert_eq!(format!("{func_type}"), String::from("fn(i32) -> i32"),); + assert_display( + FuncType::new([ValueType::I32], [ValueType::I32]), + "fn(i32) -> i32", + ); } #[test] fn display_4in_0out() { - let func_type = FuncType::new( - [ - ValueType::I32, - ValueType::I64, - ValueType::F32, - ValueType::F64, - ], - [], - ); - assert_eq!( - format!("{func_type}"), - String::from("fn(i32, i64, f32, f64)"), + assert_display( + FuncType::new( + [ + ValueType::I32, + ValueType::I64, + ValueType::F32, + ValueType::F64, + ], + [], + ), + "fn(i32, i64, f32, f64)", ); } #[test] fn display_0in_4out() { - let func_type = FuncType::new( - [], - [ - ValueType::I32, - ValueType::I64, - ValueType::F32, - ValueType::F64, - ], - ); - assert_eq!( - format!("{func_type}"), - String::from("fn() -> (i32, i64, f32, f64)"), + assert_display( + FuncType::new( + [], + [ + ValueType::I32, + ValueType::I64, + ValueType::F32, + ValueType::F64, + ], + ), + "fn() -> (i32, i64, f32, f64)", ); } #[test] fn display_4in_4out() { - let func_type = FuncType::new( - [ - ValueType::I32, - ValueType::I64, - ValueType::F32, - ValueType::F64, - ], - [ - ValueType::I32, - ValueType::I64, - ValueType::F32, - ValueType::F64, - ], - ); - assert_eq!( - format!("{func_type}"), - String::from("fn(i32, i64, f32, f64) -> (i32, i64, f32, f64)"), + assert_display( + FuncType::new( + [ + ValueType::I32, + ValueType::I64, + ValueType::F32, + ValueType::F64, + ], + [ + ValueType::I32, + ValueType::I64, + ValueType::F32, + ValueType::F64, + ], + ), + "fn(i32, i64, f32, f64) -> (i32, i64, f32, f64)", ); } }