Resolve all remaining compilation issues with this refactor.

This commit is contained in:
David Wendt 2020-07-02 19:51:32 -04:00
parent 7684736bf7
commit 0d2235d2e0
6 changed files with 64 additions and 53 deletions

View File

@ -100,7 +100,7 @@ impl<'gc> Avm2<'gc> {
let mut read = Reader::new(abc.as_ref()); let mut read = Reader::new(abc.as_ref());
let abc_file = Rc::new(read.read()?); let abc_file = Rc::new(read.read()?);
let tunit = TranslationUnit::from_abc(abc_file, context.gc_context); let tunit = TranslationUnit::from_abc(abc_file.clone(), context.gc_context);
for i in (0..abc_file.scripts.len()).rev() { for i in (0..abc_file.scripts.len()).rev() {
let script = tunit.load_script(i as u32, context.gc_context)?; let script = tunit.load_script(i as u32, context.gc_context)?;

View File

@ -160,41 +160,40 @@ impl<'gc> Class<'gc> {
class_index: u32, class_index: u32,
mc: MutationContext<'gc, '_>, mc: MutationContext<'gc, '_>,
) -> Result<GcCell<'gc, Self>, Error> { ) -> Result<GcCell<'gc, Self>, Error> {
let abc_class: Result<&AbcClass, Error> = unit let abc = unit.abc();
.abc() let abc_class: Result<&AbcClass, Error> = abc
.classes .classes
.get(class_index as usize) .get(class_index as usize)
.ok_or("LoadError: Class index not valid".into()); .ok_or("LoadError: Class index not valid".into());
let abc_class = abc_class?; let abc_class = abc_class?;
let abc_instance: Result<&AbcInstance, Error> = unit let abc_instance: Result<&AbcInstance, Error> = abc
.abc()
.instances .instances
.get(class_index as usize) .get(class_index as usize)
.ok_or("LoadError: Instance index not valid".into()); .ok_or("LoadError: Instance index not valid".into());
let abc_instance = abc_instance?; let abc_instance = abc_instance?;
let name = QName::from_abc_multiname(&unit.abc(), abc_instance.name)?; let name = QName::from_abc_multiname(&unit.abc(), abc_instance.name.clone())?;
let super_class = if abc_instance.super_name.0 == 0 { let super_class = if abc_instance.super_name.0 == 0 {
None None
} else { } else {
Some(Multiname::from_abc_multiname_static( Some(Multiname::from_abc_multiname_static(
&unit.abc(), &unit.abc(),
abc_instance.super_name, abc_instance.super_name.clone(),
)?) )?)
}; };
let protected_namespace = if let Some(ns) = abc_instance.protected_namespace { let protected_namespace = if let Some(ns) = &abc_instance.protected_namespace {
Some(Namespace::from_abc_namespace(&unit.abc(), ns)?) Some(Namespace::from_abc_namespace(&unit.abc(), ns.clone())?)
} else { } else {
None None
}; };
let mut interfaces = Vec::new(); let mut interfaces = Vec::new();
for interface_name in abc_instance.interfaces { for interface_name in abc_instance.interfaces.iter() {
interfaces.push(Multiname::from_abc_multiname_static( interfaces.push(Multiname::from_abc_multiname_static(
&unit.abc(), &unit.abc(),
interface_name, interface_name.clone(),
)?); )?);
} }
@ -238,26 +237,25 @@ impl<'gc> Class<'gc> {
self.traits_loaded = true; self.traits_loaded = true;
let abc_class: Result<&AbcClass, Error> = unit let abc = unit.abc();
.abc() let abc_class: Result<&AbcClass, Error> = abc
.classes .classes
.get(class_index as usize) .get(class_index as usize)
.ok_or_else(|| "LoadError: Class index not valid".into()); .ok_or_else(|| "LoadError: Class index not valid".into());
let abc_class = abc_class?; let abc_class = abc_class?;
let abc_instance: Result<&AbcInstance, Error> = unit let abc_instance: Result<&AbcInstance, Error> = abc
.abc()
.instances .instances
.get(class_index as usize) .get(class_index as usize)
.ok_or_else(|| "LoadError: Instance index not valid".into()); .ok_or_else(|| "LoadError: Instance index not valid".into());
let abc_instance = abc_instance?; let abc_instance = abc_instance?;
for abc_trait in abc_instance.traits { for abc_trait in abc_instance.traits.iter() {
self.instance_traits self.instance_traits
.push(Trait::from_abc_trait(unit, &abc_trait, mc)?); .push(Trait::from_abc_trait(unit, &abc_trait, mc)?);
} }
for abc_trait in abc_class.traits { for abc_trait in abc_class.traits.iter() {
self.class_traits self.class_traits
.push(Trait::from_abc_trait(unit, &abc_trait, mc)?); .push(Trait::from_abc_trait(unit, &abc_trait, mc)?);
} }
@ -363,11 +361,11 @@ impl<'gc> Class<'gc> {
/// Get this class's instance initializer. /// Get this class's instance initializer.
pub fn instance_init(&self) -> Method<'gc> { pub fn instance_init(&self) -> Method<'gc> {
self.instance_init self.instance_init.clone()
} }
/// Get this class's class initializer. /// Get this class's class initializer.
pub fn class_init(&self) -> Method<'gc> { pub fn class_init(&self) -> Method<'gc> {
self.class_init self.class_init.clone()
} }
} }

View File

@ -17,6 +17,10 @@ use std::fmt;
use std::rc::Rc; use std::rc::Rc;
use swf::avm2::types::{AbcFile, Index, Method as AbcMethod, MethodBody as AbcMethodBody}; use swf::avm2::types::{AbcFile, Index, Method as AbcMethod, MethodBody as AbcMethodBody};
#[derive(Clone, Debug, Collect)]
#[collect(require_static)]
pub struct CollectWrapper<T>(T);
/// Represents a function defined in Ruffle's code. /// Represents a function defined in Ruffle's code.
/// ///
/// Parameters are as follows: /// Parameters are as follows:
@ -42,9 +46,12 @@ pub type NativeFunction<'gc> = fn(
#[derive(Collect, Clone, Debug)] #[derive(Collect, Clone, Debug)]
#[collect(no_drop)] #[collect(no_drop)]
pub struct Avm2MethodEntry<'gc> { pub struct Avm2MethodEntry<'gc> {
/// The ABC file this function was defined in. /// The translation unit this function was defined in.
pub txunit: TranslationUnit<'gc>, pub txunit: TranslationUnit<'gc>,
/// The underlying ABC file of the above translation unit.
pub abc: CollectWrapper<Rc<AbcFile>>,
/// The ABC method this function uses. /// The ABC method this function uses.
pub abc_method: u32, pub abc_method: u32,
@ -68,6 +75,7 @@ impl<'gc> Avm2MethodEntry<'gc> {
if method_body.method.0 == abc_method.0 { if method_body.method.0 == abc_method.0 {
return Some(Self { return Some(Self {
txunit, txunit,
abc: CollectWrapper(txunit.abc()),
abc_method: abc_method.0, abc_method: abc_method.0,
abc_method_body: index as u32, abc_method_body: index as u32,
}); });
@ -91,17 +99,14 @@ impl<'gc> Avm2MethodEntry<'gc> {
/// Get a reference to the ABC method entry this refers to. /// Get a reference to the ABC method entry this refers to.
pub fn method(&self) -> &AbcMethod { pub fn method(&self) -> &AbcMethod {
self.txunit &self.abc.0.methods.get(self.abc_method as usize).unwrap()
.abc()
.methods
.get(self.abc_method as usize)
.unwrap()
} }
/// Get a reference to the ABC method body entry this refers to. /// Get a reference to the ABC method body entry this refers to.
pub fn body(&self) -> &AbcMethodBody { pub fn body(&self) -> &AbcMethodBody {
self.txunit &self
.abc() .abc
.0
.method_bodies .method_bodies
.get(self.abc_method_body as usize) .get(self.abc_method_body as usize)
.unwrap() .unwrap()
@ -346,6 +351,7 @@ impl<'gc> FunctionObject<'gc> {
"Could not resolve superclass prototype {:?}", "Could not resolve superclass prototype {:?}",
class_read class_read
.super_class_name() .super_class_name()
.as_ref()
.map(|p| p.local_name()) .map(|p| p.local_name())
.unwrap_or(Some("Object")) .unwrap_or(Some("Object"))
) )

View File

@ -439,7 +439,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
context.gc_context, context.gc_context,
trait_name, trait_name,
*slot_id, *slot_id,
default_value.unwrap_or(Value::Undefined), default_value.clone().unwrap_or(Value::Undefined),
); );
} }
TraitKind::Method { TraitKind::Method {
@ -535,7 +535,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
context.gc_context, context.gc_context,
trait_name, trait_name,
*slot_id, *slot_id,
default_value.unwrap_or(Value::Undefined), default_value.clone().unwrap_or(Value::Undefined),
); );
} }
} }

