@@ -16,14 +16,15 @@ use crate::string::{AvmString, HasStringContext, StringContext, SwfStrExt as _,
1616use crate :: tag_utils:: SwfSlice ;
1717use crate :: vminterface:: Instantiator ;
1818use crate :: { avm_error, avm_warn} ;
19- use gc_arena:: { Gc , GcCell , Mutation } ;
19+ use gc_arena:: { Gc , Mutation } ;
2020use indexmap:: IndexMap ;
2121use rand:: Rng ;
2222use ruffle_macros:: istr;
23- use smallvec:: SmallVec ;
2423use std:: borrow:: Cow ;
24+ use std:: cell:: Cell ;
2525use std:: cmp:: min;
2626use std:: fmt;
27+ use std:: rc:: Rc ;
2728use swf:: avm1:: read:: Reader ;
2829use swf:: avm1:: types:: * ;
2930use url:: form_urlencoded;
@@ -39,44 +40,6 @@ macro_rules! avm_debug {
3940 )
4041}
4142
42- /// Represents a particular register set.
43- ///
44- /// This type exists primarily because SmallVec isn't garbage-collectable.
45- #[ derive( Clone ) ]
46- pub struct RegisterSet < ' gc > ( SmallVec < [ Value < ' gc > ; 8 ] > ) ;
47-
48- unsafe impl < ' gc > gc_arena:: Collect < ' gc > for RegisterSet < ' gc > {
49- #[ inline]
50- fn trace < C : gc_arena:: collect:: Trace < ' gc > > ( & self , cc : & mut C ) {
51- for register in & self . 0 {
52- cc. trace ( register) ;
53- }
54- }
55- }
56-
57- impl < ' gc > RegisterSet < ' gc > {
58- /// Create a new register set with a given number of specified registers.
59- ///
60- /// The given registers will be set to `undefined`.
61- pub fn new ( num : u8 ) -> Self {
62- Self ( smallvec ! [ Value :: Undefined ; num as usize ] )
63- }
64-
65- /// Return a reference to a given register, if it exists.
66- pub fn get ( & self , num : u8 ) -> Option < & Value < ' gc > > {
67- self . 0 . get ( num as usize )
68- }
69-
70- /// Return a mutable reference to a given register, if it exists.
71- pub fn get_mut ( & mut self , num : u8 ) -> Option < & mut Value < ' gc > > {
72- self . 0 . get_mut ( num as usize )
73- }
74-
75- pub fn len ( & self ) -> u8 {
76- self . 0 . len ( ) as u8
77- }
78- }
79-
8043#[ derive( Clone ) ]
8144pub enum ReturnType < ' gc > {
8245 Implicit ,
@@ -206,9 +169,9 @@ pub struct Activation<'a, 'gc: 'a> {
206169 /// Registers are numbered from 1; r0 does not exist. Therefore this vec,
207170 /// while nominally starting from zero, actually starts from r1.
208171 ///
209- /// Registers are stored in a `GcCell ` so that rescopes (e.g. with) use the
172+ /// Registers are stored in a `Rc ` so that rescopes (e.g. with) use the
210173 /// same register set.
211- local_registers : Option < GcCell < ' gc , RegisterSet < ' gc > > > ,
174+ local_registers : Option < Rc < [ Cell < Value < ' gc > > ] > > ,
212175
213176 /// The base clip of this stack frame.
214177 /// This will be the MovieClip that contains the bytecode.
@@ -301,7 +264,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
301264 base_clip_unloaded : self . base_clip_unloaded ,
302265 this : self . this ,
303266 callee : self . callee ,
304- local_registers : self . local_registers ,
267+ local_registers : self . local_registers . clone ( ) ,
305268 }
306269 }
307270
@@ -2268,7 +2231,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
22682231 self . callee ,
22692232 ) ;
22702233
2271- activation. local_registers = self . local_registers ;
2234+ activation. local_registers = self . local_registers . clone ( ) ;
22722235
22732236 match catch_vars {
22742237 CatchVar :: Var ( name) => {
@@ -3061,21 +3024,22 @@ impl<'a, 'gc> Activation<'a, 'gc> {
30613024 /// Returns true if this activation has a given local register ID.
30623025 pub fn has_local_register ( & self , id : u8 ) -> bool {
30633026 self . local_registers
3064- . map ( |rs| id < rs. read ( ) . len ( ) )
3027+ . as_deref ( )
3028+ . map ( |rs| usize:: from ( id) < rs. len ( ) )
30653029 . unwrap_or ( false )
30663030 }
30673031
3068- pub fn allocate_local_registers ( & mut self , num : u8 , mc : & Mutation < ' gc > ) {
3032+ pub fn allocate_local_registers ( & mut self , num : u8 ) {
30693033 self . local_registers = match num {
30703034 0 => None ,
3071- num => Some ( GcCell :: new ( mc , RegisterSet :: new ( num ) ) ) ,
3035+ num => Some ( ( 0 ..num ) . map ( |_| Cell :: new ( Value :: Undefined ) ) . collect ( ) ) ,
30723036 } ;
30733037 }
30743038
30753039 /// Retrieve a local register.
30763040 pub fn local_register ( & self , id : u8 ) -> Option < Value < ' gc > > {
3077- if let Some ( local_registers) = self . local_registers {
3078- local_registers. read ( ) . get ( id) . cloned ( )
3041+ if let Some ( local_registers) = self . local_registers . as_deref ( ) {
3042+ local_registers. get ( usize :: from ( id) ) . map ( Cell :: get )
30793043 } else {
30803044 None
30813045 }
@@ -3084,8 +3048,8 @@ impl<'a, 'gc> Activation<'a, 'gc> {
30843048 /// Set a local register.
30853049 pub fn set_local_register ( & mut self , id : u8 , value : Value < ' gc > ) {
30863050 if let Some ( ref mut local_registers) = self . local_registers {
3087- if let Some ( r) = local_registers. write ( self . context . gc ( ) ) . get_mut ( id ) {
3088- * r = value;
3051+ if let Some ( r) = local_registers. get ( usize :: from ( id ) ) {
3052+ r . set ( value) ;
30893053 }
30903054 }
30913055 }
0 commit comments