Split has_script_fn and has_native_fn.
This commit is contained in:
parent
57140cbeeb
commit
fefa5a7dc7
@ -577,67 +577,37 @@ impl Engine {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Has a system function a Rust-native override?
|
// Does a scripted function exist?
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn has_native_override(
|
pub(crate) fn has_script_fn(
|
||||||
&self,
|
&self,
|
||||||
mods: Option<&Imports>,
|
mods: Option<&Imports>,
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
lib: &[&Module],
|
lib: &[&Module],
|
||||||
fn_name: &str,
|
hash_script: u64,
|
||||||
arg_types: &[TypeId],
|
|
||||||
) -> bool {
|
|
||||||
let hash_script = calc_fn_hash(empty(), fn_name, arg_types.len());
|
|
||||||
let hash_params = calc_fn_params_hash(arg_types.iter().cloned());
|
|
||||||
let hash_fn = combine_hashes(hash_script, hash_params);
|
|
||||||
|
|
||||||
self.has_override(mods, state, lib, Some(hash_fn), None)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Has a system function an override?
|
|
||||||
#[inline(always)]
|
|
||||||
pub(crate) fn has_override(
|
|
||||||
&self,
|
|
||||||
mods: Option<&Imports>,
|
|
||||||
state: &mut State,
|
|
||||||
lib: &[&Module],
|
|
||||||
hash_fn: Option<u64>,
|
|
||||||
hash_script: Option<u64>,
|
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let cache = state.fn_resolution_cache_mut();
|
let cache = state.fn_resolution_cache_mut();
|
||||||
|
|
||||||
if hash_script.map_or(false, |hash| cache.contains_key(&hash))
|
if let Some(result) = cache.get(&hash_script).map(|v| v.is_some()) {
|
||||||
|| hash_fn.map_or(false, |hash| cache.contains_key(&hash))
|
return result;
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// First check script-defined functions
|
// First check script-defined functions
|
||||||
if hash_script.map_or(false, |hash| lib.iter().any(|&m| m.contains_fn(hash, false)))
|
let result = lib.iter().any(|&m| m.contains_fn(hash_script, false))
|
||||||
//|| hash_fn.map_or(false, |hash| lib.iter().any(|&m| m.contains_fn(hash, false)))
|
|
||||||
// Then check registered functions
|
// Then check registered functions
|
||||||
|| hash_script.map_or(false, |hash| self.global_namespace.contains_fn(hash, false))
|
|| self.global_namespace.contains_fn(hash_script, false)
|
||||||
|| hash_fn.map_or(false, |hash| self.global_namespace.contains_fn(hash, false))
|
|
||||||
// Then check packages
|
// Then check packages
|
||||||
|| hash_script.map_or(false, |hash| self.global_modules.iter().any(|m| m.contains_fn(hash, false)))
|
|| self.global_modules.iter().any(|m| m.contains_fn(hash_script, false))
|
||||||
|| hash_fn.map_or(false, |hash| self.global_modules.iter().any(|m| m.contains_fn(hash, false)))
|
|
||||||
// Then check imported modules
|
// Then check imported modules
|
||||||
|| hash_script.map_or(false, |hash| mods.map_or(false, |m| m.contains_fn(hash)))
|
|| mods.map_or(false, |m| m.contains_fn(hash_script))
|
||||||
|| hash_fn.map_or(false, |hash| mods.map_or(false, |m| m.contains_fn(hash)))
|
|
||||||
// Then check sub-modules
|
// Then check sub-modules
|
||||||
|| hash_script.map_or(false, |hash| self.global_sub_modules.values().any(|m| m.contains_qualified_fn(hash)))
|
|| self.global_sub_modules.values().any(|m| m.contains_qualified_fn(hash_script));
|
||||||
|| hash_fn.map_or(false, |hash| self.global_sub_modules.values().any(|m| m.contains_qualified_fn(hash)))
|
|
||||||
{
|
if !result {
|
||||||
true
|
cache.insert(hash_script, None);
|
||||||
} else {
|
|
||||||
if let Some(hash_fn) = hash_fn {
|
|
||||||
cache.insert(hash_fn, None);
|
|
||||||
}
|
|
||||||
if let Some(hash_script) = hash_script {
|
|
||||||
cache.insert(hash_script, None);
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform an actual function call, native Rust or scripted, taking care of special functions.
|
/// Perform an actual function call, native Rust or scripted, taking care of special functions.
|
||||||
@ -689,7 +659,7 @@ impl Engine {
|
|||||||
Dynamic::FALSE
|
Dynamic::FALSE
|
||||||
} else {
|
} else {
|
||||||
let hash_script = calc_fn_hash(empty(), &fn_name, num_params as usize);
|
let hash_script = calc_fn_hash(empty(), &fn_name, num_params as usize);
|
||||||
self.has_override(Some(mods), state, lib, None, Some(hash_script))
|
self.has_script_fn(Some(mods), state, lib, hash_script)
|
||||||
.into()
|
.into()
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
@ -1165,7 +1135,7 @@ impl Engine {
|
|||||||
Dynamic::FALSE
|
Dynamic::FALSE
|
||||||
} else {
|
} else {
|
||||||
let hash_script = calc_fn_hash(empty(), &fn_name, num_params as usize);
|
let hash_script = calc_fn_hash(empty(), &fn_name, num_params as usize);
|
||||||
self.has_override(Some(mods), state, lib, None, Some(hash_script))
|
self.has_script_fn(Some(mods), state, lib, hash_script)
|
||||||
.into()
|
.into()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_PRINT, KEYWORD_TYPE_OF}
|
|||||||
use crate::fn_builtin::get_builtin_binary_op_fn;
|
use crate::fn_builtin::get_builtin_binary_op_fn;
|
||||||
use crate::parser::map_dynamic_to_expr;
|
use crate::parser::map_dynamic_to_expr;
|
||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
|
any::TypeId,
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
iter::empty,
|
iter::empty,
|
||||||
@ -15,8 +16,11 @@ use crate::stdlib::{
|
|||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
use crate::token::is_valid_identifier;
|
use crate::token::is_valid_identifier;
|
||||||
use crate::utils::{calc_fn_hash, get_hasher};
|
use crate::utils::get_hasher;
|
||||||
use crate::{Dynamic, Engine, Module, Position, Scope, StaticVec, AST};
|
use crate::{
|
||||||
|
calc_fn_hash, calc_fn_params_hash, combine_hashes, Dynamic, Engine, Module, Position, Scope,
|
||||||
|
StaticVec, AST,
|
||||||
|
};
|
||||||
|
|
||||||
/// Level of optimization performed.
|
/// Level of optimization performed.
|
||||||
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
|
#[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
|
||||||
@ -126,15 +130,25 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Has a system function a Rust-native override?
|
||||||
|
fn has_native_fn(state: &State, hash_script: u64, arg_types: &[TypeId]) -> bool {
|
||||||
|
let hash_params = calc_fn_params_hash(arg_types.iter().cloned());
|
||||||
|
let hash = combine_hashes(hash_script, hash_params);
|
||||||
|
|
||||||
|
// First check registered functions
|
||||||
|
state.engine.global_namespace.contains_fn(hash, false)
|
||||||
|
// Then check packages
|
||||||
|
|| state.engine.global_modules.iter().any(|m| m.contains_fn(hash, false))
|
||||||
|
// Then check sub-modules
|
||||||
|
|| state.engine.global_sub_modules.values().any(|m| m.contains_qualified_fn(hash))
|
||||||
|
}
|
||||||
|
|
||||||
/// Call a registered function
|
/// Call a registered function
|
||||||
fn call_fn_with_constant_arguments(
|
fn call_fn_with_constant_arguments(
|
||||||
state: &State,
|
state: &State,
|
||||||
fn_name: &str,
|
fn_name: &str,
|
||||||
arg_values: &mut [Dynamic],
|
arg_values: &mut [Dynamic],
|
||||||
) -> Option<Dynamic> {
|
) -> Option<Dynamic> {
|
||||||
// Search built-in's and external functions
|
|
||||||
let hash_native = calc_fn_hash(empty(), fn_name, arg_values.len());
|
|
||||||
|
|
||||||
state
|
state
|
||||||
.engine
|
.engine
|
||||||
.call_native_fn(
|
.call_native_fn(
|
||||||
@ -142,7 +156,7 @@ fn call_fn_with_constant_arguments(
|
|||||||
&mut Default::default(),
|
&mut Default::default(),
|
||||||
state.lib,
|
state.lib,
|
||||||
fn_name,
|
fn_name,
|
||||||
hash_native,
|
calc_fn_hash(empty(), fn_name, arg_values.len()),
|
||||||
arg_values.iter_mut().collect::<StaticVec<_>>().as_mut(),
|
arg_values.iter_mut().collect::<StaticVec<_>>().as_mut(),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
@ -676,7 +690,7 @@ fn optimize_expr(expr: &mut Expr, state: &mut State) {
|
|||||||
let arg_types: StaticVec<_> = arg_values.iter().map(Dynamic::type_id).collect();
|
let arg_types: StaticVec<_> = arg_values.iter().map(Dynamic::type_id).collect();
|
||||||
|
|
||||||
// Search for overloaded operators (can override built-in).
|
// Search for overloaded operators (can override built-in).
|
||||||
if !state.engine.has_native_override(Some(&Default::default()), &mut Default::default(), state.lib, x.name.as_ref(), arg_types.as_ref()) {
|
if !has_native_fn(state, x.hash.native_hash(), arg_types.as_ref()) {
|
||||||
if let Some(result) = get_builtin_binary_op_fn(x.name.as_ref(), &arg_values[0], &arg_values[1])
|
if let Some(result) = get_builtin_binary_op_fn(x.name.as_ref(), &arg_values[0], &arg_values[1])
|
||||||
.and_then(|f| {
|
.and_then(|f| {
|
||||||
let ctx = (state.engine, x.name.as_ref(), state.lib).into();
|
let ctx = (state.engine, x.name.as_ref(), state.lib).into();
|
||||||
|
Loading…
Reference in New Issue
Block a user