Pack method call args more tightly.
This commit is contained in:
parent
bc2b9bfbfd
commit
9daa894e25
@ -29,6 +29,7 @@ Breaking changes
|
|||||||
* `is_def_var` and `is_def_fn` are now reserved keywords.
|
* `is_def_var` and `is_def_fn` are now reserved keywords.
|
||||||
* `Engine::id` field is removed.
|
* `Engine::id` field is removed.
|
||||||
* `num-traits` is now a required dependency.
|
* `num-traits` is now a required dependency.
|
||||||
|
* The `in` operator is now implemented on top of the `contains` function and is no longer restricted to a few specific types.
|
||||||
|
|
||||||
Enhancements
|
Enhancements
|
||||||
------------
|
------------
|
||||||
|
@ -230,7 +230,7 @@ pub enum ChainArgument {
|
|||||||
/// Dot-property access.
|
/// Dot-property access.
|
||||||
Property(Position),
|
Property(Position),
|
||||||
/// Arguments to a dot-function call.
|
/// Arguments to a dot-function call.
|
||||||
FnCallArgs(StaticVec<(Dynamic, Position)>),
|
FnCallArgs(StaticVec<Dynamic>, StaticVec<Position>),
|
||||||
/// Index value.
|
/// Index value.
|
||||||
IndexValue(Dynamic, Position),
|
IndexValue(Dynamic, Position),
|
||||||
}
|
}
|
||||||
@ -246,7 +246,7 @@ impl ChainArgument {
|
|||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
pub fn as_index_value(self) -> Dynamic {
|
pub fn as_index_value(self) -> Dynamic {
|
||||||
match self {
|
match self {
|
||||||
Self::Property(_) | Self::FnCallArgs(_) => {
|
Self::Property(_) | Self::FnCallArgs(_, _) => {
|
||||||
panic!("expecting ChainArgument::IndexValue")
|
panic!("expecting ChainArgument::IndexValue")
|
||||||
}
|
}
|
||||||
Self::IndexValue(value, _) => value,
|
Self::IndexValue(value, _) => value,
|
||||||
@ -259,21 +259,21 @@ impl ChainArgument {
|
|||||||
/// Panics if not `ChainArgument::FnCallArgs`.
|
/// Panics if not `ChainArgument::FnCallArgs`.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
pub fn as_fn_call_args(self) -> StaticVec<(Dynamic, Position)> {
|
pub fn as_fn_call_args(self) -> (StaticVec<Dynamic>, StaticVec<Position>) {
|
||||||
match self {
|
match self {
|
||||||
Self::Property(_) | Self::IndexValue(_, _) => {
|
Self::Property(_) | Self::IndexValue(_, _) => {
|
||||||
panic!("expecting ChainArgument::FnCallArgs")
|
panic!("expecting ChainArgument::FnCallArgs")
|
||||||
}
|
}
|
||||||
Self::FnCallArgs(value) => value,
|
Self::FnCallArgs(values, positions) => (values, positions),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||||
impl From<StaticVec<(Dynamic, Position)>> for ChainArgument {
|
impl From<(StaticVec<Dynamic>, StaticVec<Position>)> for ChainArgument {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from(value: StaticVec<(Dynamic, Position)>) -> Self {
|
fn from((values, positions): (StaticVec<Dynamic>, StaticVec<Position>)) -> Self {
|
||||||
Self::FnCallArgs(value)
|
Self::FnCallArgs(values, positions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1436,16 +1436,19 @@ impl Engine {
|
|||||||
|
|
||||||
match expr {
|
match expr {
|
||||||
Expr::FnCall(x, _) if parent_chain_type == ChainType::Dot && x.namespace.is_none() => {
|
Expr::FnCall(x, _) if parent_chain_type == ChainType::Dot && x.namespace.is_none() => {
|
||||||
|
let mut arg_positions: StaticVec<_> = Default::default();
|
||||||
|
|
||||||
let arg_values = x
|
let arg_values = x
|
||||||
.args
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|arg_expr| {
|
.map(|arg_expr| {
|
||||||
|
arg_positions.push(arg_expr.position());
|
||||||
self.eval_expr(scope, mods, state, lib, this_ptr, arg_expr, level)
|
self.eval_expr(scope, mods, state, lib, this_ptr, arg_expr, level)
|
||||||
.map(|v| (v.flatten(), arg_expr.position()))
|
.map(Dynamic::flatten)
|
||||||
})
|
})
|
||||||
.collect::<Result<StaticVec<_>, _>>()?;
|
.collect::<Result<StaticVec<_>, _>>()?;
|
||||||
|
|
||||||
idx_values.push(arg_values.into());
|
idx_values.push((arg_values, arg_positions).into());
|
||||||
}
|
}
|
||||||
Expr::FnCall(_, _) if parent_chain_type == ChainType::Dot => {
|
Expr::FnCall(_, _) if parent_chain_type == ChainType::Dot => {
|
||||||
unreachable!("function call in dot chain should not be namespace-qualified")
|
unreachable!("function call in dot chain should not be namespace-qualified")
|
||||||
@ -1468,14 +1471,19 @@ impl Engine {
|
|||||||
Expr::FnCall(x, _)
|
Expr::FnCall(x, _)
|
||||||
if parent_chain_type == ChainType::Dot && x.namespace.is_none() =>
|
if parent_chain_type == ChainType::Dot && x.namespace.is_none() =>
|
||||||
{
|
{
|
||||||
x.args
|
let mut arg_positions: StaticVec<_> = Default::default();
|
||||||
|
|
||||||
|
let arg_values = x
|
||||||
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
.map(|arg_expr| {
|
.map(|arg_expr| {
|
||||||
|
arg_positions.push(arg_expr.position());
|
||||||
self.eval_expr(scope, mods, state, lib, this_ptr, arg_expr, level)
|
self.eval_expr(scope, mods, state, lib, this_ptr, arg_expr, level)
|
||||||
.map(|v| (v.flatten(), arg_expr.position()))
|
.map(Dynamic::flatten)
|
||||||
})
|
})
|
||||||
.collect::<Result<StaticVec<_>, _>>()?
|
.collect::<Result<StaticVec<_>, _>>()?;
|
||||||
.into()
|
|
||||||
|
(arg_values, arg_positions).into()
|
||||||
}
|
}
|
||||||
Expr::FnCall(_, _) if parent_chain_type == ChainType::Dot => {
|
Expr::FnCall(_, _) if parent_chain_type == ChainType::Dot => {
|
||||||
unreachable!("function call in dot chain should not be namespace-qualified")
|
unreachable!("function call in dot chain should not be namespace-qualified")
|
||||||
|
@ -885,7 +885,7 @@ impl Engine {
|
|||||||
fn_name: &str,
|
fn_name: &str,
|
||||||
mut hash: FnHash,
|
mut hash: FnHash,
|
||||||
target: &mut crate::engine::Target,
|
target: &mut crate::engine::Target,
|
||||||
call_args: &mut StaticVec<(Dynamic, Position)>,
|
(call_args, call_arg_positions): &mut (StaticVec<Dynamic>, StaticVec<Position>),
|
||||||
pos: Position,
|
pos: Position,
|
||||||
level: usize,
|
level: usize,
|
||||||
) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
||||||
@ -908,7 +908,7 @@ impl Engine {
|
|||||||
let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>();
|
let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>();
|
||||||
let mut arg_values = curry
|
let mut arg_values = curry
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.chain(call_args.iter_mut().map(|v| &mut v.0))
|
.chain(call_args.iter_mut())
|
||||||
.collect::<StaticVec<_>>();
|
.collect::<StaticVec<_>>();
|
||||||
let args = arg_values.as_mut();
|
let args = arg_values.as_mut();
|
||||||
|
|
||||||
@ -919,10 +919,10 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
KEYWORD_FN_PTR_CALL => {
|
KEYWORD_FN_PTR_CALL => {
|
||||||
if call_args.len() > 0 {
|
if call_args.len() > 0 {
|
||||||
if !call_args[0].0.is::<FnPtr>() {
|
if !call_args[0].is::<FnPtr>() {
|
||||||
return Err(self.make_type_mismatch_err::<FnPtr>(
|
return Err(self.make_type_mismatch_err::<FnPtr>(
|
||||||
self.map_type_name(obj.type_name()),
|
self.map_type_name(obj.type_name()),
|
||||||
call_args[0].1,
|
call_arg_positions[0],
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -933,7 +933,8 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FnPtr call on object
|
// FnPtr call on object
|
||||||
let fn_ptr = call_args.remove(0).0.cast::<FnPtr>();
|
let fn_ptr = call_args.remove(0).cast::<FnPtr>();
|
||||||
|
call_arg_positions.remove(0);
|
||||||
// Redirect function name
|
// Redirect function name
|
||||||
let fn_name = fn_ptr.fn_name();
|
let fn_name = fn_ptr.fn_name();
|
||||||
let args_len = call_args.len() + fn_ptr.curry().len();
|
let args_len = call_args.len() + fn_ptr.curry().len();
|
||||||
@ -946,7 +947,7 @@ impl Engine {
|
|||||||
let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>();
|
let mut curry = fn_ptr.curry().iter().cloned().collect::<StaticVec<_>>();
|
||||||
let mut arg_values = once(obj)
|
let mut arg_values = once(obj)
|
||||||
.chain(curry.iter_mut())
|
.chain(curry.iter_mut())
|
||||||
.chain(call_args.iter_mut().map(|v| &mut v.0))
|
.chain(call_args.iter_mut())
|
||||||
.collect::<StaticVec<_>>();
|
.collect::<StaticVec<_>>();
|
||||||
let args = arg_values.as_mut();
|
let args = arg_values.as_mut();
|
||||||
|
|
||||||
@ -976,7 +977,7 @@ impl Engine {
|
|||||||
.curry()
|
.curry()
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.chain(call_args.iter_mut().map(|v| mem::take(v).0))
|
.chain(call_args.iter_mut().map(|v| mem::take(v)))
|
||||||
.collect(),
|
.collect(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -1008,7 +1009,10 @@ impl Engine {
|
|||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.for_each(|(i, v)| call_args.insert(i, (v, Position::NONE)));
|
.for_each(|(i, v)| {
|
||||||
|
call_args.insert(i, v);
|
||||||
|
call_arg_positions.insert(i, Position::NONE);
|
||||||
|
});
|
||||||
// Recalculate the hash based on the new function name and new arguments
|
// Recalculate the hash based on the new function name and new arguments
|
||||||
hash = FnHash::from_script_and_native(
|
hash = FnHash::from_script_and_native(
|
||||||
calc_fn_hash(empty(), fn_name, call_args.len()),
|
calc_fn_hash(empty(), fn_name, call_args.len()),
|
||||||
@ -1020,7 +1024,7 @@ impl Engine {
|
|||||||
|
|
||||||
// Attached object pointer in front of the arguments
|
// Attached object pointer in front of the arguments
|
||||||
let mut arg_values = once(obj)
|
let mut arg_values = once(obj)
|
||||||
.chain(call_args.iter_mut().map(|v| &mut v.0))
|
.chain(call_args.iter_mut())
|
||||||
.collect::<StaticVec<_>>();
|
.collect::<StaticVec<_>>();
|
||||||
let args = arg_values.as_mut();
|
let args = arg_values.as_mut();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user