@@ -12,7 +12,7 @@ use crate::display_object::{DisplayObject, MovieClip, TDisplayObject, TDisplayOb
12
12
use crate :: ecma_conversions:: { f64_to_wrapping_i32, f64_to_wrapping_u32} ;
13
13
use crate :: loader:: MovieLoaderVMData ;
14
14
use crate :: string:: { AvmString , SwfStrExt as _, WStr , WString } ;
15
- use crate :: tag_utils:: SwfSlice ;
15
+ use crate :: tag_utils:: { SwfPosition , SwfSlice } ;
16
16
use crate :: vminterface:: Instantiator ;
17
17
use crate :: { avm_error, avm_warn} ;
18
18
use gc_arena:: { Gc , GcCell , MutationContext } ;
@@ -25,6 +25,7 @@ use std::cmp::min;
25
25
use std:: fmt;
26
26
use swf:: avm1:: read:: Reader ;
27
27
use swf:: avm1:: types:: * ;
28
+ use swf:: extensions:: ReadSwfExt ;
28
29
use url:: form_urlencoded;
29
30
30
31
use super :: object_reference:: MovieClipReference ;
@@ -480,7 +481,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
480
481
Action :: CastOp => self . action_cast_op ( ) ,
481
482
Action :: CharToAscii => self . action_char_to_ascii ( ) ,
482
483
Action :: CloneSprite => self . action_clone_sprite ( ) ,
483
- Action :: ConstantPool ( action) => self . action_constant_pool ( action) ,
484
+ Action :: ConstantPool ( action) => self . action_constant_pool ( action, data , reader ) ,
484
485
Action :: Decrement => self . action_decrement ( ) ,
485
486
Action :: DefineFunction ( action) => self . action_define_function ( action. into ( ) , data) ,
486
487
Action :: DefineFunction2 ( action) => self . action_define_function ( action, data) ,
@@ -863,21 +864,42 @@ impl<'a, 'gc> Activation<'a, 'gc> {
863
864
fn action_constant_pool (
864
865
& mut self ,
865
866
action : ConstantPool ,
867
+ data : & SwfSlice ,
868
+ reader : & mut Reader ,
866
869
) -> Result < FrameControl < ' gc > , Error < ' gc > > {
867
- let constants = action
868
- . strings
869
- . iter ( )
870
- . map ( |s| {
870
+ let current_pos = reader. pos ( data. movie . data ( ) ) ;
871
+ let swf_position = SwfPosition :: new ( data. movie . clone ( ) , current_pos) ;
872
+
873
+ let const_pool_cache = self . context . avm1 . constant_pool_cache ( ) ;
874
+
875
+ let constants = if let Some ( constants) = const_pool_cache. get ( & swf_position) {
876
+ * constants
877
+ } else {
878
+ let constants: Vec < _ > = action
879
+ . strings
880
+ . iter ( )
881
+ . map ( |s| {
882
+ self . context
883
+ . interner
884
+ . intern_wstr ( self . context . gc_context , s. decode ( self . encoding ( ) ) )
885
+ . into ( )
886
+ } )
887
+ . collect ( ) ;
888
+
889
+ let consts = Gc :: new ( self . context . gc_context , constants) ;
890
+
891
+ if consts. len ( ) > 1000 {
871
892
self . context
872
- . interner
873
- . intern_wstr ( self . context . gc_context , s. decode ( self . encoding ( ) ) )
874
- . into ( )
875
- } )
876
- . collect ( ) ;
893
+ . avm1
894
+ . constant_pool_cache ( )
895
+ . insert ( swf_position, consts) ;
896
+ }
897
+
898
+ consts
899
+ } ;
900
+
901
+ self . context . avm1 . set_constant_pool ( constants) ;
877
902
878
- self . context
879
- . avm1
880
- . set_constant_pool ( Gc :: new ( self . context . gc_context , constants) ) ;
881
903
self . set_constant_pool ( self . context . avm1 . constant_pool ( ) ) ;
882
904
883
905
Ok ( FrameControl :: Continue )
0 commit comments