Add fast-ops feature.

This commit is contained in:
Stephen Chung
2022-09-02 23:45:25 +08:00
parent 7dbc605d0b
commit 0516e8088c
7 changed files with 71 additions and 13 deletions

View File

@@ -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(),

View File

@@ -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

View File

@@ -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()
};