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 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() {
let script = tunit.load_script(i as u32, context.gc_context)?;

View File

@ -160,41 +160,40 @@ impl<'gc> Class<'gc> {
class_index: u32,
mc: MutationContext<'gc, '_>,
) -> Result<GcCell<'gc, Self>, Error> {
let abc_class: Result<&AbcClass, Error> = unit
.abc()
let abc = unit.abc();
let abc_class: Result<&AbcClass, Error> = abc
.classes
.get(class_index as usize)
.ok_or("LoadError: Class index not valid".into());
let abc_class = abc_class?;
let abc_instance: Result<&AbcInstance, Error> = unit
.abc()
let abc_instance: Result<&AbcInstance, Error> = abc
.instances
.get(class_index as usize)
.ok_or("LoadError: Instance index not valid".into());
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 {
None
} else {
Some(Multiname::from_abc_multiname_static(
&unit.abc(),
abc_instance.super_name,
abc_instance.super_name.clone(),
)?)
};
let protected_namespace = if let Some(ns) = abc_instance.protected_namespace {
Some(Namespace::from_abc_namespace(&unit.abc(), ns)?)
let protected_namespace = if let Some(ns) = &abc_instance.protected_namespace {
Some(Namespace::from_abc_namespace(&unit.abc(), ns.clone())?)
} else {
None
};
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(
&unit.abc(),
interface_name,
interface_name.clone(),
)?);
}
@ -238,26 +237,25 @@ impl<'gc> Class<'gc> {
self.traits_loaded = true;
let abc_class: Result<&AbcClass, Error> = unit
.abc()
let abc = unit.abc();
let abc_class: Result<&AbcClass, Error> = abc
.classes
.get(class_index as usize)
.ok_or_else(|| "LoadError: Class index not valid".into());
let abc_class = abc_class?;
let abc_instance: Result<&AbcInstance, Error> = unit
.abc()
let abc_instance: Result<&AbcInstance, Error> = abc
.instances
.get(class_index as usize)
.ok_or_else(|| "LoadError: Instance index not valid".into());
let abc_instance = abc_instance?;
for abc_trait in abc_instance.traits {
for abc_trait in abc_instance.traits.iter() {
self.instance_traits
.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
.push(Trait::from_abc_trait(unit, &abc_trait, mc)?);
}
@ -363,11 +361,11 @@ impl<'gc> Class<'gc> {
/// Get this class's instance initializer.
pub fn instance_init(&self) -> Method<'gc> {
self.instance_init
self.instance_init.clone()
}
/// Get this class's class initializer.
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 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.
///
/// Parameters are as follows:
@ -42,9 +46,12 @@ pub type NativeFunction<'gc> = fn(
#[derive(Collect, Clone, Debug)]
#[collect(no_drop)]
pub struct Avm2MethodEntry<'gc> {
/// The ABC file this function was defined in.
/// The translation unit this function was defined in.
pub txunit: TranslationUnit<'gc>,
/// The underlying ABC file of the above translation unit.
pub abc: CollectWrapper<Rc<AbcFile>>,
/// The ABC method this function uses.
pub abc_method: u32,
@ -68,6 +75,7 @@ impl<'gc> Avm2MethodEntry<'gc> {
if method_body.method.0 == abc_method.0 {
return Some(Self {
txunit,
abc: CollectWrapper(txunit.abc()),
abc_method: abc_method.0,
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.
pub fn method(&self) -> &AbcMethod {
self.txunit
.abc()
.methods
.get(self.abc_method as usize)
.unwrap()
&self.abc.0.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.txunit
.abc()
&self
.abc
.0
.method_bodies
.get(self.abc_method_body as usize)
.unwrap()
@ -346,6 +351,7 @@ impl<'gc> FunctionObject<'gc> {
"Could not resolve superclass prototype {:?}",
class_read
.super_class_name()
.as_ref()
.map(|p| p.local_name())
.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,
trait_name,
*slot_id,
default_value.unwrap_or(Value::Undefined),
default_value.clone().unwrap_or(Value::Undefined),
);
}
TraitKind::Method {
@ -535,7 +535,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into<Object<'gc>> + Clone + Copy
context.gc_context,
trait_name,
*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)]
pub struct CollectWrapper<T>(T);
#[derive(Clone, Debug, Collect)]
#[derive(Copy, Clone, Debug, Collect)]
#[collect(no_drop)]
pub struct TranslationUnit<'gc>(GcCell<'gc, TranslationUnitData<'gc>>);
@ -61,7 +61,7 @@ impl<'gc> TranslationUnit<'gc> {
/// Retrieve the underlying `AbcFile` for this translation unit.
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.
@ -75,16 +75,17 @@ impl<'gc> TranslationUnit<'gc> {
return Ok(method.clone());
}
let abc = write.abc.0;
drop(write);
let method: Result<Avm2MethodEntry, Error> =
let method: Result<Avm2MethodEntry<'gc>, Error> =
Avm2MethodEntry::from_method_index(self, Index::new(method_index))
.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);
}
@ -158,8 +159,8 @@ impl<'gc> Script<'gc> {
script_index: u32,
mc: MutationContext<'gc, '_>,
) -> Result<GcCell<'gc, Self>, Error> {
let script: Result<&AbcScript, Error> = unit
.abc()
let abc = unit.abc();
let script: Result<&AbcScript, Error> = abc
.scripts
.get(script_index as usize)
.ok_or_else(|| "LoadError: Script index not valid".into());
@ -195,14 +196,14 @@ impl<'gc> Script<'gc> {
self.traits_loaded = true;
let script: Result<&AbcScript, Error> = unit
.abc()
let abc = unit.abc();
let script: Result<&AbcScript, Error> = abc
.scripts
.get(script_index as usize)
.ok_or_else(|| "LoadError: Script index not valid".into());
let script = script?;
for abc_trait in script.traits {
for abc_trait in script.traits.iter() {
self.traits
.push(Trait::from_abc_trait(unit, &abc_trait, mc)?);
}
@ -212,7 +213,7 @@ impl<'gc> Script<'gc> {
/// Return the entrypoint for the script.
pub fn init(&self) -> Method<'gc> {
self.init
self.init.clone()
}
/// Return traits for this script.

View File

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