Make `Avm2MethodEntry` hold it's `TranslationUnit` rather than an `AbcFile`.
This commit is contained in:
parent
4467bc3193
commit
eaebd3c63c
|
@ -233,7 +233,7 @@ impl<'gc> Avm2<'gc> {
|
|||
frame_ref.lock()?;
|
||||
|
||||
let method = frame_ref.method();
|
||||
let abc = method.abc.as_ref().clone();
|
||||
let abc = method.abc();
|
||||
let _method_index = method.abc_method;
|
||||
let method_body_index = method.abc_method_body as usize;
|
||||
|
||||
|
@ -367,7 +367,11 @@ impl<'gc> Avm2<'gc> {
|
|||
/// Retrieve the current constant pool for the currently executing function.
|
||||
fn current_abc(&self) -> Option<Rc<AbcFile>> {
|
||||
self.current_stack_frame()
|
||||
.map(|sf| sf.read().method().abc.clone())
|
||||
.map(|sf| sf.read().method().abc())
|
||||
}
|
||||
|
||||
fn current_translation_unit(&self) -> Option<TranslationUnit<'gc>> {
|
||||
self.current_stack_frame().map(|sf| sf.read().method().translation_unit())
|
||||
}
|
||||
|
||||
/// Retrieve a int from the current constant pool.
|
||||
|
@ -407,8 +411,8 @@ impl<'gc> Avm2<'gc> {
|
|||
}
|
||||
|
||||
/// Retrieve a method entry from the current ABC file's method table.
|
||||
fn table_method(&mut self, index: Index<AbcMethod>) -> Result<Avm2MethodEntry, Error> {
|
||||
Avm2MethodEntry::from_method_index(self.current_abc().unwrap(), index.clone())
|
||||
fn table_method(&mut self, index: Index<AbcMethod>) -> Result<Avm2MethodEntry<'gc>, Error> {
|
||||
Avm2MethodEntry::from_method_index(self.current_translation_unit().unwrap(), index.clone())
|
||||
.ok_or_else(|| format!("Method index {} does not exist", index.0).into())
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ impl<'gc> RegisterSet<'gc> {
|
|||
#[collect(no_drop)]
|
||||
pub struct Activation<'gc> {
|
||||
/// The AVM method entry we're executing code out of.
|
||||
method: Avm2MethodEntry,
|
||||
method: Avm2MethodEntry<'gc>,
|
||||
|
||||
/// The current location of the instruction stream being executed.
|
||||
pc: usize,
|
||||
|
@ -125,7 +125,7 @@ impl<'gc> Activation<'gc> {
|
|||
|
||||
pub fn from_action(
|
||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||
method: Avm2MethodEntry,
|
||||
method: Avm2MethodEntry<'gc>,
|
||||
scope: Option<GcCell<'gc, Scope<'gc>>>,
|
||||
this: Option<Object<'gc>>,
|
||||
arguments: &[Value<'gc>],
|
||||
|
@ -184,7 +184,7 @@ impl<'gc> Activation<'gc> {
|
|||
}
|
||||
|
||||
/// Obtain a reference to the method being executed.
|
||||
pub fn method(&self) -> &Avm2MethodEntry {
|
||||
pub fn method(&self) -> &Avm2MethodEntry<'gc> {
|
||||
&self.method
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ use crate::avm2::object::{Object, ObjectPtr, TObject};
|
|||
use crate::avm2::r#trait::Trait;
|
||||
use crate::avm2::return_value::ReturnValue;
|
||||
use crate::avm2::scope::Scope;
|
||||
use crate::avm2::script::TranslationUnit;
|
||||
use crate::avm2::script_object::{ScriptObjectClass, ScriptObjectData};
|
||||
use crate::avm2::value::Value;
|
||||
use crate::avm2::{Avm2, Error};
|
||||
|
@ -39,10 +40,10 @@ pub type NativeFunction<'gc> = fn(
|
|||
|
||||
/// Represents a reference to an AVM2 method and body.
|
||||
#[derive(Collect, Clone, Debug)]
|
||||
#[collect(require_static)]
|
||||
pub struct Avm2MethodEntry {
|
||||
#[collect(no_drop)]
|
||||
pub struct Avm2MethodEntry<'gc> {
|
||||
/// The ABC file this function was defined in.
|
||||
pub abc: Rc<AbcFile>,
|
||||
pub txunit: TranslationUnit<'gc>,
|
||||
|
||||
/// The ABC method this function uses.
|
||||
pub abc_method: u32,
|
||||
|
@ -51,17 +52,22 @@ pub struct Avm2MethodEntry {
|
|||
pub abc_method_body: u32,
|
||||
}
|
||||
|
||||
impl Avm2MethodEntry {
|
||||
impl<'gc> Avm2MethodEntry<'gc> {
|
||||
/// Construct an `Avm2MethodEntry` from an `AbcFile` and method index.
|
||||
///
|
||||
/// The method body index will be determined by searching through the ABC
|
||||
/// for a matching method. If none exists, this function returns `None`.
|
||||
pub fn from_method_index(abc: Rc<AbcFile>, abc_method: Index<AbcMethod>) -> Option<Self> {
|
||||
pub fn from_method_index(
|
||||
txunit: TranslationUnit<'gc>,
|
||||
abc_method: Index<AbcMethod>,
|
||||
) -> Option<Self> {
|
||||
let abc = txunit.abc();
|
||||
|
||||
if abc.methods.get(abc_method.0 as usize).is_some() {
|
||||
for (index, method_body) in abc.method_bodies.iter().enumerate() {
|
||||
if method_body.method.0 == abc_method.0 {
|
||||
return Some(Self {
|
||||
abc,
|
||||
txunit,
|
||||
abc_method: abc_method.0,
|
||||
abc_method_body: index as u32,
|
||||
});
|
||||
|
@ -75,17 +81,27 @@ impl Avm2MethodEntry {
|
|||
/// Get the underlying ABC file.
|
||||
#[allow(dead_code)]
|
||||
pub fn abc(&self) -> Rc<AbcFile> {
|
||||
self.abc.clone()
|
||||
self.txunit.abc().clone()
|
||||
}
|
||||
|
||||
/// Get the underlying translation unit this method was defined in.
|
||||
pub fn translation_unit(&self) -> TranslationUnit<'gc> {
|
||||
self.txunit
|
||||
}
|
||||
|
||||
/// Get a reference to the ABC method entry this refers to.
|
||||
pub fn method(&self) -> &AbcMethod {
|
||||
self.abc.methods.get(self.abc_method as usize).unwrap()
|
||||
self.txunit
|
||||
.abc()
|
||||
.methods
|
||||
.get(self.abc_method as usize)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Get a reference to the ABC method body entry this refers to.
|
||||
pub fn body(&self) -> &AbcMethodBody {
|
||||
self.abc
|
||||
self.txunit
|
||||
.abc()
|
||||
.method_bodies
|
||||
.get(self.abc_method_body as usize)
|
||||
.unwrap()
|
||||
|
@ -100,7 +116,7 @@ pub enum Method<'gc> {
|
|||
Native(NativeFunction<'gc>),
|
||||
|
||||
/// An ABC-provided method entry.
|
||||
Entry(Avm2MethodEntry),
|
||||
Entry(Avm2MethodEntry<'gc>),
|
||||
}
|
||||
|
||||
unsafe impl<'gc> Collect for Method<'gc> {
|
||||
|
@ -130,14 +146,14 @@ impl<'gc> From<NativeFunction<'gc>> for Method<'gc> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'gc> From<Avm2MethodEntry> for Method<'gc> {
|
||||
fn from(a2me: Avm2MethodEntry) -> Self {
|
||||
impl<'gc> From<Avm2MethodEntry<'gc>> for Method<'gc> {
|
||||
fn from(a2me: Avm2MethodEntry<'gc>) -> Self {
|
||||
Self::Entry(a2me)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gc> Method<'gc> {
|
||||
pub fn as_entry(self) -> Result<Avm2MethodEntry, Error> {
|
||||
pub fn as_entry(self) -> Result<Avm2MethodEntry<'gc>, Error> {
|
||||
match self {
|
||||
Method::Native(_) => {
|
||||
Err("Attempted to unwrap a native method as a user-defined one".into())
|
||||
|
@ -152,7 +168,7 @@ impl<'gc> Method<'gc> {
|
|||
#[collect(no_drop)]
|
||||
pub struct Avm2Function<'gc> {
|
||||
/// The AVM method entry used to create this function.
|
||||
pub method: Avm2MethodEntry,
|
||||
pub method: Avm2MethodEntry<'gc>,
|
||||
|
||||
/// Closure scope stack at time of creation
|
||||
pub scope: Option<GcCell<'gc, Scope<'gc>>>,
|
||||
|
@ -175,7 +191,7 @@ pub enum Executable<'gc> {
|
|||
/// Code defined in a loaded ABC file.
|
||||
Action {
|
||||
/// The method code to execute from a given ABC file.
|
||||
method: Avm2MethodEntry,
|
||||
method: Avm2MethodEntry<'gc>,
|
||||
|
||||
/// The scope stack to pull variables from.
|
||||
scope: Option<GcCell<'gc, Scope<'gc>>>,
|
||||
|
|
|
@ -80,7 +80,7 @@ impl<'gc> TranslationUnit<'gc> {
|
|||
drop(write);
|
||||
|
||||
let method: Result<Avm2MethodEntry, Error> =
|
||||
Avm2MethodEntry::from_method_index(abc, Index::new(method_index))
|
||||
Avm2MethodEntry::from_method_index(self, Index::new(method_index))
|
||||
.ok_or_else(|| "Method index does not exist".into());
|
||||
let method = method?.into();
|
||||
|
||||
|
|
Loading…
Reference in New Issue