Reduce data sizes.
This commit is contained in:
parent
6c06481457
commit
bda8c2b636
@ -277,7 +277,7 @@ impl Engine {
|
|||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
if self.debugger.is_some() {
|
if self.debugger.is_some() {
|
||||||
global.debugger.status = crate::eval::DebuggerStatus::Terminate;
|
global.debugger_mut().status = crate::eval::DebuggerStatus::Terminate;
|
||||||
let node = &crate::ast::Stmt::Noop(Position::NONE);
|
let node = &crate::ast::Stmt::Noop(Position::NONE);
|
||||||
self.run_debugger(global, caches, scope, this_ptr, node)?;
|
self.run_debugger(global, caches, scope, this_ptr, node)?;
|
||||||
}
|
}
|
||||||
|
@ -244,7 +244,7 @@ impl Engine {
|
|||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
if self.debugger.is_some() {
|
if self.debugger.is_some() {
|
||||||
global.debugger.status = crate::eval::DebuggerStatus::Terminate;
|
global.debugger_mut().status = crate::eval::DebuggerStatus::Terminate;
|
||||||
let mut this = Dynamic::NULL;
|
let mut this = Dynamic::NULL;
|
||||||
let node = &crate::ast::Stmt::Noop(Position::NONE);
|
let node = &crate::ast::Stmt::Noop(Position::NONE);
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ impl Engine {
|
|||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
if self.debugger.is_some() {
|
if self.debugger.is_some() {
|
||||||
global.debugger.status = crate::eval::DebuggerStatus::Terminate;
|
global.debugger_mut().status = crate::eval::DebuggerStatus::Terminate;
|
||||||
let mut this = crate::Dynamic::NULL;
|
let mut this = crate::Dynamic::NULL;
|
||||||
let node = &crate::ast::Stmt::Noop(crate::Position::NONE);
|
let node = &crate::ast::Stmt::Noop(crate::Position::NONE);
|
||||||
self.run_debugger(global, caches, scope, &mut this, node)?;
|
self.run_debugger(global, caches, scope, &mut this, node)?;
|
||||||
|
@ -61,7 +61,7 @@ fn print_current_source(
|
|||||||
) {
|
) {
|
||||||
let current_source = &mut *context
|
let current_source = &mut *context
|
||||||
.global_runtime_state_mut()
|
.global_runtime_state_mut()
|
||||||
.debugger
|
.debugger_mut()
|
||||||
.state_mut()
|
.state_mut()
|
||||||
.write_lock::<ImmutableString>()
|
.write_lock::<ImmutableString>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -241,7 +241,7 @@ fn debug_callback(
|
|||||||
DebuggerEvent::End => println!("\x1b[31m! Script end\x1b[39m"),
|
DebuggerEvent::End => println!("\x1b[31m! Script end\x1b[39m"),
|
||||||
DebuggerEvent::Step => (),
|
DebuggerEvent::Step => (),
|
||||||
DebuggerEvent::BreakPoint(n) => {
|
DebuggerEvent::BreakPoint(n) => {
|
||||||
match context.global_runtime_state().debugger.break_points()[n] {
|
match context.global_runtime_state().debugger().break_points()[n] {
|
||||||
#[cfg(not(feature = "no_position"))]
|
#[cfg(not(feature = "no_position"))]
|
||||||
BreakPoint::AtPosition { .. } => (),
|
BreakPoint::AtPosition { .. } => (),
|
||||||
BreakPoint::AtFunctionName { ref name, .. }
|
BreakPoint::AtFunctionName { ref name, .. }
|
||||||
@ -260,7 +260,7 @@ fn debug_callback(
|
|||||||
"! Return from function call '{}' => {:?}",
|
"! Return from function call '{}' => {:?}",
|
||||||
context
|
context
|
||||||
.global_runtime_state()
|
.global_runtime_state()
|
||||||
.debugger
|
.debugger()
|
||||||
.call_stack()
|
.call_stack()
|
||||||
.last()
|
.last()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -273,7 +273,7 @@ fn debug_callback(
|
|||||||
"! Return from function call '{}' with error: {}",
|
"! Return from function call '{}' with error: {}",
|
||||||
context
|
context
|
||||||
.global_runtime_state()
|
.global_runtime_state()
|
||||||
.debugger
|
.debugger()
|
||||||
.call_stack()
|
.call_stack()
|
||||||
.last()
|
.last()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -373,7 +373,7 @@ fn debug_callback(
|
|||||||
["backtrace" | "bt"] => {
|
["backtrace" | "bt"] => {
|
||||||
for frame in context
|
for frame in context
|
||||||
.global_runtime_state()
|
.global_runtime_state()
|
||||||
.debugger
|
.debugger()
|
||||||
.call_stack()
|
.call_stack()
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
@ -384,7 +384,7 @@ fn debug_callback(
|
|||||||
["info" | "i", "break" | "b"] => Iterator::for_each(
|
["info" | "i", "break" | "b"] => Iterator::for_each(
|
||||||
context
|
context
|
||||||
.global_runtime_state()
|
.global_runtime_state()
|
||||||
.debugger
|
.debugger()
|
||||||
.break_points()
|
.break_points()
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate(),
|
.enumerate(),
|
||||||
@ -402,13 +402,13 @@ fn debug_callback(
|
|||||||
if let Ok(n) = n.parse::<usize>() {
|
if let Ok(n) = n.parse::<usize>() {
|
||||||
let range = 1..=context
|
let range = 1..=context
|
||||||
.global_runtime_state_mut()
|
.global_runtime_state_mut()
|
||||||
.debugger
|
.debugger()
|
||||||
.break_points()
|
.break_points()
|
||||||
.len();
|
.len();
|
||||||
if range.contains(&n) {
|
if range.contains(&n) {
|
||||||
context
|
context
|
||||||
.global_runtime_state_mut()
|
.global_runtime_state_mut()
|
||||||
.debugger
|
.debugger_mut()
|
||||||
.break_points_mut()
|
.break_points_mut()
|
||||||
.get_mut(n - 1)
|
.get_mut(n - 1)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -425,13 +425,13 @@ fn debug_callback(
|
|||||||
if let Ok(n) = n.parse::<usize>() {
|
if let Ok(n) = n.parse::<usize>() {
|
||||||
let range = 1..=context
|
let range = 1..=context
|
||||||
.global_runtime_state_mut()
|
.global_runtime_state_mut()
|
||||||
.debugger
|
.debugger()
|
||||||
.break_points()
|
.break_points()
|
||||||
.len();
|
.len();
|
||||||
if range.contains(&n) {
|
if range.contains(&n) {
|
||||||
context
|
context
|
||||||
.global_runtime_state_mut()
|
.global_runtime_state_mut()
|
||||||
.debugger
|
.debugger_mut()
|
||||||
.break_points_mut()
|
.break_points_mut()
|
||||||
.get_mut(n - 1)
|
.get_mut(n - 1)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -448,13 +448,13 @@ fn debug_callback(
|
|||||||
if let Ok(n) = n.parse::<usize>() {
|
if let Ok(n) = n.parse::<usize>() {
|
||||||
let range = 1..=context
|
let range = 1..=context
|
||||||
.global_runtime_state_mut()
|
.global_runtime_state_mut()
|
||||||
.debugger
|
.debugger()
|
||||||
.break_points()
|
.break_points()
|
||||||
.len();
|
.len();
|
||||||
if range.contains(&n) {
|
if range.contains(&n) {
|
||||||
context
|
context
|
||||||
.global_runtime_state_mut()
|
.global_runtime_state_mut()
|
||||||
.debugger
|
.debugger_mut()
|
||||||
.break_points_mut()
|
.break_points_mut()
|
||||||
.remove(n - 1);
|
.remove(n - 1);
|
||||||
println!("Break-point #{n} deleted.")
|
println!("Break-point #{n} deleted.")
|
||||||
@ -468,7 +468,7 @@ fn debug_callback(
|
|||||||
["delete" | "d"] => {
|
["delete" | "d"] => {
|
||||||
context
|
context
|
||||||
.global_runtime_state_mut()
|
.global_runtime_state_mut()
|
||||||
.debugger
|
.debugger_mut()
|
||||||
.break_points_mut()
|
.break_points_mut()
|
||||||
.clear();
|
.clear();
|
||||||
println!("All break-points deleted.");
|
println!("All break-points deleted.");
|
||||||
@ -483,7 +483,7 @@ fn debug_callback(
|
|||||||
println!("Break-point added for {bp}");
|
println!("Break-point added for {bp}");
|
||||||
context
|
context
|
||||||
.global_runtime_state_mut()
|
.global_runtime_state_mut()
|
||||||
.debugger
|
.debugger_mut()
|
||||||
.break_points_mut()
|
.break_points_mut()
|
||||||
.push(bp);
|
.push(bp);
|
||||||
} else {
|
} else {
|
||||||
@ -500,7 +500,7 @@ fn debug_callback(
|
|||||||
println!("Break-point added for {bp}");
|
println!("Break-point added for {bp}");
|
||||||
context
|
context
|
||||||
.global_runtime_state_mut()
|
.global_runtime_state_mut()
|
||||||
.debugger
|
.debugger_mut()
|
||||||
.break_points_mut()
|
.break_points_mut()
|
||||||
.push(bp);
|
.push(bp);
|
||||||
}
|
}
|
||||||
@ -523,7 +523,7 @@ fn debug_callback(
|
|||||||
println!("Break-point added {bp}");
|
println!("Break-point added {bp}");
|
||||||
context
|
context
|
||||||
.global_runtime_state_mut()
|
.global_runtime_state_mut()
|
||||||
.debugger
|
.debugger_mut()
|
||||||
.break_points_mut()
|
.break_points_mut()
|
||||||
.push(bp);
|
.push(bp);
|
||||||
} else {
|
} else {
|
||||||
@ -539,7 +539,7 @@ fn debug_callback(
|
|||||||
println!("Break-point added for {bp}");
|
println!("Break-point added for {bp}");
|
||||||
context
|
context
|
||||||
.global_runtime_state_mut()
|
.global_runtime_state_mut()
|
||||||
.debugger
|
.debugger_mut()
|
||||||
.break_points_mut()
|
.break_points_mut()
|
||||||
.push(bp);
|
.push(bp);
|
||||||
}
|
}
|
||||||
@ -553,7 +553,7 @@ fn debug_callback(
|
|||||||
println!("Break-point added {bp}");
|
println!("Break-point added {bp}");
|
||||||
context
|
context
|
||||||
.global_runtime_state_mut()
|
.global_runtime_state_mut()
|
||||||
.debugger
|
.debugger_mut()
|
||||||
.break_points_mut()
|
.break_points_mut()
|
||||||
.push(bp);
|
.push(bp);
|
||||||
}
|
}
|
||||||
|
@ -663,9 +663,10 @@ impl Engine {
|
|||||||
let reset =
|
let reset =
|
||||||
self.run_debugger_with_reset(global, caches, scope, this_ptr, rhs)?;
|
self.run_debugger_with_reset(global, caches, scope, this_ptr, rhs)?;
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
let global = &mut *RestoreOnDrop::lock(global, move |g| {
|
let global =
|
||||||
g.debugger.reset_status(reset)
|
&mut *RestoreOnDrop::lock_if(reset.is_some(), global, move |g| {
|
||||||
});
|
g.debugger_mut().reset_status(reset)
|
||||||
|
});
|
||||||
|
|
||||||
let crate::ast::FnCallExpr {
|
let crate::ast::FnCallExpr {
|
||||||
name, hashes, args, ..
|
name, hashes, args, ..
|
||||||
@ -832,9 +833,11 @@ impl Engine {
|
|||||||
global, caches, scope, this_ptr, _node,
|
global, caches, scope, this_ptr, _node,
|
||||||
)?;
|
)?;
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
let global = &mut *RestoreOnDrop::lock(global, move |g| {
|
let global = &mut *RestoreOnDrop::lock_if(
|
||||||
g.debugger.reset_status(reset)
|
reset.is_some(),
|
||||||
});
|
global,
|
||||||
|
move |g| g.debugger_mut().reset_status(reset),
|
||||||
|
);
|
||||||
|
|
||||||
let crate::ast::FnCallExpr {
|
let crate::ast::FnCallExpr {
|
||||||
name, hashes, args, ..
|
name, hashes, args, ..
|
||||||
@ -956,9 +959,11 @@ impl Engine {
|
|||||||
global, caches, scope, this_ptr, _node,
|
global, caches, scope, this_ptr, _node,
|
||||||
)?;
|
)?;
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
let global = &mut *RestoreOnDrop::lock(global, move |g| {
|
let global = &mut *RestoreOnDrop::lock_if(
|
||||||
g.debugger.reset_status(reset)
|
reset.is_some(),
|
||||||
});
|
global,
|
||||||
|
move |g| g.debugger_mut().reset_status(reset),
|
||||||
|
);
|
||||||
|
|
||||||
let crate::ast::FnCallExpr {
|
let crate::ast::FnCallExpr {
|
||||||
name, hashes, args, ..
|
name, hashes, args, ..
|
||||||
|
@ -419,7 +419,7 @@ impl Engine {
|
|||||||
if let Some(cmd) =
|
if let Some(cmd) =
|
||||||
self.run_debugger_with_reset_raw(global, caches, scope, this_ptr, node)?
|
self.run_debugger_with_reset_raw(global, caches, scope, this_ptr, node)?
|
||||||
{
|
{
|
||||||
global.debugger.status = cmd;
|
global.debugger_mut().status = cmd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,24 +469,28 @@ impl Engine {
|
|||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
let event = match global.debugger.status {
|
if let Some(ref dbg) = global.debugger {
|
||||||
DebuggerStatus::Init => Some(DebuggerEvent::Start),
|
let event = match dbg.status {
|
||||||
DebuggerStatus::NEXT if node.is_stmt() => Some(DebuggerEvent::Step),
|
DebuggerStatus::Init => Some(DebuggerEvent::Start),
|
||||||
DebuggerStatus::INTO if node.is_expr() => Some(DebuggerEvent::Step),
|
DebuggerStatus::NEXT if node.is_stmt() => Some(DebuggerEvent::Step),
|
||||||
DebuggerStatus::STEP => Some(DebuggerEvent::Step),
|
DebuggerStatus::INTO if node.is_expr() => Some(DebuggerEvent::Step),
|
||||||
DebuggerStatus::Terminate => Some(DebuggerEvent::End),
|
DebuggerStatus::STEP => Some(DebuggerEvent::Step),
|
||||||
_ => None,
|
DebuggerStatus::Terminate => Some(DebuggerEvent::End),
|
||||||
};
|
_ => None,
|
||||||
|
};
|
||||||
|
|
||||||
let event = match event {
|
let event = match event {
|
||||||
Some(e) => e,
|
Some(e) => e,
|
||||||
None => match global.debugger.is_break_point(global.source(), node) {
|
None => match dbg.is_break_point(global.source(), node) {
|
||||||
Some(bp) => DebuggerEvent::BreakPoint(bp),
|
Some(bp) => DebuggerEvent::BreakPoint(bp),
|
||||||
None => return Ok(None),
|
None => return Ok(None),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
self.run_debugger_raw(global, caches, scope, this_ptr, node, event)
|
self.run_debugger_raw(global, caches, scope, this_ptr, node, event)
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/// Run the debugger callback unconditionally.
|
/// Run the debugger callback unconditionally.
|
||||||
///
|
///
|
||||||
@ -513,19 +517,19 @@ impl Engine {
|
|||||||
|
|
||||||
match command {
|
match command {
|
||||||
DebuggerCommand::Continue => {
|
DebuggerCommand::Continue => {
|
||||||
global.debugger.status = DebuggerStatus::CONTINUE;
|
global.debugger_mut().status = DebuggerStatus::CONTINUE;
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
DebuggerCommand::Next => {
|
DebuggerCommand::Next => {
|
||||||
global.debugger.status = DebuggerStatus::CONTINUE;
|
global.debugger_mut().status = DebuggerStatus::CONTINUE;
|
||||||
Ok(Some(DebuggerStatus::NEXT))
|
Ok(Some(DebuggerStatus::NEXT))
|
||||||
}
|
}
|
||||||
DebuggerCommand::StepOver => {
|
DebuggerCommand::StepOver => {
|
||||||
global.debugger.status = DebuggerStatus::CONTINUE;
|
global.debugger_mut().status = DebuggerStatus::CONTINUE;
|
||||||
Ok(Some(DebuggerStatus::STEP))
|
Ok(Some(DebuggerStatus::STEP))
|
||||||
}
|
}
|
||||||
DebuggerCommand::StepInto => {
|
DebuggerCommand::StepInto => {
|
||||||
global.debugger.status = DebuggerStatus::STEP;
|
global.debugger_mut().status = DebuggerStatus::STEP;
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
DebuggerCommand::FunctionExit => {
|
DebuggerCommand::FunctionExit => {
|
||||||
@ -539,7 +543,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
_ => global.level,
|
_ => global.level,
|
||||||
};
|
};
|
||||||
global.debugger.status = DebuggerStatus::FunctionExit(level);
|
global.debugger_mut().status = DebuggerStatus::FunctionExit(level);
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,9 +227,10 @@ impl Engine {
|
|||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, expr)?;
|
let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, expr)?;
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
let global = &mut *crate::types::RestoreOnDrop::lock(global, move |g| {
|
let global =
|
||||||
g.debugger.reset_status(reset)
|
&mut *crate::types::RestoreOnDrop::lock_if(reset.is_some(), global, move |g| {
|
||||||
});
|
g.debugger_mut().reset_status(reset)
|
||||||
|
});
|
||||||
|
|
||||||
self.track_operation(global, expr.position())?;
|
self.track_operation(global, expr.position())?;
|
||||||
|
|
||||||
@ -260,9 +261,10 @@ impl Engine {
|
|||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, expr)?;
|
let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, expr)?;
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
let global = &mut *crate::types::RestoreOnDrop::lock(global, move |g| {
|
let global =
|
||||||
g.debugger.reset_status(reset)
|
&mut *crate::types::RestoreOnDrop::lock_if(reset.is_some(), global, move |g| {
|
||||||
});
|
g.debugger_mut().reset_status(reset)
|
||||||
|
});
|
||||||
|
|
||||||
self.track_operation(global, expr.position())?;
|
self.track_operation(global, expr.position())?;
|
||||||
|
|
||||||
|
@ -25,10 +25,11 @@ pub type GlobalConstants =
|
|||||||
pub struct GlobalRuntimeState {
|
pub struct GlobalRuntimeState {
|
||||||
/// Names of imported [modules][crate::Module].
|
/// Names of imported [modules][crate::Module].
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
imports: crate::StaticVec<ImmutableString>,
|
imports: Option<Box<crate::StaticVec<ImmutableString>>>,
|
||||||
/// Stack of imported [modules][crate::Module].
|
/// Stack of imported [modules][crate::Module].
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
modules: crate::StaticVec<crate::SharedModule>,
|
modules: Option<Box<crate::StaticVec<crate::SharedModule>>>,
|
||||||
|
|
||||||
/// The current stack of loaded [modules][crate::Module] containing script-defined functions.
|
/// The current stack of loaded [modules][crate::Module] containing script-defined functions.
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
pub lib: crate::StaticVec<crate::SharedModule>,
|
pub lib: crate::StaticVec<crate::SharedModule>,
|
||||||
@ -74,7 +75,7 @@ pub struct GlobalRuntimeState {
|
|||||||
pub tag: Dynamic,
|
pub tag: Dynamic,
|
||||||
/// Debugging interface.
|
/// Debugging interface.
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
pub debugger: super::Debugger,
|
pub(crate) debugger: Option<super::Debugger>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlobalRuntimeState {
|
impl GlobalRuntimeState {
|
||||||
@ -84,9 +85,9 @@ impl GlobalRuntimeState {
|
|||||||
pub fn new(engine: &Engine) -> Self {
|
pub fn new(engine: &Engine) -> Self {
|
||||||
Self {
|
Self {
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
imports: crate::StaticVec::new_const(),
|
imports: None,
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
modules: crate::StaticVec::new_const(),
|
modules: None,
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
lib: crate::StaticVec::new_const(),
|
lib: crate::StaticVec::new_const(),
|
||||||
source: None,
|
source: None,
|
||||||
@ -110,36 +111,28 @@ impl GlobalRuntimeState {
|
|||||||
tag: engine.default_tag().clone(),
|
tag: engine.default_tag().clone(),
|
||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
debugger: crate::eval::Debugger::new(
|
debugger: engine.debugger.as_ref().map(|(init, ..)| {
|
||||||
if engine.debugger.is_some() {
|
crate::eval::Debugger::new(crate::eval::DebuggerStatus::Init, init(engine))
|
||||||
crate::eval::DebuggerStatus::Init
|
}),
|
||||||
} else {
|
|
||||||
crate::eval::DebuggerStatus::CONTINUE
|
|
||||||
},
|
|
||||||
match engine.debugger {
|
|
||||||
Some((ref init, ..)) => init(engine),
|
|
||||||
None => Dynamic::UNIT,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Get the length of the stack of globally-imported [modules][crate::Module].
|
/// Get the length of the stack of globally-imported [modules][crate::Module].
|
||||||
///
|
///
|
||||||
/// Not available under `no_module`.
|
/// Not available under `no_module`.
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn num_imports(&self) -> usize {
|
pub fn num_imports(&self) -> usize {
|
||||||
self.modules.len()
|
self.modules.as_ref().map_or(0, |m| m.len())
|
||||||
}
|
}
|
||||||
/// Get the globally-imported [module][crate::Module] at a particular index.
|
/// Get the globally-imported [module][crate::Module] at a particular index.
|
||||||
///
|
///
|
||||||
/// Not available under `no_module`.
|
/// Not available under `no_module`.
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_shared_import(&self, index: usize) -> Option<crate::SharedModule> {
|
pub fn get_shared_import(&self, index: usize) -> Option<crate::SharedModule> {
|
||||||
self.modules.get(index).cloned()
|
self.modules.as_ref().and_then(|m| m.get(index).cloned())
|
||||||
}
|
}
|
||||||
/// Get a mutable reference to the globally-imported [module][crate::Module] at a
|
/// Get a mutable reference to the globally-imported [module][crate::Module] at a
|
||||||
/// particular index.
|
/// particular index.
|
||||||
@ -147,13 +140,13 @@ impl GlobalRuntimeState {
|
|||||||
/// Not available under `no_module`.
|
/// Not available under `no_module`.
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub(crate) fn get_shared_import_mut(
|
pub(crate) fn get_shared_import_mut(
|
||||||
&mut self,
|
&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
) -> Option<&mut crate::SharedModule> {
|
) -> Option<&mut crate::SharedModule> {
|
||||||
self.modules.get_mut(index)
|
self.modules.as_mut().and_then(|m| m.get_mut(index))
|
||||||
}
|
}
|
||||||
/// Get the index of a globally-imported [module][crate::Module] by name.
|
/// Get the index of a globally-imported [module][crate::Module] by name.
|
||||||
///
|
///
|
||||||
@ -162,33 +155,44 @@ impl GlobalRuntimeState {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn find_import(&self, name: &str) -> Option<usize> {
|
pub fn find_import(&self, name: &str) -> Option<usize> {
|
||||||
self.imports
|
self.imports.as_ref().and_then(|imports| {
|
||||||
.iter()
|
imports
|
||||||
.rev()
|
.iter()
|
||||||
.position(|key| key.as_str() == name)
|
.rev()
|
||||||
.map(|i| self.imports.len() - 1 - i)
|
.position(|key| key.as_str() == name)
|
||||||
|
.map(|i| imports.len() - 1 - i)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/// Push an imported [module][crate::Module] onto the stack.
|
/// Push an imported [module][crate::Module] onto the stack.
|
||||||
///
|
///
|
||||||
/// Not available under `no_module`.
|
/// Not available under `no_module`.
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn push_import(
|
pub fn push_import(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: impl Into<ImmutableString>,
|
name: impl Into<ImmutableString>,
|
||||||
module: impl Into<crate::SharedModule>,
|
module: impl Into<crate::SharedModule>,
|
||||||
) {
|
) {
|
||||||
self.imports.push(name.into());
|
if self.imports.is_none() {
|
||||||
self.modules.push(module.into());
|
self.imports = Some(crate::StaticVec::new_const().into());
|
||||||
|
self.modules = Some(crate::StaticVec::new_const().into());
|
||||||
|
}
|
||||||
|
self.imports.as_mut().unwrap().push(name.into());
|
||||||
|
self.modules.as_mut().unwrap().push(module.into());
|
||||||
}
|
}
|
||||||
/// Truncate the stack of globally-imported [modules][crate::Module] to a particular length.
|
/// Truncate the stack of globally-imported [modules][crate::Module] to a particular length.
|
||||||
///
|
///
|
||||||
/// Not available under `no_module`.
|
/// Not available under `no_module`.
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn truncate_imports(&mut self, size: usize) {
|
pub fn truncate_imports(&mut self, size: usize) {
|
||||||
self.imports.truncate(size);
|
if size == 0 {
|
||||||
self.modules.truncate(size);
|
self.imports = None;
|
||||||
|
self.modules = None;
|
||||||
|
} else if self.imports.is_some() {
|
||||||
|
self.imports.as_mut().unwrap().truncate(size);
|
||||||
|
self.modules.as_mut().unwrap().truncate(size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/// Get an iterator to the stack of globally-imported [modules][crate::Module] in reverse order.
|
/// Get an iterator to the stack of globally-imported [modules][crate::Module] in reverse order.
|
||||||
///
|
///
|
||||||
@ -198,8 +202,9 @@ impl GlobalRuntimeState {
|
|||||||
pub fn iter_imports(&self) -> impl Iterator<Item = (&str, &crate::Module)> {
|
pub fn iter_imports(&self) -> impl Iterator<Item = (&str, &crate::Module)> {
|
||||||
self.imports
|
self.imports
|
||||||
.iter()
|
.iter()
|
||||||
.zip(self.modules.iter())
|
.flat_map(|x| x.iter())
|
||||||
.rev()
|
.rev()
|
||||||
|
.zip(self.modules.iter().flat_map(|x| x.iter()).rev())
|
||||||
.map(|(name, module)| (name.as_str(), &**module))
|
.map(|(name, module)| (name.as_str(), &**module))
|
||||||
}
|
}
|
||||||
/// Get an iterator to the stack of globally-imported [modules][crate::Module] in reverse order.
|
/// Get an iterator to the stack of globally-imported [modules][crate::Module] in reverse order.
|
||||||
@ -210,7 +215,11 @@ impl GlobalRuntimeState {
|
|||||||
pub(crate) fn iter_imports_raw(
|
pub(crate) fn iter_imports_raw(
|
||||||
&self,
|
&self,
|
||||||
) -> impl Iterator<Item = (&ImmutableString, &crate::SharedModule)> {
|
) -> impl Iterator<Item = (&ImmutableString, &crate::SharedModule)> {
|
||||||
self.imports.iter().zip(self.modules.iter()).rev()
|
self.imports
|
||||||
|
.iter()
|
||||||
|
.flat_map(|x| x.iter())
|
||||||
|
.rev()
|
||||||
|
.zip(self.modules.iter().flat_map(|x| x.iter()).rev())
|
||||||
}
|
}
|
||||||
/// Get an iterator to the stack of globally-imported [modules][crate::Module] in forward order.
|
/// Get an iterator to the stack of globally-imported [modules][crate::Module] in forward order.
|
||||||
///
|
///
|
||||||
@ -220,18 +229,21 @@ impl GlobalRuntimeState {
|
|||||||
pub fn scan_imports_raw(
|
pub fn scan_imports_raw(
|
||||||
&self,
|
&self,
|
||||||
) -> impl Iterator<Item = (&ImmutableString, &crate::SharedModule)> {
|
) -> impl Iterator<Item = (&ImmutableString, &crate::SharedModule)> {
|
||||||
self.imports.iter().zip(self.modules.iter())
|
self.imports
|
||||||
|
.iter()
|
||||||
|
.flat_map(|x| x.iter())
|
||||||
|
.zip(self.modules.iter().flat_map(|x| x.iter()))
|
||||||
}
|
}
|
||||||
/// Can the particular function with [`Dynamic`] parameter(s) exist in the stack of
|
/// Can the particular function with [`Dynamic`] parameter(s) exist in the stack of
|
||||||
/// globally-imported [modules][crate::Module]?
|
/// globally-imported [modules][crate::Module]?
|
||||||
///
|
///
|
||||||
/// Not available under `no_module`.
|
/// Not available under `no_module`.
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub(crate) fn may_contain_dynamic_fn(&self, hash_script: u64) -> bool {
|
pub(crate) fn may_contain_dynamic_fn(&self, hash_script: u64) -> bool {
|
||||||
self.modules
|
self.modules.as_ref().map_or(false, |m| {
|
||||||
.iter()
|
m.iter().any(|m| m.may_contain_dynamic_fn(hash_script))
|
||||||
.any(|m| m.may_contain_dynamic_fn(hash_script))
|
})
|
||||||
}
|
}
|
||||||
/// Does the specified function hash key exist in the stack of globally-imported
|
/// Does the specified function hash key exist in the stack of globally-imported
|
||||||
/// [modules][crate::Module]?
|
/// [modules][crate::Module]?
|
||||||
@ -242,7 +254,9 @@ impl GlobalRuntimeState {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn contains_qualified_fn(&self, hash: u64) -> bool {
|
pub fn contains_qualified_fn(&self, hash: u64) -> bool {
|
||||||
self.modules.iter().any(|m| m.contains_qualified_fn(hash))
|
self.modules
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |m| m.iter().any(|m| m.contains_qualified_fn(hash)))
|
||||||
}
|
}
|
||||||
/// Get the specified function via its hash key from the stack of globally-imported
|
/// Get the specified function via its hash key from the stack of globally-imported
|
||||||
/// [modules][crate::Module].
|
/// [modules][crate::Module].
|
||||||
@ -255,10 +269,11 @@ impl GlobalRuntimeState {
|
|||||||
&self,
|
&self,
|
||||||
hash: u64,
|
hash: u64,
|
||||||
) -> Option<(&crate::func::CallableFunction, Option<&ImmutableString>)> {
|
) -> Option<(&crate::func::CallableFunction, Option<&ImmutableString>)> {
|
||||||
self.modules
|
self.modules.as_ref().and_then(|m| {
|
||||||
.iter()
|
m.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.find_map(|m| m.get_qualified_fn(hash).map(|f| (f, m.id_raw())))
|
.find_map(|m| m.get_qualified_fn(hash).map(|f| (f, m.id_raw())))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
/// Does the specified [`TypeId`][std::any::TypeId] iterator exist in the stack of
|
/// Does the specified [`TypeId`][std::any::TypeId] iterator exist in the stack of
|
||||||
/// globally-imported [modules][crate::Module]?
|
/// globally-imported [modules][crate::Module]?
|
||||||
@ -269,7 +284,9 @@ impl GlobalRuntimeState {
|
|||||||
#[inline]
|
#[inline]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn contains_iter(&self, id: std::any::TypeId) -> bool {
|
pub fn contains_iter(&self, id: std::any::TypeId) -> bool {
|
||||||
self.modules.iter().any(|m| m.contains_qualified_iter(id))
|
self.modules
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |m| m.iter().any(|m| m.contains_qualified_iter(id)))
|
||||||
}
|
}
|
||||||
/// Get the specified [`TypeId`][std::any::TypeId] iterator from the stack of globally-imported
|
/// Get the specified [`TypeId`][std::any::TypeId] iterator from the stack of globally-imported
|
||||||
/// [modules][crate::Module].
|
/// [modules][crate::Module].
|
||||||
@ -280,9 +297,8 @@ impl GlobalRuntimeState {
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn get_iter(&self, id: std::any::TypeId) -> Option<&crate::func::IteratorFn> {
|
pub fn get_iter(&self, id: std::any::TypeId) -> Option<&crate::func::IteratorFn> {
|
||||||
self.modules
|
self.modules
|
||||||
.iter()
|
.as_ref()
|
||||||
.rev()
|
.and_then(|m| m.iter().rev().find_map(|m| m.get_qualified_iter(id)))
|
||||||
.find_map(|m| m.get_qualified_iter(id))
|
|
||||||
}
|
}
|
||||||
/// Get the current source.
|
/// Get the current source.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -311,15 +327,42 @@ impl GlobalRuntimeState {
|
|||||||
pub(crate) fn hash_idx_set(&mut self) -> u64 {
|
pub(crate) fn hash_idx_set(&mut self) -> u64 {
|
||||||
self.fn_hash_indexing.1
|
self.fn_hash_indexing.1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return a reference to the debugging interface.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the debugging interface is not set.
|
||||||
|
#[cfg(feature = "debugging")]
|
||||||
|
pub fn debugger(&self) -> &super::Debugger {
|
||||||
|
self.debugger.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
/// Return a mutable reference to the debugging interface.
|
||||||
|
///
|
||||||
|
/// # Panics
|
||||||
|
///
|
||||||
|
/// Panics if the debugging interface is not set.
|
||||||
|
#[cfg(feature = "debugging")]
|
||||||
|
pub fn debugger_mut(&mut self) -> &mut super::Debugger {
|
||||||
|
self.debugger.as_mut().unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
impl<K: Into<ImmutableString>, M: Into<crate::SharedModule>> Extend<(K, M)> for GlobalRuntimeState {
|
impl<K: Into<ImmutableString>, M: Into<crate::SharedModule>> Extend<(K, M)> for GlobalRuntimeState {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn extend<T: IntoIterator<Item = (K, M)>>(&mut self, iter: T) {
|
fn extend<T: IntoIterator<Item = (K, M)>>(&mut self, iter: T) {
|
||||||
|
if self.imports.is_none() {
|
||||||
|
self.imports = Some(crate::StaticVec::new_const().into());
|
||||||
|
self.modules = Some(crate::StaticVec::new_const().into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let imports = self.imports.as_mut().unwrap();
|
||||||
|
let modules = self.modules.as_mut().unwrap();
|
||||||
|
|
||||||
for (k, m) in iter {
|
for (k, m) in iter {
|
||||||
self.imports.push(k.into());
|
imports.push(k.into());
|
||||||
self.modules.push(m.into());
|
modules.push(m.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,7 +194,9 @@ impl Engine {
|
|||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, stmt)?;
|
let reset = self.run_debugger_with_reset(global, caches, scope, this_ptr, stmt)?;
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
let global = &mut *RestoreOnDrop::lock(global, move |g| g.debugger.reset_status(reset));
|
let global = &mut *RestoreOnDrop::lock_if(reset.is_some(), global, move |g| {
|
||||||
|
g.debugger_mut().reset_status(reset)
|
||||||
|
});
|
||||||
|
|
||||||
// Coded this way for better branch prediction.
|
// Coded this way for better branch prediction.
|
||||||
// Popular branches are lifted out of the `match` statement into their own branches.
|
// Popular branches are lifted out of the `match` statement into their own branches.
|
||||||
|
@ -364,7 +364,10 @@ impl Engine {
|
|||||||
|
|
||||||
// Push a new call stack frame
|
// Push a new call stack frame
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
let orig_call_stack_len = global.debugger.call_stack().len();
|
let orig_call_stack_len = global
|
||||||
|
.debugger
|
||||||
|
.as_ref()
|
||||||
|
.map_or(0, |dbg| dbg.call_stack().len());
|
||||||
|
|
||||||
let backup = &mut ArgBackup::new();
|
let backup = &mut ArgBackup::new();
|
||||||
|
|
||||||
@ -381,10 +384,12 @@ impl Engine {
|
|||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
if self.debugger.is_some() {
|
if self.debugger.is_some() {
|
||||||
global.debugger.push_call_stack_frame(
|
let source = source.clone().or_else(|| global.source.clone());
|
||||||
|
|
||||||
|
global.debugger_mut().push_call_stack_frame(
|
||||||
self.get_interned_string(name),
|
self.get_interned_string(name),
|
||||||
args.iter().map(|v| (*v).clone()).collect(),
|
args.iter().map(|v| (*v).clone()).collect(),
|
||||||
source.clone().or_else(|| global.source.clone()),
|
source,
|
||||||
pos,
|
pos,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -410,10 +415,10 @@ impl Engine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
{
|
if self.debugger.is_some() {
|
||||||
use crate::eval::{DebuggerEvent, DebuggerStatus};
|
use crate::eval::{DebuggerEvent, DebuggerStatus};
|
||||||
|
|
||||||
let trigger = match global.debugger.status {
|
let trigger = match global.debugger().status {
|
||||||
DebuggerStatus::FunctionExit(n) => n >= global.level,
|
DebuggerStatus::FunctionExit(n) => n >= global.level,
|
||||||
DebuggerStatus::Next(.., true) => true,
|
DebuggerStatus::Next(.., true) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
@ -436,7 +441,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pop the call stack
|
// Pop the call stack
|
||||||
global.debugger.rewind_call_stack(orig_call_stack_len);
|
global.debugger_mut().rewind_call_stack(orig_call_stack_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = _result?;
|
let result = _result?;
|
||||||
@ -714,11 +719,15 @@ impl Engine {
|
|||||||
|
|
||||||
// Do not match function exit for arguments
|
// Do not match function exit for arguments
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
let reset = global.debugger.clear_status_if(|status| {
|
let reset = global.debugger.as_mut().and_then(|dbg| {
|
||||||
matches!(status, crate::eval::DebuggerStatus::FunctionExit(..))
|
dbg.clear_status_if(|status| {
|
||||||
|
matches!(status, crate::eval::DebuggerStatus::FunctionExit(..))
|
||||||
|
})
|
||||||
});
|
});
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
let global = &mut *RestoreOnDrop::lock(global, move |g| g.debugger.reset_status(reset));
|
let global = &mut *RestoreOnDrop::lock_if(reset.is_some(), global, move |g| {
|
||||||
|
g.debugger_mut().reset_status(reset)
|
||||||
|
});
|
||||||
|
|
||||||
self.eval_expr(global, caches, scope, this_ptr, arg_expr)
|
self.eval_expr(global, caches, scope, this_ptr, arg_expr)
|
||||||
.map(|r| (r, arg_expr.start_position()))
|
.map(|r| (r, arg_expr.start_position()))
|
||||||
|
@ -83,7 +83,10 @@ impl Engine {
|
|||||||
let orig_imports_len = global.num_imports();
|
let orig_imports_len = global.num_imports();
|
||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
let orig_call_stack_len = global.debugger.call_stack().len();
|
let orig_call_stack_len = global
|
||||||
|
.debugger
|
||||||
|
.as_ref()
|
||||||
|
.map_or(0, |dbg| dbg.call_stack().len());
|
||||||
|
|
||||||
// Put arguments into scope as variables
|
// Put arguments into scope as variables
|
||||||
scope.extend(fn_def.params.iter().cloned().zip(args.iter_mut().map(|v| {
|
scope.extend(fn_def.params.iter().cloned().zip(args.iter_mut().map(|v| {
|
||||||
@ -94,10 +97,12 @@ impl Engine {
|
|||||||
// Push a new call stack frame
|
// Push a new call stack frame
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
if self.debugger.is_some() {
|
if self.debugger.is_some() {
|
||||||
global.debugger.push_call_stack_frame(
|
let source = global.source.clone();
|
||||||
|
|
||||||
|
global.debugger_mut().push_call_stack_frame(
|
||||||
fn_def.name.clone(),
|
fn_def.name.clone(),
|
||||||
scope.iter().skip(orig_scope_len).map(|(.., v)| v).collect(),
|
scope.iter().skip(orig_scope_len).map(|(.., v)| v).collect(),
|
||||||
global.source.clone(),
|
source,
|
||||||
pos,
|
pos,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -126,7 +131,7 @@ impl Engine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
{
|
if self.debugger.is_some() {
|
||||||
let node = crate::ast::Stmt::Noop(fn_def.body.position());
|
let node = crate::ast::Stmt::Noop(fn_def.body.position());
|
||||||
self.run_debugger(global, caches, scope, this_ptr, &node)?;
|
self.run_debugger(global, caches, scope, this_ptr, &node)?;
|
||||||
}
|
}
|
||||||
@ -156,12 +161,13 @@ impl Engine {
|
|||||||
});
|
});
|
||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
{
|
if self.debugger.is_some() {
|
||||||
let trigger = match global.debugger.status {
|
let trigger = match global.debugger_mut().status {
|
||||||
crate::eval::DebuggerStatus::FunctionExit(n) => n >= global.level,
|
crate::eval::DebuggerStatus::FunctionExit(n) => n >= global.level,
|
||||||
crate::eval::DebuggerStatus::Next(.., true) => true,
|
crate::eval::DebuggerStatus::Next(.., true) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if trigger {
|
if trigger {
|
||||||
let node = crate::ast::Stmt::Noop(fn_def.body.end_position().or_else(pos));
|
let node = crate::ast::Stmt::Noop(fn_def.body.end_position().or_else(pos));
|
||||||
let node = (&node).into();
|
let node = (&node).into();
|
||||||
@ -176,7 +182,11 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Pop the call stack
|
// Pop the call stack
|
||||||
global.debugger.rewind_call_stack(orig_call_stack_len);
|
global
|
||||||
|
.debugger
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.rewind_call_stack(orig_call_stack_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove all local variables and imported modules
|
// Remove all local variables and imported modules
|
||||||
|
@ -36,49 +36,55 @@ mod debugging_functions {
|
|||||||
pub fn back_trace(ctx: NativeCallContext) -> Array {
|
pub fn back_trace(ctx: NativeCallContext) -> Array {
|
||||||
use crate::debugger::CallStackFrame;
|
use crate::debugger::CallStackFrame;
|
||||||
|
|
||||||
ctx.global_runtime_state()
|
if let Some(ref debugger) = ctx.global_runtime_state().debugger {
|
||||||
.debugger
|
debugger
|
||||||
.call_stack()
|
.call_stack()
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.filter(|CallStackFrame { fn_name, args, .. }| {
|
.filter(|CallStackFrame { fn_name, args, .. }| {
|
||||||
fn_name.as_str() != "back_trace" || !args.is_empty()
|
fn_name.as_str() != "back_trace" || !args.is_empty()
|
||||||
})
|
})
|
||||||
.map(
|
.map(
|
||||||
|frame @ CallStackFrame {
|
|frame @ CallStackFrame {
|
||||||
fn_name: _fn_name,
|
fn_name: _fn_name,
|
||||||
args: _args,
|
args: _args,
|
||||||
source: _source,
|
source: _source,
|
||||||
pos: _pos,
|
pos: _pos,
|
||||||
}| {
|
}| {
|
||||||
let display = frame.to_string();
|
let display = frame.to_string();
|
||||||
|
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
{
|
{
|
||||||
use crate::INT;
|
use crate::INT;
|
||||||
|
|
||||||
let mut map = Map::new();
|
let mut map = Map::new();
|
||||||
map.insert("display".into(), display.into());
|
map.insert("display".into(), display.into());
|
||||||
map.insert("fn_name".into(), _fn_name.into());
|
map.insert("fn_name".into(), _fn_name.into());
|
||||||
if !_args.is_empty() {
|
if !_args.is_empty() {
|
||||||
map.insert("args".into(), Dynamic::from_array(_args.clone().to_vec()));
|
map.insert(
|
||||||
|
"args".into(),
|
||||||
|
Dynamic::from_array(_args.clone().to_vec()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if let Some(source) = _source {
|
||||||
|
map.insert("source".into(), source.into());
|
||||||
|
}
|
||||||
|
if !_pos.is_none() {
|
||||||
|
map.insert("line".into(), (_pos.line().unwrap() as INT).into());
|
||||||
|
map.insert(
|
||||||
|
"position".into(),
|
||||||
|
(_pos.position().unwrap_or(0) as INT).into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Dynamic::from_map(map)
|
||||||
}
|
}
|
||||||
if let Some(source) = _source {
|
#[cfg(feature = "no_object")]
|
||||||
map.insert("source".into(), source.into());
|
display.into()
|
||||||
}
|
},
|
||||||
if !_pos.is_none() {
|
)
|
||||||
map.insert("line".into(), (_pos.line().unwrap() as INT).into());
|
.collect()
|
||||||
map.insert(
|
} else {
|
||||||
"position".into(),
|
Array::new()
|
||||||
(_pos.position().unwrap_or(0) as INT).into(),
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
Dynamic::from_map(map)
|
|
||||||
}
|
|
||||||
#[cfg(feature = "no_object")]
|
|
||||||
display.into()
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use crate::module::ModuleFlags;
|
use crate::module::ModuleFlags;
|
||||||
use crate::plugin::*;
|
use crate::plugin::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
def_package, Dynamic, ExclusiveRange, ImmutableString, InclusiveRange, RhaiResultOf,
|
def_package, Dynamic, ExclusiveRange, ImmutableString, InclusiveRange, Position, RhaiResultOf,
|
||||||
SmartString, StaticVec, INT, MAX_USIZE_INT, ERR, Position
|
SmartString, StaticVec, ERR, INT, MAX_USIZE_INT,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
@ -1224,11 +1224,9 @@ mod string_functions {
|
|||||||
|
|
||||||
// Check if string will be over max size limit
|
// Check if string will be over max size limit
|
||||||
if _ctx.engine().max_string_size() > 0 && len > _ctx.engine().max_string_size() {
|
if _ctx.engine().max_string_size() > 0 && len > _ctx.engine().max_string_size() {
|
||||||
return Err(ERR::ErrorDataTooLarge(
|
return Err(
|
||||||
"Length of string".to_string(),
|
ERR::ErrorDataTooLarge("Length of string".to_string(), Position::NONE).into(),
|
||||||
Position::NONE,
|
);
|
||||||
)
|
|
||||||
.into());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let orig_len = string.chars().count();
|
let orig_len = string.chars().count();
|
||||||
@ -1242,11 +1240,9 @@ mod string_functions {
|
|||||||
|
|
||||||
if _ctx.engine().max_string_size() > 0 && string.len() > _ctx.engine().max_string_size()
|
if _ctx.engine().max_string_size() > 0 && string.len() > _ctx.engine().max_string_size()
|
||||||
{
|
{
|
||||||
return Err(ERR::ErrorDataTooLarge(
|
return Err(
|
||||||
"Length of string".to_string(),
|
ERR::ErrorDataTooLarge("Length of string".to_string(), Position::NONE).into(),
|
||||||
Position::NONE,
|
);
|
||||||
)
|
|
||||||
.into());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1284,11 +1280,9 @@ mod string_functions {
|
|||||||
|
|
||||||
// Check if string will be over max size limit
|
// Check if string will be over max size limit
|
||||||
if _ctx.engine().max_string_size() > 0 && len > _ctx.engine().max_string_size() {
|
if _ctx.engine().max_string_size() > 0 && len > _ctx.engine().max_string_size() {
|
||||||
return Err(ERR::ErrorDataTooLarge(
|
return Err(
|
||||||
"Length of string".to_string(),
|
ERR::ErrorDataTooLarge("Length of string".to_string(), Position::NONE).into(),
|
||||||
Position::NONE,
|
);
|
||||||
)
|
|
||||||
.into());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut str_len = string.chars().count();
|
let mut str_len = string.chars().count();
|
||||||
@ -1309,11 +1303,9 @@ mod string_functions {
|
|||||||
|
|
||||||
if _ctx.engine().max_string_size() > 0 && string.len() > _ctx.engine().max_string_size()
|
if _ctx.engine().max_string_size() > 0 && string.len() > _ctx.engine().max_string_size()
|
||||||
{
|
{
|
||||||
return Err(ERR::ErrorDataTooLarge(
|
return Err(
|
||||||
"Length of string".to_string(),
|
ERR::ErrorDataTooLarge("Length of string".to_string(), Position::NONE).into(),
|
||||||
Position::NONE,
|
);
|
||||||
)
|
|
||||||
.into());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,13 +59,13 @@ fn test_debugger_state() -> Result<(), Box<EvalAltResult>> {
|
|||||||
// Print debugger state - which is an object map
|
// Print debugger state - which is an object map
|
||||||
println!(
|
println!(
|
||||||
"Current state = {}",
|
"Current state = {}",
|
||||||
context.global_runtime_state_mut().debugger.state()
|
context.global_runtime_state_mut().debugger().state()
|
||||||
);
|
);
|
||||||
|
|
||||||
// Modify state
|
// Modify state
|
||||||
let mut state = context
|
let mut state = context
|
||||||
.global_runtime_state_mut()
|
.global_runtime_state_mut()
|
||||||
.debugger
|
.debugger_mut()
|
||||||
.state_mut()
|
.state_mut()
|
||||||
.write_lock::<Map>()
|
.write_lock::<Map>()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user