Remove checks for number of arguments.

This commit is contained in:
Stephen Chung 2020-05-11 10:29:33 +08:00
parent 8aa0e2ceb4
commit 314ec5e4d2
3 changed files with 11 additions and 55 deletions

View File

@ -131,12 +131,6 @@ pub fn by_value<T: Clone + 'static>(data: &mut Dynamic) -> T {
mem::take(data).cast::<T>()
}
/// This macro counts the number of arguments via recursion.
macro_rules! count_args {
() => { 0_usize };
( $head:ident $($tail:ident)* ) => { 1_usize + count_args!($($tail)*) };
}
/// This macro creates a closure wrapping a registered function.
macro_rules! make_func {
($fn_name:ident : $fn:ident : $map:expr ; $($par:ident => $convert:expr),*) => {
@ -147,12 +141,7 @@ macro_rules! make_func {
// ^ dereferencing function
move |args: &mut FnCallArgs, pos: Position| {
// Check for length at the beginning to avoid per-element bound checks.
const NUM_ARGS: usize = count_args!($($par)*);
if args.len() != NUM_ARGS {
return Err(Box::new(EvalAltResult::ErrorFunctionArgsMismatch($fn_name.clone(), NUM_ARGS, args.len(), pos)));
}
// The arguments are assumed to be of the correct number and types!
#[allow(unused_variables, unused_mut)]
let mut drain = args.iter_mut();

View File

@ -300,7 +300,7 @@ impl Module {
) -> u64 {
let f = move |_: &mut FnCallArgs, pos| {
func()
.map(|v| v.into())
.map(Into::<Dynamic>::into)
.map_err(|err| EvalAltResult::set_position(err, pos))
};
let arg_types = vec![];
@ -328,7 +328,7 @@ impl Module {
) -> u64 {
let f = move |args: &mut FnCallArgs, pos| {
func(mem::take(args[0]).cast::<A>())
.map(|v| v.into())
.map(Into::<Dynamic>::into)
.map_err(|err| EvalAltResult::set_position(err, pos))
};
let arg_types = vec![TypeId::of::<A>()];
@ -356,7 +356,7 @@ impl Module {
) -> u64 {
let f = move |args: &mut FnCallArgs, pos| {
func(args[0].downcast_mut::<A>().unwrap())
.map(|v| v.into())
.map(Into::<Dynamic>::into)
.map_err(|err| EvalAltResult::set_position(err, pos))
};
let arg_types = vec![TypeId::of::<A>()];
@ -389,7 +389,7 @@ impl Module {
let b = mem::take(args[1]).cast::<B>();
func(a, b)
.map(|v| v.into())
.map(Into::<Dynamic>::into)
.map_err(|err| EvalAltResult::set_position(err, pos))
};
let arg_types = vec![TypeId::of::<A>(), TypeId::of::<B>()];
@ -426,7 +426,7 @@ impl Module {
let a = args[0].downcast_mut::<A>().unwrap();
func(a, b)
.map(|v| v.into())
.map(Into::<Dynamic>::into)
.map_err(|err| EvalAltResult::set_position(err, pos))
};
let arg_types = vec![TypeId::of::<A>(), TypeId::of::<B>()];
@ -466,7 +466,7 @@ impl Module {
let c = mem::take(args[2]).cast::<C>();
func(a, b, c)
.map(|v| v.into())
.map(Into::<Dynamic>::into)
.map_err(|err| EvalAltResult::set_position(err, pos))
};
let arg_types = vec![TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
@ -507,7 +507,7 @@ impl Module {
let a = args[0].downcast_mut::<A>().unwrap();
func(a, b, c)
.map(|v| v.into())
.map(Into::<Dynamic>::into)
.map_err(|err| EvalAltResult::set_position(err, pos))
};
let arg_types = vec![TypeId::of::<A>(), TypeId::of::<B>(), TypeId::of::<C>()];
@ -639,7 +639,7 @@ impl Module {
// Index all variables
for (var_name, value) in module.variables.iter() {
// Qualifiers + variable name
let hash = calc_fn_hash(qualifiers.iter().map(|v| *v), var_name, empty());
let hash = calc_fn_hash(qualifiers.iter().map(|&v| v), var_name, empty());
variables.push((hash, value.clone()));
}
// Index all Rust functions
@ -653,7 +653,7 @@ impl Module {
// 1) Calculate a hash in a similar manner to script-defined functions,
// i.e. qualifiers + function name + dummy parameter types (one for each parameter).
let hash_fn_def = calc_fn_hash(
qualifiers.iter().map(|v| *v),
qualifiers.iter().map(|&v| v),
fn_name,
repeat(EMPTY_TYPE_ID()).take(params.len()),
);
@ -674,7 +674,7 @@ impl Module {
}
// Qualifiers + function name + placeholders (one for each parameter)
let hash = calc_fn_hash(
qualifiers.iter().map(|v| *v),
qualifiers.iter().map(|&v| v),
&fn_def.name,
repeat(EMPTY_TYPE_ID()).take(fn_def.params.len()),
);

View File

@ -63,25 +63,6 @@ macro_rules! def_package {
};
}
/// Check whether the correct number of arguments is passed to the function.
fn check_num_args(
name: &str,
num_args: usize,
args: &mut FnCallArgs,
pos: Position,
) -> Result<(), Box<EvalAltResult>> {
if args.len() != num_args {
Err(Box::new(EvalAltResult::ErrorFunctionArgsMismatch(
name.to_string(),
num_args,
args.len(),
pos,
)))
} else {
Ok(())
}
}
/// Add a function with no parameters to the package.
///
/// `map_result` is a function that maps the return type of the function to `Result<Dynamic, EvalAltResult>`.
@ -121,8 +102,6 @@ pub fn reg_none<R>(
let hash = calc_fn_hash(empty(), fn_name, ([] as [TypeId; 0]).iter().cloned());
let f = Box::new(move |args: &mut FnCallArgs, pos: Position| {
check_num_args(fn_name, 0, args, pos)?;
let r = func();
map_result(r, pos)
});
@ -171,8 +150,6 @@ pub fn reg_unary<T: Variant + Clone, R>(
let hash = calc_fn_hash(empty(), fn_name, [TypeId::of::<T>()].iter().cloned());
let f = Box::new(move |args: &mut FnCallArgs, pos: Position| {
check_num_args(fn_name, 1, args, pos)?;
let mut drain = args.iter_mut();
let x = mem::take(*drain.next().unwrap()).cast::<T>();
@ -231,8 +208,6 @@ pub fn reg_unary_mut<T: Variant + Clone, R>(
let hash = calc_fn_hash(empty(), fn_name, [TypeId::of::<T>()].iter().cloned());
let f = Box::new(move |args: &mut FnCallArgs, pos: Position| {
check_num_args(fn_name, 1, args, pos)?;
let mut drain = args.iter_mut();
let x: &mut T = drain.next().unwrap().downcast_mut().unwrap();
@ -288,8 +263,6 @@ pub fn reg_binary<A: Variant + Clone, B: Variant + Clone, R>(
);
let f = Box::new(move |args: &mut FnCallArgs, pos: Position| {
check_num_args(fn_name, 2, args, pos)?;
let mut drain = args.iter_mut();
let x = mem::take(*drain.next().unwrap()).cast::<A>();
let y = mem::take(*drain.next().unwrap()).cast::<B>();
@ -353,8 +326,6 @@ pub fn reg_binary_mut<A: Variant + Clone, B: Variant + Clone, R>(
);
let f = Box::new(move |args: &mut FnCallArgs, pos: Position| {
check_num_args(fn_name, 2, args, pos)?;
let mut drain = args.iter_mut();
let x: &mut A = drain.next().unwrap().downcast_mut().unwrap();
let y = mem::take(*drain.next().unwrap()).cast::<B>();
@ -394,8 +365,6 @@ pub fn reg_trinary<A: Variant + Clone, B: Variant + Clone, C: Variant + Clone, R
);
let f = Box::new(move |args: &mut FnCallArgs, pos: Position| {
check_num_args(fn_name, 3, args, pos)?;
let mut drain = args.iter_mut();
let x = mem::take(*drain.next().unwrap()).cast::<A>();
let y = mem::take(*drain.next().unwrap()).cast::<B>();
@ -436,8 +405,6 @@ pub fn reg_trinary_mut<A: Variant + Clone, B: Variant + Clone, C: Variant + Clon
);
let f = Box::new(move |args: &mut FnCallArgs, pos: Position| {
check_num_args(fn_name, 3, args, pos)?;
let mut drain = args.iter_mut();
let x: &mut A = drain.next().unwrap().downcast_mut().unwrap();
let y = mem::take(*drain.next().unwrap()).cast::<B>();