Skip to content

Commit

Permalink
Cleanup some test code (#540)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Robbepop committed Oct 26, 2022
1 parent 52c8a0a commit 37f3365
Showing 1 changed file with 138 additions and 64 deletions.
202 changes: 138 additions & 64 deletions crates/wasmi/src/func_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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, " -> ")?;
Expand All @@ -47,19 +46,33 @@ impl Display for FuncType {
}
}

/// Writes the elements of a `slice` separated by the `separator`.
fn write_slice<T>(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<I, O>(inputs: I, outputs: O) -> Self
/// Creates a new [`FuncType`].
pub fn new<P, R>(params: P, results: R) -> Self
where
I: IntoIterator<Item = ValueType>,
O: IntoIterator<Item = ValueType>,
P: IntoIterator<Item = ValueType>,
R: IntoIterator<Item = ValueType>,
{
let mut inputs_outputs = inputs.into_iter().collect::<Vec<_>>();
let len_inputs = inputs_outputs.len();
inputs_outputs.extend(outputs);
let mut params_results = params.into_iter().collect::<Vec<_>>();
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,
}
}

Expand All @@ -68,10 +81,6 @@ impl FuncType {
&self.params_results[..self.len_params]
}

// pub fn into_params(self) -> impl ExactSizeIterator<Item = ValueType> + '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..]
Expand All @@ -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<FuncType>, 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)",
);
}
}

0 comments on commit 37f3365

Please sign in to comment.