2022-01-25 07:32:42 +01:00
|
|
|
#![cfg(feature = "debugging")]
|
|
|
|
|
|
|
|
use crate::def_package;
|
|
|
|
use crate::plugin::*;
|
|
|
|
#[cfg(feature = "no_std")]
|
|
|
|
use std::prelude::v1::*;
|
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
|
|
|
#[cfg(not(feature = "no_index"))]
|
2022-02-09 06:12:43 +01:00
|
|
|
use crate::{Array, Dynamic, NativeCallContext};
|
2022-01-25 07:32:42 +01:00
|
|
|
|
|
|
|
#[cfg(not(feature = "no_function"))]
|
2022-02-09 06:12:43 +01:00
|
|
|
#[cfg(not(feature = "no_index"))]
|
2022-01-25 07:32:42 +01:00
|
|
|
#[cfg(not(feature = "no_object"))]
|
|
|
|
use crate::Map;
|
|
|
|
|
|
|
|
def_package! {
|
|
|
|
/// Package of basic debugging utilities.
|
2022-02-10 05:33:48 +01:00
|
|
|
pub DebuggingPackage(lib) {
|
2022-01-25 07:32:42 +01:00
|
|
|
lib.standard = true;
|
|
|
|
|
|
|
|
combine_with_exported_module!(lib, "debugging", debugging_functions);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[export_module]
|
|
|
|
mod debugging_functions {
|
2022-02-02 07:47:35 +01:00
|
|
|
/// Get an array of object maps containing the function calls stack.
|
|
|
|
///
|
|
|
|
/// If there is no debugging interface registered, an empty array is returned.
|
|
|
|
///
|
|
|
|
/// An array of strings is returned under `no_object`.
|
2022-01-25 07:32:42 +01:00
|
|
|
#[cfg(not(feature = "no_function"))]
|
|
|
|
#[cfg(not(feature = "no_index"))]
|
2022-02-02 07:47:35 +01:00
|
|
|
pub fn back_trace(ctx: NativeCallContext) -> Array {
|
2022-01-25 07:32:42 +01:00
|
|
|
if let Some(global) = ctx.global_runtime_state() {
|
|
|
|
global
|
|
|
|
.debugger
|
|
|
|
.call_stack()
|
|
|
|
.iter()
|
|
|
|
.rev()
|
2022-02-02 07:47:35 +01:00
|
|
|
.filter(|crate::debugger::CallStackFrame { fn_name, args, .. }| {
|
|
|
|
fn_name != "back_trace" || !args.is_empty()
|
|
|
|
})
|
2022-01-25 07:32:42 +01:00
|
|
|
.map(
|
|
|
|
|frame @ crate::debugger::CallStackFrame {
|
2022-01-25 16:59:35 +01:00
|
|
|
fn_name: _fn_name,
|
|
|
|
args: _args,
|
|
|
|
source: _source,
|
|
|
|
pos: _pos,
|
2022-01-25 07:32:42 +01:00
|
|
|
}| {
|
2022-01-26 15:16:11 +01:00
|
|
|
let display = frame.to_string();
|
2022-01-25 07:32:42 +01:00
|
|
|
|
|
|
|
#[cfg(not(feature = "no_object"))]
|
|
|
|
{
|
|
|
|
let mut map = Map::new();
|
2022-01-26 15:16:11 +01:00
|
|
|
map.insert("display".into(), display.into());
|
2022-01-25 16:59:35 +01:00
|
|
|
map.insert("fn_name".into(), _fn_name.into());
|
|
|
|
if !_args.is_empty() {
|
2022-01-25 07:32:42 +01:00
|
|
|
map.insert(
|
|
|
|
"args".into(),
|
2022-01-25 16:59:35 +01:00
|
|
|
Dynamic::from_array(_args.clone().to_vec()),
|
2022-01-25 07:32:42 +01:00
|
|
|
);
|
|
|
|
}
|
2022-01-25 16:59:35 +01:00
|
|
|
if !_source.is_empty() {
|
|
|
|
map.insert("source".into(), _source.into());
|
2022-01-25 07:32:42 +01:00
|
|
|
}
|
2022-01-25 16:59:35 +01:00
|
|
|
if !_pos.is_none() {
|
|
|
|
map.insert(
|
|
|
|
"line".into(),
|
|
|
|
(_pos.line().unwrap() as crate::INT).into(),
|
|
|
|
);
|
2022-01-25 07:32:42 +01:00
|
|
|
map.insert(
|
2022-01-25 14:31:35 +01:00
|
|
|
"position".into(),
|
2022-01-25 16:59:35 +01:00
|
|
|
(_pos.position().unwrap_or(0) as crate::INT).into(),
|
2022-01-25 07:32:42 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
Dynamic::from_map(map)
|
|
|
|
}
|
|
|
|
#[cfg(feature = "no_object")]
|
2022-01-29 04:09:43 +01:00
|
|
|
display.into()
|
2022-01-25 07:32:42 +01:00
|
|
|
},
|
|
|
|
)
|
|
|
|
.collect()
|
|
|
|
} else {
|
|
|
|
Array::new()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|