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

This commit is contained in:
Lord-McSweeney 2024-07-03 14:55:45 +03:00 committed by Lord-McSweeney
parent fb168f46b3
commit 86b8f3fe61
2 changed files with 25 additions and 22 deletions

View File

@ -1409,7 +1409,7 @@ impl<'gc> Object<'gc> {
Self::Program3DObject(o) => WeakObject::Program3DObject(Program3DObjectWeak(Gc::downgrade(o.0))), Self::Program3DObject(o) => WeakObject::Program3DObject(Program3DObjectWeak(Gc::downgrade(o.0))),
Self::NetStreamObject(o) => WeakObject::NetStreamObject(NetStreamObjectWeak(Gc::downgrade(o.0))), Self::NetStreamObject(o) => WeakObject::NetStreamObject(NetStreamObjectWeak(Gc::downgrade(o.0))),
Self::NetConnectionObject(o) => WeakObject::NetConnectionObject(NetConnectionObjectWeak(Gc::downgrade(o.0))), Self::NetConnectionObject(o) => WeakObject::NetConnectionObject(NetConnectionObjectWeak(Gc::downgrade(o.0))),
Self::ResponderObject(o) => WeakObject::ResponderObject(ResponderObjectWeak(GcCell::downgrade(o.0))), Self::ResponderObject(o) => WeakObject::ResponderObject(ResponderObjectWeak(Gc::downgrade(o.0))),
Self::ShaderDataObject(o) => WeakObject::ShaderDataObject(ShaderDataObjectWeak(Gc::downgrade(o.0))), Self::ShaderDataObject(o) => WeakObject::ShaderDataObject(ShaderDataObjectWeak(Gc::downgrade(o.0))),
Self::SocketObject(o) => WeakObject::SocketObject(SocketObjectWeak(Gc::downgrade(o.0))), Self::SocketObject(o) => WeakObject::SocketObject(SocketObjectWeak(Gc::downgrade(o.0))),
Self::FileReferenceObject(o) => WeakObject::FileReferenceObject(FileReferenceObjectWeak(Gc::downgrade(o.0))), Self::FileReferenceObject(o) => WeakObject::FileReferenceObject(FileReferenceObjectWeak(Gc::downgrade(o.0))),

View File

@ -5,8 +5,11 @@ use crate::avm2::{Activation, Error};
use crate::context::UpdateContext; use crate::context::UpdateContext;
use crate::net_connection::ResponderCallback; use crate::net_connection::ResponderCallback;
use flash_lso::types::Value as AMFValue; use flash_lso::types::Value as AMFValue;
use gc_arena::Mutation; use gc_arena::barrier::unlock;
use gc_arena::{Collect, GcCell, GcWeakCell}; use gc_arena::{
lock::{Lock, RefLock},
Collect, Gc, GcWeak, Mutation,
};
use std::cell::{Ref, RefMut}; use std::cell::{Ref, RefMut};
use std::fmt; use std::fmt;
@ -15,14 +18,14 @@ pub fn responder_allocator<'gc>(
class: ClassObject<'gc>, class: ClassObject<'gc>,
activation: &mut Activation<'_, 'gc>, activation: &mut Activation<'_, 'gc>,
) -> Result<Object<'gc>, Error<'gc>> { ) -> Result<Object<'gc>, Error<'gc>> {
let base = ScriptObjectData::new(class); let base = ScriptObjectData::new(class).into();
Ok(ResponderObject(GcCell::new( Ok(ResponderObject(Gc::new(
activation.context.gc(), activation.context.gc(),
ResponderObjectData { ResponderObjectData {
base, base,
result: Default::default(), result: Lock::new(None),
status: Default::default(), status: Lock::new(None),
}, },
)) ))
.into()) .into())
@ -30,23 +33,23 @@ pub fn responder_allocator<'gc>(
#[derive(Clone, Collect, Copy)] #[derive(Clone, Collect, Copy)]
#[collect(no_drop)] #[collect(no_drop)]
pub struct ResponderObject<'gc>(pub GcCell<'gc, ResponderObjectData<'gc>>); pub struct ResponderObject<'gc>(pub Gc<'gc, ResponderObjectData<'gc>>);
#[derive(Clone, Collect, Copy, Debug)] #[derive(Clone, Collect, Copy, Debug)]
#[collect(no_drop)] #[collect(no_drop)]
pub struct ResponderObjectWeak<'gc>(pub GcWeakCell<'gc, ResponderObjectData<'gc>>); pub struct ResponderObjectWeak<'gc>(pub GcWeak<'gc, ResponderObjectData<'gc>>);
impl<'gc> TObject<'gc> for ResponderObject<'gc> { impl<'gc> TObject<'gc> for ResponderObject<'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), ResponderObjectData, 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 value_of(&self, _mc: &Mutation<'gc>) -> Result<Value<'gc>, Error<'gc>> { fn value_of(&self, _mc: &Mutation<'gc>) -> Result<Value<'gc>, Error<'gc>> {
@ -60,21 +63,21 @@ impl<'gc> TObject<'gc> for ResponderObject<'gc> {
impl<'gc> ResponderObject<'gc> { impl<'gc> ResponderObject<'gc> {
pub fn result(&self) -> Option<FunctionObject<'gc>> { pub fn result(&self) -> Option<FunctionObject<'gc>> {
self.0.read().result self.0.result.get()
} }
pub fn status(&self) -> Option<FunctionObject<'gc>> { pub fn status(&self) -> Option<FunctionObject<'gc>> {
self.0.read().status self.0.status.get()
} }
pub fn set_callbacks( pub fn set_callbacks(
&self, &self,
gc_context: &Mutation<'gc>, mc: &Mutation<'gc>,
result: Option<FunctionObject<'gc>>, result: Option<FunctionObject<'gc>>,
status: Option<FunctionObject<'gc>>, status: Option<FunctionObject<'gc>>,
) { ) {
self.0.write(gc_context).result = result; unlock!(Gc::write(mc, self.0), ResponderObjectData, result).set(result);
self.0.write(gc_context).status = status; unlock!(Gc::write(mc, self.0), ResponderObjectData, status).set(status);
} }
pub fn send_callback( pub fn send_callback(
@ -84,8 +87,8 @@ impl<'gc> ResponderObject<'gc> {
message: &AMFValue, message: &AMFValue,
) -> Result<(), Error<'gc>> { ) -> Result<(), Error<'gc>> {
let function = match callback { let function = match callback {
ResponderCallback::Result => self.0.read().result, ResponderCallback::Result => self.0.result.get(),
ResponderCallback::Status => self.0.read().status, ResponderCallback::Status => self.0.status.get(),
}; };
if let Some(function) = function { if let Some(function) = function {
@ -102,13 +105,13 @@ impl<'gc> ResponderObject<'gc> {
#[collect(no_drop)] #[collect(no_drop)]
pub struct ResponderObjectData<'gc> { pub struct ResponderObjectData<'gc> {
/// Base script object /// Base script object
base: ScriptObjectData<'gc>, base: RefLock<ScriptObjectData<'gc>>,
/// Method to call with any result /// Method to call with any result
result: Option<FunctionObject<'gc>>, result: Lock<Option<FunctionObject<'gc>>>,
/// Method to call with status info (likely errors) /// Method to call with status info (likely errors)
status: Option<FunctionObject<'gc>>, status: Lock<Option<FunctionObject<'gc>>>,
} }
impl fmt::Debug for ResponderObject<'_> { impl fmt::Debug for ResponderObject<'_> {