diff --git a/core/src/avm2/activation.rs b/core/src/avm2/activation.rs index 8b946c9dc..ecadb4dcc 100644 --- a/core/src/avm2/activation.rs +++ b/core/src/avm2/activation.rs @@ -30,7 +30,7 @@ use std::cmp::{min, Ordering}; use std::sync::Arc; use swf::avm2::types::{ Class as AbcClass, Exception, Index, Method as AbcMethod, MethodFlags as AbcMethodFlags, - Multiname as AbcMultiname, Namespace as AbcNamespace, + Namespace as AbcNamespace, }; use super::error::make_mismatch_error; @@ -771,24 +771,6 @@ impl<'a, 'gc> Activation<'a, 'gc> { .pool_namespace(index, &mut self.context) } - /// Retrieve a multiname from the current constant pool. - /// The name is guaranteed to be fully initialized. - fn pool_multiname_and_initialize( - &mut self, - method: Gc<'gc, BytecodeMethod<'gc>>, - index: Index, - ) -> Result>, Error<'gc>> { - let name = method - .translation_unit() - .pool_maybe_uninitialized_multiname(index, &mut self.context)?; - if name.has_lazy_component() { - let name = name.fill_with_runtime_params(self)?; - Ok(Gc::new(self.context.gc_context, name)) - } else { - Ok(name) - } - } - /// Retrieve a method entry from the current ABC file's method table. fn table_method( &mut self, @@ -931,9 +913,10 @@ impl<'a, 'gc> Activation<'a, 'gc> { multiname, num_args, } => self.op_call_property(*multiname, *num_args), - Op::CallPropLex { index, num_args } => { - self.op_call_prop_lex(method, *index, *num_args) - } + Op::CallPropLex { + multiname, + num_args, + } => self.op_call_prop_lex(*multiname, *num_args), Op::CallPropVoid { multiname, num_args, @@ -941,18 +924,22 @@ impl<'a, 'gc> Activation<'a, 'gc> { Op::CallStatic { index, num_args } => { self.op_call_static(method, *index, *num_args) } - Op::CallSuper { index, num_args } => self.op_call_super(method, *index, *num_args), - Op::CallSuperVoid { index, num_args } => { - self.op_call_super_void(method, *index, *num_args) - } + Op::CallSuper { + multiname, + num_args, + } => self.op_call_super(*multiname, *num_args), + Op::CallSuperVoid { + multiname, + num_args, + } => self.op_call_super_void(*multiname, *num_args), Op::ReturnValue => self.op_return_value(method), Op::ReturnVoid => self.op_return_void(), Op::GetProperty { multiname } => self.op_get_property(*multiname), Op::SetProperty { multiname } => self.op_set_property(*multiname), Op::InitProperty { multiname } => self.op_init_property(*multiname), Op::DeleteProperty { multiname } => self.op_delete_property(*multiname), - Op::GetSuper { index } => self.op_get_super(method, *index), - Op::SetSuper { index } => self.op_set_super(method, *index), + Op::GetSuper { multiname } => self.op_get_super(*multiname), + Op::SetSuper { multiname } => self.op_set_super(*multiname), Op::In => self.op_in(), Op::PushScope => self.op_push_scope(), Op::NewCatch { index } => self.op_newcatch(method, *index), @@ -965,7 +952,7 @@ impl<'a, 'gc> Activation<'a, 'gc> { Op::FindProperty { multiname } => self.op_find_property(*multiname), Op::FindPropStrict { multiname } => self.op_find_prop_strict(*multiname), Op::GetLex { multiname } => self.op_get_lex(*multiname), - Op::GetDescendants { index } => self.op_get_descendants(method, *index), + Op::GetDescendants { multiname } => self.op_get_descendants(*multiname), Op::GetSlot { index } => self.op_get_slot(*index), Op::SetSlot { index } => self.op_set_slot(*index), Op::GetGlobalSlot { index } => self.op_get_global_slot(*index), @@ -1261,12 +1248,11 @@ impl<'a, 'gc> Activation<'a, 'gc> { fn op_call_prop_lex( &mut self, - method: Gc<'gc, BytecodeMethod<'gc>>, - index: Index, + multiname: Gc<'gc, Multiname<'gc>>, arg_count: u32, ) -> Result, Error<'gc>> { let args = self.pop_stack_args(arg_count); - let multiname = self.pool_multiname_and_initialize(method, index)?; + let multiname = multiname.fill_with_runtime_params(self)?; let receiver = self .pop_stack() .coerce_to_object_or_typeerror(self, Some(&multiname))?; @@ -1320,12 +1306,11 @@ impl<'a, 'gc> Activation<'a, 'gc> { fn op_call_super( &mut self, - method: Gc<'gc, BytecodeMethod<'gc>>, - index: Index, + multiname: Gc<'gc, Multiname<'gc>>, arg_count: u32, ) -> Result, Error<'gc>> { let args = self.pop_stack_args(arg_count); - let multiname = self.pool_multiname_and_initialize(method, index)?; + let multiname = multiname.fill_with_runtime_params(self)?; let receiver = self .pop_stack() .coerce_to_object_or_typeerror(self, Some(&multiname))?; @@ -1341,12 +1326,11 @@ impl<'a, 'gc> Activation<'a, 'gc> { fn op_call_super_void( &mut self, - method: Gc<'gc, BytecodeMethod<'gc>>, - index: Index, + multiname: Gc<'gc, Multiname<'gc>>, arg_count: u32, ) -> Result, Error<'gc>> { let args = self.pop_stack_args(arg_count); - let multiname = self.pool_multiname_and_initialize(method, index)?; + let multiname = multiname.fill_with_runtime_params(self)?; let receiver = self .pop_stack() .coerce_to_object_or_typeerror(self, Some(&multiname))?; @@ -1550,10 +1534,9 @@ impl<'a, 'gc> Activation<'a, 'gc> { fn op_get_super( &mut self, - method: Gc<'gc, BytecodeMethod<'gc>>, - index: Index, + multiname: Gc<'gc, Multiname<'gc>>, ) -> Result, Error<'gc>> { - let multiname = self.pool_multiname_and_initialize(method, index)?; + let multiname = multiname.fill_with_runtime_params(self)?; let object = self .pop_stack() .coerce_to_object_or_typeerror(self, Some(&multiname))?; @@ -1569,11 +1552,10 @@ impl<'a, 'gc> Activation<'a, 'gc> { fn op_set_super( &mut self, - method: Gc<'gc, BytecodeMethod<'gc>>, - index: Index, + multiname: Gc<'gc, Multiname<'gc>>, ) -> Result, Error<'gc>> { let value = self.pop_stack(); - let multiname = self.pool_multiname_and_initialize(method, index)?; + let multiname = multiname.fill_with_runtime_params(self)?; let object = self .pop_stack() .coerce_to_object_or_typeerror(self, Some(&multiname))?; @@ -1730,10 +1712,9 @@ impl<'a, 'gc> Activation<'a, 'gc> { fn op_get_descendants( &mut self, - method: Gc<'gc, BytecodeMethod<'gc>>, - index: Index, + multiname: Gc<'gc, Multiname<'gc>>, ) -> Result, Error<'gc>> { - let multiname = self.pool_multiname_and_initialize(method, index)?; + let multiname = multiname.fill_with_runtime_params(self)?; let object = self.pop_stack().coerce_to_object_or_typeerror(self, None)?; if let Some(descendants) = object.xml_descendants(self, &multiname) { self.push_stack(descendants); diff --git a/core/src/avm2/op.rs b/core/src/avm2/op.rs index 71ae55a90..8bc00c624 100644 --- a/core/src/avm2/op.rs +++ b/core/src/avm2/op.rs @@ -3,9 +3,7 @@ use crate::avm2::multiname::Multiname; use crate::string::AvmAtom; use gc_arena::{Collect, Gc, GcCell}; -use swf::avm2::types::{ - Class as AbcClass, Exception, Index, LookupSwitch, Method, Multiname as AbcMultiname, Namespace, -}; +use swf::avm2::types::{Class as AbcClass, Exception, Index, LookupSwitch, Method, Namespace}; #[derive(Clone, Collect, Debug)] #[collect(no_drop)] @@ -41,8 +39,7 @@ pub enum Op<'gc> { num_args: u32, }, CallPropLex { - #[collect(require_static)] - index: Index, + multiname: Gc<'gc, Multiname<'gc>>, num_args: u32, }, @@ -58,14 +55,12 @@ pub enum Op<'gc> { num_args: u32, }, CallSuper { - #[collect(require_static)] - index: Index, + multiname: Gc<'gc, Multiname<'gc>>, num_args: u32, }, CallSuperVoid { - #[collect(require_static)] - index: Index, + multiname: Gc<'gc, Multiname<'gc>>, num_args: u32, }, @@ -133,8 +128,7 @@ pub enum Op<'gc> { multiname: Gc<'gc, Multiname<'gc>>, }, GetDescendants { - #[collect(require_static)] - index: Index, + multiname: Gc<'gc, Multiname<'gc>>, }, GetGlobalScope, GetGlobalSlot { @@ -159,8 +153,7 @@ pub enum Op<'gc> { index: u32, }, GetSuper { - #[collect(require_static)] - index: Index, + multiname: Gc<'gc, Multiname<'gc>>, }, GreaterEquals, GreaterThan, @@ -318,8 +311,7 @@ pub enum Op<'gc> { index: u32, }, SetSuper { - #[collect(require_static)] - index: Index, + multiname: Gc<'gc, Multiname<'gc>>, }, Sf32, Sf64, diff --git a/core/src/avm2/verify.rs b/core/src/avm2/verify.rs index 96fcdef3e..3affc7b7c 100644 --- a/core/src/avm2/verify.rs +++ b/core/src/avm2/verify.rs @@ -832,7 +832,14 @@ fn resolve_op<'gc>( num_args, } } - AbcOp::CallPropLex { index, num_args } => Op::CallPropLex { index, num_args }, + AbcOp::CallPropLex { index, num_args } => { + let multiname = pool_multiname(activation, translation_unit, index)?; + + Op::CallPropLex { + multiname, + num_args, + } + } AbcOp::CallPropVoid { index, num_args } => { let multiname = pool_multiname(activation, translation_unit, index)?; @@ -842,8 +849,22 @@ fn resolve_op<'gc>( } } AbcOp::CallStatic { index, num_args } => Op::CallStatic { index, num_args }, - AbcOp::CallSuper { index, num_args } => Op::CallSuper { index, num_args }, - AbcOp::CallSuperVoid { index, num_args } => Op::CallSuperVoid { index, num_args }, + AbcOp::CallSuper { index, num_args } => { + let multiname = pool_multiname(activation, translation_unit, index)?; + + Op::CallSuper { + multiname, + num_args, + } + } + AbcOp::CallSuperVoid { index, num_args } => { + let multiname = pool_multiname(activation, translation_unit, index)?; + + Op::CallSuperVoid { + multiname, + num_args, + } + } AbcOp::ReturnValue => Op::ReturnValue, AbcOp::ReturnVoid => Op::ReturnVoid, AbcOp::GetProperty { index } => { @@ -866,8 +887,16 @@ fn resolve_op<'gc>( Op::DeleteProperty { multiname } } - AbcOp::GetSuper { index } => Op::GetSuper { index }, - AbcOp::SetSuper { index } => Op::SetSuper { index }, + AbcOp::GetSuper { index } => { + let multiname = pool_multiname(activation, translation_unit, index)?; + + Op::GetSuper { multiname } + } + AbcOp::SetSuper { index } => { + let multiname = pool_multiname(activation, translation_unit, index)?; + + Op::SetSuper { multiname } + } AbcOp::In => Op::In, AbcOp::PushScope => Op::PushScope, AbcOp::NewCatch { index } => Op::NewCatch { index }, @@ -898,7 +927,11 @@ fn resolve_op<'gc>( Op::GetLex { multiname } } - AbcOp::GetDescendants { index } => Op::GetDescendants { index }, + AbcOp::GetDescendants { index } => { + let multiname = pool_multiname(activation, translation_unit, index)?; + + Op::GetDescendants { multiname } + } AbcOp::GetSlot { index } => Op::GetSlot { index }, AbcOp::SetSlot { index } => Op::SetSlot { index }, AbcOp::GetGlobalSlot { index } => Op::GetGlobalSlot { index },