From 0d2235d2e02af9a30def356295d906c3b816a37e Mon Sep 17 00:00:00 2001 From: David Wendt Date: Thu, 2 Jul 2020 19:51:32 -0400 Subject: [PATCH] Resolve all remaining compilation issues with this refactor. --- core/src/avm2.rs | 2 +- core/src/avm2/class.rs | 34 ++++++++++++++++------------------ core/src/avm2/function.rs | 22 ++++++++++++++-------- core/src/avm2/object.rs | 4 ++-- core/src/avm2/script.rs | 27 ++++++++++++++------------- core/src/avm2/trait.rs | 28 +++++++++++++++++----------- 6 files changed, 64 insertions(+), 53 deletions(-) diff --git a/core/src/avm2.rs b/core/src/avm2.rs index cec4583b2..501f05b97 100644 --- a/core/src/avm2.rs +++ b/core/src/avm2.rs @@ -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)?; diff --git a/core/src/avm2/class.rs b/core/src/avm2/class.rs index 99ba2e958..b7a6ca180 100644 --- a/core/src/avm2/class.rs +++ b/core/src/avm2/class.rs @@ -160,41 +160,40 @@ impl<'gc> Class<'gc> { class_index: u32, mc: MutationContext<'gc, '_>, ) -> Result, 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() } } diff --git a/core/src/avm2/function.rs b/core/src/avm2/function.rs index 3cf03e663..0a2e2506c 100644 --- a/core/src/avm2/function.rs +++ b/core/src/avm2/function.rs @@ -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); + /// 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>, + /// 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")) ) diff --git a/core/src/avm2/object.rs b/core/src/avm2/object.rs index eabfa40c2..b88312f5d 100644 --- a/core/src/avm2/object.rs +++ b/core/src/avm2/object.rs @@ -439,7 +439,7 @@ pub trait TObject<'gc>: 'gc + Collect + Debug + Into> + 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> + Clone + Copy context.gc_context, trait_name, *slot_id, - default_value.unwrap_or(Value::Undefined), + default_value.clone().unwrap_or(Value::Undefined), ); } } diff --git a/core/src/avm2/script.rs b/core/src/avm2/script.rs index 3bb1a968e..a0010a556 100644 --- a/core/src/avm2/script.rs +++ b/core/src/avm2/script.rs @@ -14,7 +14,7 @@ use swf::avm2::types::{AbcFile, Index, Script as AbcScript}; #[collect(require_static)] pub struct CollectWrapper(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 { - 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 = + let method: Result, 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, 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. diff --git a/core/src/avm2/trait.rs b/core/src/avm2/trait.rs index 41a70ff63..456946c39 100644 --- a/core/src/avm2/trait.rs +++ b/core/src/avm2/trait.rs @@ -87,9 +87,9 @@ impl<'gc> Trait<'gc> { abc_trait: &AbcTrait, mc: MutationContext<'gc, '_>, ) -> Result { - 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 {