Fix op-assignment overrides.
This commit is contained in:
@@ -1360,40 +1360,56 @@ impl Engine {
|
||||
let arg_types = once(lhs_ptr.type_id()).chain(once(rhs_val.type_id()));
|
||||
let hash_fn = calc_fn_hash(empty(), op, 2, arg_types);
|
||||
|
||||
if let Some(CallableFunction::Method(func)) = self
|
||||
match self
|
||||
.global_module
|
||||
.get_fn(hash_fn, false)
|
||||
.or_else(|| self.packages.get_fn(hash_fn, false))
|
||||
{
|
||||
if cfg!(not(feature = "no_closure")) && lhs_ptr.is_shared() {
|
||||
let mut lock_guard = lhs_ptr.write_lock::<Dynamic>().unwrap();
|
||||
let lhs_ptr_inner = lock_guard.deref_mut();
|
||||
// op= function registered as method
|
||||
Some(func) if func.is_method() => {
|
||||
let mut lock_guard;
|
||||
let lhs_ptr_inner;
|
||||
|
||||
if cfg!(not(feature = "no_closure")) && lhs_ptr.is_shared() {
|
||||
lock_guard = lhs_ptr.write_lock::<Dynamic>().unwrap();
|
||||
lhs_ptr_inner = lock_guard.deref_mut();
|
||||
} else {
|
||||
lhs_ptr_inner = lhs_ptr;
|
||||
}
|
||||
|
||||
let args = &mut [lhs_ptr_inner, &mut rhs_val];
|
||||
|
||||
// Overriding exact implementation
|
||||
func(self, lib, &mut [lhs_ptr_inner, &mut rhs_val])?;
|
||||
} else {
|
||||
// Overriding exact implementation
|
||||
func(self, lib, &mut [lhs_ptr, &mut rhs_val])?;
|
||||
if func.is_plugin_fn() {
|
||||
func.get_plugin_fn().call(args)?;
|
||||
} else {
|
||||
func.get_native_fn()(self, lib, args)?;
|
||||
}
|
||||
}
|
||||
} else if run_builtin_op_assignment(op, lhs_ptr, &rhs_val)?.is_none() {
|
||||
// Not built in, map to `var = var op rhs`
|
||||
let op = &op[..op.len() - 1]; // extract operator without =
|
||||
// Built-in op-assignment function
|
||||
_ if run_builtin_op_assignment(op, lhs_ptr, &rhs_val)?.is_some() => {}
|
||||
// Not built-in: expand to `var = var op rhs`
|
||||
_ => {
|
||||
let op = &op[..op.len() - 1]; // extract operator without =
|
||||
|
||||
// Clone the LHS value
|
||||
let args = &mut [&mut lhs_ptr.clone(), &mut rhs_val];
|
||||
// Clone the LHS value
|
||||
let args = &mut [&mut lhs_ptr.clone(), &mut rhs_val];
|
||||
|
||||
// Run function
|
||||
let (value, _) = self
|
||||
.exec_fn_call(
|
||||
state, lib, op, 0, args, false, false, false, None, None, level,
|
||||
)
|
||||
.map_err(|err| err.new_position(*op_pos))?;
|
||||
// Run function
|
||||
let (value, _) = self
|
||||
.exec_fn_call(
|
||||
state, lib, op, 0, args, false, false, false, None, None,
|
||||
level,
|
||||
)
|
||||
.map_err(|err| err.new_position(*op_pos))?;
|
||||
|
||||
let value = value.flatten();
|
||||
if cfg!(not(feature = "no_closure")) && lhs_ptr.is_shared() {
|
||||
*lhs_ptr.write_lock::<Dynamic>().unwrap() = value;
|
||||
} else {
|
||||
*lhs_ptr = value;
|
||||
let value = value.flatten();
|
||||
|
||||
if cfg!(not(feature = "no_closure")) && lhs_ptr.is_shared() {
|
||||
*lhs_ptr.write_lock::<Dynamic>().unwrap() = value;
|
||||
} else {
|
||||
*lhs_ptr = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Default::default())
|
||||
|
@@ -49,6 +49,7 @@ macro_rules! gen_array_functions {
|
||||
macro_rules! reg_functions {
|
||||
($mod_name:ident += $root:ident ; $($arg_type:ident),+) => { $(
|
||||
set_exported_fn!($mod_name, "push", $root::$arg_type::push);
|
||||
set_exported_fn!($mod_name, "+=", $root::$arg_type::push);
|
||||
set_exported_fn!($mod_name, "insert", $root::$arg_type::insert);
|
||||
|
||||
$mod_name.set_raw_fn("pad",
|
||||
@@ -58,8 +59,6 @@ macro_rules! reg_functions {
|
||||
}
|
||||
|
||||
def_package!(crate:BasicArrayPackage:"Basic array utilities.", lib, {
|
||||
combine_with_exported_module!(lib, "array", array_functions);
|
||||
|
||||
reg_functions!(lib += basic; INT, bool, char, ImmutableString, FnPtr, Array, Unit);
|
||||
|
||||
#[cfg(not(feature = "only_i32"))]
|
||||
@@ -77,6 +76,9 @@ def_package!(crate:BasicArrayPackage:"Basic array utilities.", lib, {
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
reg_functions!(lib += map; Map);
|
||||
|
||||
// Merge in the module at the end to override `+=` for arrays
|
||||
combine_with_exported_module!(lib, "array", array_functions);
|
||||
|
||||
// Register array iterator
|
||||
lib.set_iter(
|
||||
TypeId::of::<Array>(),
|
||||
|
Reference in New Issue
Block a user