View File

@ -14,7 +14,7 @@ use swf::avm2::types::{AbcFile, Index, Script as AbcScript};
#[collect(require_static)] #[collect(require_static)]
pub struct CollectWrapper<T>(T); pub struct CollectWrapper<T>(T);
#[derive(Clone, Debug, Collect)] #[derive(Copy, Clone, Debug, Collect)]
#[collect(no_drop)] #[collect(no_drop)]
pub struct TranslationUnit<'gc>(GcCell<'gc, TranslationUnitData<'gc>>); pub struct TranslationUnit<'gc>(GcCell<'gc, TranslationUnitData<'gc>>);
@ -61,7 +61,7 @@ impl<'gc> TranslationUnit<'gc> {
/// Retrieve the underlying `AbcFile` for this translation unit. /// Retrieve the underlying `AbcFile` for this translation unit.
pub fn abc(self) -> Rc<AbcFile> { pub fn abc(self) -> Rc<AbcFile> {
self.0.read().abc.0 self.0.read().abc.0.clone()
} }
/// Load a method from the ABC file and return it's method definition. /// Load a method from the ABC file and return it's method definition.
@ -75,16 +75,17 @@ impl<'gc> TranslationUnit<'gc> {
return Ok(method.clone()); return Ok(method.clone());
} }
let abc = write.abc.0;
drop(write); drop(write);
let method: Result<Avm2MethodEntry, Error> = let method: Result<Avm2MethodEntry<'gc>, Error> =
Avm2MethodEntry::from_method_index(self, Index::new(method_index)) Avm2MethodEntry::from_method_index(self, Index::new(method_index))
.ok_or_else(|| "Method index does not exist".into()); .ok_or_else(|| "Method index does not exist".into());
let method = method?.into(); let method: Method<'gc> = method?.into();
self.0.write(mc).methods.insert(method_index, method); self.0
.write(mc)
.methods
.insert(method_index, method.clone());
return Ok(method); return Ok(method);
} }
@ -158,8 +159,8 @@ impl<'gc> Script<'gc> {
script_index: u32, script_index: u32,
mc: MutationContext<'gc, '_>, mc: MutationContext<'gc, '_>,
) -> Result<GcCell<'gc, Self>, Error> { ) -> Result<GcCell<'gc, Self>, Error> {
let script: Result<&AbcScript, Error> = unit let abc = unit.abc();
.abc() let script: Result<&AbcScript, Error> = abc
.scripts .scripts
.get(script_index as usize) .get(script_index as usize)
.ok_or_else(|| "LoadError: Script index not valid".into()); .ok_or_else(|| "LoadError: Script index not valid".into());
@ -195,14 +196,14 @@ impl<'gc> Script<'gc> {
self.traits_loaded = true; self.traits_loaded = true;
let script: Result<&AbcScript, Error> = unit let abc = unit.abc();
.abc() let script: Result<&AbcScript, Error> = abc
.scripts .scripts
.get(script_index as usize) .get(script_index as usize)
.ok_or_else(|| "LoadError: Script index not valid".into()); .ok_or_else(|| "LoadError: Script index not valid".into());
let script = script?; let script = script?;
for abc_trait in script.traits { for abc_trait in script.traits.iter() {
self.traits self.traits
.push(Trait::from_abc_trait(unit, &abc_trait, mc)?); .push(Trait::from_abc_trait(unit, &abc_trait, mc)?);
} }
@ -212,7 +213,7 @@ impl<'gc> Script<'gc> {
/// Return the entrypoint for the script. /// Return the entrypoint for the script.
pub fn init(&self) -> Method<'gc> { pub fn init(&self) -> Method<'gc> {
self.init self.init.clone()
} }
/// Return traits for this script. /// Return traits for this script.

View File

@ -87,9 +87,9 @@ impl<'gc> Trait<'gc> {
abc_trait: &AbcTrait, abc_trait: &AbcTrait,
mc: MutationContext<'gc, '_>, mc: MutationContext<'gc, '_>,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
let name = QName::from_abc_multiname(&unit.abc(), abc_trait.name)?; let name = QName::from_abc_multiname(&unit.abc(), abc_trait.name.clone())?;
Ok(match abc_trait.kind { Ok(match &abc_trait.kind {
AbcTraitKind::Slot { AbcTraitKind::Slot {
slot_id, slot_id,
type_name, type_name,
@ -99,8 +99,11 @@ impl<'gc> Trait<'gc> {
is_final: abc_trait.is_final, is_final: abc_trait.is_final,
is_override: abc_trait.is_override, is_override: abc_trait.is_override,
kind: TraitKind::Slot { kind: TraitKind::Slot {
slot_id, slot_id: *slot_id,
type_name: Multiname::from_abc_multiname_static(&unit.abc(), type_name)?, type_name: Multiname::from_abc_multiname_static(
&unit.abc(),
type_name.clone(),
)?,
default_value: if let Some(dv) = value { default_value: if let Some(dv) = value {
Some(abc_default_value(&unit.abc(), &dv)?) Some(abc_default_value(&unit.abc(), &dv)?)
} else { } else {
@ -113,7 +116,7 @@ impl<'gc> Trait<'gc> {
is_final: abc_trait.is_final, is_final: abc_trait.is_final,
is_override: abc_trait.is_override, is_override: abc_trait.is_override,
kind: TraitKind::Method { kind: TraitKind::Method {
disp_id, disp_id: *disp_id,
method: unit.load_method(method.0, mc)?, method: unit.load_method(method.0, mc)?,
}, },
}, },
@ -122,7 +125,7 @@ impl<'gc> Trait<'gc> {
is_final: abc_trait.is_final, is_final: abc_trait.is_final,
is_override: abc_trait.is_override, is_override: abc_trait.is_override,
kind: TraitKind::Getter { kind: TraitKind::Getter {
disp_id, disp_id: *disp_id,
method: unit.load_method(method.0, mc)?, method: unit.load_method(method.0, mc)?,
}, },
}, },
@ -131,7 +134,7 @@ impl<'gc> Trait<'gc> {
is_final: abc_trait.is_final, is_final: abc_trait.is_final,
is_override: abc_trait.is_override, is_override: abc_trait.is_override,
kind: TraitKind::Setter { kind: TraitKind::Setter {
disp_id, disp_id: *disp_id,
method: unit.load_method(method.0, mc)?, method: unit.load_method(method.0, mc)?,
}, },
}, },
@ -140,7 +143,7 @@ impl<'gc> Trait<'gc> {
is_final: abc_trait.is_final, is_final: abc_trait.is_final,
is_override: abc_trait.is_override, is_override: abc_trait.is_override,
kind: TraitKind::Class { kind: TraitKind::Class {
slot_id, slot_id: *slot_id,
class: unit.load_class(class.0, mc)?, class: unit.load_class(class.0, mc)?,
}, },
}, },
@ -149,7 +152,7 @@ impl<'gc> Trait<'gc> {
is_final: abc_trait.is_final, is_final: abc_trait.is_final,
is_override: abc_trait.is_override, is_override: abc_trait.is_override,
kind: TraitKind::Function { kind: TraitKind::Function {
slot_id, slot_id: *slot_id,
function: unit.load_method(function.0, mc)?, function: unit.load_method(function.0, mc)?,
}, },
}, },
@ -162,8 +165,11 @@ impl<'gc> Trait<'gc> {
is_final: abc_trait.is_final, is_final: abc_trait.is_final,
is_override: abc_trait.is_override, is_override: abc_trait.is_override,
kind: TraitKind::Const { kind: TraitKind::Const {
slot_id, slot_id: *slot_id,
type_name: Multiname::from_abc_multiname_static(&unit.abc(), type_name)?, type_name: Multiname::from_abc_multiname_static(
&unit.abc(),
type_name.clone(),
)?,
default_value: if let Some(dv) = value { default_value: if let Some(dv) = value {
Some(abc_default_value(&unit.abc(), &dv)?) Some(abc_default_value(&unit.abc(), &dv)?)
} else { } else {