avm2: Use `Gc` instead of `GcCell` in `QNameObject` and `ErrorObject`
This commit is contained in:
parent
bc5328892a
commit
3d80fc16c4
|
@ -1397,10 +1397,10 @@ impl<'gc> Object<'gc> {
|
|||
Self::BitmapDataObject(o) => WeakObject::BitmapDataObject(BitmapDataObjectWeak(Gc::downgrade(o.0))),
|
||||
Self::DateObject(o) => WeakObject::DateObject(DateObjectWeak(Gc::downgrade(o.0))),
|
||||
Self::DictionaryObject(o) => WeakObject::DictionaryObject(DictionaryObjectWeak(Gc::downgrade(o.0))),
|
||||
Self::QNameObject(o) => WeakObject::QNameObject(QNameObjectWeak(GcCell::downgrade(o.0))),
|
||||
Self::QNameObject(o) => WeakObject::QNameObject(QNameObjectWeak(Gc::downgrade(o.0))),
|
||||
Self::TextFormatObject(o) => WeakObject::TextFormatObject(TextFormatObjectWeak(Gc::downgrade(o.0))),
|
||||
Self::ProxyObject(o) => WeakObject::ProxyObject(ProxyObjectWeak(Gc::downgrade(o.0))),
|
||||
Self::ErrorObject(o) => WeakObject::ErrorObject(ErrorObjectWeak(GcCell::downgrade(o.0))),
|
||||
Self::ErrorObject(o) => WeakObject::ErrorObject(ErrorObjectWeak(Gc::downgrade(o.0))),
|
||||
Self::Stage3DObject(o) => WeakObject::Stage3DObject(Stage3DObjectWeak(Gc::downgrade(o.0))),
|
||||
Self::Context3DObject(o) => WeakObject::Context3DObject(Context3DObjectWeak(Gc::downgrade(o.0))),
|
||||
Self::IndexBuffer3DObject(o) => WeakObject::IndexBuffer3DObject(IndexBuffer3DObjectWeak(Gc::downgrade(o.0))),
|
||||
|
|
|
@ -8,7 +8,8 @@ use crate::avm2::value::Value;
|
|||
use crate::avm2::Error;
|
||||
use crate::string::WString;
|
||||
use core::fmt;
|
||||
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::fmt::Debug;
|
||||
use tracing::{enabled, Level};
|
||||
|
@ -18,15 +19,17 @@ pub fn error_allocator<'gc>(
|
|||
class: ClassObject<'gc>,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
) -> Result<Object<'gc>, Error<'gc>> {
|
||||
let base = ScriptObjectData::new(class);
|
||||
let base = ScriptObjectData::new(class).into();
|
||||
|
||||
Ok(ErrorObject(GcCell::new(
|
||||
let call_stack = (enabled!(Level::INFO) || cfg!(feature = "avm_debug"))
|
||||
.then(|| activation.avm2().call_stack().read().clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
Ok(ErrorObject(Gc::new(
|
||||
activation.context.gc_context,
|
||||
ErrorObjectData {
|
||||
base,
|
||||
call_stack: (enabled!(Level::INFO) || cfg!(feature = "avm_debug"))
|
||||
.then(|| activation.avm2().call_stack().read().clone())
|
||||
.unwrap_or_default(),
|
||||
call_stack: RefLock::new(call_stack),
|
||||
},
|
||||
))
|
||||
.into())
|
||||
|
@ -34,17 +37,17 @@ pub fn error_allocator<'gc>(
|
|||
|
||||
#[derive(Clone, Collect, Copy)]
|
||||
#[collect(no_drop)]
|
||||
pub struct ErrorObject<'gc>(pub GcCell<'gc, ErrorObjectData<'gc>>);
|
||||
pub struct ErrorObject<'gc>(pub Gc<'gc, ErrorObjectData<'gc>>);
|
||||
|
||||
#[derive(Clone, Collect, Copy, Debug)]
|
||||
#[collect(no_drop)]
|
||||
pub struct ErrorObjectWeak<'gc>(pub GcWeakCell<'gc, ErrorObjectData<'gc>>);
|
||||
pub struct ErrorObjectWeak<'gc>(pub GcWeak<'gc, ErrorObjectData<'gc>>);
|
||||
|
||||
impl fmt::Debug for ErrorObject<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("ErrorObject")
|
||||
.field("class", &self.debug_class_name())
|
||||
.field("ptr", &self.0.as_ptr())
|
||||
.field("ptr", &Gc::as_ptr(self.0))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
@ -53,9 +56,9 @@ impl fmt::Debug for ErrorObject<'_> {
|
|||
#[collect(no_drop)]
|
||||
pub struct ErrorObjectData<'gc> {
|
||||
/// Base script object
|
||||
base: ScriptObjectData<'gc>,
|
||||
base: RefLock<ScriptObjectData<'gc>>,
|
||||
|
||||
call_stack: CallStack<'gc>,
|
||||
call_stack: RefLock<CallStack<'gc>>,
|
||||
}
|
||||
|
||||
impl<'gc> ErrorObject<'gc> {
|
||||
|
@ -105,28 +108,29 @@ impl<'gc> ErrorObject<'gc> {
|
|||
}
|
||||
|
||||
pub fn call_stack(&self) -> Ref<CallStack<'gc>> {
|
||||
Ref::map(self.0.read(), |r| &r.call_stack)
|
||||
self.0.call_stack.borrow()
|
||||
}
|
||||
|
||||
fn debug_class_name(&self) -> Box<dyn Debug + 'gc> {
|
||||
self.0
|
||||
.try_read()
|
||||
.map(|obj| obj.base.instance_class().debug_name())
|
||||
.base
|
||||
.try_borrow()
|
||||
.map(|base| base.instance_class().debug_name())
|
||||
.unwrap_or_else(|err| Box::new(err))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for ErrorObject<'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>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
unlock!(Gc::write(mc, self.0), ErrorObjectData, base).borrow_mut()
|
||||
}
|
||||
|
||||
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>> {
|
||||
|
|
|
@ -9,7 +9,8 @@ use crate::avm2::Error;
|
|||
use crate::avm2::Multiname;
|
||||
use crate::avm2::Namespace;
|
||||
use core::fmt;
|
||||
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};
|
||||
|
||||
/// A class instance allocator that allocates QName objects.
|
||||
|
@ -17,13 +18,13 @@ pub fn q_name_allocator<'gc>(
|
|||
class: ClassObject<'gc>,
|
||||
activation: &mut Activation<'_, 'gc>,
|
||||
) -> Result<Object<'gc>, Error<'gc>> {
|
||||
let base = ScriptObjectData::new(class);
|
||||
let base = ScriptObjectData::new(class).into();
|
||||
|
||||
Ok(QNameObject(GcCell::new(
|
||||
Ok(QNameObject(Gc::new(
|
||||
activation.context.gc_context,
|
||||
QNameObjectData {
|
||||
base,
|
||||
name: Multiname::any(activation.context.gc_context),
|
||||
name: RefLock::new(Multiname::any(activation.context.gc_context)),
|
||||
},
|
||||
))
|
||||
.into())
|
||||
|
@ -32,16 +33,16 @@ pub fn q_name_allocator<'gc>(
|
|||
/// An Object which represents a boxed QName.
|
||||
#[derive(Collect, Clone, Copy)]
|
||||
#[collect(no_drop)]
|
||||
pub struct QNameObject<'gc>(pub GcCell<'gc, QNameObjectData<'gc>>);
|
||||
pub struct QNameObject<'gc>(pub Gc<'gc, QNameObjectData<'gc>>);
|
||||
|
||||
#[derive(Collect, Clone, Copy, Debug)]
|
||||
#[collect(no_drop)]
|
||||
pub struct QNameObjectWeak<'gc>(pub GcWeakCell<'gc, QNameObjectData<'gc>>);
|
||||
pub struct QNameObjectWeak<'gc>(pub GcWeak<'gc, QNameObjectData<'gc>>);
|
||||
|
||||
impl fmt::Debug for QNameObject<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("QNameObject")
|
||||
.field("ptr", &self.0.as_ptr())
|
||||
.field("ptr", &Gc::as_ptr(self.0))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
@ -50,10 +51,10 @@ impl fmt::Debug for QNameObject<'_> {
|
|||
#[collect(no_drop)]
|
||||
pub struct QNameObjectData<'gc> {
|
||||
/// All normal script data.
|
||||
base: ScriptObjectData<'gc>,
|
||||
base: RefLock<ScriptObjectData<'gc>>,
|
||||
|
||||
/// The Multiname this object is associated with.
|
||||
name: Multiname<'gc>,
|
||||
name: RefLock<Multiname<'gc>>,
|
||||
}
|
||||
|
||||
impl<'gc> QNameObject<'gc> {
|
||||
|
@ -63,11 +64,14 @@ impl<'gc> QNameObject<'gc> {
|
|||
name: Multiname<'gc>,
|
||||
) -> Result<Object<'gc>, Error<'gc>> {
|
||||
let class = activation.avm2().classes().qname;
|
||||
let base = ScriptObjectData::new(class);
|
||||
let base = ScriptObjectData::new(class).into();
|
||||
|
||||
let this: Object<'gc> = QNameObject(GcCell::new(
|
||||
let this: Object<'gc> = QNameObject(Gc::new(
|
||||
activation.context.gc_context,
|
||||
QNameObjectData { base, name },
|
||||
QNameObjectData {
|
||||
base,
|
||||
name: RefLock::new(name),
|
||||
},
|
||||
))
|
||||
.into();
|
||||
this.install_instance_slots(activation.context.gc_context);
|
||||
|
@ -76,21 +80,19 @@ impl<'gc> QNameObject<'gc> {
|
|||
}
|
||||
|
||||
pub fn name(&self) -> Ref<Multiname<'gc>> {
|
||||
let read = self.0.read();
|
||||
|
||||
Ref::map(read, |r| &r.name)
|
||||
self.0.name.borrow()
|
||||
}
|
||||
|
||||
pub fn set_namespace(&self, mc: &Mutation<'gc>, namespace: Namespace<'gc>) {
|
||||
let mut write = self.0.write(mc);
|
||||
let mut write_name = unlock!(Gc::write(mc, self.0), QNameObjectData, name).borrow_mut();
|
||||
|
||||
write.name.set_single_namespace(namespace);
|
||||
write_name.set_single_namespace(namespace);
|
||||
}
|
||||
|
||||
pub fn set_local_name(&self, mc: &Mutation<'gc>, local: AvmString<'gc>) {
|
||||
let mut write = self.0.write(mc);
|
||||
let mut write_name = unlock!(Gc::write(mc, self.0), QNameObjectData, name).borrow_mut();
|
||||
|
||||
write.name.set_local_name(local);
|
||||
write_name.set_local_name(local);
|
||||
}
|
||||
|
||||
pub fn local_name(&self) -> AvmString<'gc> {
|
||||
|
@ -100,22 +102,21 @@ impl<'gc> QNameObject<'gc> {
|
|||
}
|
||||
|
||||
pub fn set_is_qname(&self, mc: &Mutation<'gc>, is_qname: bool) {
|
||||
let mut write = self.0.write(mc);
|
||||
let mut write_name = unlock!(Gc::write(mc, self.0), QNameObjectData, name).borrow_mut();
|
||||
|
||||
write.name.set_is_qname(is_qname);
|
||||
write_name.set_is_qname(is_qname);
|
||||
}
|
||||
|
||||
pub fn uri(&self) -> Option<AvmString<'gc>> {
|
||||
let read = self.0.read();
|
||||
let name = self.0.name.borrow();
|
||||
|
||||
if read.name.is_any_namespace() {
|
||||
if name.is_any_namespace() {
|
||||
None
|
||||
} else if read.name.namespace_set().len() > 1 {
|
||||
} else if name.namespace_set().len() > 1 {
|
||||
Some("".into())
|
||||
} else {
|
||||
Some(
|
||||
read.name
|
||||
.namespace_set()
|
||||
name.namespace_set()
|
||||
.first()
|
||||
.expect("Malformed multiname")
|
||||
.as_uri(),
|
||||
|
@ -124,21 +125,23 @@ impl<'gc> QNameObject<'gc> {
|
|||
}
|
||||
|
||||
pub fn init_name(self, mc: &Mutation<'gc>, name: Multiname<'gc>) {
|
||||
self.0.write(mc).name = name;
|
||||
let mut write_name = unlock!(Gc::write(mc, self.0), QNameObjectData, name).borrow_mut();
|
||||
|
||||
*write_name = name;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gc> TObject<'gc> for QNameObject<'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>> {
|
||||
RefMut::map(self.0.write(mc), |write| &mut write.base)
|
||||
unlock!(Gc::write(mc, self.0), QNameObjectData, base).borrow_mut()
|
||||
}
|
||||
|
||||
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>> {
|
||||
|
|
Loading…
Reference in New Issue