Fix bang function calls under no_closure.
This commit is contained in:
parent
5685ca8411
commit
774fd7514e
@ -8,6 +8,7 @@ Bug fixes
|
|||||||
---------
|
---------
|
||||||
|
|
||||||
* Printing of integral floating-point numbers is fixed (used to only prints `0.0`).
|
* Printing of integral floating-point numbers is fixed (used to only prints `0.0`).
|
||||||
|
* `func!()` calls now work properly under `no_closure`.
|
||||||
|
|
||||||
|
|
||||||
Version 1.1.2
|
Version 1.1.2
|
||||||
|
@ -108,7 +108,6 @@ pub fn ensure_no_data_race(
|
|||||||
args: &FnCallArgs,
|
args: &FnCallArgs,
|
||||||
is_method_call: bool,
|
is_method_call: bool,
|
||||||
) -> Result<(), Box<EvalAltResult>> {
|
) -> Result<(), Box<EvalAltResult>> {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
|
||||||
if let Some((n, _)) = args
|
if let Some((n, _)) = args
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
@ -245,18 +244,16 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let (first, second) = args
|
let (first_arg, rest_args) =
|
||||||
.split_first()
|
args.split_first().expect("has two arguments");
|
||||||
.expect("op-assignment has two arguments");
|
|
||||||
|
|
||||||
get_builtin_op_assignment_fn(fn_name, *first, second[0]).map(
|
get_builtin_op_assignment_fn(fn_name, *first_arg, rest_args[0])
|
||||||
|f| FnResolutionCacheEntry {
|
.map(|f| FnResolutionCacheEntry {
|
||||||
func: CallableFunction::from_method(
|
func: CallableFunction::from_method(
|
||||||
Box::new(f) as Box<FnAny>
|
Box::new(f) as Box<FnAny>
|
||||||
),
|
),
|
||||||
source: None,
|
source: None,
|
||||||
},
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
.map(Box::new)
|
.map(Box::new)
|
||||||
});
|
});
|
||||||
@ -645,7 +642,7 @@ impl Engine {
|
|||||||
is_ref_mut: bool,
|
is_ref_mut: bool,
|
||||||
is_method_call: bool,
|
is_method_call: bool,
|
||||||
pos: Position,
|
pos: Position,
|
||||||
_capture_scope: Option<Scope>,
|
captured_scope: Option<Scope>,
|
||||||
_level: usize,
|
_level: usize,
|
||||||
) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
||||||
fn no_method_err(name: &str, pos: Position) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
fn no_method_err(name: &str, pos: Position) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
||||||
@ -727,27 +724,11 @@ impl Engine {
|
|||||||
return Ok((Dynamic::UNIT, false));
|
return Ok((Dynamic::UNIT, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
let scope = &mut Scope::new();
|
let mut scope = captured_scope.unwrap_or_else(|| Scope::new());
|
||||||
|
|
||||||
// Move captured variables into scope
|
|
||||||
#[cfg(not(feature = "no_closure"))]
|
|
||||||
if !func.externals.is_empty() {
|
|
||||||
if let Some(captured) = _capture_scope {
|
|
||||||
captured
|
|
||||||
.into_iter()
|
|
||||||
.filter(|(name, _, _)| func.externals.contains(name.as_ref()))
|
|
||||||
.for_each(|(name, value, _)| {
|
|
||||||
// Consume the scope values.
|
|
||||||
scope.push_dynamic(name, value);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let result = if _is_method_call {
|
let result = if _is_method_call {
|
||||||
// Method call of script function - map first argument to `this`
|
// Method call of script function - map first argument to `this`
|
||||||
let (first, rest) = args
|
let (first_arg, rest_args) = args.split_first_mut().expect("has arguments");
|
||||||
.split_first_mut()
|
|
||||||
.expect("method call has first parameter");
|
|
||||||
|
|
||||||
let orig_source = state.source.take();
|
let orig_source = state.source.take();
|
||||||
state.source = source;
|
state.source = source;
|
||||||
@ -755,13 +736,13 @@ impl Engine {
|
|||||||
let level = _level + 1;
|
let level = _level + 1;
|
||||||
|
|
||||||
let result = self.call_script_fn(
|
let result = self.call_script_fn(
|
||||||
scope,
|
&mut scope,
|
||||||
mods,
|
mods,
|
||||||
state,
|
state,
|
||||||
lib,
|
lib,
|
||||||
&mut Some(*first),
|
&mut Some(*first_arg),
|
||||||
func,
|
func,
|
||||||
rest,
|
rest_args,
|
||||||
pos,
|
pos,
|
||||||
level,
|
level,
|
||||||
);
|
);
|
||||||
@ -787,8 +768,9 @@ impl Engine {
|
|||||||
|
|
||||||
let level = _level + 1;
|
let level = _level + 1;
|
||||||
|
|
||||||
let result =
|
let result = self.call_script_fn(
|
||||||
self.call_script_fn(scope, mods, state, lib, &mut None, func, args, pos, level);
|
&mut scope, mods, state, lib, &mut None, func, args, pos, level,
|
||||||
|
);
|
||||||
|
|
||||||
// Restore the original source
|
// Restore the original source
|
||||||
state.source = orig_source;
|
state.source = orig_source;
|
||||||
@ -1263,15 +1245,17 @@ impl Engine {
|
|||||||
// avoid cloning the value
|
// avoid cloning the value
|
||||||
if curry.is_empty() && !args_expr.is_empty() && args_expr[0].is_variable_access(false) {
|
if curry.is_empty() && !args_expr.is_empty() && args_expr[0].is_variable_access(false) {
|
||||||
// func(x, ...) -> x.func(...)
|
// func(x, ...) -> x.func(...)
|
||||||
for index in 1..args_expr.len() {
|
let (first_expr, rest_expr) = args_expr.split_first().expect("has arguments");
|
||||||
|
|
||||||
|
for index in 0..rest_expr.len() {
|
||||||
let (value, _) = self.get_arg_value(
|
let (value, _) = self.get_arg_value(
|
||||||
scope, mods, state, lib, this_ptr, level, args_expr, constants, index,
|
scope, mods, state, lib, this_ptr, level, rest_expr, constants, index,
|
||||||
)?;
|
)?;
|
||||||
arg_values.push(value.flatten());
|
arg_values.push(value.flatten());
|
||||||
}
|
}
|
||||||
|
|
||||||
let (mut target, _pos) =
|
let (mut target, _pos) =
|
||||||
self.search_namespace(scope, mods, state, lib, this_ptr, &args_expr[0])?;
|
self.search_namespace(scope, mods, state, lib, this_ptr, first_expr)?;
|
||||||
|
|
||||||
if target.as_ref().is_read_only() {
|
if target.as_ref().is_read_only() {
|
||||||
target = target.into_owned();
|
target = target.into_owned();
|
||||||
@ -1370,9 +1354,7 @@ impl Engine {
|
|||||||
args.extend(arg_values.iter_mut());
|
args.extend(arg_values.iter_mut());
|
||||||
} else {
|
} else {
|
||||||
// Turn it into a method call only if the object is not shared and not a simple value
|
// Turn it into a method call only if the object is not shared and not a simple value
|
||||||
let (first, rest) = arg_values
|
let (first, rest) = arg_values.split_first_mut().expect("has arguments");
|
||||||
.split_first_mut()
|
|
||||||
.expect("arguments list is not empty");
|
|
||||||
first_arg_value = Some(first);
|
first_arg_value = Some(first);
|
||||||
let obj_ref = target.take_ref().expect("`target` is reference");
|
let obj_ref = target.take_ref().expect("`target` is reference");
|
||||||
args.push(obj_ref);
|
args.push(obj_ref);
|
||||||
|
Loading…
Reference in New Issue
Block a user