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:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
|
- fast-ops
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
benchmark:
|
benchmark:
|
||||||
|
@ -39,9 +39,10 @@ serde_bytes = "0.11"
|
|||||||
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
|
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std"]
|
default = ["std", "fast_ops"]
|
||||||
std = ["ahash/std", "ahash/runtime-rng", "num-traits/std", "smartstring/std"]
|
std = ["ahash/std", "ahash/runtime-rng", "num-traits/std", "smartstring/std"]
|
||||||
unchecked = [] # unchecked arithmetic
|
unchecked = [] # unchecked arithmetic
|
||||||
|
fast_ops = [] # ignore overloaded standard operators
|
||||||
sync = [] # restrict to only types that implement Send + Sync
|
sync = [] # restrict to only types that implement Send + Sync
|
||||||
no_position = [] # do not track position in the parser
|
no_position = [] # do not track position in the parser
|
||||||
no_optimize = [] # no script optimizer
|
no_optimize = [] # no script optimizer
|
||||||
|
@ -190,6 +190,8 @@ pub struct FnCallExpr {
|
|||||||
pub args: StaticVec<Expr>,
|
pub args: StaticVec<Expr>,
|
||||||
/// Does this function call capture the parent scope?
|
/// Does this function call capture the parent scope?
|
||||||
pub capture_parent_scope: bool,
|
pub capture_parent_scope: bool,
|
||||||
|
/// Is this function call a simple symbol-based operator?
|
||||||
|
pub is_standard_operator: bool,
|
||||||
/// [Position] of the function name.
|
/// [Position] of the function name.
|
||||||
pub pos: Position,
|
pub pos: Position,
|
||||||
}
|
}
|
||||||
@ -204,6 +206,9 @@ impl fmt::Debug for FnCallExpr {
|
|||||||
if self.capture_parent_scope {
|
if self.capture_parent_scope {
|
||||||
ff.field("capture_parent_scope", &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)
|
ff.field("hash", &self.hashes)
|
||||||
.field("name", &self.name)
|
.field("name", &self.name)
|
||||||
.field("args", &self.args);
|
.field("args", &self.args);
|
||||||
@ -662,6 +667,7 @@ impl Expr {
|
|||||||
hashes: calc_fn_hash(f.fn_name(), 1).into(),
|
hashes: calc_fn_hash(f.fn_name(), 1).into(),
|
||||||
args: once(Self::StringConstant(f.fn_name().into(), pos)).collect(),
|
args: once(Self::StringConstant(f.fn_name().into(), pos)).collect(),
|
||||||
capture_parent_scope: false,
|
capture_parent_scope: false,
|
||||||
|
is_standard_operator: false,
|
||||||
pos,
|
pos,
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -222,11 +222,39 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
namespace,
|
namespace,
|
||||||
capture_parent_scope: capture,
|
capture_parent_scope: capture,
|
||||||
|
is_standard_operator,
|
||||||
hashes,
|
hashes,
|
||||||
args,
|
args,
|
||||||
..
|
..
|
||||||
} = expr;
|
} = 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"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
if !namespace.is_empty() {
|
if !namespace.is_empty() {
|
||||||
// Qualified function call
|
// Qualified function call
|
||||||
|
@ -614,8 +614,9 @@ impl Engine {
|
|||||||
args.shrink_to_fit();
|
args.shrink_to_fit();
|
||||||
|
|
||||||
return Ok(FnCallExpr {
|
return Ok(FnCallExpr {
|
||||||
name: id,
|
name: state.get_interned_string(id),
|
||||||
capture_parent_scope,
|
capture_parent_scope,
|
||||||
|
is_standard_operator: false,
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
namespace,
|
namespace,
|
||||||
hashes,
|
hashes,
|
||||||
@ -687,6 +688,7 @@ impl Engine {
|
|||||||
return Ok(FnCallExpr {
|
return Ok(FnCallExpr {
|
||||||
name: state.get_interned_string(id),
|
name: state.get_interned_string(id),
|
||||||
capture_parent_scope,
|
capture_parent_scope,
|
||||||
|
is_standard_operator: false,
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
namespace,
|
namespace,
|
||||||
hashes,
|
hashes,
|
||||||
@ -2339,6 +2341,7 @@ impl Engine {
|
|||||||
name: state.get_interned_string(op.as_ref()),
|
name: state.get_interned_string(op.as_ref()),
|
||||||
hashes: FnCallHashes::from_native(hash),
|
hashes: FnCallHashes::from_native(hash),
|
||||||
pos,
|
pos,
|
||||||
|
is_standard_operator: op_token.is_standard_symbol(),
|
||||||
..Default::default()
|
..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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,8 @@ fn test_optimizer_run() -> Result<(), Box<EvalAltResult>> {
|
|||||||
run_test(&mut engine)?;
|
run_test(&mut engine)?;
|
||||||
|
|
||||||
// Override == operator
|
// Override == operator
|
||||||
|
#[cfg(not(feature = "fast_ops"))]
|
||||||
|
{
|
||||||
engine.register_fn("==", |_x: INT, _y: INT| false);
|
engine.register_fn("==", |_x: INT, _y: INT| false);
|
||||||
|
|
||||||
engine.set_optimization_level(OptimizationLevel::Simple);
|
engine.set_optimization_level(OptimizationLevel::Simple);
|
||||||
@ -64,6 +66,7 @@ fn test_optimizer_run() -> Result<(), Box<EvalAltResult>> {
|
|||||||
engine.eval::<INT>("if 1 == 1 || 2 > 3 { 42 } else { 123 }")?,
|
engine.eval::<INT>("if 1 == 1 || 2 > 3 { 42 } else { 123 }")?,
|
||||||
123
|
123
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user