Fixup ArgBackup.
This commit is contained in:
parent
963af0653e
commit
a704d26986
@ -37,6 +37,7 @@ struct ArgBackup<'a> {
|
|||||||
|
|
||||||
impl<'a> ArgBackup<'a> {
|
impl<'a> ArgBackup<'a> {
|
||||||
/// Create a new `ArgBackup`.
|
/// Create a new `ArgBackup`.
|
||||||
|
#[inline(always)]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
orig_mut: None,
|
orig_mut: None,
|
||||||
@ -60,8 +61,8 @@ impl<'a> ArgBackup<'a> {
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics when `args` is empty.
|
/// Panics when `args` is empty.
|
||||||
#[inline]
|
#[inline(always)]
|
||||||
fn change_first_arg_to_copy(&mut self, args: &mut FnCallArgs<'a>) {
|
pub fn change_first_arg_to_copy(&mut self, args: &mut FnCallArgs<'a>) {
|
||||||
// Clone the original value.
|
// Clone the original value.
|
||||||
self.value_copy = args[0].clone();
|
self.value_copy = args[0].clone();
|
||||||
|
|
||||||
@ -86,7 +87,7 @@ impl<'a> ArgBackup<'a> {
|
|||||||
/// If `change_first_arg_to_copy` has been called, this function **MUST** be called _BEFORE_
|
/// 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.
|
/// exiting 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>) {
|
pub fn restore_first_arg(mut self, args: &mut FnCallArgs<'a>) {
|
||||||
if let Some(p) = self.orig_mut.take() {
|
if let Some(p) = self.orig_mut.take() {
|
||||||
args[0] = p;
|
args[0] = p;
|
||||||
}
|
}
|
||||||
@ -94,7 +95,7 @@ impl<'a> ArgBackup<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for ArgBackup<'_> {
|
impl Drop for ArgBackup<'_> {
|
||||||
#[inline]
|
#[inline(always)]
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// Panic if the shorter lifetime leaks.
|
// Panic if the shorter lifetime leaks.
|
||||||
assert!(
|
assert!(
|
||||||
@ -382,15 +383,12 @@ impl Engine {
|
|||||||
let mut _result = if let Some(FnResolutionCacheEntry { func, source }) = func {
|
let mut _result = if let Some(FnResolutionCacheEntry { func, source }) = func {
|
||||||
assert!(func.is_native());
|
assert!(func.is_native());
|
||||||
|
|
||||||
|
let mut backup = ArgBackup::new();
|
||||||
|
|
||||||
// Calling pure function but the first argument is a reference?
|
// Calling pure function but the first argument is a reference?
|
||||||
let mut backup: Option<ArgBackup> = None;
|
|
||||||
if is_ref_mut && func.is_pure() && !args.is_empty() {
|
if is_ref_mut && func.is_pure() && !args.is_empty() {
|
||||||
// Clone the first argument
|
// Clone the first argument
|
||||||
backup = Some(ArgBackup::new());
|
backup.change_first_arg_to_copy(args);
|
||||||
backup
|
|
||||||
.as_mut()
|
|
||||||
.expect("`Some`")
|
|
||||||
.change_first_arg_to_copy(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let source = match (source.as_str(), parent_source.as_str()) {
|
let source = match (source.as_str(), parent_source.as_str()) {
|
||||||
@ -420,9 +418,7 @@ impl Engine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Restore the original reference
|
// Restore the original reference
|
||||||
if let Some(bk) = backup {
|
backup.restore_first_arg(args);
|
||||||
bk.restore_first_arg(args)
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
result
|
||||||
} else {
|
} else {
|
||||||
@ -711,7 +707,7 @@ impl Engine {
|
|||||||
// Method call of script function - map first argument to `this`
|
// Method call of script function - map first argument to `this`
|
||||||
let (first_arg, rest_args) = args.split_first_mut().unwrap();
|
let (first_arg, rest_args) = args.split_first_mut().unwrap();
|
||||||
|
|
||||||
let result = self.call_script_fn(
|
self.call_script_fn(
|
||||||
scope,
|
scope,
|
||||||
global,
|
global,
|
||||||
state,
|
state,
|
||||||
@ -722,19 +718,14 @@ impl Engine {
|
|||||||
true,
|
true,
|
||||||
pos,
|
pos,
|
||||||
level,
|
level,
|
||||||
);
|
)
|
||||||
|
|
||||||
result?
|
|
||||||
} else {
|
} else {
|
||||||
// Normal call of script function
|
// Normal call of script function
|
||||||
|
let mut backup = ArgBackup::new();
|
||||||
|
|
||||||
// The first argument is a reference?
|
// The first argument is a reference?
|
||||||
let mut backup: Option<ArgBackup> = None;
|
|
||||||
if is_ref_mut && !args.is_empty() {
|
if is_ref_mut && !args.is_empty() {
|
||||||
backup = Some(ArgBackup::new());
|
backup.change_first_arg_to_copy(args);
|
||||||
backup
|
|
||||||
.as_mut()
|
|
||||||
.expect("`Some`")
|
|
||||||
.change_first_arg_to_copy(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = self.call_script_fn(
|
let result = self.call_script_fn(
|
||||||
@ -742,17 +733,15 @@ impl Engine {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Restore the original reference
|
// Restore the original reference
|
||||||
if let Some(bk) = backup {
|
backup.restore_first_arg(args);
|
||||||
bk.restore_first_arg(args)
|
|
||||||
}
|
|
||||||
|
|
||||||
result?
|
result
|
||||||
};
|
};
|
||||||
|
|
||||||
// Restore the original source
|
// Restore the original source
|
||||||
mem::swap(&mut global.source, &mut source);
|
mem::swap(&mut global.source, &mut source);
|
||||||
|
|
||||||
return Ok((result, false));
|
return Ok((result?, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Native function call
|
// Native function call
|
||||||
|
Loading…
Reference in New Issue
Block a user