avm2: Pre-pool multinames for several ops
`CallPropLex`, `GetSuper`, `SetSuper`, `CallSuper`, `CallSuperVoid`, `GetDescendants`
This commit is contained in:
parent
a7021f4fee
commit
efe878211a
|
@ -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<AbcMultiname>,
|
||||
) -> Result<Gc<'gc, Multiname<'gc>>, 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<AbcMultiname>,
|
||||
multiname: Gc<'gc, Multiname<'gc>>,
|
||||
arg_count: u32,
|
||||
) -> Result<FrameControl<'gc>, 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<AbcMultiname>,
|
||||
multiname: Gc<'gc, Multiname<'gc>>,
|
||||
arg_count: u32,
|
||||
) -> Result<FrameControl<'gc>, 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<AbcMultiname>,
|
||||
multiname: Gc<'gc, Multiname<'gc>>,
|
||||
arg_count: u32,
|
||||
) -> Result<FrameControl<'gc>, 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<AbcMultiname>,
|
||||
multiname: Gc<'gc, Multiname<'gc>>,
|
||||
) -> Result<FrameControl<'gc>, 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<AbcMultiname>,
|
||||
multiname: Gc<'gc, Multiname<'gc>>,
|
||||
) -> Result<FrameControl<'gc>, 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<AbcMultiname>,
|
||||
multiname: Gc<'gc, Multiname<'gc>>,
|
||||
) -> Result<FrameControl<'gc>, 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);
|
||||
|
|
|
@ -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<AbcMultiname>,
|
||||
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<AbcMultiname>,
|
||||
multiname: Gc<'gc, Multiname<'gc>>,
|
||||
|
||||
num_args: u32,
|
||||
},
|
||||
CallSuperVoid {
|
||||
#[collect(require_static)]
|
||||
index: Index<AbcMultiname>,
|
||||
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<AbcMultiname>,
|
||||
multiname: Gc<'gc, Multiname<'gc>>,
|
||||
},
|
||||
GetGlobalScope,
|
||||
GetGlobalSlot {
|
||||
|
@ -159,8 +153,7 @@ pub enum Op<'gc> {
|
|||
index: u32,
|
||||
},
|
||||
GetSuper {
|
||||
#[collect(require_static)]
|
||||
index: Index<AbcMultiname>,
|
||||
multiname: Gc<'gc, Multiname<'gc>>,
|
||||
},
|
||||
GreaterEquals,
|
||||
GreaterThan,
|
||||
|
@ -318,8 +311,7 @@ pub enum Op<'gc> {
|
|||
index: u32,
|
||||
},
|
||||
SetSuper {
|
||||
#[collect(require_static)]
|
||||
index: Index<AbcMultiname>,
|
||||
multiname: Gc<'gc, Multiname<'gc>>,
|
||||
},
|
||||
Sf32,
|
||||
Sf64,
|
||||
|
|
|
@ -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 },
|
||||
|
|
Loading…
Reference in New Issue