Always call native for op-assignment operators.

This commit is contained in:
Stephen Chung 2021-02-23 20:32:50 +08:00
parent 123e9d6901
commit 6f876e85cc
4 changed files with 54 additions and 43 deletions

View File

@ -1156,21 +1156,33 @@ impl Engine {
}
let args = &mut [lhs_ptr_inner, &mut new_val];
let hash_fn = calc_native_fn_hash(
empty(),
op,
args.iter().map(|a| a.type_id()),
)
.unwrap();
match self.exec_fn_call(
mods, state, lib, op, None, args, true, false, false,
op_pos, None, None, level,
match self.call_native_fn(
mods, state, lib, op, hash_fn, args, true, false, op_pos,
None,
) {
Ok(_) => (),
Err(err) if matches!(err.as_ref(), EvalAltResult::ErrorFunctionNotFound(f, _) if f.starts_with(op)) =>
{
// Expand to `var = var op rhs`
let op = &op[..op.len() - 1]; // extract operator without =
let hash_fn = calc_native_fn_hash(
empty(),
op,
args.iter().map(|a| a.type_id()),
)
.unwrap();
// Run function
let (value, _) = self.exec_fn_call(
mods, state, lib, op, None, args, true, false,
false, op_pos, None, None, level,
let (value, _) = self.call_native_fn(
mods, state, lib, op, hash_fn, args, true, false,
op_pos, None,
)?;
*args[0] = value.flatten();
@ -1277,21 +1289,29 @@ impl Engine {
}
let args = &mut [lhs_ptr_inner, &mut new_val];
let hash_fn =
calc_native_fn_hash(empty(), op, args.iter().map(|a| a.type_id()))
.unwrap();
match self.exec_fn_call(
mods, state, lib, op, None, args, true, false, false, op_pos, None,
None, level,
match self.call_native_fn(
mods, state, lib, op, hash_fn, args, true, false, op_pos, None,
) {
Ok(_) => (),
Err(err) if matches!(err.as_ref(), EvalAltResult::ErrorFunctionNotFound(f, _) if f.starts_with(op)) =>
{
// Expand to `var = var op rhs`
let op = &op[..op.len() - 1]; // extract operator without =
let hash_fn = calc_native_fn_hash(
empty(),
op,
args.iter().map(|a| a.type_id()),
)
.unwrap();
// Run function
let (value, _) = self.exec_fn_call(
mods, state, lib, op, None, args, true, false, false,
op_pos, None, None, level,
let (value, _) = self.call_native_fn(
mods, state, lib, op, hash_fn, args, true, false, op_pos,
None,
)?;
*args[0] = value.flatten();
@ -1757,12 +1777,9 @@ impl Engine {
for value in rhs_value.iter_mut() {
let args = &mut [&mut lhs_value.clone(), value];
// Qualifiers (none) + function name + number of arguments + argument `TypeId`'s.
let hash_fn =
calc_native_fn_hash(empty(), OP_EQUALS, args.iter().map(|a| a.type_id()))
.unwrap();
let pos = rhs.position();
if self
@ -2090,10 +2107,11 @@ impl Engine {
}
let args = &mut [lhs_ptr_inner, &mut rhs_val];
let hash_fn =
calc_native_fn_hash(empty(), op, args.iter().map(|a| a.type_id())).unwrap();
match self.exec_fn_call(
mods, state, lib, op, None, args, true, false, false, *op_pos, None, None,
level,
match self.call_native_fn(
mods, state, lib, op, hash_fn, args, true, false, *op_pos, None,
) {
Ok(_) => (),
Err(err) if matches!(err.as_ref(), EvalAltResult::ErrorFunctionNotFound(f, _) if f.starts_with(op.as_ref())) =>
@ -2102,9 +2120,8 @@ impl Engine {
let op = &op[..op.len() - 1]; // extract operator without =
// Run function
let (value, _) = self.exec_fn_call(
mods, state, lib, op, None, args, false, false, false, *op_pos,
None, None, level,
let (value, _) = self.call_native_fn(
mods, state, lib, op, hash_fn, args, false, false, *op_pos, None,
)?;
*args[0] = value.flatten();

View File

@ -214,17 +214,20 @@ impl Engine {
// Try all permutations with `Dynamic` wildcards
_ => {
// Qualifiers (none) + function name + number of arguments + argument `TypeId`'s.
let arg_types = args.iter().enumerate().map(|(i, a)| {
let mask = 1usize << (num_args - i - 1);
if bitmask & mask != 0 {
// Replace with `Dynamic`
TypeId::of::<Dynamic>()
} else {
a.type_id()
}
});
hash = calc_native_fn_hash(empty(), fn_name, arg_types).unwrap();
hash = calc_native_fn_hash(
empty(),
fn_name,
args.iter().enumerate().map(|(i, a)| {
let mask = 1usize << (num_args - i - 1);
if bitmask & mask != 0 {
// Replace with `Dynamic`
TypeId::of::<Dynamic>()
} else {
a.type_id()
}
}),
)
.unwrap();
// Stop when all permutations are exhausted
if hash == hash_fn {
@ -613,9 +616,8 @@ impl Engine {
ensure_no_data_race(fn_name, args, is_ref)?;
}
// Qualifiers (none) + function name + number of arguments + argument `TypeId`'s.
let arg_types = args.iter().map(|a| a.type_id());
let hash_fn = calc_native_fn_hash(empty(), fn_name, arg_types).unwrap();
let hash_fn =
calc_native_fn_hash(empty(), fn_name, args.iter().map(|a| a.type_id())).unwrap();
match fn_name {
// type_of

View File

@ -1855,7 +1855,6 @@ impl Module {
// Index all variables
module.variables.iter().for_each(|(var_name, value)| {
// Qualifiers + variable name
let hash_var =
crate::calc_script_fn_hash(qualifiers.iter().map(|&v| v), var_name, 0).unwrap();
variables.insert(hash_var, value.clone());
@ -1888,7 +1887,6 @@ impl Module {
functions.insert(hash, func.clone());
}
// Qualifiers + function name + number of arguments.
let hash_qualified_script =
crate::calc_script_fn_hash(qualifiers.iter().cloned(), name, *params)
.unwrap();

View File

@ -347,7 +347,6 @@ fn parse_fn_call(
let qualifiers = modules.iter().map(|m| m.name.as_str());
calc_script_fn_hash(qualifiers, &id, 0)
} else {
// Qualifiers (none) + function name + no parameters.
calc_script_fn_hash(empty(), &id, 0)
};
@ -399,7 +398,6 @@ fn parse_fn_call(
let qualifiers = modules.iter().map(|m| m.name.as_str());
calc_script_fn_hash(qualifiers, &id, args.len())
} else {
// Qualifiers (none) + function name + number of arguments.
calc_script_fn_hash(empty(), &id, args.len())
};
@ -1016,7 +1014,6 @@ fn parse_primary(
});
lib.insert(
// Qualifiers (none) + function name + number of arguments.
calc_script_fn_hash(empty(), &func.name, func.params.len()).unwrap(),
func,
);
@ -1246,7 +1243,6 @@ fn parse_primary(
}
.map(|x| match x.as_mut() {
(_, Some((ref mut hash, ref mut namespace)), Ident { name, .. }) => {
// Qualifiers + variable name
*hash =
calc_script_fn_hash(namespace.iter().map(|v| v.name.as_str()), name, 0).unwrap();
@ -2621,8 +2617,6 @@ fn parse_stmt(
};
let func = parse_fn(input, &mut new_state, lib, access, settings, _comments)?;
// Qualifiers (none) + function name + number of arguments.
let hash = calc_script_fn_hash(empty(), &func.name, func.params.len()).unwrap();
if lib.contains_key(&hash) {