From 64261c8f06bb179beee5275500e33e161fa823ba Mon Sep 17 00:00:00 2001 From: Lord-McSweeney Date: Thu, 4 Jul 2024 21:59:12 +0300 Subject: [PATCH] avm2: Use `Gc` instead of `GcCell` in `RegExpObject` --- core/src/avm2/object.rs | 2 +- core/src/avm2/object/regexp_object.rs | 44 +++++++++++++++------------ 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/core/src/avm2/object.rs b/core/src/avm2/object.rs index 4e6d367a0..b4644012a 100644 --- a/core/src/avm2/object.rs +++ b/core/src/avm2/object.rs @@ -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))), diff --git a/core/src/avm2/object/regexp_object.rs b/core/src/avm2/object/regexp_object.rs index 192dfefbc..6efb034b4 100644 --- a/core/src/avm2/object/regexp_object.rs +++ b/core/src/avm2/object/regexp_object.rs @@ -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, 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>, - regexp: RegExp<'gc>, + regexp: RefLock>, } impl<'gc> RegExpObject<'gc> { @@ -59,11 +60,14 @@ impl<'gc> RegExpObject<'gc> { regexp: RegExp<'gc>, ) -> Result, 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> { - Ref::map(self.0.read(), |read| &read.base) + self.0.base.borrow() } fn base_mut(&self, mc: &Mutation<'gc>) -> RefMut> { - 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, 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(®exp.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>> { - Some(Ref::map(self.0.read(), |d| &d.regexp)) + Some(self.0.regexp.borrow()) } fn as_regexp_mut(&self, mc: &Mutation<'gc>) -> Option>> { - Some(RefMut::map(self.0.write(mc), |d| &mut d.regexp)) + Some(unlock!(Gc::write(mc, self.0), RegExpObjectData, regexp).borrow_mut()) } }