Refactor fast operators.
This commit is contained in:
@@ -3,17 +3,9 @@
|
||||
use super::{Caches, EvalContext, GlobalRuntimeState, Target};
|
||||
use crate::ast::{Expr, FnCallExpr, OpAssignment};
|
||||
use crate::engine::{KEYWORD_THIS, OP_CONCAT};
|
||||
use crate::eval::FnResolutionCacheEntry;
|
||||
use crate::func::{
|
||||
calc_fn_params_hash, combine_hashes, gen_fn_call_signature, get_builtin_binary_op_fn,
|
||||
CallableFunction,
|
||||
};
|
||||
use crate::func::get_builtin_binary_op_fn;
|
||||
use crate::types::dynamic::AccessMode;
|
||||
use crate::{Dynamic, Engine, Module, Position, RhaiResult, RhaiResultOf, Scope, ERR};
|
||||
#[cfg(feature = "no_std")]
|
||||
use hashbrown::hash_map::Entry;
|
||||
#[cfg(not(feature = "no_std"))]
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::num::NonZeroUsize;
|
||||
#[cfg(feature = "no_std")]
|
||||
use std::prelude::v1::*;
|
||||
@@ -231,83 +223,31 @@ impl Engine {
|
||||
} = expr;
|
||||
|
||||
// Short-circuit native binary operator call if under Fast Operators mode
|
||||
if expr.is_native_operator && self.fast_operators() && (args.len() == 1 || args.len() == 2)
|
||||
{
|
||||
if expr.is_native_operator && self.fast_operators() && args.len() == 2 {
|
||||
let mut lhs = self
|
||||
.get_arg_value(scope, global, caches, lib, this_ptr, &args[0], level)?
|
||||
.0
|
||||
.flatten();
|
||||
|
||||
let mut rhs = if args.len() == 2 {
|
||||
self.get_arg_value(scope, global, caches, lib, this_ptr, &args[1], level)?
|
||||
.0
|
||||
.flatten()
|
||||
} else {
|
||||
Dynamic::UNIT
|
||||
};
|
||||
let mut rhs = self
|
||||
.get_arg_value(scope, global, caches, lib, this_ptr, &args[1], level)?
|
||||
.0
|
||||
.flatten();
|
||||
|
||||
let mut operands = [&mut lhs, &mut rhs];
|
||||
let operands = if args.len() == 2 {
|
||||
&mut operands[..]
|
||||
} else {
|
||||
&mut operands[0..1]
|
||||
};
|
||||
let operands = &mut [&mut lhs, &mut rhs];
|
||||
|
||||
let hash = calc_fn_params_hash(operands.iter().map(|a| a.type_id()));
|
||||
let hash = combine_hashes(hashes.native, hash);
|
||||
if let Some(func) = get_builtin_binary_op_fn(name, operands[0], operands[1]) {
|
||||
// Built-in found
|
||||
let context = (self, name, None, &*global, lib, pos, level + 1).into();
|
||||
let result = func(context, operands);
|
||||
return self.check_return_value(result, pos);
|
||||
}
|
||||
|
||||
let cache = caches.fn_resolution_cache_mut();
|
||||
let local_entry: CallableFunction;
|
||||
|
||||
let func = match cache.map.entry(hash) {
|
||||
Entry::Vacant(entry) => {
|
||||
let func = if args.len() == 2 {
|
||||
get_builtin_binary_op_fn(name, operands[0], operands[1])
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if let Some(f) = func {
|
||||
if cache.filter.is_absent_and_set(hash) {
|
||||
// Do not cache "one-hit wonders"
|
||||
local_entry = CallableFunction::from_fn_builtin(f);
|
||||
&local_entry
|
||||
} else {
|
||||
// Cache repeated calls
|
||||
&entry
|
||||
.insert(Some(FnResolutionCacheEntry {
|
||||
func: CallableFunction::from_fn_builtin(f),
|
||||
source: None,
|
||||
}))
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.func
|
||||
}
|
||||
} else {
|
||||
let result = self.exec_fn_call(
|
||||
None, global, caches, lib, name, *hashes, operands, false, false, pos,
|
||||
level,
|
||||
);
|
||||
return result.map(|(v, ..)| v);
|
||||
}
|
||||
}
|
||||
Entry::Occupied(entry) => {
|
||||
if let Some(entry) = entry.into_mut() {
|
||||
&entry.func
|
||||
} else {
|
||||
let sig = gen_fn_call_signature(self, name, operands);
|
||||
return Err(ERR::ErrorFunctionNotFound(sig, pos).into());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let context = (self, name, None, &*global, lib, pos, level).into();
|
||||
let result = if func.is_plugin_fn() {
|
||||
func.get_plugin_fn().unwrap().call(context, operands)
|
||||
} else {
|
||||
func.get_native_fn().unwrap()(context, operands)
|
||||
};
|
||||
return self.check_return_value(result, pos);
|
||||
return self
|
||||
.exec_fn_call(
|
||||
None, global, caches, lib, name, *hashes, operands, false, false, pos, level,
|
||||
)
|
||||
.map(|(v, ..)| v);
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no_module"))]
|
||||
|
Reference in New Issue
Block a user