Add source info to native calls.
This commit is contained in:
parent
ef48f47b74
commit
1bbf473ec7
@ -13,6 +13,7 @@ Enhancements
|
|||||||
------------
|
------------
|
||||||
|
|
||||||
* Source information is provided when there is an error within a call to a function defined in another module.
|
* Source information is provided when there is an error within a call to a function defined in another module.
|
||||||
|
* Source information is provided to the `NativeCallContext` for native Rust functions.
|
||||||
|
|
||||||
|
|
||||||
Version 0.19.9
|
Version 0.19.9
|
||||||
|
@ -126,11 +126,14 @@ impl Imports {
|
|||||||
}
|
}
|
||||||
/// Get specified function via its hash key.
|
/// Get specified function via its hash key.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn get_fn(&self, hash: NonZeroU64) -> Option<&CallableFunction> {
|
pub fn get_fn(
|
||||||
|
&self,
|
||||||
|
hash: NonZeroU64,
|
||||||
|
) -> Option<(&CallableFunction, &Option<ImmutableString>)> {
|
||||||
self.0
|
self.0
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.find_map(|(_, m)| m.get_qualified_fn(hash))
|
.find_map(|(_, m)| m.get_qualified_fn(hash).map(|f| (f, m.id_raw())))
|
||||||
}
|
}
|
||||||
/// Does the specified [`TypeId`][std::any::TypeId] iterator exist in this stack of imported [modules][Module]?
|
/// Does the specified [`TypeId`][std::any::TypeId] iterator exist in this stack of imported [modules][Module]?
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
@ -2046,15 +2049,16 @@ impl Engine {
|
|||||||
match self
|
match self
|
||||||
.global_namespace
|
.global_namespace
|
||||||
.get_fn(hash_fn, false)
|
.get_fn(hash_fn, false)
|
||||||
|
.map(|f| (f, None))
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
self.global_modules
|
self.global_modules.iter().find_map(|m| {
|
||||||
.iter()
|
m.get_fn(hash_fn, false).map(|f| (f, m.id_raw().as_ref()))
|
||||||
.find_map(|m| m.get_fn(hash_fn, false))
|
|
||||||
})
|
})
|
||||||
.or_else(|| mods.get_fn(hash_fn))
|
})
|
||||||
|
.or_else(|| mods.get_fn(hash_fn).map(|(f, source)| (f, source.as_ref())))
|
||||||
{
|
{
|
||||||
// op= function registered as method
|
// op= function registered as method
|
||||||
Some(func) if func.is_method() => {
|
Some((func, source)) if func.is_method() => {
|
||||||
let mut lock_guard;
|
let mut lock_guard;
|
||||||
let lhs_ptr_inner;
|
let lhs_ptr_inner;
|
||||||
|
|
||||||
@ -2068,14 +2072,16 @@ impl Engine {
|
|||||||
let args = &mut [lhs_ptr_inner, &mut rhs_val];
|
let args = &mut [lhs_ptr_inner, &mut rhs_val];
|
||||||
|
|
||||||
// Overriding exact implementation
|
// Overriding exact implementation
|
||||||
|
let source = if source.is_none() {
|
||||||
|
state.source.as_ref()
|
||||||
|
} else {
|
||||||
|
source
|
||||||
|
};
|
||||||
if func.is_plugin_fn() {
|
if func.is_plugin_fn() {
|
||||||
func.get_plugin_fn()
|
func.get_plugin_fn()
|
||||||
.call((self, &state.source, &*mods, lib).into(), args)?;
|
.call((self, source, &*mods, lib).into(), args)?;
|
||||||
} else {
|
} else {
|
||||||
func.get_native_fn()(
|
func.get_native_fn()((self, source, &*mods, lib).into(), args)?;
|
||||||
(self, &state.source, &*mods, lib).into(),
|
|
||||||
args,
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Built-in op-assignment function
|
// Built-in op-assignment function
|
||||||
|
@ -176,15 +176,14 @@ impl Engine {
|
|||||||
self.inc_operations(state, pos)?;
|
self.inc_operations(state, pos)?;
|
||||||
|
|
||||||
// Check if function access already in the cache
|
// Check if function access already in the cache
|
||||||
if !state.functions_cache.contains_key(&hash_fn) {
|
let func = &*state.functions_cache.entry(hash_fn).or_insert_with(|| {
|
||||||
// Search for the native function
|
// Search for the native function
|
||||||
// First search registered functions (can override packages)
|
// First search registered functions (can override packages)
|
||||||
// Then search packages
|
// Then search packages
|
||||||
// Finally search modules
|
// Finally search modules
|
||||||
|
|
||||||
//lib.get_fn(hash_fn, pub_only)
|
//lib.get_fn(hash_fn, pub_only)
|
||||||
let f = self
|
self.global_namespace
|
||||||
.global_namespace
|
|
||||||
.get_fn(hash_fn, pub_only)
|
.get_fn(hash_fn, pub_only)
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|f| (f, None))
|
.map(|f| (f, None))
|
||||||
@ -195,13 +194,11 @@ impl Engine {
|
|||||||
.map(|f| (f, m.id_raw().clone()))
|
.map(|f| (f, m.id_raw().clone()))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.or_else(|| mods.get_fn(hash_fn).cloned().map(|f| (f, None)));
|
.or_else(|| {
|
||||||
|
mods.get_fn(hash_fn)
|
||||||
// Store into cache
|
.map(|(f, source)| (f.clone(), source.clone()))
|
||||||
state.functions_cache.insert(hash_fn, f);
|
})
|
||||||
}
|
});
|
||||||
|
|
||||||
let func = state.functions_cache.get(&hash_fn).unwrap();
|
|
||||||
|
|
||||||
if let Some((func, source)) = func {
|
if let Some((func, source)) = func {
|
||||||
assert!(func.is_native());
|
assert!(func.is_native());
|
||||||
@ -212,9 +209,9 @@ impl Engine {
|
|||||||
|
|
||||||
// Run external function
|
// Run external function
|
||||||
let source = if source.is_none() {
|
let source = if source.is_none() {
|
||||||
&state.source
|
state.source.as_ref()
|
||||||
} else {
|
} else {
|
||||||
source
|
source.as_ref()
|
||||||
};
|
};
|
||||||
let result = if func.is_plugin_fn() {
|
let result = if func.is_plugin_fn() {
|
||||||
func.get_plugin_fn()
|
func.get_plugin_fn()
|
||||||
@ -1240,10 +1237,10 @@ impl Engine {
|
|||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
Some(f) if f.is_plugin_fn() => f
|
Some(f) if f.is_plugin_fn() => f.get_plugin_fn().clone().call(
|
||||||
.get_plugin_fn()
|
(self, module.id_raw().as_ref(), &*mods, lib).into(),
|
||||||
.clone()
|
args.as_mut(),
|
||||||
.call((self, module.id_raw(), &*mods, lib).into(), args.as_mut()),
|
),
|
||||||
Some(f) if f.is_native() => {
|
Some(f) if f.is_native() => {
|
||||||
if !f.is_method() {
|
if !f.is_method() {
|
||||||
// Clone first argument
|
// Clone first argument
|
||||||
@ -1254,7 +1251,10 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f.get_native_fn()((self, module.id_raw(), &*mods, lib).into(), args.as_mut())
|
f.get_native_fn()(
|
||||||
|
(self, module.id_raw().as_ref(), &*mods, lib).into(),
|
||||||
|
args.as_mut(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Some(f) => unreachable!("unknown function type: {:?}", f),
|
Some(f) => unreachable!("unknown function type: {:?}", f),
|
||||||
None if def_val.is_some() => Ok(def_val.unwrap().clone()),
|
None if def_val.is_some() => Ok(def_val.unwrap().clone()),
|
||||||
|
@ -63,14 +63,14 @@ pub struct NativeCallContext<'e, 's, 'a, 'm, 'pm: 'm> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'e, 's, 'a, 'm, 'pm: 'm, M: AsRef<[&'pm Module]> + ?Sized>
|
impl<'e, 's, 'a, 'm, 'pm: 'm, M: AsRef<[&'pm Module]> + ?Sized>
|
||||||
From<(&'e Engine, &'s Option<ImmutableString>, &'a Imports, &'m M)>
|
From<(&'e Engine, Option<&'s ImmutableString>, &'a Imports, &'m M)>
|
||||||
for NativeCallContext<'e, 's, 'a, 'm, 'pm>
|
for NativeCallContext<'e, 's, 'a, 'm, 'pm>
|
||||||
{
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from(value: (&'e Engine, &'s Option<ImmutableString>, &'a Imports, &'m M)) -> Self {
|
fn from(value: (&'e Engine, Option<&'s ImmutableString>, &'a Imports, &'m M)) -> Self {
|
||||||
Self {
|
Self {
|
||||||
engine: value.0,
|
engine: value.0,
|
||||||
source: value.1.as_ref().map(|s| s.as_str()),
|
source: value.1.map(|s| s.as_str()),
|
||||||
mods: Some(value.2),
|
mods: Some(value.2),
|
||||||
lib: value.3.as_ref(),
|
lib: value.3.as_ref(),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user