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

This commit is contained in:
Lord-McSweeney 2024-07-04 21:59:12 +03:00 committed by Lord-McSweeney
parent 562be06fb1
commit 64261c8f06
2 changed files with 25 additions and 21 deletions

View File

@ -1387,7 +1387,7 @@ impl<'gc> Object<'gc> {
Self::DispatchObject(o) => WeakObject::DispatchObject(DispatchObjectWeak(GcCell::downgrade(o.0))),
Self::XmlObject(o) => WeakObject::XmlObject(XmlObjectWeak(Gc::downgrade(o.0))),
Self::XmlListObject(o) => WeakObject::XmlListObject(XmlListObjectWeak(GcCell::downgrade(o.0))),
Self::RegExpObject(o) => WeakObject::RegExpObject(RegExpObjectWeak(GcCell::downgrade(o.0))),
Self::RegExpObject(o) => WeakObject::RegExpObject(RegExpObjectWeak(Gc::downgrade(o.0))),
Self::ByteArrayObject(o) => WeakObject::ByteArrayObject(ByteArrayObjectWeak(Gc::downgrade(o.0))),
Self::LoaderInfoObject(o) => WeakObject::LoaderInfoObject(LoaderInfoObjectWeak(GcCell::downgrade(o.0))),
Self::ClassObject(o) => WeakObject::ClassObject(ClassObjectWeak(GcCell::downgrade(o.0))),

View File

@ -8,7 +8,8 @@ use crate::avm2::value::Value;
use crate::avm2::Error;
use crate::string::{AvmString, 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};
/// A class instance allocator that allocates RegExp objects.
@ -16,13 +17,13 @@ pub fn reg_exp_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(RegExpObject(GcCell::new(
Ok(RegExpObject(Gc::new(
activation.context.gc_context,
RegExpObjectData {
base,
regexp: RegExp::new(""),
regexp: RefLock::new(RegExp::new("")),
},
))
.into())
@ -30,16 +31,16 @@ pub fn reg_exp_allocator<'gc>(
#[derive(Clone, Collect, Copy)]
#[collect(no_drop)]
pub struct RegExpObject<'gc>(pub GcCell<'gc, RegExpObjectData<'gc>>);
pub struct RegExpObject<'gc>(pub Gc<'gc, RegExpObjectData<'gc>>);
#[derive(Clone, Collect, Copy, Debug)]
#[collect(no_drop)]
pub struct RegExpObjectWeak<'gc>(pub GcWeakCell<'gc, RegExpObjectData<'gc>>);
pub struct RegExpObjectWeak<'gc>(pub GcWeak<'gc, RegExpObjectData<'gc>>);
impl fmt::Debug for RegExpObject<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RegExpObject")
.field("ptr", &self.0.as_ptr())
.field("ptr", &Gc::as_ptr(self.0))
.finish()
}
}
@ -48,9 +49,9 @@ impl fmt::Debug for RegExpObject<'_> {
#[collect(no_drop)]
pub struct RegExpObjectData<'gc> {
/// Base script object
base: ScriptObjectData<'gc>,
base: RefLock<ScriptObjectData<'gc>>,
regexp: RegExp<'gc>,
regexp: RefLock<RegExp<'gc>>,
}
impl<'gc> RegExpObject<'gc> {
@ -59,11 +60,14 @@ impl<'gc> RegExpObject<'gc> {
regexp: RegExp<'gc>,
) -> Result<Object<'gc>, Error<'gc>> {
let class = activation.avm2().classes().regexp;
let base = ScriptObjectData::new(class);
let base = ScriptObjectData::new(class).into();
let this: Object<'gc> = RegExpObject(GcCell::new(
let this: Object<'gc> = RegExpObject(Gc::new(
activation.context.gc_context,
RegExpObjectData { base, regexp },
RegExpObjectData {
base,
regexp: RefLock::new(regexp),
},
))
.into();
this.install_instance_slots(activation.context.gc_context);
@ -76,25 +80,25 @@ impl<'gc> RegExpObject<'gc> {
impl<'gc> TObject<'gc> for RegExpObject<'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), RegExpObjectData, 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>> {
let read = self.0.read();
let regexp = self.0.regexp.borrow();
let mut s = WString::new();
s.push_byte(b'/');
s.push_str(&read.regexp.source());
s.push_str(&regexp.source());
s.push_byte(b'/');
let flags = read.regexp.flags();
let flags = regexp.flags();
if flags.contains(RegExpFlags::GLOBAL) {
s.push_byte(b'g');
@ -121,10 +125,10 @@ impl<'gc> TObject<'gc> for RegExpObject<'gc> {
}
fn as_regexp(&self) -> Option<Ref<RegExp<'gc>>> {
Some(Ref::map(self.0.read(), |d| &d.regexp))
Some(self.0.regexp.borrow())
}
fn as_regexp_mut(&self, mc: &Mutation<'gc>) -> Option<RefMut<RegExp<'gc>>> {
Some(RefMut::map(self.0.write(mc), |d| &mut d.regexp))
Some(unlock!(Gc::write(mc, self.0), RegExpObjectData, regexp).borrow_mut())
}
}