Fix shared variable assignment.

This commit is contained in:
Stephen Chung 2022-06-26 18:09:15 +08:00
parent d9875ff81c
commit 0031678cd4
5 changed files with 28 additions and 19 deletions

View File

@ -56,12 +56,7 @@ impl Engine {
.shared_lib()
.iter_fn()
.filter(|f| f.func.is_script())
.map(|f| {
f.func
.get_script_fn_def()
.expect("script-defined function")
.clone()
})
.map(|f| f.func.get_script_fn_def().unwrap().clone())
.collect();
crate::optimizer::optimize_into_ast(

View File

@ -146,7 +146,7 @@ impl Engine {
let target_is_shared = false;
if target_is_shared {
lock_guard = target.write_lock::<Dynamic>().expect("`Dynamic`");
lock_guard = target.write_lock::<Dynamic>().unwrap();
lhs_ptr_inner = &mut *lock_guard;
} else {
lhs_ptr_inner = &mut *target;
@ -181,7 +181,20 @@ impl Engine {
}
} else {
// Normal assignment
*target.as_mut() = new_val;
#[cfg(not(feature = "no_closure"))]
if target.is_shared() {
// Handle case where target is a `Dynamic` shared value
// (returned by a variable resolver, for example)
*target.write_lock::<Dynamic>().unwrap() = new_val;
} else {
*target.as_mut() = new_val;
}
#[cfg(feature = "no_closure")]
{
*target.as_mut() = new_val;
}
}
target.propagate_changed_value(op_info.pos)
@ -251,8 +264,8 @@ impl Engine {
let var_name = lhs.get_variable_name(false).expect("`Expr::Variable`");
#[cfg(not(feature = "no_closure"))]
// Temp results from expressions are flattened so should never be shared.
// A shared value may be provided by a variable resolver, however.
// Also handle case where target is a `Dynamic` shared value
// (returned by a variable resolver, for example)
let is_temp_result = !lhs_ptr.is_ref() && !lhs_ptr.is_shared();
#[cfg(feature = "no_closure")]
let is_temp_result = !lhs_ptr.is_ref();

View File

@ -578,7 +578,7 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b
// Then check ranges
if value.is::<INT>() && !ranges.is_empty() {
let value = value.as_int().expect("`INT`");
let value = value.as_int().unwrap();
// Only one range or all ranges without conditions
if ranges.len() == 1

View File

@ -1520,7 +1520,7 @@ fn get_next_token_inner(
}
#[cfg(any(not(feature = "no_float"), feature = "decimal"))]
'.' => {
stream.get_next().expect("`.`");
stream.get_next().unwrap();
// Check if followed by digits or something that cannot start a property name
match stream.peek_next().unwrap_or('\0') {
@ -1567,7 +1567,7 @@ fn get_next_token_inner(
'+' | '-' => {
result.push(next_char);
pos.advance();
result.push(stream.get_next().expect("`+` or `-`"));
result.push(stream.get_next().unwrap());
pos.advance();
}
// Not a floating-point number

View File

@ -196,13 +196,14 @@ fn test_var_resolver() -> Result<(), Box<EvalAltResult>> {
#[cfg(not(feature = "no_closure"))]
{
assert_eq!(engine.eval_with_scope::<INT>(&mut scope, "HELLO")?, 1);
assert_eq!(engine.eval::<INT>("HELLO")?, 1);
*base.write_lock::<INT>().unwrap() = 42;
assert_eq!(engine.eval_with_scope::<INT>(&mut scope, "HELLO")?, 42);
assert_eq!(
engine.eval_with_scope::<INT>(&mut scope, "HELLO = HELLO * 2; HELLO")?,
84
);
assert_eq!(engine.eval::<INT>("HELLO")?, 42);
engine.run("HELLO = 123")?;
assert_eq!(base.as_int().unwrap(), 123);
assert_eq!(engine.eval::<INT>("HELLO = HELLO + 1; HELLO")?, 124);
assert_eq!(engine.eval::<INT>("HELLO = HELLO * 2; HELLO")?, 248);
assert_eq!(base.as_int().unwrap(), 248);
}
assert_eq!(engine.eval_with_scope::<INT>(&mut scope, "chameleon")?, 1);