Pass Position into function calls.
This commit is contained in:
parent
4438c358d5
commit
5443368359
@ -1016,8 +1016,8 @@ impl Engine {
|
||||
let args = &mut [target_val, &mut idx_val2, &mut new_val.0];
|
||||
|
||||
self.exec_fn_call(
|
||||
mods, state, lib, FN_IDX_SET, 0, args, is_ref, true, false, None,
|
||||
None, level,
|
||||
mods, state, lib, FN_IDX_SET, 0, args, is_ref, true, false,
|
||||
new_val.1, None, None, level,
|
||||
)
|
||||
.map_err(|err| match *err {
|
||||
EvalAltResult::ErrorFunctionNotFound(fn_sig, _)
|
||||
@ -1061,9 +1061,8 @@ impl Engine {
|
||||
let args = idx_val.as_fn_call_args();
|
||||
self.make_method_call(
|
||||
mods, state, lib, name, *hash, target, args, def_value, *native, false,
|
||||
level,
|
||||
*pos, level,
|
||||
)
|
||||
.map_err(|err| err.fill_position(*pos))
|
||||
}
|
||||
// xxx.module::fn_name(...) - syntax error
|
||||
Expr::FnCall(_, _) => unreachable!(),
|
||||
@ -1094,8 +1093,8 @@ impl Engine {
|
||||
let mut new_val = new_val;
|
||||
let mut args = [target_val, &mut new_val.as_mut().unwrap().0];
|
||||
self.exec_fn_call(
|
||||
mods, state, lib, setter, 0, &mut args, is_ref, true, false, None,
|
||||
None, level,
|
||||
mods, state, lib, setter, 0, &mut args, is_ref, true, false, *pos,
|
||||
None, None, level,
|
||||
)
|
||||
.map(|(v, _)| (v, true))
|
||||
.map_err(|err| err.fill_position(*pos))
|
||||
@ -1105,8 +1104,8 @@ impl Engine {
|
||||
let ((getter, _), IdentX { pos, .. }) = x.as_ref();
|
||||
let mut args = [target_val];
|
||||
self.exec_fn_call(
|
||||
mods, state, lib, getter, 0, &mut args, is_ref, true, false, None,
|
||||
None, level,
|
||||
mods, state, lib, getter, 0, &mut args, is_ref, true, false, *pos,
|
||||
None, None, level,
|
||||
)
|
||||
.map(|(v, _)| (v, false))
|
||||
.map_err(|err| err.fill_position(*pos))
|
||||
@ -1133,12 +1132,10 @@ impl Engine {
|
||||
} = x.as_ref();
|
||||
let def_value = def_value.as_ref();
|
||||
let args = idx_val.as_fn_call_args();
|
||||
let (val, _) = self
|
||||
.make_method_call(
|
||||
let (val, _) = self.make_method_call(
|
||||
mods, state, lib, name, *hash, target, args, def_value,
|
||||
*native, false, level,
|
||||
)
|
||||
.map_err(|err| err.fill_position(*pos))?;
|
||||
*native, false, *pos, level,
|
||||
)?;
|
||||
val.into()
|
||||
}
|
||||
// {xxx:map}.module::fn_name(...) - syntax error
|
||||
@ -1164,7 +1161,7 @@ impl Engine {
|
||||
let (mut val, updated) = self
|
||||
.exec_fn_call(
|
||||
mods, state, lib, getter, 0, args, is_ref, true, false,
|
||||
None, None, level,
|
||||
*pos, None, None, level,
|
||||
)
|
||||
.map_err(|err| err.fill_position(*pos))?;
|
||||
|
||||
@ -1191,7 +1188,7 @@ impl Engine {
|
||||
arg_values[1] = val;
|
||||
self.exec_fn_call(
|
||||
mods, state, lib, setter, 0, arg_values, is_ref, true,
|
||||
false, None, None, level,
|
||||
false, *pos, None, None, level,
|
||||
)
|
||||
.or_else(
|
||||
|err| match *err {
|
||||
@ -1217,12 +1214,10 @@ impl Engine {
|
||||
} = f.as_ref();
|
||||
let def_value = def_value.as_ref();
|
||||
let args = idx_val.as_fn_call_args();
|
||||
let (mut val, _) = self
|
||||
.make_method_call(
|
||||
let (mut val, _) = self.make_method_call(
|
||||
mods, state, lib, name, *hash, target, args, def_value,
|
||||
*native, false, level,
|
||||
)
|
||||
.map_err(|err| err.fill_position(*pos))?;
|
||||
*native, false, *pos, level,
|
||||
)?;
|
||||
let val = &mut val;
|
||||
let target = &mut val.into();
|
||||
|
||||
@ -1475,8 +1470,8 @@ impl Engine {
|
||||
let mut idx = idx;
|
||||
let args = &mut [target, &mut idx];
|
||||
self.exec_fn_call(
|
||||
_mods, state, _lib, FN_IDX_GET, 0, args, _is_ref, true, false, None, None,
|
||||
_level,
|
||||
_mods, state, _lib, FN_IDX_GET, 0, args, _is_ref, true, false, idx_pos, None,
|
||||
None, _level,
|
||||
)
|
||||
.map(|(v, _)| v.into())
|
||||
.map_err(|err| match *err {
|
||||
@ -1530,11 +1525,12 @@ impl Engine {
|
||||
let hash =
|
||||
calc_native_fn_hash(empty(), OP_EQUALS, args.iter().map(|a| a.type_id()));
|
||||
|
||||
let pos = rhs.position();
|
||||
|
||||
if self
|
||||
.call_native_fn(
|
||||
mods, state, lib, OP_EQUALS, hash, args, false, false, def_value,
|
||||
)
|
||||
.map_err(|err| err.fill_position(rhs.position()))?
|
||||
mods, state, lib, OP_EQUALS, hash, args, false, false, pos, def_value,
|
||||
)?
|
||||
.0
|
||||
.as_bool()
|
||||
.unwrap_or(false)
|
||||
@ -1654,11 +1650,10 @@ impl Engine {
|
||||
let ((getter, _), IdentX { pos, .. }) = p.as_ref();
|
||||
let mut args = [target.as_mut()];
|
||||
self.exec_fn_call(
|
||||
mods, state, lib, getter, 0, &mut args, is_ref, true, false, None,
|
||||
None, level,
|
||||
mods, state, lib, getter, 0, &mut args, is_ref, true, false, *pos,
|
||||
None, None, level,
|
||||
)
|
||||
.map(|(v, _)| (v.into(), *pos))
|
||||
.map_err(|err| err.fill_position(*pos))
|
||||
}
|
||||
}
|
||||
// var.???
|
||||
@ -1764,9 +1759,8 @@ impl Engine {
|
||||
let def_value = def_value.as_ref();
|
||||
self.make_function_call(
|
||||
scope, mods, state, lib, this_ptr, name, args, def_value, *hash, *native,
|
||||
false, *cap_scope, level,
|
||||
false, *pos, *cap_scope, level,
|
||||
)
|
||||
.map_err(|err| err.fill_position(*pos))
|
||||
}
|
||||
|
||||
// Namespace-qualified function call
|
||||
@ -1783,9 +1777,8 @@ impl Engine {
|
||||
let def_value = def_value.as_ref();
|
||||
self.make_qualified_function_call(
|
||||
scope, mods, state, lib, this_ptr, namespace, name, args, def_value, *hash,
|
||||
level,
|
||||
*pos, level,
|
||||
)
|
||||
.map_err(|err| err.fill_position(*pos))
|
||||
}
|
||||
|
||||
Expr::In(x, _) => {
|
||||
@ -1984,12 +1977,10 @@ impl Engine {
|
||||
let args = &mut [&mut lhs_ptr.as_mut().clone(), &mut rhs_val];
|
||||
|
||||
// Run function
|
||||
let (value, _) = self
|
||||
.exec_fn_call(
|
||||
mods, state, lib, op, 0, args, false, false, false, None, None,
|
||||
level,
|
||||
)
|
||||
.map_err(|err| err.fill_position(*op_pos))?;
|
||||
let (value, _) = self.exec_fn_call(
|
||||
mods, state, lib, op, 0, args, false, false, false, *op_pos, None,
|
||||
None, level,
|
||||
)?;
|
||||
|
||||
let value = value.flatten();
|
||||
|
||||
@ -2023,10 +2014,10 @@ impl Engine {
|
||||
|
||||
let result = self
|
||||
.exec_fn_call(
|
||||
mods, state, lib, op, 0, args, false, false, false, None, None, level,
|
||||
mods, state, lib, op, 0, args, false, false, false, *op_pos, None,
|
||||
None, level,
|
||||
)
|
||||
.map(|(v, _)| v)
|
||||
.map_err(|err| err.fill_position(*op_pos))?;
|
||||
.map(|(v, _)| v)?;
|
||||
|
||||
Some((result, rhs_expr.position()))
|
||||
};
|
||||
|
@ -1611,7 +1611,17 @@ impl Engine {
|
||||
crate::fn_call::ensure_no_data_race(name, args, false)?;
|
||||
}
|
||||
|
||||
self.call_script_fn(scope, &mut mods, &mut state, lib, this_ptr, fn_def, args, 0)
|
||||
self.call_script_fn(
|
||||
scope,
|
||||
&mut mods,
|
||||
&mut state,
|
||||
lib,
|
||||
this_ptr,
|
||||
fn_def,
|
||||
args,
|
||||
Position::NONE,
|
||||
0,
|
||||
)
|
||||
}
|
||||
/// Optimize the [`AST`] with constants defined in an external Scope.
|
||||
/// An optimized copy of the [`AST`] is returned while the original [`AST`] is consumed.
|
||||
|
@ -149,7 +149,6 @@ pub fn ensure_no_data_race(
|
||||
|
||||
impl Engine {
|
||||
/// Call a native Rust function registered with the [`Engine`].
|
||||
/// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
|
||||
///
|
||||
/// ## WARNING
|
||||
///
|
||||
@ -166,6 +165,7 @@ impl Engine {
|
||||
args: &mut FnCallArgs,
|
||||
is_ref: bool,
|
||||
pub_only: bool,
|
||||
pos: Position,
|
||||
def_val: Option<&Dynamic>,
|
||||
) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
||||
self.inc_operations(state)?;
|
||||
@ -204,7 +204,7 @@ impl Engine {
|
||||
EvalAltResult::ErrorMismatchOutputType(
|
||||
self.map_type_name(type_name::<ImmutableString>()).into(),
|
||||
typ.into(),
|
||||
Position::NONE,
|
||||
pos,
|
||||
)
|
||||
})?)
|
||||
.into(),
|
||||
@ -215,7 +215,7 @@ impl Engine {
|
||||
EvalAltResult::ErrorMismatchOutputType(
|
||||
self.map_type_name(type_name::<ImmutableString>()).into(),
|
||||
typ.into(),
|
||||
Position::NONE,
|
||||
pos,
|
||||
)
|
||||
})?)
|
||||
.into(),
|
||||
@ -247,7 +247,7 @@ impl Engine {
|
||||
prop,
|
||||
self.map_type_name(args[0].type_name())
|
||||
),
|
||||
Position::NONE,
|
||||
pos,
|
||||
)
|
||||
.into();
|
||||
}
|
||||
@ -262,7 +262,7 @@ impl Engine {
|
||||
self.map_type_name(args[0].type_name()),
|
||||
self.map_type_name(args[1].type_name()),
|
||||
),
|
||||
Position::NONE,
|
||||
pos,
|
||||
)
|
||||
.into();
|
||||
}
|
||||
@ -276,7 +276,7 @@ impl Engine {
|
||||
self.map_type_name(args[0].type_name()),
|
||||
self.map_type_name(args[1].type_name()),
|
||||
),
|
||||
Position::NONE,
|
||||
pos,
|
||||
)
|
||||
.into();
|
||||
}
|
||||
@ -290,7 +290,7 @@ impl Engine {
|
||||
self.map_type_name(args[0].type_name()),
|
||||
self.map_type_name(args[1].type_name()),
|
||||
),
|
||||
Position::NONE,
|
||||
pos,
|
||||
)
|
||||
.into();
|
||||
}
|
||||
@ -309,13 +309,12 @@ impl Engine {
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
Position::NONE,
|
||||
pos,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
|
||||
/// Call a script-defined function.
|
||||
/// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
|
||||
///
|
||||
/// ## WARNING
|
||||
///
|
||||
@ -332,6 +331,7 @@ impl Engine {
|
||||
this_ptr: &mut Option<&mut Dynamic>,
|
||||
fn_def: &crate::ast::ScriptFnDef,
|
||||
args: &mut FnCallArgs,
|
||||
pos: Position,
|
||||
level: usize,
|
||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
self.inc_operations(state)?;
|
||||
@ -340,7 +340,7 @@ impl Engine {
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
if level > self.max_call_levels() {
|
||||
return Err(Box::new(EvalAltResult::ErrorStackOverflow(Position::NONE)));
|
||||
return Err(Box::new(EvalAltResult::ErrorStackOverflow(pos)));
|
||||
}
|
||||
|
||||
let orig_scope_level = state.scope_level;
|
||||
@ -392,17 +392,14 @@ impl Engine {
|
||||
EvalAltResult::ErrorInFunctionCall(
|
||||
format!("{} > {}", fn_def.name, name),
|
||||
err,
|
||||
Position::NONE,
|
||||
pos,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
// System errors are passed straight-through
|
||||
err if err.is_system_exception() => Err(Box::new(err)),
|
||||
// Other errors are wrapped in `ErrorInFunctionCall`
|
||||
_ => {
|
||||
EvalAltResult::ErrorInFunctionCall(fn_def.name.to_string(), err, Position::NONE)
|
||||
.into()
|
||||
}
|
||||
_ => EvalAltResult::ErrorInFunctionCall(fn_def.name.to_string(), err, pos).into(),
|
||||
});
|
||||
|
||||
// Remove all local variables
|
||||
@ -456,7 +453,6 @@ impl Engine {
|
||||
}
|
||||
|
||||
/// Perform an actual function call, native Rust or scripted, taking care of special functions.
|
||||
/// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
|
||||
///
|
||||
/// ## WARNING
|
||||
///
|
||||
@ -474,6 +470,7 @@ impl Engine {
|
||||
is_ref: bool,
|
||||
_is_method: bool,
|
||||
pub_only: bool,
|
||||
pos: Position,
|
||||
_capture_scope: Option<Scope>,
|
||||
def_val: Option<&Dynamic>,
|
||||
_level: usize,
|
||||
@ -511,7 +508,7 @@ impl Engine {
|
||||
fn_name, fn_name
|
||||
)
|
||||
.into(),
|
||||
Position::NONE,
|
||||
pos,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
@ -558,6 +555,7 @@ impl Engine {
|
||||
&mut Some(*first),
|
||||
func,
|
||||
rest,
|
||||
pos,
|
||||
_level,
|
||||
)?
|
||||
} else {
|
||||
@ -566,8 +564,9 @@ impl Engine {
|
||||
let mut backup: ArgBackup = Default::default();
|
||||
backup.change_first_arg_to_copy(is_ref, args);
|
||||
|
||||
let result = self
|
||||
.call_script_fn(scope, mods, state, lib, &mut None, func, args, _level);
|
||||
let result = self.call_script_fn(
|
||||
scope, mods, state, lib, &mut None, func, args, pos, _level,
|
||||
);
|
||||
|
||||
// Restore the original reference
|
||||
backup.restore_first_arg(args);
|
||||
@ -587,6 +586,7 @@ impl Engine {
|
||||
args,
|
||||
is_ref,
|
||||
pub_only,
|
||||
pos,
|
||||
def_val,
|
||||
)
|
||||
}
|
||||
@ -594,7 +594,7 @@ impl Engine {
|
||||
|
||||
// Normal native function call
|
||||
_ => self.call_native_fn(
|
||||
mods, state, lib, fn_name, hash_fn, args, is_ref, pub_only, def_val,
|
||||
mods, state, lib, fn_name, hash_fn, args, is_ref, pub_only, pos, def_val,
|
||||
),
|
||||
}
|
||||
}
|
||||
@ -625,7 +625,6 @@ impl Engine {
|
||||
}
|
||||
|
||||
/// Evaluate a text string as a script - used primarily for 'eval'.
|
||||
/// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
|
||||
fn eval_script_expr(
|
||||
&self,
|
||||
scope: &mut Scope,
|
||||
@ -633,6 +632,7 @@ impl Engine {
|
||||
state: &mut State,
|
||||
lib: &[&Module],
|
||||
script: &str,
|
||||
pos: Position,
|
||||
_level: usize,
|
||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
self.inc_operations(state)?;
|
||||
@ -646,7 +646,7 @@ impl Engine {
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
#[cfg(not(feature = "unchecked"))]
|
||||
if _level > self.max_call_levels() {
|
||||
return Err(Box::new(EvalAltResult::ErrorStackOverflow(Position::NONE)));
|
||||
return Err(Box::new(EvalAltResult::ErrorStackOverflow(pos)));
|
||||
}
|
||||
|
||||
// Compile the script text
|
||||
@ -672,7 +672,6 @@ impl Engine {
|
||||
}
|
||||
|
||||
/// Call a dot method.
|
||||
/// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
pub(crate) fn make_method_call(
|
||||
&self,
|
||||
@ -686,6 +685,7 @@ impl Engine {
|
||||
def_val: Option<&Dynamic>,
|
||||
native: bool,
|
||||
pub_only: bool,
|
||||
pos: Position,
|
||||
level: usize,
|
||||
) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
||||
let is_ref = target.is_ref();
|
||||
@ -716,7 +716,8 @@ impl Engine {
|
||||
|
||||
// Map it to name(args) in function-call style
|
||||
self.exec_fn_call(
|
||||
mods, state, lib, fn_name, hash, args, false, false, pub_only, None, def_val, level,
|
||||
mods, state, lib, fn_name, hash, args, false, false, pub_only, pos, None, def_val,
|
||||
level,
|
||||
)
|
||||
} else if fn_name == KEYWORD_FN_PTR_CALL
|
||||
&& call_args.len() > 0
|
||||
@ -743,7 +744,8 @@ impl Engine {
|
||||
|
||||
// Map it to name(args) in function-call style
|
||||
self.exec_fn_call(
|
||||
mods, state, lib, fn_name, hash, args, is_ref, true, pub_only, None, def_val, level,
|
||||
mods, state, lib, fn_name, hash, args, is_ref, true, pub_only, pos, None, def_val,
|
||||
level,
|
||||
)
|
||||
} else if fn_name == KEYWORD_FN_PTR_CURRY && obj.is::<FnPtr>() {
|
||||
// Curry call
|
||||
@ -811,7 +813,8 @@ impl Engine {
|
||||
let args = arg_values.as_mut();
|
||||
|
||||
self.exec_fn_call(
|
||||
mods, state, lib, fn_name, hash, args, is_ref, true, pub_only, None, def_val, level,
|
||||
mods, state, lib, fn_name, hash, args, is_ref, true, pub_only, pos, None, def_val,
|
||||
level,
|
||||
)
|
||||
}?;
|
||||
|
||||
@ -824,7 +827,6 @@ impl Engine {
|
||||
}
|
||||
|
||||
/// Call a function in normal function-call style.
|
||||
/// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
|
||||
pub(crate) fn make_function_call(
|
||||
&self,
|
||||
scope: &mut Scope,
|
||||
@ -838,6 +840,7 @@ impl Engine {
|
||||
mut hash_script: u64,
|
||||
native: bool,
|
||||
pub_only: bool,
|
||||
pos: Position,
|
||||
capture_scope: bool,
|
||||
level: usize,
|
||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
@ -956,9 +959,8 @@ impl Engine {
|
||||
let script = script.as_str().map_err(|typ| {
|
||||
self.make_type_mismatch_err::<ImmutableString>(typ, args_expr[0].position())
|
||||
})?;
|
||||
let result = self
|
||||
.eval_script_expr(scope, mods, state, lib, script, level + 1)
|
||||
.map_err(|err| err.fill_position(args_expr[0].position()));
|
||||
let pos = args_expr[0].position();
|
||||
let result = self.eval_script_expr(scope, mods, state, lib, script, pos, level + 1);
|
||||
|
||||
// IMPORTANT! If the eval defines new variables in the current scope,
|
||||
// all variable offsets from this point on will be mis-aligned.
|
||||
@ -1029,13 +1031,13 @@ impl Engine {
|
||||
let args = args.as_mut();
|
||||
|
||||
self.exec_fn_call(
|
||||
mods, state, lib, name, hash, args, is_ref, false, pub_only, capture, def_val, level,
|
||||
mods, state, lib, name, hash, args, is_ref, false, pub_only, pos, capture, def_val,
|
||||
level,
|
||||
)
|
||||
.map(|(v, _)| v)
|
||||
}
|
||||
|
||||
/// Call a namespace-qualified function in normal function-call style.
|
||||
/// [`Position`] in [`EvalAltResult`] is [`None`][Position::None] and must be set afterwards.
|
||||
pub(crate) fn make_qualified_function_call(
|
||||
&self,
|
||||
scope: &mut Scope,
|
||||
@ -1048,6 +1050,7 @@ impl Engine {
|
||||
args_expr: impl AsRef<[Expr]>,
|
||||
def_val: Option<&Dynamic>,
|
||||
hash_script: u64,
|
||||
pos: Position,
|
||||
level: usize,
|
||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||
let args_expr = args_expr.as_ref();
|
||||
@ -1143,7 +1146,9 @@ impl Engine {
|
||||
let args = args.as_mut();
|
||||
let new_scope = &mut Default::default();
|
||||
let fn_def = f.get_fn_def().clone();
|
||||
self.call_script_fn(new_scope, mods, state, lib, &mut None, &fn_def, args, level)
|
||||
self.call_script_fn(
|
||||
new_scope, mods, state, lib, &mut None, &fn_def, args, pos, level,
|
||||
)
|
||||
}
|
||||
Some(f) if f.is_plugin_fn() => f
|
||||
.get_plugin_fn()
|
||||
@ -1177,7 +1182,7 @@ impl Engine {
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
),
|
||||
Position::NONE,
|
||||
pos,
|
||||
)
|
||||
.into(),
|
||||
}
|
||||
|
@ -164,6 +164,7 @@ impl<'e, 'a, 'm, 'pm> NativeCallContext<'e, 'a, 'm, 'pm> {
|
||||
is_method,
|
||||
is_method,
|
||||
public_only,
|
||||
Position::NONE,
|
||||
None,
|
||||
def_value,
|
||||
0,
|
||||
|
@ -142,6 +142,7 @@ fn call_fn_with_constant_arguments(
|
||||
arg_values.iter_mut().collect::<StaticVec<_>>().as_mut(),
|
||||
false,
|
||||
true,
|
||||
Position::NONE,
|
||||
None,
|
||||
)
|
||||
.ok()
|
||||
|
Loading…
Reference in New Issue
Block a user