Make Engine reentrant to prepare for parallel execution.

This commit is contained in:
Stephen Chung
2020-04-07 13:23:06 +08:00
parent e204ae1a2c
commit e795a50ae2
44 changed files with 415 additions and 404 deletions

View File

@@ -3,7 +3,7 @@ use rhai::{Array, Engine, EvalAltResult, RegisterFn, INT};
#[test]
fn test_arrays() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = [1, 2, 3]; x[1]")?, 2);
assert_eq!(engine.eval::<INT>("let y = [1, 2, 3]; y[1] = 5; y[1]")?, 5);

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult, INT};
#[test]
fn test_binary_ops() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("10 % 4")?, 2);
assert_eq!(engine.eval::<INT>("10 << 4")?, 160);

View File

@@ -2,14 +2,14 @@ use rhai::{Engine, EvalAltResult, INT};
#[test]
fn test_left_shift() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("4 << 2")?, 16);
Ok(())
}
#[test]
fn test_right_shift() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("9 >> 1")?, 4);
Ok(())
}

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult};
#[test]
fn test_bool_op1() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<bool>("true && (false || true)")?, true);
assert_eq!(engine.eval::<bool>("true & (false | true)")?, true);
@@ -12,7 +12,7 @@ fn test_bool_op1() -> Result<(), EvalAltResult> {
#[test]
fn test_bool_op2() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<bool>("false && (false || true)")?, false);
assert_eq!(engine.eval::<bool>("false & (false | true)")?, false);
@@ -22,7 +22,7 @@ fn test_bool_op2() -> Result<(), EvalAltResult> {
#[test]
fn test_bool_op3() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert!(engine.eval::<bool>("true && (false || 123)").is_err());
assert_eq!(engine.eval::<bool>("true && (true || 123)")?, true);
@@ -34,7 +34,7 @@ fn test_bool_op3() -> Result<(), EvalAltResult> {
#[test]
fn test_bool_op_short_circuit() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(
engine.eval::<bool>(
@@ -63,7 +63,7 @@ fn test_bool_op_short_circuit() -> Result<(), EvalAltResult> {
#[test]
fn test_bool_op_no_short_circuit1() {
let mut engine = Engine::new();
let engine = Engine::new();
assert!(engine
.eval::<bool>(
@@ -78,7 +78,7 @@ fn test_bool_op_no_short_circuit1() {
#[test]
fn test_bool_op_no_short_circuit2() {
let mut engine = Engine::new();
let engine = Engine::new();
assert!(engine
.eval::<bool>(

View File

@@ -20,7 +20,7 @@ fn test_fn() -> Result<(), EvalAltResult> {
#[test]
fn test_call_fn() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
let mut scope = Scope::new();
scope.push("foo", 42 as INT);

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult};
#[test]
fn test_chars() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<char>("'y'")?, 'y');
assert_eq!(engine.eval::<char>("'\\u2764'")?, '❤');

View File

@@ -2,13 +2,13 @@ use rhai::{Engine, INT};
#[test]
fn test_comments() {
let mut engine = Engine::new();
let engine = Engine::new();
assert!(engine
.eval::<INT>("let x = 5; x // I am a single line comment, yay!")
.is_ok());
assert!(engine
.eval::<INT>("let /* I am a multiline comment, yay! */ x = 5; x")
.eval::<INT>("let /* I am a multi-line comment, yay! */ x = 5; x")
.is_ok());
}

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult, INT};
#[test]
fn test_or_equals() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = 16; x |= 74; x")?, 90);
assert_eq!(engine.eval::<bool>("let x = true; x |= false; x")?, true);
@@ -13,7 +13,7 @@ fn test_or_equals() -> Result<(), EvalAltResult> {
#[test]
fn test_and_equals() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = 16; x &= 31; x")?, 16);
assert_eq!(engine.eval::<bool>("let x = true; x &= false; x")?, false);
@@ -25,42 +25,42 @@ fn test_and_equals() -> Result<(), EvalAltResult> {
#[test]
fn test_xor_equals() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = 90; x ^= 12; x")?, 86);
Ok(())
}
#[test]
fn test_multiply_equals() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = 2; x *= 3; x")?, 6);
Ok(())
}
#[test]
fn test_divide_equals() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = 6; x /= 2; x")?, 3);
Ok(())
}
#[test]
fn test_left_shift_equals() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = 9; x >>=1; x")?, 4);
Ok(())
}
#[test]
fn test_right_shift_equals() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = 4; x<<= 2; x")?, 16);
Ok(())
}
#[test]
fn test_modulo_equals() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = 10; x %= 4; x")?, 2);
Ok(())
}

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult, INT};
#[test]
fn test_constant() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("const x = 123; x")?, 123);

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult, INT};
#[test]
fn test_decrement() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = 10; x -= 7; x")?, 3);

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult, Scope, INT};
#[test]
fn test_eval() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(
engine.eval::<INT>(
@@ -19,7 +19,7 @@ fn test_eval() -> Result<(), EvalAltResult> {
#[test]
#[cfg(not(feature = "no_function"))]
fn test_eval_function() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
let mut scope = Scope::new();
assert_eq!(
@@ -62,7 +62,7 @@ fn test_eval_function() -> Result<(), EvalAltResult> {
#[test]
#[cfg(not(feature = "no_function"))]
fn test_eval_override() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(
engine.eval::<String>(

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult, Scope, INT};
#[test]
fn test_expressions() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
let mut scope = Scope::new();
scope.push("x", 10 as INT);

View File

@@ -5,7 +5,7 @@ const EPSILON: FLOAT = 0.000_000_000_1;
#[test]
fn test_float() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(
engine.eval::<bool>("let x = 0.0; let y = 1.0; x < y")?,

View File

@@ -3,7 +3,7 @@ use rhai::{Engine, EvalAltResult, INT};
#[cfg(not(feature = "no_index"))]
#[test]
fn test_for_array() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
let script = r"
let sum1 = 0;
@@ -33,7 +33,7 @@ fn test_for_array() -> Result<(), EvalAltResult> {
#[cfg(not(feature = "no_object"))]
#[test]
fn test_for_object() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
let script = r#"
let sum = 0;

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult, INT};
#[test]
fn test_if() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("if true { 55 }")?, 55);
assert_eq!(engine.eval::<INT>("if false { 55 } else { 44 }")?, 44);
@@ -30,7 +30,7 @@ fn test_if() -> Result<(), EvalAltResult> {
#[test]
fn test_if_expr() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(
engine.eval::<INT>(

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult, INT};
#[test]
fn test_increment() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = 1; x += 2; x")?, 3);
assert_eq!(

View File

@@ -4,9 +4,12 @@ use rhai::{Engine, EvalAltResult, INT};
#[test]
fn test_internal_fn() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("fn addme(a, b) { a+b } addme(3, 4)")?, 7);
assert_eq!(
engine.eval::<INT>("fn add_me(a, b) { a+b } add_me(3, 4)")?,
7
);
assert_eq!(engine.eval::<INT>("fn bob() { return 4; 5 } bob()")?, 4);
Ok(())
@@ -14,15 +17,15 @@ fn test_internal_fn() -> Result<(), EvalAltResult> {
#[test]
fn test_big_internal_fn() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(
engine.eval::<INT>(
r"
fn mathme(a, b, c, d, e, f) {
fn math_me(a, b, c, d, e, f) {
a - b * c + d * e - f
}
mathme(100, 5, 2, 9, 6, 32)
math_me(100, 5, 2, 9, 6, 32)
",
)?,
112
@@ -33,7 +36,7 @@ fn test_big_internal_fn() -> Result<(), EvalAltResult> {
#[test]
fn test_internal_fn_overloading() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(
engine.eval::<INT>(

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult, INT};
#[test]
fn test_loop() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(
engine.eval::<INT>(

View File

@@ -4,7 +4,7 @@ use rhai::{AnyExt, Engine, EvalAltResult, Map, INT};
#[test]
fn test_map_indexing() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
#[cfg(not(feature = "no_index"))]
{
@@ -75,7 +75,7 @@ fn test_map_indexing() -> Result<(), EvalAltResult> {
#[test]
fn test_map_assign() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
let x = engine.eval::<Map>(r#"let x = #{a: 1, b: true, "c$": "hello"}; x"#)?;
let a = x.get("a").cloned().expect("should have property a");
@@ -91,7 +91,7 @@ fn test_map_assign() -> Result<(), EvalAltResult> {
#[test]
fn test_map_return() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
let x = engine.eval::<Map>(r#"#{a: 1, b: true, "c$": "hello"}"#)?;
let a = x.get("a").cloned().expect("should have property a");
@@ -107,7 +107,7 @@ fn test_map_return() -> Result<(), EvalAltResult> {
#[test]
fn test_map_for() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(
engine.eval::<INT>(

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult, INT};
#[test]
fn test_math() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("1 + 2")?, 3);
assert_eq!(engine.eval::<INT>("1 - 2")?, -1);

View File

@@ -3,7 +3,7 @@ use rhai::{Engine, EvalAltResult, RegisterFn, INT};
#[test]
#[cfg(not(feature = "no_stdlib"))]
fn test_mismatched_op() {
let mut engine = Engine::new();
let engine = Engine::new();
assert!(
matches!(engine.eval::<INT>(r#"60 + "hello""#).expect_err("expects error"),

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult};
#[test]
fn test_not() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(
engine.eval::<bool>("let not_true = !true; not_true")?,

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult, INT};
#[test]
fn test_number_literal() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("65")?, 65);
@@ -11,7 +11,7 @@ fn test_number_literal() -> Result<(), EvalAltResult> {
#[test]
fn test_hex_literal() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = 0xf; x")?, 15);
assert_eq!(engine.eval::<INT>("let x = 0xff; x")?, 255);
@@ -21,7 +21,7 @@ fn test_hex_literal() -> Result<(), EvalAltResult> {
#[test]
fn test_octal_literal() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = 0o77; x")?, 63);
assert_eq!(engine.eval::<INT>("let x = 0o1234; x")?, 668);
@@ -31,7 +31,7 @@ fn test_octal_literal() -> Result<(), EvalAltResult> {
#[test]
fn test_binary_literal() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = 0b1111; x")?, 15);
assert_eq!(

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult, INT};
#[test]
fn test_ops() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("60 + 5")?, 65);
assert_eq!(engine.eval::<INT>("(1 + 2) * (6 - 4) / 2")?, 3);
@@ -11,8 +11,8 @@ fn test_ops() -> Result<(), EvalAltResult> {
}
#[test]
fn test_op_prec() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
fn test_op_precedence() -> Result<(), EvalAltResult> {
let engine = Engine::new();
assert_eq!(
engine.eval::<INT>("let x = 0; if x == 10 || true { x = 1} x")?,

View File

@@ -8,7 +8,7 @@ const EPSILON: FLOAT = 0.000_000_000_1;
#[test]
fn test_power_of() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("2 ~ 3")?, 8);
assert_eq!(engine.eval::<INT>("(-2 ~ 3)")?, -8);
@@ -29,7 +29,7 @@ fn test_power_of() -> Result<(), EvalAltResult> {
#[test]
fn test_power_of_equals() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = 2; x ~= 3; x")?, 8);
assert_eq!(engine.eval::<INT>("let x = -2; x ~= 3; x")?, -8);

View File

@@ -1,5 +1,3 @@
#![cfg(not(feature = "no_object"))]
///! This test simulates an external command object that is driven by a script.
use rhai::{Engine, EvalAltResult, RegisterFn, Scope, INT};
use std::sync::{Arc, Mutex};
@@ -40,8 +38,9 @@ impl CommandWrapper {
}
}
#[cfg(not(feature = "no_object"))]
#[test]
fn test_side_effects() -> Result<(), EvalAltResult> {
fn test_side_effects_command() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let mut scope = Scope::new();
@@ -79,3 +78,22 @@ fn test_side_effects() -> Result<(), EvalAltResult> {
Ok(())
}
#[test]
fn test_side_effects_print() -> Result<(), EvalAltResult> {
use std::sync::RwLock;
let result = RwLock::new(String::from(""));
{
let mut engine = Engine::new();
// Override action of 'print' function
engine.on_print(|s| result.write().unwrap().push_str(s));
engine.consume("print(40 + 2);")?;
}
assert_eq!(*result.read().unwrap(), "42");
Ok(())
}

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult};
#[test]
fn test_string() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(
engine.eval::<String>(r#""Test string: \u2764""#)?,

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult};
#[test]
fn test_throw() {
let mut engine = Engine::new();
let engine = Engine::new();
assert!(matches!(
engine.eval::<()>(r#"if true { throw "hello" }"#).expect_err("expects error"),

View File

@@ -4,7 +4,7 @@ use rhai::{Engine, EvalAltResult, INT};
// TODO also add test case for unary after compound
// Hah, turns out unary + has a good use after all!
fn test_unary_after_binary() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("10 % +4")?, 2);
assert_eq!(engine.eval::<INT>("10 << +4")?, 160);

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult, INT};
#[test]
fn test_unary_minus() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<INT>("let x = -5; x")?, -5);

View File

@@ -2,21 +2,21 @@ use rhai::{Engine, EvalAltResult};
#[test]
fn test_unit() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
engine.eval::<()>("let x = (); x")?;
Ok(())
}
#[test]
fn test_unit_eq() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(engine.eval::<bool>("let x = (); let y = (); x == y")?, true);
Ok(())
}
#[test]
fn test_unit_with_spaces() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
engine.eval::<()>("let x = ( ); x")?;
Ok(())
}

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult, Scope, INT};
#[test]
fn test_var_scope() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
let mut scope = Scope::new();
engine.eval_with_scope::<()>(&mut scope, "let x = 4 + 5")?;
@@ -21,7 +21,7 @@ fn test_var_scope() -> Result<(), EvalAltResult> {
#[test]
fn test_scope_eval() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
// First create the state
let mut scope = Scope::new();

View File

@@ -2,7 +2,7 @@ use rhai::{Engine, EvalAltResult, INT};
#[test]
fn test_while() -> Result<(), EvalAltResult> {
let mut engine = Engine::new();
let engine = Engine::new();
assert_eq!(
engine.eval::<INT>(