@@ -77,6 +77,10 @@ pub struct Activation<'a, 'gc: 'a> {
77
77
/// The index where the scope frame starts.
78
78
scope_depth : usize ,
79
79
80
+ /// The index where the default XML namespace frame starts.
81
+ /// Used to implement proper function-level scoping for default XML namespace.
82
+ default_xml_namespace_depth : usize ,
83
+
80
84
/// In avmplus, some behavior differs slightly depending on whether the JIT
81
85
/// or the interpreter is used. Most methods are executed in "JIT mode", but
82
86
/// in some cases "interpreter mode" is used instead: for example, script
@@ -125,6 +129,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
125
129
bound_class : None ,
126
130
stack_depth : context. avm2 . stack . len ( ) ,
127
131
scope_depth : context. avm2 . scope_stack . len ( ) ,
132
+ default_xml_namespace_depth : context. avm2 . default_xml_namespace_stack . len ( ) ,
128
133
is_interpreter : false ,
129
134
context,
130
135
}
@@ -149,6 +154,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
149
154
bound_class : None ,
150
155
stack_depth : context. avm2 . stack . len ( ) ,
151
156
scope_depth : context. avm2 . scope_stack . len ( ) ,
157
+ default_xml_namespace_depth : context. avm2 . default_xml_namespace_stack . len ( ) ,
152
158
is_interpreter : false ,
153
159
context,
154
160
}
@@ -177,6 +183,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
177
183
bound_class : Some ( script. global_class ( ) ) ,
178
184
stack_depth : context. avm2 . stack . len ( ) ,
179
185
scope_depth : context. avm2 . scope_stack . len ( ) ,
186
+ default_xml_namespace_depth : 0 , // Scripts inherit global default XML namespace
180
187
is_interpreter : true , // Script initializers are always in interpreter mode
181
188
context,
182
189
} ;
@@ -377,6 +384,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
377
384
self . bound_class = bound_class;
378
385
self . stack_depth = self . context . avm2 . stack . len ( ) ;
379
386
self . scope_depth = self . context . avm2 . scope_stack . len ( ) ;
387
+ self . default_xml_namespace_depth = self . context . avm2 . default_xml_namespace_stack . len ( ) ;
380
388
self . is_interpreter = false ;
381
389
382
390
// Resolve parameters and return type
@@ -483,6 +491,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
483
491
bound_class,
484
492
stack_depth : context. avm2 . stack . len ( ) ,
485
493
scope_depth : context. avm2 . scope_stack . len ( ) ,
494
+ default_xml_namespace_depth : context. avm2 . default_xml_namespace_stack . len ( ) , // Builtin functions start with isolated scope
486
495
is_interpreter : false ,
487
496
context,
488
497
}
@@ -626,6 +635,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
626
635
pub fn cleanup ( & mut self ) {
627
636
self . clear_stack_and_locals ( ) ;
628
637
self . clear_scope ( ) ;
638
+ self . clear_default_xml_namespace ( ) ;
629
639
}
630
640
631
641
/// Clears the operand stack used by this activation.
@@ -650,6 +660,13 @@ impl<'a, 'gc> Activation<'a, 'gc> {
650
660
self . avm2 ( ) . scope_stack . truncate ( scope_depth) ;
651
661
}
652
662
663
+ /// Clears the default XML namespace stack used by this activation.
664
+ #[ inline]
665
+ fn clear_default_xml_namespace ( & mut self ) {
666
+ let default_xml_namespace_depth = self . default_xml_namespace_depth ;
667
+ self . avm2 ( ) . default_xml_namespace_stack . truncate ( default_xml_namespace_depth) ;
668
+ }
669
+
653
670
/// Get the superclass of the class that defined the currently-executing
654
671
/// method, if it exists.
655
672
///
@@ -664,6 +681,12 @@ impl<'a, 'gc> Activation<'a, 'gc> {
664
681
self . bound_class
665
682
}
666
683
684
+ /// Get the current default XML namespace.
685
+ /// Returns an empty string if no default XML namespace is set.
686
+ pub fn default_xml_namespace ( & self ) -> AvmString < ' gc > {
687
+ self . context . avm2 . current_default_xml_namespace ( self . strings_ref ( ) )
688
+ }
689
+
667
690
/// Retrieve a method entry from the current ABC file's method table.
668
691
fn table_method (
669
692
& mut self ,
@@ -845,7 +868,7 @@ impl<'a, 'gc> Activation<'a, 'gc> {
845
868
Op :: BkptLine { line_num } => self . op_bkpt_line ( * line_num) ,
846
869
Op :: Timestamp => self . op_timestamp ( ) ,
847
870
Op :: TypeOf => self . op_type_of ( ) ,
848
- Op :: Dxns { .. } => self . op_dxns ( ) ,
871
+ Op :: Dxns { string } => self . op_dxns ( * string ) ,
849
872
Op :: DxnsLate => self . op_dxns_late ( ) ,
850
873
Op :: EscXAttr => self . op_esc_xattr ( ) ,
851
874
Op :: EscXElem => self . op_esc_elem ( ) ,
@@ -2627,14 +2650,21 @@ impl<'a, 'gc> Activation<'a, 'gc> {
2627
2650
}
2628
2651
2629
2652
/// Implements `Op::Dxns`
2630
- fn op_dxns ( & mut self ) -> Result < ( ) , Error < ' gc > > {
2631
- Err ( "Unimplemented opcode Dxns." . into ( ) )
2653
+ fn op_dxns ( & mut self , string : AvmAtom < ' gc > ) -> Result < ( ) , Error < ' gc > > {
2654
+ let namespace_uri: AvmString < ' gc > = string. into ( ) ;
2655
+ self . avm2 ( ) . push_default_xml_namespace ( namespace_uri) ;
2656
+
2657
+ Ok ( ( ) )
2632
2658
}
2633
2659
2634
2660
/// Implements `Op::DxnsLate`
2635
2661
fn op_dxns_late ( & mut self ) -> Result < ( ) , Error < ' gc > > {
2636
- let _ = self . pop_stack ( ) ;
2637
- Err ( "Unimplemented opcode DxnsLate." . into ( ) )
2662
+ let namespace_value = self . pop_stack ( ) ;
2663
+ let namespace_uri = namespace_value. coerce_to_string ( self ) ?;
2664
+
2665
+ self . avm2 ( ) . push_default_xml_namespace ( namespace_uri) ;
2666
+
2667
+ Ok ( ( ) )
2638
2668
}
2639
2669
2640
2670
/// Implements `Op::EscXAttr`
0 commit comments