Cleanup code.

This commit is contained in:
Stephen Chung 2023-04-27 15:24:55 +08:00
parent 76e6c1b9e4
commit 3dbfc1e99f

View File

@ -750,7 +750,7 @@ impl Engine {
target: &mut crate::eval::Target, target: &mut crate::eval::Target,
mut call_args: &mut [Dynamic], mut call_args: &mut [Dynamic],
first_arg_pos: Position, first_arg_pos: Position,
fn_call_pos: Position, pos: Position,
) -> RhaiResultOf<(Dynamic, bool)> { ) -> RhaiResultOf<(Dynamic, bool)> {
let is_ref_mut = target.is_ref(); let is_ref_mut = target.is_ref();
@ -774,29 +774,24 @@ impl Engine {
match fn_def { match fn_def {
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
Some(fn_def) if fn_def.params.len() == args.len() => self Some(fn_def) if fn_def.params.len() == args.len() => {
.call_script_fn( let scope = &mut Scope::new();
global, let environ = fn_ptr.encapsulated_environ().map(|r| r.as_ref());
caches,
&mut Scope::new(), self.call_script_fn(
None, global, caches, scope, None, environ, fn_def, args, true, pos,
fn_ptr.encapsulated_environ().map(|r| r.as_ref()),
fn_def,
args,
true,
fn_call_pos,
) )
.map(|v| (v, false)), .map(|v| (v, false))
}
_ => { _ => {
let _is_anon = false;
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
let is_anon = fn_ptr.is_anonymous(); let _is_anon = fn_ptr.is_anonymous();
#[cfg(feature = "no_function")]
let is_anon = false;
// Redirect function name // Redirect function name
let fn_name = fn_ptr.fn_name(); let fn_name = fn_ptr.fn_name();
// Recalculate hashes // Recalculate hashes
let new_hash = if !is_anon && !is_valid_function_name(fn_name) { let new_hash = if !_is_anon && !is_valid_function_name(fn_name) {
FnCallHashes::from_native_only(calc_fn_hash(None, fn_name, args.len())) FnCallHashes::from_native_only(calc_fn_hash(None, fn_name, args.len()))
} else { } else {
FnCallHashes::from_hash(calc_fn_hash(None, fn_name, args.len())) FnCallHashes::from_hash(calc_fn_hash(None, fn_name, args.len()))
@ -804,16 +799,7 @@ impl Engine {
// Map it to name(args) in function-call style // Map it to name(args) in function-call style
self.exec_fn_call( self.exec_fn_call(
global, global, caches, None, fn_name, None, new_hash, args, false, false, pos,
caches,
None,
fn_name,
None,
new_hash,
args,
false,
false,
fn_call_pos,
) )
} }
} }
@ -824,7 +810,7 @@ impl Engine {
if call_args.is_empty() { if call_args.is_empty() {
return Err(self.make_type_mismatch_err::<FnPtr>( return Err(self.make_type_mismatch_err::<FnPtr>(
self.map_type_name(target.type_name()), self.map_type_name(target.type_name()),
fn_call_pos, pos,
)); ));
} }
if !call_args[0].is_fnptr() { if !call_args[0].is_fnptr() {
@ -837,28 +823,11 @@ impl Engine {
// FnPtr call on object // FnPtr call on object
let fn_ptr = call_args[0].take().cast::<FnPtr>(); let fn_ptr = call_args[0].take().cast::<FnPtr>();
let (fn_name, is_anon, fn_curry, _environ, fn_def) = {
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
let is_anon = fn_ptr.is_anonymous(); let (is_anon, (fn_name, fn_curry, environ, fn_def)) =
(fn_ptr.is_anonymous(), fn_ptr.take_data());
#[cfg(feature = "no_function")] #[cfg(feature = "no_function")]
let is_anon = false; let (is_anon, (fn_name, fn_curry, _), fn_def) = (false, fn_ptr.take_data(), ());
#[cfg(not(feature = "no_function"))]
let (fn_name, fn_curry, environ, fn_def) = fn_ptr.take_data();
#[cfg(feature = "no_function")]
let (fn_name, fn_curry, environ) = fn_ptr.take_data();
(
fn_name,
is_anon,
fn_curry,
environ,
#[cfg(not(feature = "no_function"))]
fn_def,
#[cfg(feature = "no_function")]
(),
)
};
// Replace the first argument with the object pointer, adding the curried arguments // Replace the first argument with the object pointer, adding the curried arguments
call_args = &mut call_args[1..]; call_args = &mut call_args[1..];
@ -877,16 +846,12 @@ impl Engine {
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]
ensure_no_data_race(&fn_def.name, args, false)?; ensure_no_data_race(&fn_def.name, args, false)?;
let scope = &mut Scope::new();
let this_ptr = Some(target.as_mut());
let environ = environ.as_deref();
self.call_script_fn( self.call_script_fn(
global, global, caches, scope, this_ptr, environ, &fn_def, args, true, pos,
caches,
&mut Scope::new(),
Some(target),
_environ.as_deref(),
&fn_def,
args,
true,
fn_call_pos,
) )
.map(|v| (v, false)) .map(|v| (v, false))
} }
@ -918,16 +883,8 @@ impl Engine {
// Map it to name(args) in function-call style // Map it to name(args) in function-call style
self.exec_fn_call( self.exec_fn_call(
global, global, caches, None, &fn_name, None, new_hash, args, is_ref_mut, true,
caches, pos,
None,
&fn_name,
None,
new_hash,
args,
is_ref_mut,
true,
fn_call_pos,
) )
} }
} }
@ -936,7 +893,7 @@ impl Engine {
if !target.is_fnptr() { if !target.is_fnptr() {
return Err(self.make_type_mismatch_err::<FnPtr>( return Err(self.make_type_mismatch_err::<FnPtr>(
self.map_type_name(target.type_name()), self.map_type_name(target.type_name()),
fn_call_pos, pos,
)); ));
} }
@ -998,14 +955,13 @@ impl Engine {
)) ))
} }
_ => { _ => {
let _is_anon = false;
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
let is_anon = fn_ptr.is_anonymous(); let _is_anon = fn_ptr.is_anonymous();
#[cfg(feature = "no_function")]
let is_anon = false;
// Recalculate the hash based on the new function name and new arguments // Recalculate the hash based on the new function name and new arguments
let args_len = call_args.len() + 1; let args_len = call_args.len() + 1;
hash = match is_anon { hash = match _is_anon {
false if !is_valid_function_name(fn_name) => { false if !is_valid_function_name(fn_name) => {
FnCallHashes::from_native_only(calc_fn_hash( FnCallHashes::from_native_only(calc_fn_hash(
None, fn_name, args_len, None, fn_name, args_len,
@ -1031,16 +987,13 @@ impl Engine {
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
Some((fn_def, environ)) => { Some((fn_def, environ)) => {
// Linked to scripted function // Linked to scripted function
let scope = &mut Scope::new();
let environ = environ.as_deref();
let this_ptr = Some(target.as_mut());
let args = &mut call_args.iter_mut().collect::<FnArgsVec<_>>();
self.call_script_fn( self.call_script_fn(
global, global, caches, scope, this_ptr, environ, &*fn_def, args, true, pos,
caches,
&mut Scope::new(),
Some(target),
environ.as_deref(),
&*fn_def,
&mut call_args.iter_mut().collect::<FnArgsVec<_>>(),
true,
fn_call_pos,
) )
.map(|v| (v, false)) .map(|v| (v, false))
} }
@ -1053,16 +1006,8 @@ impl Engine {
args.extend(call_args.iter_mut()); args.extend(call_args.iter_mut());
self.exec_fn_call( self.exec_fn_call(
global, global, caches, None, fn_name, None, hash, &mut args, is_ref_mut, true,
caches, pos,
None,
fn_name,
None,
hash,
&mut args,
is_ref_mut,
true,
fn_call_pos,
) )
} }
} }
@ -1071,7 +1016,7 @@ impl Engine {
// Propagate the changed value back to the source if necessary // Propagate the changed value back to the source if necessary
if updated { if updated {
target.propagate_changed_value(fn_call_pos)?; target.propagate_changed_value(pos)?;
} }
Ok((result, updated)) Ok((result, updated))
@ -1093,8 +1038,8 @@ impl Engine {
pos: Position, pos: Position,
) -> RhaiResult { ) -> RhaiResult {
let mut first_arg = first_arg; let mut first_arg = first_arg;
let mut a_expr = args_expr; let mut args_expr = args_expr;
let mut total_args = usize::from(first_arg.is_some()) + a_expr.len(); let mut total_args = usize::from(first_arg.is_some()) + args_expr.len();
let mut curry = FnArgsVec::new_const(); let mut curry = FnArgsVec::new_const();
let mut name = fn_name; let mut name = fn_name;
let mut hashes = hashes; let mut hashes = hashes;
@ -1119,28 +1064,22 @@ impl Engine {
let fn_ptr = arg_value.cast::<FnPtr>(); let fn_ptr = arg_value.cast::<FnPtr>();
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
let (fn_name, is_anon, fn_curry, _environ, fn_def) = { let (is_anon, (fn_name, fn_curry, _environ, fn_def)) =
let is_anon = fn_ptr.is_anonymous(); (fn_ptr.is_anonymous(), fn_ptr.take_data());
let (fn_name, fn_curry, environ, fn_def) = fn_ptr.take_data();
(fn_name, is_anon, fn_curry, environ, fn_def)
};
#[cfg(feature = "no_function")] #[cfg(feature = "no_function")]
let (fn_name, is_anon, fn_curry, _environ) = { let (is_anon, (fn_name, fn_curry, _environ)) = (false, fn_ptr.take_data());
let (fn_name, fn_curry, environ) = fn_ptr.take_data();
(fn_name, false, fn_curry, environ)
};
curry.extend(fn_curry.into_iter()); curry.extend(fn_curry.into_iter());
// Linked to scripted function? // Linked to scripted function?
#[cfg(not(feature = "no_function"))] #[cfg(not(feature = "no_function"))]
if let Some(fn_def) = fn_def { if let Some(fn_def) = fn_def {
if fn_def.params.len() == curry.len() + a_expr.len() { if fn_def.params.len() == curry.len() + args_expr.len() {
// Evaluate arguments // Evaluate arguments
let mut arg_values = curry let mut arg_values = curry
.into_iter() .into_iter()
.map(Ok) .map(Ok)
.chain(a_expr.iter().map(|expr| -> Result<_, crate::RhaiError> { .chain(args_expr.iter().map(|expr| -> Result<_, crate::RhaiError> {
let this_ptr = this_ptr.as_deref_mut(); let this_ptr = this_ptr.as_deref_mut();
self.get_arg_value(global, caches, scope, this_ptr, expr) self.get_arg_value(global, caches, scope, this_ptr, expr)
.map(|(v, ..)| v) .map(|(v, ..)| v)
@ -1161,9 +1100,9 @@ impl Engine {
name = &redirected; name = &redirected;
// Shift the arguments // Shift the arguments
first_arg = a_expr.get(0); first_arg = args_expr.get(0);
if !a_expr.is_empty() { if !args_expr.is_empty() {
a_expr = &a_expr[1..]; args_expr = &args_expr[1..];
} }
total_args -= 1; total_args -= 1;
@ -1207,7 +1146,7 @@ impl Engine {
let mut fn_ptr = arg_value.cast::<FnPtr>(); let mut fn_ptr = arg_value.cast::<FnPtr>();
// Append the new curried arguments to the existing list. // Append the new curried arguments to the existing list.
for expr in a_expr { for expr in args_expr {
let (value, ..) = let (value, ..) =
self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?; self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?;
fn_ptr.add_curry(value); fn_ptr.add_curry(value);
@ -1237,7 +1176,7 @@ impl Engine {
.map_err(|typ| self.make_type_mismatch_err::<ImmutableString>(typ, arg_pos))?; .map_err(|typ| self.make_type_mismatch_err::<ImmutableString>(typ, arg_pos))?;
let (arg_value, arg_pos) = let (arg_value, arg_pos) =
self.get_arg_value(global, caches, scope, this_ptr, &a_expr[0])?; self.get_arg_value(global, caches, scope, this_ptr, &args_expr[0])?;
let num_params = arg_value let num_params = arg_value
.as_int() .as_int()
@ -1264,15 +1203,20 @@ impl Engine {
.into_immutable_string() .into_immutable_string()
.map_err(|typ| self.make_type_mismatch_err::<ImmutableString>(typ, arg_pos))?; .map_err(|typ| self.make_type_mismatch_err::<ImmutableString>(typ, arg_pos))?;
let (arg_value, arg_pos) = let (arg_value, arg_pos) = self.get_arg_value(
self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), &a_expr[0])?; global,
caches,
scope,
this_ptr.as_deref_mut(),
&args_expr[0],
)?;
let fn_name = arg_value let fn_name = arg_value
.into_immutable_string() .into_immutable_string()
.map_err(|typ| self.make_type_mismatch_err::<ImmutableString>(typ, arg_pos))?; .map_err(|typ| self.make_type_mismatch_err::<ImmutableString>(typ, arg_pos))?;
let (arg_value, arg_pos) = let (arg_value, arg_pos) =
self.get_arg_value(global, caches, scope, this_ptr, &a_expr[1])?; self.get_arg_value(global, caches, scope, this_ptr, &args_expr[1])?;
let num_params = arg_value let num_params = arg_value
.as_int() .as_int()
@ -1354,7 +1298,7 @@ impl Engine {
// If so, do it separately because we cannot convert the first argument (if it is a simple // If so, do it separately because we cannot convert the first argument (if it is a simple
// variable access) to &mut because `scope` is needed. // variable access) to &mut because `scope` is needed.
if capture_scope && !scope.is_empty() { if capture_scope && !scope.is_empty() {
for expr in first_arg.iter().copied().chain(a_expr.iter()) { for expr in first_arg.iter().copied().chain(args_expr.iter()) {
let (value, ..) = let (value, ..) =
self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?; self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?;
arg_values.push(value.flatten()); arg_values.push(value.flatten());
@ -1381,11 +1325,13 @@ impl Engine {
if curry.is_empty() && first_arg.map_or(false, |expr| expr.is_variable_access(false)) { if curry.is_empty() && first_arg.map_or(false, |expr| expr.is_variable_access(false)) {
let first_expr = first_arg.unwrap(); let first_expr = first_arg.unwrap();
self.track_operation(global, first_expr.position())?;
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]
self.run_debugger(global, caches, scope, this_ptr.as_deref_mut(), first_expr)?; self.run_debugger(global, caches, scope, this_ptr.as_deref_mut(), first_expr)?;
// func(x, ...) -> x.func(...) // func(x, ...) -> x.func(...)
for expr in a_expr { for expr in args_expr {
let (value, ..) = let (value, ..) =
self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?; self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?;
arg_values.push(value.flatten()); arg_values.push(value.flatten());
@ -1398,8 +1344,6 @@ impl Engine {
target = target.into_owned(); target = target.into_owned();
} }
self.track_operation(global, first_expr.position())?;
if target.is_shared() || target.is_temp_value() { if target.is_shared() || target.is_temp_value() {
arg_values.insert(0, target.take_or_clone().flatten()); arg_values.insert(0, target.take_or_clone().flatten());
} else { } else {
@ -1410,7 +1354,7 @@ impl Engine {
} }
} else { } else {
// func(..., ...) // func(..., ...)
for expr in first_arg.into_iter().chain(a_expr.iter()) { for expr in first_arg.into_iter().chain(args_expr.iter()) {
let (value, ..) = let (value, ..) =
self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?; self.get_arg_value(global, caches, scope, this_ptr.as_deref_mut(), expr)?;
arg_values.push(value.flatten()); arg_values.push(value.flatten());
@ -1450,14 +1394,13 @@ impl Engine {
// If so, convert to method-call style in order to leverage potential &mut first argument // If so, convert to method-call style in order to leverage potential &mut first argument
// and avoid cloning the value // and avoid cloning the value
if !args_expr.is_empty() && args_expr[0].is_variable_access(true) { if !args_expr.is_empty() && args_expr[0].is_variable_access(true) {
// Get target reference to first argument
let first_arg = &args_expr[0];
self.track_operation(global, first_arg.position())?;
#[cfg(feature = "debugging")] #[cfg(feature = "debugging")]
self.run_debugger( self.run_debugger(global, caches, scope, this_ptr.as_deref_mut(), first_arg)?;
global,
caches,
scope,
this_ptr.as_deref_mut(),
&args_expr[0],
)?;
// func(x, ...) -> x.func(...) // func(x, ...) -> x.func(...)
arg_values.push(Dynamic::UNIT); arg_values.push(Dynamic::UNIT);
@ -1468,11 +1411,6 @@ impl Engine {
arg_values.push(value.flatten()); arg_values.push(value.flatten());
} }
// Get target reference to first argument
let first_arg = &args_expr[0];
self.track_operation(global, first_arg.position())?;
let target = self.search_scope_only(global, caches, scope, this_ptr, first_arg)?; let target = self.search_scope_only(global, caches, scope, this_ptr, first_arg)?;
#[cfg(not(feature = "no_closure"))] #[cfg(not(feature = "no_closure"))]