Streamline ref object backup.
This commit is contained in:
parent
b76e8da5ee
commit
521c8fad27
@ -25,6 +25,7 @@ Breaking changes
|
|||||||
Enhancements
|
Enhancements
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
* Function calls are more optimized and should now run faster.
|
||||||
* `range` function now supports negative step and decreasing streams (i.e. to < from).
|
* `range` function now supports negative step and decreasing streams (i.e. to < from).
|
||||||
* More information is provided to the error variable captured by the `catch` statement in an _object map_.
|
* More information is provided to the error variable captured by the `catch` statement in an _object map_.
|
||||||
* Previously, `private` functions in an `AST` cannot be called with `call_fn` etc. This is inconvenient when trying to call a function inside a script which also serves as a loadable module exporting part (but not all) of the functions. Now, all functions (`private` or not) can be called in an `AST`. The `private` keyword is relegated to preventing a function from being exported.
|
* Previously, `private` functions in an `AST` cannot be called with `call_fn` etc. This is inconvenient when trying to call a function inside a script which also serves as a loadable module exporting part (but not all) of the functions. Now, all functions (`private` or not) can be called in an `AST`. The `private` keyword is relegated to preventing a function from being exported.
|
||||||
|
@ -75,12 +75,7 @@ impl<'a> ArgBackup<'a> {
|
|||||||
///
|
///
|
||||||
/// If `restore_first_arg` is called before the end of the scope, the shorter lifetime will not leak.
|
/// If `restore_first_arg` is called before the end of the scope, the shorter lifetime will not leak.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn change_first_arg_to_copy(&mut self, normalize: bool, args: &mut FnCallArgs<'a>) {
|
fn change_first_arg_to_copy(&mut self, args: &mut FnCallArgs<'a>) {
|
||||||
// Only do it for method calls with arguments.
|
|
||||||
if !normalize || args.is_empty() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clone the original value.
|
// Clone the original value.
|
||||||
self.value_copy = args[0].clone();
|
self.value_copy = args[0].clone();
|
||||||
|
|
||||||
@ -105,7 +100,7 @@ impl<'a> ArgBackup<'a> {
|
|||||||
/// If `change_first_arg_to_copy` has been called, this function **MUST** be called _BEFORE_ exiting
|
/// If `change_first_arg_to_copy` has been called, this function **MUST** be called _BEFORE_ exiting
|
||||||
/// the current scope. Otherwise it is undefined behavior as the shorter lifetime will leak.
|
/// the current scope. Otherwise it is undefined behavior as the shorter lifetime will leak.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn restore_first_arg(&mut self, args: &mut FnCallArgs<'a>) {
|
fn restore_first_arg(mut self, args: &mut FnCallArgs<'a>) {
|
||||||
if let Some(this_pointer) = self.orig_mut.take() {
|
if let Some(this_pointer) = self.orig_mut.take() {
|
||||||
args[0] = this_pointer;
|
args[0] = this_pointer;
|
||||||
}
|
}
|
||||||
@ -340,8 +335,11 @@ impl Engine {
|
|||||||
assert!(func.is_native());
|
assert!(func.is_native());
|
||||||
|
|
||||||
// Calling pure function but the first argument is a reference?
|
// Calling pure function but the first argument is a reference?
|
||||||
let mut backup: ArgBackup = Default::default();
|
let mut backup: Option<ArgBackup> = None;
|
||||||
backup.change_first_arg_to_copy(is_ref && func.is_pure(), args);
|
if is_ref && func.is_pure() && !args.is_empty() {
|
||||||
|
backup = Some(Default::default());
|
||||||
|
backup.as_mut().unwrap().change_first_arg_to_copy(args);
|
||||||
|
}
|
||||||
|
|
||||||
// Run external function
|
// Run external function
|
||||||
let source = src.as_ref().or_else(|| source.as_ref()).map(|s| s.as_str());
|
let source = src.as_ref().or_else(|| source.as_ref()).map(|s| s.as_str());
|
||||||
@ -353,7 +351,9 @@ impl Engine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Restore the original reference
|
// Restore the original reference
|
||||||
|
if let Some(backup) = backup {
|
||||||
backup.restore_first_arg(args);
|
backup.restore_first_arg(args);
|
||||||
|
}
|
||||||
|
|
||||||
let result = result.map_err(|err| err.fill_position(pos))?;
|
let result = result.map_err(|err| err.fill_position(pos))?;
|
||||||
|
|
||||||
@ -772,8 +772,11 @@ impl Engine {
|
|||||||
} else {
|
} else {
|
||||||
// Normal call of script function
|
// Normal call of script function
|
||||||
// The first argument is a reference?
|
// The first argument is a reference?
|
||||||
let mut backup: ArgBackup = Default::default();
|
let mut backup: Option<ArgBackup> = None;
|
||||||
backup.change_first_arg_to_copy(is_ref, args);
|
if is_ref && !args.is_empty() {
|
||||||
|
backup = Some(Default::default());
|
||||||
|
backup.as_mut().unwrap().change_first_arg_to_copy(args);
|
||||||
|
}
|
||||||
|
|
||||||
let orig_source = mem::take(&mut state.source);
|
let orig_source = mem::take(&mut state.source);
|
||||||
state.source = source;
|
state.source = source;
|
||||||
@ -787,7 +790,9 @@ impl Engine {
|
|||||||
state.source = orig_source;
|
state.source = orig_source;
|
||||||
|
|
||||||
// Restore the original reference
|
// Restore the original reference
|
||||||
|
if let Some(backup) = backup {
|
||||||
backup.restore_first_arg(args);
|
backup.restore_first_arg(args);
|
||||||
|
}
|
||||||
|
|
||||||
result?
|
result?
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user