diff --git a/src/api/call_fn.rs b/src/api/call_fn.rs index 7d248e30..67861e16 100644 --- a/src/api/call_fn.rs +++ b/src/api/call_fn.rs @@ -171,7 +171,7 @@ impl Engine { let mut arg_values = StaticVec::new_const(); args.parse(&mut arg_values); - let result = self._call_fn( + self._call_fn( options, scope, &mut GlobalRuntimeState::new(self), @@ -179,19 +179,20 @@ impl Engine { ast, name.as_ref(), arg_values.as_mut(), - )?; + ) + .and_then(|result| { + // Bail out early if the return type needs no cast + if TypeId::of::() == TypeId::of::() { + return Ok(reify!(result => T)); + } - // Bail out early if the return type needs no cast - if TypeId::of::() == TypeId::of::() { - return Ok(reify!(result => T)); - } + // Cast return type + let typ = self.map_type_name(result.type_name()); - // Cast return type - let typ = self.map_type_name(result.type_name()); - - result.try_cast().ok_or_else(|| { - let t = self.map_type_name(type_name::()).into(); - ERR::ErrorMismatchOutputType(t, typ.into(), Position::NONE).into() + result.try_cast().ok_or_else(|| { + let t = self.map_type_name(type_name::()).into(); + ERR::ErrorMismatchOutputType(t, typ.into(), Position::NONE).into() + }) }) } /// Call a script function defined in an [`AST`] with multiple [`Dynamic`] arguments. diff --git a/src/api/eval.rs b/src/api/eval.rs index 9dbfb17f..563be055 100644 --- a/src/api/eval.rs +++ b/src/api/eval.rs @@ -233,34 +233,29 @@ impl Engine { ast.resolver().cloned(), ); - let statements = ast.statements(); + auto_restore!(global => move |g| { + #[cfg(not(feature = "no_module"))] + { + g.embedded_module_resolver = orig_embedded_module_resolver; + } - if statements.is_empty() { - return Ok(Dynamic::UNIT); - } + #[cfg(not(feature = "no_function"))] + g.lib.truncate(orig_lib_len); - let result = self.eval_global_statements(global, caches, scope, statements); + g.source = orig_source; + }); - #[cfg(feature = "debugging")] - if self.is_debugger_registered() { - global.debugger_mut().status = crate::eval::DebuggerStatus::Terminate; - let mut this = Dynamic::NULL; - let node = &crate::ast::Stmt::Noop(Position::NONE); - - self.run_debugger(global, caches, scope, &mut this, node)?; - } - - #[cfg(not(feature = "no_module"))] - { - global.embedded_module_resolver = orig_embedded_module_resolver; - } - - #[cfg(not(feature = "no_function"))] - global.lib.truncate(orig_lib_len); - - global.source = orig_source; - - result + self.eval_global_statements(global, caches, scope, ast.statements()) + .and_then(|r| { + #[cfg(feature = "debugging")] + if self.is_debugger_registered() { + global.debugger_mut().status = crate::eval::DebuggerStatus::Terminate; + let mut this = Dynamic::NULL; + let node = &crate::ast::Stmt::Noop(Position::NONE); + self.run_debugger(global, caches, scope, &mut this, node)?; + } + Ok(r) + }) } } diff --git a/src/api/run.rs b/src/api/run.rs index fd20d4ef..8ecf8b2e 100644 --- a/src/api/run.rs +++ b/src/api/run.rs @@ -126,24 +126,17 @@ impl Engine { global.embedded_module_resolver = ast.resolver().cloned(); } - let statements = ast.statements(); - - let result = if !statements.is_empty() { - self.eval_global_statements(global, caches, scope, statements) - .map(|_| ()) - } else { - Ok(()) - }; - - #[cfg(feature = "debugging")] - if self.is_debugger_registered() { - global.debugger_mut().status = crate::eval::DebuggerStatus::Terminate; - let mut this = crate::Dynamic::NULL; - let node = &crate::ast::Stmt::Noop(crate::Position::NONE); - self.run_debugger(global, caches, scope, &mut this, node)?; - } - - result + self.eval_global_statements(global, caches, scope, ast.statements()) + .and_then(|_| { + #[cfg(feature = "debugging")] + if self.is_debugger_registered() { + global.debugger_mut().status = crate::eval::DebuggerStatus::Terminate; + let mut this = crate::Dynamic::NULL; + let node = &crate::ast::Stmt::Noop(crate::Position::NONE); + self.run_debugger(global, caches, scope, &mut this, node)?; + } + Ok(()) + }) } } diff --git a/src/func/native.rs b/src/func/native.rs index 4774f4be..e9e3b76d 100644 --- a/src/func/native.rs +++ b/src/func/native.rs @@ -303,19 +303,20 @@ impl<'a> NativeCallContext<'a> { let mut args: StaticVec<_> = arg_values.iter_mut().collect(); - let result = self._call_fn_raw(fn_name, &mut args, false, false, false)?; + self._call_fn_raw(fn_name, &mut args, false, false, false) + .and_then(|result| { + // Bail out early if the return type needs no cast + if TypeId::of::() == TypeId::of::() { + return Ok(reify!(result => T)); + } - // Bail out early if the return type needs no cast - if TypeId::of::() == TypeId::of::() { - return Ok(reify!(result => T)); - } + let typ = self.engine().map_type_name(result.type_name()); - let typ = self.engine().map_type_name(result.type_name()); - - result.try_cast().ok_or_else(|| { - let t = self.engine().map_type_name(type_name::()).into(); - ERR::ErrorMismatchOutputType(t, typ.into(), Position::NONE).into() - }) + result.try_cast().ok_or_else(|| { + let t = self.engine().map_type_name(type_name::()).into(); + ERR::ErrorMismatchOutputType(t, typ.into(), Position::NONE).into() + }) + }) } /// Call a registered native Rust function inside the call context with the provided arguments. /// @@ -333,19 +334,20 @@ impl<'a> NativeCallContext<'a> { let mut args: StaticVec<_> = arg_values.iter_mut().collect(); - let result = self._call_fn_raw(fn_name, &mut args, true, false, false)?; + self._call_fn_raw(fn_name, &mut args, true, false, false) + .and_then(|result| { + // Bail out early if the return type needs no cast + if TypeId::of::() == TypeId::of::() { + return Ok(reify!(result => T)); + } - // Bail out early if the return type needs no cast - if TypeId::of::() == TypeId::of::() { - return Ok(reify!(result => T)); - } + let typ = self.engine().map_type_name(result.type_name()); - let typ = self.engine().map_type_name(result.type_name()); - - result.try_cast().ok_or_else(|| { - let t = self.engine().map_type_name(type_name::()).into(); - ERR::ErrorMismatchOutputType(t, typ.into(), Position::NONE).into() - }) + result.try_cast().ok_or_else(|| { + let t = self.engine().map_type_name(type_name::()).into(); + ERR::ErrorMismatchOutputType(t, typ.into(), Position::NONE).into() + }) + }) } /// Call a function (native Rust or scripted) inside the call context. /// diff --git a/src/func/script.rs b/src/func/script.rs index 6120d714..14f83f04 100644 --- a/src/func/script.rs +++ b/src/func/script.rs @@ -205,12 +205,12 @@ impl Engine { } // First check script-defined functions - let result = global.lib.iter().any(|m| m.contains_fn(hash_script)) + let r = global.lib.iter().any(|m| m.contains_fn(hash_script)) // Then check the global namespace and packages || self.global_modules.iter().any(|m| m.contains_fn(hash_script)); #[cfg(not(feature = "no_module"))] - let result = result || + let r = r || // Then check imported modules global.contains_qualified_fn(hash_script) // Then check sub-modules @@ -218,11 +218,11 @@ impl Engine { m.values().any(|m| m.contains_qualified_fn(hash_script)) }); - if !result && !cache.filter.is_absent_and_set(hash_script) { + if !r && !cache.filter.is_absent_and_set(hash_script) { // Do not cache "one-hit wonders" cache.map.insert(hash_script, None); } - result + r } } diff --git a/src/types/fn_ptr.rs b/src/types/fn_ptr.rs index d3fe8698..0b36e2f9 100644 --- a/src/types/fn_ptr.rs +++ b/src/types/fn_ptr.rs @@ -158,18 +158,18 @@ impl FnPtr { let ctx = (engine, self.fn_name(), None, &*global, Position::NONE).into(); - let result = self.call_raw(&ctx, None, arg_values)?; + self.call_raw(&ctx, None, arg_values).and_then(|result| { + // Bail out early if the return type needs no cast + if TypeId::of::() == TypeId::of::() { + return Ok(reify!(result => T)); + } - // Bail out early if the return type needs no cast - if TypeId::of::() == TypeId::of::() { - return Ok(reify!(result => T)); - } + let typ = engine.map_type_name(result.type_name()); - let typ = engine.map_type_name(result.type_name()); - - result.try_cast().ok_or_else(|| { - let t = engine.map_type_name(type_name::()).into(); - ERR::ErrorMismatchOutputType(t, typ.into(), Position::NONE).into() + result.try_cast().ok_or_else(|| { + let t = engine.map_type_name(type_name::()).into(); + ERR::ErrorMismatchOutputType(t, typ.into(), Position::NONE).into() + }) }) } /// Call the function pointer with curried arguments (if any). @@ -187,18 +187,18 @@ impl FnPtr { let mut arg_values = crate::StaticVec::new_const(); args.parse(&mut arg_values); - let result = self.call_raw(context, None, arg_values)?; + self.call_raw(context, None, arg_values).and_then(|result| { + // Bail out early if the return type needs no cast + if TypeId::of::() == TypeId::of::() { + return Ok(reify!(result => T)); + } - // Bail out early if the return type needs no cast - if TypeId::of::() == TypeId::of::() { - return Ok(reify!(result => T)); - } + let typ = context.engine().map_type_name(result.type_name()); - let typ = context.engine().map_type_name(result.type_name()); - - result.try_cast().ok_or_else(|| { - let t = context.engine().map_type_name(type_name::()).into(); - ERR::ErrorMismatchOutputType(t, typ.into(), Position::NONE).into() + result.try_cast().ok_or_else(|| { + let t = context.engine().map_type_name(type_name::()).into(); + ERR::ErrorMismatchOutputType(t, typ.into(), Position::NONE).into() + }) }) } /// Call the function pointer with curried arguments (if any).