avm2: Improve `Debug` impl for `StageObject`

This builds off of the previous work for `ScriptObject` and
`ClassObject`. We now print both the class name and the stored
`DisplayObject`.
This commit is contained in:
Aaron Hill 2022-08-11 18:32:17 -05:00
parent d6532c87c2
commit a99c7e381b
2 changed files with 44 additions and 23 deletions

View File

@ -189,7 +189,12 @@ impl<'gc> ScriptObjectData<'gc> {
.map(|cls| cls.inner_class_definition().read().is_sealed())
.unwrap_or(false)
{
Err(format!("Cannot get undefined property {:?}", local_name).into())
Err(format!(
"Cannot get undefined property {:?} on class {:?}",
local_name,
self.instance_of()
)
.into())
} else {
Ok(Value::Undefined)
}
@ -449,32 +454,28 @@ impl<'gc> ScriptObjectData<'gc> {
pub fn set_vtable(&mut self, vtable: VTable<'gc>) {
self.vtable = Some(vtable);
}
pub fn debug_class_name(&self) -> Box<dyn std::fmt::Debug + 'gc> {
let class_name = self
.instance_of()
.map(|class_obj| class_obj.debug_class_name());
match class_name {
Some(class_name) => Box::new(class_name),
None => Box::new("<None>"),
}
}
}
impl<'gc> Debug for ScriptObject<'gc> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
let mut fmt = f.debug_struct("ScriptObject");
let mut f = f.debug_struct("ScriptObject");
let class_name = self
.0
.try_read()
.map(|obj| obj.instance_of())
.transpose()
.map(|class_obj| class_obj.map(|c| c.debug_class_name()));
match self.0.try_read() {
Ok(obj) => f.field("name", &obj.debug_class_name()),
Err(err) => f.field("name", &err),
};
match class_name {
Some(Ok(class_name)) => {
fmt.field("class", &class_name);
}
Some(Err(err)) => {
fmt.field("class", &err);
}
None => {
fmt.field("class", &"<None>");
}
}
fmt.field("ptr", &self.0.as_ptr());
fmt.finish()
f.field("ptr", &self.0.as_ptr()).finish()
}
}

View File

@ -8,6 +8,7 @@ use crate::avm2::Error;
use crate::display_object::DisplayObject;
use gc_arena::{Collect, GcCell, MutationContext};
use std::cell::{Ref, RefMut};
use std::fmt::Debug;
/// A class instance allocator that allocates Stage objects.
pub fn stage_allocator<'gc>(
@ -26,7 +27,7 @@ pub fn stage_allocator<'gc>(
.into())
}
#[derive(Clone, Collect, Debug, Copy)]
#[derive(Clone, Collect, Copy)]
#[collect(no_drop)]
pub struct StageObject<'gc>(GcCell<'gc, StageObjectData<'gc>>);
@ -131,3 +132,22 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
Ok(Value::Object(Object::from(*self)))
}
}
impl<'gc> Debug for StageObject<'gc> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self.0.try_read() {
Ok(obj) => f
.debug_struct("StageObject")
.field("name", &obj.base.debug_class_name())
.field("display_object", &obj.display_object)
.field("ptr", &self.0.as_ptr())
.finish(),
Err(err) => f
.debug_struct("StageObject")
.field("name", &err)
.field("display_object", &err)
.field("ptr", &self.0.as_ptr())
.finish(),
}
}
}