avm2: Use `Gc` instead of `GcCell` in `StageObject`

This commit is contained in:
Lord-McSweeney 2024-07-04 13:11:53 +03:00 committed by Lord-McSweeney
parent 3d80fc16c4
commit ee4c08cc31
2 changed files with 21 additions and 27 deletions

View File

@ -1381,7 +1381,7 @@ impl<'gc> Object<'gc> {
Self::PrimitiveObject(o) => WeakObject::PrimitiveObject(PrimitiveObjectWeak(GcCell::downgrade(o.0))), Self::PrimitiveObject(o) => WeakObject::PrimitiveObject(PrimitiveObjectWeak(GcCell::downgrade(o.0))),
Self::NamespaceObject(o) => WeakObject::NamespaceObject(NamespaceObjectWeak(GcCell::downgrade(o.0))), Self::NamespaceObject(o) => WeakObject::NamespaceObject(NamespaceObjectWeak(GcCell::downgrade(o.0))),
Self::ArrayObject(o) => WeakObject::ArrayObject(ArrayObjectWeak(GcCell::downgrade(o.0))), Self::ArrayObject(o) => WeakObject::ArrayObject(ArrayObjectWeak(GcCell::downgrade(o.0))),
Self::StageObject(o) => WeakObject::StageObject(StageObjectWeak(GcCell::downgrade(o.0))), Self::StageObject(o) => WeakObject::StageObject(StageObjectWeak(Gc::downgrade(o.0))),
Self::DomainObject(o) => WeakObject::DomainObject(DomainObjectWeak(Gc::downgrade(o.0))), Self::DomainObject(o) => WeakObject::DomainObject(DomainObjectWeak(Gc::downgrade(o.0))),
Self::EventObject(o) => WeakObject::EventObject(EventObjectWeak(GcCell::downgrade(o.0))), Self::EventObject(o) => WeakObject::EventObject(EventObjectWeak(GcCell::downgrade(o.0))),
Self::DispatchObject(o) => WeakObject::DispatchObject(DispatchObjectWeak(GcCell::downgrade(o.0))), Self::DispatchObject(o) => WeakObject::DispatchObject(DispatchObjectWeak(GcCell::downgrade(o.0))),

View File

@ -6,23 +6,24 @@ use crate::avm2::object::{ClassObject, Object, ObjectPtr, TObject};
use crate::avm2::value::Value; use crate::avm2::value::Value;
use crate::avm2::Error; use crate::avm2::Error;
use crate::display_object::DisplayObject; use crate::display_object::DisplayObject;
use gc_arena::{Collect, GcCell, GcWeakCell, Mutation}; use gc_arena::barrier::unlock;
use gc_arena::{lock::RefLock, Collect, Gc, GcWeak, Mutation};
use std::cell::{Ref, RefMut}; use std::cell::{Ref, RefMut};
use std::fmt::Debug; use std::fmt::Debug;
#[derive(Clone, Collect, Copy)] #[derive(Clone, Collect, Copy)]
#[collect(no_drop)] #[collect(no_drop)]
pub struct StageObject<'gc>(pub GcCell<'gc, StageObjectData<'gc>>); pub struct StageObject<'gc>(pub Gc<'gc, StageObjectData<'gc>>);
#[derive(Clone, Collect, Copy, Debug)] #[derive(Clone, Collect, Copy, Debug)]
#[collect(no_drop)] #[collect(no_drop)]
pub struct StageObjectWeak<'gc>(pub GcWeakCell<'gc, StageObjectData<'gc>>); pub struct StageObjectWeak<'gc>(pub GcWeak<'gc, StageObjectData<'gc>>);
#[derive(Clone, Collect)] #[derive(Clone, Collect)]
#[collect(no_drop)] #[collect(no_drop)]
pub struct StageObjectData<'gc> { pub struct StageObjectData<'gc> {
/// The base data common to all AVM2 objects. /// The base data common to all AVM2 objects.
base: ScriptObjectData<'gc>, base: RefLock<ScriptObjectData<'gc>>,
/// The associated display object, if one exists. /// The associated display object, if one exists.
display_object: Option<DisplayObject<'gc>>, display_object: Option<DisplayObject<'gc>>,
@ -44,10 +45,10 @@ impl<'gc> StageObject<'gc> {
display_object: DisplayObject<'gc>, display_object: DisplayObject<'gc>,
class: ClassObject<'gc>, class: ClassObject<'gc>,
) -> Result<Self, Error<'gc>> { ) -> Result<Self, Error<'gc>> {
let instance = Self(GcCell::new( let instance = Self(Gc::new(
activation.context.gc_context, activation.context.gc_context,
StageObjectData { StageObjectData {
base: ScriptObjectData::new(class), base: ScriptObjectData::new(class).into(),
display_object: Some(display_object), display_object: Some(display_object),
}, },
)); ));
@ -94,10 +95,10 @@ impl<'gc> StageObject<'gc> {
display_object: DisplayObject<'gc>, display_object: DisplayObject<'gc>,
) -> Result<Self, Error<'gc>> { ) -> Result<Self, Error<'gc>> {
let class = activation.avm2().classes().graphics; let class = activation.avm2().classes().graphics;
let this = Self(GcCell::new( let this = Self(Gc::new(
activation.context.gc_context, activation.context.gc_context,
StageObjectData { StageObjectData {
base: ScriptObjectData::new(class), base: ScriptObjectData::new(class).into(),
display_object: Some(display_object), display_object: Some(display_object),
}, },
)); ));
@ -111,19 +112,19 @@ impl<'gc> StageObject<'gc> {
impl<'gc> TObject<'gc> for StageObject<'gc> { impl<'gc> TObject<'gc> for StageObject<'gc> {
fn base(&self) -> Ref<ScriptObjectData<'gc>> { fn base(&self) -> Ref<ScriptObjectData<'gc>> {
Ref::map(self.0.read(), |read| &read.base) self.0.base.borrow()
} }
fn base_mut(&self, mc: &Mutation<'gc>) -> RefMut<ScriptObjectData<'gc>> { fn base_mut(&self, mc: &Mutation<'gc>) -> RefMut<ScriptObjectData<'gc>> {
RefMut::map(self.0.write(mc), |write| &mut write.base) unlock!(Gc::write(mc, self.0), StageObjectData, base).borrow_mut()
} }
fn as_ptr(&self) -> *const ObjectPtr { fn as_ptr(&self) -> *const ObjectPtr {
self.0.as_ptr() as *const ObjectPtr Gc::as_ptr(self.0) as *const ObjectPtr
} }
fn as_display_object(&self) -> Option<DisplayObject<'gc>> { fn as_display_object(&self) -> Option<DisplayObject<'gc>> {
self.0.read().display_object self.0.display_object
} }
fn value_of(&self, _mc: &Mutation<'gc>) -> Result<Value<'gc>, Error<'gc>> { fn value_of(&self, _mc: &Mutation<'gc>) -> Result<Value<'gc>, Error<'gc>> {
@ -133,19 +134,12 @@ impl<'gc> TObject<'gc> for StageObject<'gc> {
impl<'gc> Debug for StageObject<'gc> { impl<'gc> Debug for StageObject<'gc> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match self.0.try_read() { let base = self.0.base.borrow();
Ok(obj) => f
.debug_struct("StageObject") f.debug_struct("StageObject")
.field("name", &obj.base.debug_class_name()) .field("name", &base.debug_class_name())
// .field("display_object", &obj.display_object) TODO(moulins) // .field("display_object", &self.0.display_object) TODO(moulins)
.field("ptr", &self.0.as_ptr()) .field("ptr", &Gc::as_ptr(self.0))
.finish(), .finish()
Err(err) => f
.debug_struct("StageObject")
.field("name", &err)
.field("display_object", &err)
.field("ptr", &self.0.as_ptr())
.finish(),
}
} }
} }