core: Allow toggling avm_debug output on and off with ctrl+alt+d, defaults to off
This commit is contained in:
parent
2df3b81f92
commit
7f7281493f
|
@ -47,9 +47,10 @@ pub use timer::Timers;
|
|||
pub use value::Value;
|
||||
|
||||
macro_rules! avm_debug {
|
||||
($($arg:tt)*) => (
|
||||
#[cfg(feature = "avm_debug")]
|
||||
log::debug!($($arg)*)
|
||||
($avm: expr, $($arg:tt)*) => (
|
||||
if $avm.show_debug_output() {
|
||||
log::debug!($($arg)*)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -87,6 +88,9 @@ pub struct Avm1<'gc> {
|
|||
/// The maximum amount of functions that can be called before a `Error::FunctionRecursionLimit`
|
||||
/// is raised. This defaults to 256 but can be changed per movie.
|
||||
max_recursion_depth: u16,
|
||||
|
||||
#[cfg(feature = "avm_debug")]
|
||||
pub debug_output: bool,
|
||||
}
|
||||
|
||||
unsafe impl<'gc> gc_arena::Collect for Avm1<'gc> {
|
||||
|
@ -125,6 +129,9 @@ impl<'gc> Avm1<'gc> {
|
|||
],
|
||||
halted: false,
|
||||
max_recursion_depth: 255,
|
||||
|
||||
#[cfg(feature = "avm_debug")]
|
||||
debug_output: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -346,7 +353,7 @@ impl<'gc> Avm1<'gc> {
|
|||
|
||||
fn push(&mut self, value: impl Into<Value<'gc>>) {
|
||||
let value = value.into();
|
||||
avm_debug!("Stack push {}: {:?}", self.stack.len(), value);
|
||||
avm_debug!(self, "Stack push {}: {:?}", self.stack.len(), value);
|
||||
self.stack.push(value);
|
||||
}
|
||||
|
||||
|
@ -357,7 +364,7 @@ impl<'gc> Avm1<'gc> {
|
|||
Value::Undefined
|
||||
});
|
||||
|
||||
avm_debug!("Stack pop {}: {:?}", self.stack.len(), value);
|
||||
avm_debug!(self, "Stack pop {}: {:?}", self.stack.len(), value);
|
||||
|
||||
value
|
||||
}
|
||||
|
@ -384,6 +391,25 @@ impl<'gc> Avm1<'gc> {
|
|||
pub fn set_max_recursion_depth(&mut self, max_recursion_depth: u16) {
|
||||
self.max_recursion_depth = max_recursion_depth
|
||||
}
|
||||
|
||||
#[cfg(feature = "avm_debug")]
|
||||
#[inline]
|
||||
pub fn show_debug_output(&self) -> bool {
|
||||
self.debug_output
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "avm_debug"))]
|
||||
pub const fn show_debug_output(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(feature = "avm_debug")]
|
||||
pub fn set_show_debug_output(&mut self, visible: bool) {
|
||||
self.debug_output = visible;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "avm_debug"))]
|
||||
pub const fn set_show_debug_output(&self, _visible: bool) {}
|
||||
}
|
||||
|
||||
pub fn root_error_handler<'gc>(
|
||||
|
|
|
@ -24,9 +24,10 @@ use swf::avm1::types::{Action, CatchVar, Function, TryBlock};
|
|||
use url::form_urlencoded;
|
||||
|
||||
macro_rules! avm_debug {
|
||||
($($arg:tt)*) => (
|
||||
#[cfg(feature = "avm_debug")]
|
||||
log::debug!($($arg)*)
|
||||
($avm: expr, $($arg:tt)*) => (
|
||||
if $avm.show_debug_output() {
|
||||
log::debug!($($arg)*)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -227,7 +228,7 @@ pub struct Activation<'a, 'gc: 'a> {
|
|||
|
||||
impl Drop for Activation<'_, '_> {
|
||||
fn drop(&mut self) {
|
||||
avm_debug!("END {}", self.id);
|
||||
avm_debug!(self.avm, "END {}", self.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,7 +244,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
this: Object<'gc>,
|
||||
arguments: Option<Object<'gc>>,
|
||||
) -> Self {
|
||||
avm_debug!("START {}", id);
|
||||
avm_debug!(avm, "START {}", id);
|
||||
Self {
|
||||
avm,
|
||||
id,
|
||||
|
@ -265,7 +266,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
scope: GcCell<'gc, Scope<'gc>>,
|
||||
) -> Activation<'b, 'gc> {
|
||||
let id = self.id.child(name);
|
||||
avm_debug!("START {}", id);
|
||||
avm_debug!(self.avm, "START {}", id);
|
||||
Activation {
|
||||
avm: self.avm,
|
||||
id,
|
||||
|
@ -295,7 +296,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
let global_scope = GcCell::allocate(mc, Scope::from_global_object(globals));
|
||||
let child_scope = GcCell::allocate(mc, Scope::new_local_scope(global_scope, mc));
|
||||
let empty_constant_pool = GcCell::allocate(mc, Vec::new());
|
||||
avm_debug!("START {}", id);
|
||||
avm_debug!(avm, "START {}", id);
|
||||
|
||||
Self {
|
||||
avm,
|
||||
|
@ -419,7 +420,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
//Executing beyond the end of a function constitutes an implicit return.
|
||||
Ok(FrameControl::Return(ReturnType::Implicit))
|
||||
} else if let Some(action) = reader.read_action()? {
|
||||
avm_debug!("({}) Action: {:?}", self.id.depth(), action);
|
||||
avm_debug!(self.avm, "({}) Action: {:?}", self.id.depth(), action);
|
||||
|
||||
match action {
|
||||
Action::Add => self.action_add(context),
|
||||
|
@ -2368,6 +2369,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
) -> Result<FrameControl<'gc>, Error<'gc>> {
|
||||
let value = self.avm.pop();
|
||||
avm_debug!(
|
||||
self.avm,
|
||||
"Thrown exception: {}",
|
||||
value
|
||||
.coerce_to_string(self, context)
|
||||
|
|
|
@ -282,7 +282,7 @@ impl<'gc> Executable<'gc> {
|
|||
.unwrap_or(ac.player_version)
|
||||
};
|
||||
|
||||
let name = if cfg!(feature = "avm_debug") {
|
||||
let name = if activation.avm.show_debug_output() {
|
||||
let mut result = match &af.name {
|
||||
None => name.to_string(),
|
||||
Some(name) => name.to_string(),
|
||||
|
|
|
@ -15,9 +15,10 @@ use swf::avm2::read::Reader;
|
|||
|
||||
#[macro_export]
|
||||
macro_rules! avm_debug {
|
||||
($($arg:tt)*) => (
|
||||
#[cfg(feature = "avm_debug")]
|
||||
log::debug!($($arg)*)
|
||||
($avm: expr, $($arg:tt)*) => (
|
||||
if $avm.show_debug_output() {
|
||||
log::debug!($($arg)*)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -57,6 +58,9 @@ pub struct Avm2<'gc> {
|
|||
|
||||
/// System prototypes.
|
||||
system_prototypes: SystemPrototypes<'gc>,
|
||||
|
||||
#[cfg(feature = "avm_debug")]
|
||||
pub debug_output: bool,
|
||||
}
|
||||
|
||||
impl<'gc> Avm2<'gc> {
|
||||
|
@ -68,6 +72,9 @@ impl<'gc> Avm2<'gc> {
|
|||
stack: Vec::new(),
|
||||
globals,
|
||||
system_prototypes,
|
||||
|
||||
#[cfg(feature = "avm_debug")]
|
||||
debug_output: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,7 +142,7 @@ impl<'gc> Avm2<'gc> {
|
|||
/// Push a value onto the operand stack.
|
||||
fn push(&mut self, value: impl Into<Value<'gc>>) {
|
||||
let value = value.into();
|
||||
avm_debug!("Stack push {}: {:?}", self.stack.len(), value);
|
||||
avm_debug!(self, "Stack push {}: {:?}", self.stack.len(), value);
|
||||
self.stack.push(value);
|
||||
}
|
||||
|
||||
|
@ -147,7 +154,7 @@ impl<'gc> Avm2<'gc> {
|
|||
Value::Undefined
|
||||
});
|
||||
|
||||
avm_debug!("Stack pop {}: {:?}", self.stack.len(), value);
|
||||
avm_debug!(self, "Stack pop {}: {:?}", self.stack.len(), value);
|
||||
|
||||
value
|
||||
}
|
||||
|
@ -161,4 +168,23 @@ impl<'gc> Avm2<'gc> {
|
|||
|
||||
args
|
||||
}
|
||||
|
||||
#[cfg(feature = "avm_debug")]
|
||||
#[inline]
|
||||
pub fn show_debug_output(&self) -> bool {
|
||||
self.debug_output
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "avm_debug"))]
|
||||
pub const fn show_debug_output(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[cfg(feature = "avm_debug")]
|
||||
pub fn set_show_debug_output(&mut self, visible: bool) {
|
||||
self.debug_output = visible;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "avm_debug"))]
|
||||
pub const fn set_show_debug_output(&self, _visible: bool) {}
|
||||
}
|
||||
|
|
|
@ -415,7 +415,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
) -> Result<FrameControl<'gc>, Error> {
|
||||
let op = reader.read_op();
|
||||
if let Ok(Some(op)) = op {
|
||||
avm_debug!("Opcode: {:?}", op);
|
||||
avm_debug!(self.avm2, "Opcode: {:?}", op);
|
||||
|
||||
let result = match op {
|
||||
Op::PushByte { value } => self.op_push_byte(value),
|
||||
|
@ -1093,7 +1093,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
index: Index<AbcMultiname>,
|
||||
) -> Result<FrameControl<'gc>, Error> {
|
||||
let multiname = self.pool_multiname(method, index, context.gc_context)?;
|
||||
avm_debug!("Resolving {:?}", multiname);
|
||||
avm_debug!(self.avm2, "Resolving {:?}", multiname);
|
||||
let result = if let Some(scope) = self.scope() {
|
||||
scope.read().find(&multiname, self, context)?
|
||||
} else {
|
||||
|
@ -1113,7 +1113,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
index: Index<AbcMultiname>,
|
||||
) -> Result<FrameControl<'gc>, Error> {
|
||||
let multiname = self.pool_multiname(method, index, context.gc_context)?;
|
||||
avm_debug!("Resolving {:?}", multiname);
|
||||
avm_debug!(self.avm2, "Resolving {:?}", multiname);
|
||||
let found: Result<Object<'gc>, Error> = if let Some(scope) = self.scope() {
|
||||
scope.read().find(&multiname, self, context)?
|
||||
} else {
|
||||
|
@ -1134,7 +1134,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
index: Index<AbcMultiname>,
|
||||
) -> Result<FrameControl<'gc>, Error> {
|
||||
let multiname = self.pool_multiname_static(method, index, context.gc_context)?;
|
||||
avm_debug!("Resolving {:?}", multiname);
|
||||
avm_debug!(self.avm2, "Resolving {:?}", multiname);
|
||||
let found: Result<Value<'gc>, Error> = if let Some(scope) = self.scope() {
|
||||
scope
|
||||
.write(context.gc_context)
|
||||
|
@ -1607,9 +1607,9 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
let register_name = self.pool_string(method, register_name)?;
|
||||
let value = self.local_register(register as u32)?;
|
||||
|
||||
avm_debug!("Debug: {} = {:?}", register_name, value);
|
||||
avm_debug!(self.avm2, "Debug: {} = {:?}", register_name, value);
|
||||
} else {
|
||||
avm_debug!("Unknown debugging mode!");
|
||||
avm_debug!(self.avm2, "Unknown debugging mode!");
|
||||
}
|
||||
|
||||
Ok(FrameControl::Continue)
|
||||
|
@ -1636,7 +1636,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
) -> Result<FrameControl<'gc>, Error> {
|
||||
let file_name = self.pool_string(method, file_name)?;
|
||||
|
||||
avm_debug!("File: {}", file_name);
|
||||
avm_debug!(self.avm2, "File: {}", file_name);
|
||||
|
||||
Ok(FrameControl::Continue)
|
||||
}
|
||||
|
@ -1653,7 +1653,7 @@ impl<'a, 'gc: 'a> Activation<'a, 'gc> {
|
|||
|
||||
#[allow(unused_variables)]
|
||||
fn op_debug_line(&mut self, line_num: u32) -> Result<FrameControl<'gc>, Error> {
|
||||
avm_debug!("Line: {}", line_num);
|
||||
avm_debug!(self.avm2, "Line: {}", line_num);
|
||||
|
||||
Ok(FrameControl::Continue)
|
||||
}
|
||||
|
|
|
@ -431,6 +431,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
|
|||
let fn_proto = activation.avm2().prototypes().function;
|
||||
let trait_name = trait_entry.name().clone();
|
||||
avm_debug!(
|
||||
activation.avm2(),
|
||||
"Installing trait {:?} of kind {:?}",
|
||||
trait_name,
|
||||
trait_entry.kind()
|
||||
|
|
|
@ -451,6 +451,32 @@ impl Player {
|
|||
}
|
||||
}
|
||||
|
||||
if cfg!(feature = "avm_debug") {
|
||||
if let PlayerEvent::KeyDown {
|
||||
key_code: KeyCode::D,
|
||||
} = event
|
||||
{
|
||||
if self.input.is_key_down(KeyCode::Control) && self.input.is_key_down(KeyCode::Alt)
|
||||
{
|
||||
self.mutate_with_update_context(|avm1, avm2, _context| {
|
||||
if avm1.show_debug_output() {
|
||||
log::info!(
|
||||
"AVM Debugging turned off! Press CTRL+ALT+D to turn off again."
|
||||
);
|
||||
avm1.set_show_debug_output(false);
|
||||
avm2.set_show_debug_output(false);
|
||||
} else {
|
||||
log::info!(
|
||||
"AVM Debugging turned on! Press CTRL+ALT+D to turn on again."
|
||||
);
|
||||
avm1.set_show_debug_output(true);
|
||||
avm2.set_show_debug_output(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update mouse position from mouse events.
|
||||
if let PlayerEvent::MouseMove { x, y }
|
||||
| PlayerEvent::MouseDown { x, y }
|
||||
|
|
Loading…
Reference in New Issue