@@ -571,6 +571,16 @@ impl<'a, 'gc> Activation<'a, 'gc> {
571571 self . context . avm1 . push ( value) ;
572572 }
573573
574+ fn pop_call_args ( & mut self , num_args : usize ) -> Vec < Value < ' gc > > {
575+ ( 0 ..num_args. min ( self . context . avm1 . stack_len ( ) ) )
576+ . map ( |_| {
577+ let arg = self . context . avm1 . pop ( ) ;
578+ // Unwrap MovieClipReferences, if possible.
579+ arg. as_object ( self ) . map ( Value :: from) . unwrap_or ( arg)
580+ } )
581+ . collect ( )
582+ }
583+
574584 fn action_add ( & mut self ) -> Result < FrameControl < ' gc > , Error < ' gc > > {
575585 let a = self . context . avm1 . pop ( ) ;
576586 let b = self . context . avm1 . pop ( ) ;
@@ -754,16 +764,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
754764 let fn_name_value = self . context . avm1 . pop ( ) ;
755765 let fn_name = fn_name_value. coerce_to_string ( self ) ?;
756766 let num_args = self . context . avm1 . pop ( ) . coerce_to_u32 ( self ) ? as usize ;
757- let num_args = num_args. min ( self . context . avm1 . stack_len ( ) ) ;
758- let mut args = Vec :: with_capacity ( num_args) ;
759- for _ in 0 ..num_args {
760- let arg = self . context . avm1 . pop ( ) ;
761- if let Value :: MovieClip ( _) = arg {
762- args. push ( Value :: Object ( arg. coerce_to_object ( self ) ) ) ;
763- } else {
764- args. push ( arg) ;
765- }
766- }
767+ let args = self . pop_call_args ( num_args) ;
767768
768769 let variable = self . get_variable ( fn_name) ?;
769770
@@ -784,16 +785,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
784785 let method_name = self . context . avm1 . pop ( ) ;
785786 let object_val = self . context . avm1 . pop ( ) ;
786787 let num_args = self . context . avm1 . pop ( ) . coerce_to_u32 ( self ) ? as usize ;
787- let num_args = num_args. min ( self . context . avm1 . stack_len ( ) ) ;
788- let mut args = Vec :: with_capacity ( num_args) ;
789- for _ in 0 ..num_args {
790- let arg = self . context . avm1 . pop ( ) ;
791- if let Value :: MovieClip ( _) = arg {
792- args. push ( Value :: Object ( arg. coerce_to_object ( self ) ) ) ;
793- } else {
794- args. push ( arg) ;
795- }
796- }
788+ let args = self . pop_call_args ( num_args) ;
797789
798790 // Can not call method on undefined/null.
799791 if matches ! ( object_val, Value :: Undefined | Value :: Null ) {
@@ -825,13 +817,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
825817 let obj = self . context . avm1 . pop ( ) ;
826818 let constr = self . context . avm1 . pop ( ) . coerce_to_object ( self ) ;
827819
828- let is_instance_of = if let Value :: Object ( obj) = obj {
829- let prototype = constr
830- . get ( istr ! ( self , "prototype" ) , self ) ?
831- . coerce_to_object ( self ) ;
832- obj. is_instance_of ( self , constr, prototype) ?
833- } else if let Value :: MovieClip ( _) = obj {
834- let obj = obj. coerce_to_object ( self ) ;
820+ let is_instance_of = if let Some ( obj) = obj. as_object ( self ) {
835821 let prototype = constr
836822 . get ( istr ! ( self , "prototype" ) , self ) ?
837823 . coerce_to_object ( self ) ;
@@ -944,10 +930,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
944930 let name = name_val. coerce_to_string ( self ) ?;
945931 let object = self . context . avm1 . pop ( ) ;
946932
947- let success = if let Value :: Object ( object) = object {
948- object. delete ( self , name)
949- } else if let Value :: MovieClip ( _) = object {
950- let object = object. coerce_to_object ( self ) ;
933+ let success = if let Some ( object) = object. as_object ( self ) {
951934 object. delete ( self , name)
952935 } else {
953936 avm_warn ! ( self , "Cannot delete property {} from {:?}" , name, object) ;
@@ -1003,23 +986,16 @@ impl<'a, 'gc> Activation<'a, 'gc> {
1003986 fn action_enumerate ( & mut self ) -> Result < FrameControl < ' gc > , Error < ' gc > > {
1004987 let name_value = self . context . avm1 . pop ( ) ;
1005988 let name = name_value. coerce_to_string ( self ) ?;
1006- let object : Value < ' gc > = self . get_variable ( name) ?. into ( ) ;
989+ let value : Value < ' gc > = self . get_variable ( name) ?. into ( ) ;
1007990 self . context . avm1 . push ( Value :: Undefined ) ; // Sentinel that indicates end of enumeration
1008991
1009- match object {
1010- Value :: MovieClip ( _) => {
1011- let ob = object. coerce_to_object ( self ) ;
1012- for k in ob. get_keys ( self , false ) . into_iter ( ) . rev ( ) {
1013- self . stack_push ( k. into ( ) ) ;
1014- }
1015- }
1016- Value :: Object ( ob) => {
1017- for k in ob. get_keys ( self , false ) . into_iter ( ) . rev ( ) {
1018- self . stack_push ( k. into ( ) ) ;
1019- }
992+ if let Some ( object) = value. as_object ( self ) {
993+ for k in object. get_keys ( self , false ) . into_iter ( ) . rev ( ) {
994+ self . stack_push ( k. into ( ) ) ;
1020995 }
1021- _ => avm_error ! ( self , "Cannot enumerate properties of {}" , name) ,
1022- } ;
996+ } else {
997+ avm_error ! ( self , "Cannot enumerate properties of {}" , name) ;
998+ }
1023999
10241000 Ok ( FrameControl :: Continue )
10251001 }
@@ -1029,12 +1005,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
10291005
10301006 self . context . avm1 . push ( Value :: Undefined ) ; // Sentinel that indicates end of enumeration
10311007
1032- if let Value :: MovieClip ( _) = value {
1033- let object = value. coerce_to_object ( self ) ;
1034- for k in object. get_keys ( self , false ) . into_iter ( ) . rev ( ) {
1035- self . stack_push ( k. into ( ) ) ;
1036- }
1037- } else if let Value :: Object ( object) = value {
1008+ if let Some ( object) = value. as_object ( self ) {
10381009 for k in object. get_keys ( self , false ) . into_iter ( ) . rev ( ) {
10391010 self . stack_push ( k. into ( ) ) ;
10401011 }
@@ -1253,11 +1224,8 @@ impl<'a, 'gc> Activation<'a, 'gc> {
12531224 let mut clip_target: Option < DisplayObject < ' gc > > = if level_target > -1 {
12541225 self . get_level ( level_target)
12551226 } else if action. is_load_vars ( ) || action. is_target_sprite ( ) {
1256- if let Value :: Object ( target) = target_val {
1227+ if let Some ( target) = target_val. as_object ( self ) {
12571228 target. as_display_object ( )
1258- } else if let Value :: MovieClip ( _) = target_val {
1259- let tgt = target_val. coerce_to_object ( self ) ;
1260- tgt. as_display_object ( )
12611229 } else {
12621230 let start = self . target_clip_or_root ( ) ;
12631231 self . resolve_target_display_object ( start, target_val, true ) ?
@@ -1508,13 +1476,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
15081476 let constr = self . context . avm1 . pop ( ) . coerce_to_object ( self ) ;
15091477 let obj = self . context . avm1 . pop ( ) ;
15101478
1511- let result = if let Value :: Object ( obj) = obj {
1512- let prototype = constr
1513- . get ( istr ! ( self , "prototype" ) , self ) ?
1514- . coerce_to_object ( self ) ;
1515- obj. is_instance_of ( self , constr, prototype) ?
1516- } else if let Value :: MovieClip ( _) = obj {
1517- let obj = obj. coerce_to_object ( self ) ;
1479+ let result = if let Some ( obj) = obj. as_object ( self ) {
15181480 let prototype = constr
15191481 . get ( istr ! ( self , "prototype" ) , self ) ?
15201482 . coerce_to_object ( self ) ;
@@ -1676,16 +1638,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
16761638 let method_name = self . context . avm1 . pop ( ) ;
16771639 let object_val = self . context . avm1 . pop ( ) ;
16781640 let num_args = self . context . avm1 . pop ( ) . coerce_to_u32 ( self ) ? as usize ;
1679- let num_args = num_args. min ( self . context . avm1 . stack_len ( ) ) ;
1680- let mut args = Vec :: with_capacity ( num_args) ;
1681- for _ in 0 ..num_args {
1682- let arg = self . context . avm1 . pop ( ) ;
1683- if let Value :: MovieClip ( _) = arg {
1684- args. push ( Value :: Object ( arg. coerce_to_object ( self ) ) ) ;
1685- } else {
1686- args. push ( arg) ;
1687- }
1688- }
1641+ let args = self . pop_call_args ( num_args) ;
16891642
16901643 // Can not call method on undefined/null.
16911644 if matches ! ( object_val, Value :: Undefined | Value :: Null ) {
@@ -1728,16 +1681,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
17281681 let fn_name_val = self . context . avm1 . pop ( ) ;
17291682 let fn_name = fn_name_val. coerce_to_string ( self ) ?;
17301683 let num_args = self . context . avm1 . pop ( ) . coerce_to_u32 ( self ) ? as usize ;
1731- let num_args = num_args. min ( self . context . avm1 . stack_len ( ) ) ;
1732- let mut args = Vec :: with_capacity ( num_args) ;
1733- for _ in 0 ..num_args {
1734- let arg = self . context . avm1 . pop ( ) ;
1735- if let Value :: MovieClip ( _) = arg {
1736- args. push ( Value :: Object ( arg. coerce_to_object ( self ) ) ) ;
1737- } else {
1738- args. push ( arg) ;
1739- }
1740- }
1684+ let args = self . pop_call_args ( num_args) ;
17411685
17421686 let name_value: Value < ' gc > = self . resolve ( fn_name) ?. into ( ) ;
17431687 let constructor = name_value. coerce_to_object ( self ) ;
@@ -2683,10 +2627,8 @@ impl<'a, 'gc> Activation<'a, 'gc> {
26832627 first_element = false ;
26842628
26852629 // Resolve the value to an object while traversing the path.
2686- object = if let Value :: Object ( o) = val {
2630+ object = if let Some ( o) = val. as_object ( self ) {
26872631 o
2688- } else if let Value :: MovieClip ( _) = val {
2689- val. coerce_to_object ( self )
26902632 } else {
26912633 return Ok ( None ) ;
26922634 } ;
0 commit comments