Add DebuggingPackage.
This commit is contained in:
parent
0e5f62574d
commit
aee35e5f20
@ -9,6 +9,7 @@ New features
|
|||||||
|
|
||||||
* A debugging interface is added.
|
* A debugging interface is added.
|
||||||
* A new bin tool, `rhai-dbg` (aka _The Rhai Debugger_), is added to showcase the debugging interface.
|
* A new bin tool, `rhai-dbg` (aka _The Rhai Debugger_), is added to showcase the debugging interface.
|
||||||
|
* A new package, `DebuggingPackage`, is added which contains the `stack_trace` function to get the current call stack anywhere in a script.
|
||||||
|
|
||||||
|
|
||||||
Version 1.4.2
|
Version 1.4.2
|
||||||
|
80
src/packages/debugging.rs
Normal file
80
src/packages/debugging.rs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#![cfg(feature = "debugging")]
|
||||||
|
|
||||||
|
use crate::def_package;
|
||||||
|
use crate::plugin::*;
|
||||||
|
#[cfg(feature = "no_std")]
|
||||||
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_function"))]
|
||||||
|
use crate::{Dynamic, NativeCallContext, INT};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_function"))]
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
use crate::Array;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_function"))]
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
use crate::Map;
|
||||||
|
|
||||||
|
def_package! {
|
||||||
|
/// Package of basic debugging utilities.
|
||||||
|
crate::DebuggingPackage => |lib| {
|
||||||
|
lib.standard = true;
|
||||||
|
|
||||||
|
combine_with_exported_module!(lib, "debugging", debugging_functions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[export_module]
|
||||||
|
mod debugging_functions {
|
||||||
|
#[cfg(not(feature = "no_function"))]
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
pub fn stack_trace(ctx: NativeCallContext) -> Array {
|
||||||
|
if let Some(global) = ctx.global_runtime_state() {
|
||||||
|
global
|
||||||
|
.debugger
|
||||||
|
.call_stack()
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.map(
|
||||||
|
|frame @ crate::debugger::CallStackFrame {
|
||||||
|
fn_name,
|
||||||
|
args,
|
||||||
|
source,
|
||||||
|
pos,
|
||||||
|
}| {
|
||||||
|
let call = frame.to_string();
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_object"))]
|
||||||
|
{
|
||||||
|
let mut map = Map::new();
|
||||||
|
map.insert("call".into(), call.into());
|
||||||
|
map.insert("fn_name".into(), fn_name.into());
|
||||||
|
if !args.is_empty() {
|
||||||
|
map.insert(
|
||||||
|
"args".into(),
|
||||||
|
Dynamic::from_array(args.clone().to_vec()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if !source.is_empty() {
|
||||||
|
map.insert("source".into(), source.into());
|
||||||
|
}
|
||||||
|
if !pos.is_none() {
|
||||||
|
map.insert("line".into(), (pos.line().unwrap() as INT).into());
|
||||||
|
map.insert(
|
||||||
|
"pos".into(),
|
||||||
|
(pos.position().unwrap_or(0) as INT).into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Dynamic::from_map(map)
|
||||||
|
}
|
||||||
|
#[cfg(feature = "no_object")]
|
||||||
|
call.into()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
Array::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ pub(crate) mod arithmetic;
|
|||||||
pub(crate) mod array_basic;
|
pub(crate) mod array_basic;
|
||||||
mod bit_field;
|
mod bit_field;
|
||||||
pub(crate) mod blob_basic;
|
pub(crate) mod blob_basic;
|
||||||
|
mod debugging;
|
||||||
mod fn_basic;
|
mod fn_basic;
|
||||||
mod iter_basic;
|
mod iter_basic;
|
||||||
mod lang_core;
|
mod lang_core;
|
||||||
@ -24,6 +25,8 @@ pub use array_basic::BasicArrayPackage;
|
|||||||
pub use bit_field::BitFieldPackage;
|
pub use bit_field::BitFieldPackage;
|
||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
pub use blob_basic::BasicBlobPackage;
|
pub use blob_basic::BasicBlobPackage;
|
||||||
|
#[cfg(feature = "debugging")]
|
||||||
|
pub use debugging::DebuggingPackage;
|
||||||
pub use fn_basic::BasicFnPackage;
|
pub use fn_basic::BasicFnPackage;
|
||||||
pub use iter_basic::BasicIteratorPackage;
|
pub use iter_basic::BasicIteratorPackage;
|
||||||
pub use lang_core::LanguageCorePackage;
|
pub use lang_core::LanguageCorePackage;
|
||||||
|
@ -13,6 +13,7 @@ def_package! {
|
|||||||
/// * [`BasicStringPackage`][super::BasicStringPackage]
|
/// * [`BasicStringPackage`][super::BasicStringPackage]
|
||||||
/// * [`BasicIteratorPackage`][super::BasicIteratorPackage]
|
/// * [`BasicIteratorPackage`][super::BasicIteratorPackage]
|
||||||
/// * [`BasicFnPackage`][super::BasicFnPackage]
|
/// * [`BasicFnPackage`][super::BasicFnPackage]
|
||||||
|
/// * [`DebuggingPackage`][super::DebuggingPackage]
|
||||||
crate::CorePackage => |lib| {
|
crate::CorePackage => |lib| {
|
||||||
lib.standard = true;
|
lib.standard = true;
|
||||||
|
|
||||||
@ -21,5 +22,7 @@ def_package! {
|
|||||||
super::BasicStringPackage::init(lib);
|
super::BasicStringPackage::init(lib);
|
||||||
super::BasicIteratorPackage::init(lib);
|
super::BasicIteratorPackage::init(lib);
|
||||||
super::BasicFnPackage::init(lib);
|
super::BasicFnPackage::init(lib);
|
||||||
|
#[cfg(feature = "debugging")]
|
||||||
|
super::DebuggingPackage::init(lib);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
34
tests/debugging.rs
Normal file
34
tests/debugging.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#![cfg(feature = "debugging")]
|
||||||
|
use rhai::{Engine, EvalAltResult, INT};
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
use rhai::Array;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_debugging() -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let engine = Engine::new();
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_function"))]
|
||||||
|
#[cfg(not(feature = "no_index"))]
|
||||||
|
{
|
||||||
|
let r = engine.eval::<Array>(
|
||||||
|
"
|
||||||
|
fn foo(x) {
|
||||||
|
if x >= 5 {
|
||||||
|
stack_trace()
|
||||||
|
} else {
|
||||||
|
foo(x+1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foo(0)
|
||||||
|
",
|
||||||
|
)?;
|
||||||
|
|
||||||
|
assert_eq!(r.len(), 6);
|
||||||
|
|
||||||
|
assert_eq!(engine.eval::<INT>("len(stack_trace())")?, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user