Add fast-ops feature.
This commit is contained in:
parent
7dbc605d0b
commit
0516e8088c
1
.github/workflows/benchmark.yml
vendored
1
.github/workflows/benchmark.yml
vendored
@ -3,6 +3,7 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- fast-ops
|
||||
|
||||
jobs:
|
||||
benchmark:
|
||||
|
@ -39,9 +39,10 @@ serde_bytes = "0.11"
|
||||
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
default = ["std", "fast_ops"]
|
||||
std = ["ahash/std", "ahash/runtime-rng", "num-traits/std", "smartstring/std"]
|
||||
unchecked = [] # unchecked arithmetic
|
||||
fast_ops = [] # ignore overloaded standard operators
|
||||
sync = [] # restrict to only types that implement Send + Sync
|
||||
no_position = [] # do not track position in the parser
|
||||
no_optimize = [] # no script optimizer
|
||||
|
@ -190,6 +190,8 @@ pub struct FnCallExpr {
|
||||
pub args: StaticVec<Expr>,
|
||||
/// Does this function call capture the parent scope?
|
||||
pub capture_parent_scope: bool,
|
||||
/// Is this function call a simple symbol-based operator?
|
||||
pub is_standard_operator: bool,
|
||||
/// [Position] of the function name.
|
||||
pub pos: Position,
|
||||
}
|
||||
@ -204,6 +206,9 @@ impl fmt::Debug for FnCallExpr {
|
||||
if self.capture_parent_scope {
|
||||
ff.field("capture_parent_scope", &self.capture_parent_scope);
|
||||
}
|
||||
if self.is_standard_operator {
|
||||
ff.field("is_standard_operator", &self.is_standard_operator);
|
||||
}
|
||||
ff.field("hash", &self.hashes)
|
||||
.field("name", &self.name)
|
||||
.field("args", &self.args);
|
||||
@ -662,6 +667,7 @@ impl Expr {
|
||||
hashes: calc_fn_hash(f.fn_name(), 1).into(),
|
||||
args: once(Self::StringConstant(f.fn_name().into(), pos)).collect(),
|
||||
capture_parent_scope: false,
|
||||
is_standard_operator: false,
|
||||
pos,
|
||||
}
|
||||
.into(),
|
||||
|
@ -222,11 +222,39 @@ impl Engine {
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
namespace,
|
||||
capture_parent_scope: capture,
|
||||
is_standard_operator,
|
||||
hashes,
|
||||
args,
|
||||
..
|
||||
} = expr;
|
||||
|
||||
#[cfg(feature = "fast_ops")]
|
||||
if *is_standard_operator {
|
||||
let mut lhs = self
|
||||
.get_arg_value(scope, global, caches, lib, this_ptr, &args[0], level)?
|
||||
.0
|
||||
.flatten();
|
||||
|
||||
let mut rhs = self
|
||||
.get_arg_value(scope, global, caches, lib, this_ptr, &args[1], level)?
|
||||
.0
|
||||
.flatten();
|
||||
|
||||
let arg_values = &mut [&mut lhs, &mut rhs];
|
||||
|
||||
return if let Some(f) =
|
||||
crate::func::get_builtin_binary_op_fn(&name, arg_values[0], arg_values[1])
|
||||
{
|
||||
let context = (self, name, None, &*global, lib, pos, level).into();
|
||||
(f)(context, arg_values)
|
||||
} else {
|
||||
self.exec_fn_call(
|
||||
None, global, caches, lib, name, *hashes, arg_values, false, false, pos, level,
|
||||
)
|
||||
.map(|(v, ..)| v)
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
if !namespace.is_empty() {
|
||||
// Qualified function call
|
||||
|
@ -614,8 +614,9 @@ impl Engine {
|
||||
args.shrink_to_fit();
|
||||
|
||||
return Ok(FnCallExpr {
|
||||
name: id,
|
||||
name: state.get_interned_string(id),
|
||||
capture_parent_scope,
|
||||
is_standard_operator: false,
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
namespace,
|
||||
hashes,
|
||||
@ -687,6 +688,7 @@ impl Engine {
|
||||
return Ok(FnCallExpr {
|
||||
name: state.get_interned_string(id),
|
||||
capture_parent_scope,
|
||||
is_standard_operator: false,
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
namespace,
|
||||
hashes,
|
||||
@ -2339,6 +2341,7 @@ impl Engine {
|
||||
name: state.get_interned_string(op.as_ref()),
|
||||
hashes: FnCallHashes::from_native(hash),
|
||||
pos,
|
||||
is_standard_operator: op_token.is_standard_symbol(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
@ -169,6 +169,22 @@ fn test_arrays() -> Result<(), Box<EvalAltResult>> {
|
||||
"
|
||||
)?);
|
||||
|
||||
let value = vec![
|
||||
String::from("hello"),
|
||||
String::from("world"),
|
||||
String::from("foo"),
|
||||
String::from("bar"),
|
||||
];
|
||||
|
||||
let array: Dynamic = value.into();
|
||||
|
||||
assert_eq!(array.type_name(), "array");
|
||||
|
||||
let array = array.cast::<Array>();
|
||||
|
||||
assert_eq!(array[0].type_name(), "string");
|
||||
assert_eq!(array.len(), 4);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -49,21 +49,24 @@ fn test_optimizer_run() -> Result<(), Box<EvalAltResult>> {
|
||||
run_test(&mut engine)?;
|
||||
|
||||
// Override == operator
|
||||
engine.register_fn("==", |_x: INT, _y: INT| false);
|
||||
#[cfg(not(feature = "fast_ops"))]
|
||||
{
|
||||
engine.register_fn("==", |_x: INT, _y: INT| false);
|
||||
|
||||
engine.set_optimization_level(OptimizationLevel::Simple);
|
||||
engine.set_optimization_level(OptimizationLevel::Simple);
|
||||
|
||||
assert_eq!(
|
||||
engine.eval::<INT>("if 1 == 1 || 2 > 3 { 42 } else { 123 }")?,
|
||||
123
|
||||
);
|
||||
assert_eq!(
|
||||
engine.eval::<INT>("if 1 == 1 || 2 > 3 { 42 } else { 123 }")?,
|
||||
123
|
||||
);
|
||||
|
||||
engine.set_optimization_level(OptimizationLevel::Full);
|
||||
engine.set_optimization_level(OptimizationLevel::Full);
|
||||
|
||||
assert_eq!(
|
||||
engine.eval::<INT>("if 1 == 1 || 2 > 3 { 42 } else { 123 }")?,
|
||||
123
|
||||
);
|
||||
assert_eq!(
|
||||
engine.eval::<INT>("if 1 == 1 || 2 > 3 { 42 } else { 123 }")?,
|
||||
123
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user