avm2: Use TU's method cache for callstatic, newfunction opcodes
This commit is contained in:
parent
4b23f4dfb7
commit
22a0711d85
|
@ -727,8 +727,10 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
method: Gc<'gc, BytecodeMethod<'gc>>,
|
||||
index: Index<AbcMethod>,
|
||||
is_function: bool,
|
||||
) -> Result<Gc<'gc, BytecodeMethod<'gc>>, Error> {
|
||||
BytecodeMethod::from_method_index(method.translation_unit(), index, is_function, self)
|
||||
) -> Result<Method<'gc>, Error> {
|
||||
method
|
||||
.translation_unit()
|
||||
.load_method(index, is_function, self)
|
||||
}
|
||||
|
||||
/// Retrieve a class entry from the current ABC file's method table.
|
||||
|
@ -1209,7 +1211,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
let method = self.table_method(method, index, false)?;
|
||||
// TODO: What scope should the function be executed with?
|
||||
let scope = self.create_scopechain();
|
||||
let function = FunctionObject::from_method(self, method.into(), scope, None, None);
|
||||
let function = FunctionObject::from_method(self, method, scope, None, None);
|
||||
let value = function.call(Some(receiver), &args, self)?;
|
||||
|
||||
self.context.avm2.push(value);
|
||||
|
@ -1707,7 +1709,7 @@ impl<'a, 'gc, 'gc_context> Activation<'a, 'gc, 'gc_context> {
|
|||
let method_entry = self.table_method(method, index, true)?;
|
||||
let scope = self.create_scopechain();
|
||||
|
||||
let new_fn = FunctionObject::from_function(self, method_entry.into(), scope)?;
|
||||
let new_fn = FunctionObject::from_function(self, method_entry, scope)?;
|
||||
|
||||
self.context.avm2.push(new_fn);
|
||||
|
||||
|
|
|
@ -277,9 +277,9 @@ impl<'gc> Class<'gc> {
|
|||
)?);
|
||||
}
|
||||
|
||||
let instance_init = unit.load_method(abc_instance.init_method.0, false, activation)?;
|
||||
let instance_init = unit.load_method(abc_instance.init_method, false, activation)?;
|
||||
let native_instance_init = instance_init.clone();
|
||||
let class_init = unit.load_method(abc_class.init_method.0, false, activation)?;
|
||||
let class_init = unit.load_method(abc_class.init_method, false, activation)?;
|
||||
|
||||
let mut attributes = ClassAttributes::empty();
|
||||
attributes.set(ClassAttributes::SEALED, abc_instance.is_sealed);
|
||||
|
|
|
@ -15,7 +15,7 @@ use gc_arena::{Collect, Gc, GcCell, MutationContext};
|
|||
use std::cell::Ref;
|
||||
use std::mem::drop;
|
||||
use std::rc::Rc;
|
||||
use swf::avm2::types::{AbcFile, Index, Script as AbcScript};
|
||||
use swf::avm2::types::{AbcFile, Index, Method as AbcMethod, Script as AbcScript};
|
||||
|
||||
#[derive(Copy, Clone, Debug, Collect)]
|
||||
#[collect(no_drop)]
|
||||
|
@ -87,26 +87,22 @@ impl<'gc> TranslationUnit<'gc> {
|
|||
/// Load a method from the ABC file and return its method definition.
|
||||
pub fn load_method(
|
||||
self,
|
||||
method_index: u32,
|
||||
method_index: Index<AbcMethod>,
|
||||
is_function: bool,
|
||||
activation: &mut Activation<'_, 'gc, '_>,
|
||||
) -> Result<Method<'gc>, Error> {
|
||||
let read = self.0.read();
|
||||
if let Some(Some(method)) = read.methods.get(method_index as usize) {
|
||||
if let Some(Some(method)) = read.methods.get(method_index.0 as usize) {
|
||||
return Ok(method.clone());
|
||||
}
|
||||
|
||||
drop(read);
|
||||
|
||||
let method: Result<Gc<'gc, BytecodeMethod<'gc>>, Error> = BytecodeMethod::from_method_index(
|
||||
self,
|
||||
Index::new(method_index),
|
||||
is_function,
|
||||
activation,
|
||||
);
|
||||
let method: Result<Gc<'gc, BytecodeMethod<'gc>>, Error> =
|
||||
BytecodeMethod::from_method_index(self, method_index, is_function, activation);
|
||||
let method: Method<'gc> = method?.into();
|
||||
|
||||
self.0.write(activation.context.gc_context).methods[method_index as usize] =
|
||||
self.0.write(activation.context.gc_context).methods[method_index.0 as usize] =
|
||||
Some(method.clone());
|
||||
|
||||
Ok(method)
|
||||
|
@ -298,7 +294,7 @@ impl<'gc> Script<'gc> {
|
|||
.ok_or_else(|| "LoadError: Script index not valid".into());
|
||||
let script = script?;
|
||||
|
||||
let init = unit.load_method(script.init_method.0, false, activation)?;
|
||||
let init = unit.load_method(script.init_method, false, activation)?;
|
||||
|
||||
Ok(Self(GcCell::allocate(
|
||||
activation.context.gc_context,
|
||||
|
|
|
@ -214,7 +214,7 @@ impl<'gc> Trait<'gc> {
|
|||
attributes: trait_attribs_from_abc_traits(abc_trait),
|
||||
kind: TraitKind::Method {
|
||||
disp_id: *disp_id,
|
||||
method: unit.load_method(method.0, false, activation)?,
|
||||
method: unit.load_method(*method, false, activation)?,
|
||||
},
|
||||
},
|
||||
AbcTraitKind::Getter { disp_id, method } => Trait {
|
||||
|
@ -222,7 +222,7 @@ impl<'gc> Trait<'gc> {
|
|||
attributes: trait_attribs_from_abc_traits(abc_trait),
|
||||
kind: TraitKind::Getter {
|
||||
disp_id: *disp_id,
|
||||
method: unit.load_method(method.0, false, activation)?,
|
||||
method: unit.load_method(*method, false, activation)?,
|
||||
},
|
||||
},
|
||||
AbcTraitKind::Setter { disp_id, method } => Trait {
|
||||
|
@ -230,7 +230,7 @@ impl<'gc> Trait<'gc> {
|
|||
attributes: trait_attribs_from_abc_traits(abc_trait),
|
||||
kind: TraitKind::Setter {
|
||||
disp_id: *disp_id,
|
||||
method: unit.load_method(method.0, false, activation)?,
|
||||
method: unit.load_method(*method, false, activation)?,
|
||||
},
|
||||
},
|
||||
AbcTraitKind::Class { slot_id, class } => Trait {
|
||||
|
@ -246,7 +246,7 @@ impl<'gc> Trait<'gc> {
|
|||
attributes: trait_attribs_from_abc_traits(abc_trait),
|
||||
kind: TraitKind::Function {
|
||||
slot_id: *slot_id,
|
||||
function: unit.load_method(function.0, true, activation)?,
|
||||
function: unit.load_method(*function, true, activation)?,
|
||||
},
|
||||
},
|
||||
AbcTraitKind::Const {
|
||||
|
|
|
@ -24,9 +24,12 @@ pub struct ConstantPool {
|
|||
pub multinames: Vec<Multiname>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Index<T>(pub u32, pub PhantomData<T>);
|
||||
|
||||
// see: https://github.com/rust-lang/rust/issues/26925
|
||||
impl<T: Clone> Copy for Index<T> {}
|
||||
|
||||
impl<T> Index<T> {
|
||||
pub fn new(i: u32) -> Index<T> {
|
||||
Index(i, PhantomData)
|
||||
|
|
Loading…
Reference in New Issue