diff --git a/core/src/avm2.rs b/core/src/avm2.rs index e9abbb8b9..801872fa4 100644 --- a/core/src/avm2.rs +++ b/core/src/avm2.rs @@ -1,6 +1,5 @@ //! ActionScript Virtual Machine 2 (AS3) support -use crate::avm2::domain::Domain; use crate::avm2::globals::SystemPrototypes; use crate::avm2::scope::Scope; use crate::avm2::script::{Script, TranslationUnit}; @@ -39,6 +38,7 @@ mod traits; mod value; pub use crate::avm2::activation::Activation; +pub use crate::avm2::domain::Domain; pub use crate::avm2::names::{Namespace, QName}; pub use crate::avm2::object::{Object, StageObject, TObject}; pub use crate::avm2::value::Value; @@ -129,11 +129,11 @@ impl<'gc> Avm2<'gc> { _abc_name: &str, _lazy_init: bool, context: &mut UpdateContext<'_, 'gc, '_>, + domain: GcCell<'gc, Domain<'gc>>, ) -> Result<(), Error> { let mut read = Reader::new(abc.as_ref()); let abc_file = Rc::new(read.read()?); - let domain = Domain::movie_domain(context.gc_context, context.avm2.globals); let tunit = TranslationUnit::from_abc(abc_file.clone(), domain, context.gc_context); for i in (0..abc_file.scripts.len()).rev() { diff --git a/core/src/display_object/movie_clip.rs b/core/src/display_object/movie_clip.rs index 6f5640d9d..23e0dd317 100644 --- a/core/src/display_object/movie_clip.rs +++ b/core/src/display_object/movie_clip.rs @@ -466,6 +466,7 @@ impl<'gc> MovieClip<'gc> { let flags = reader.read_u32()?; let name = reader.read_c_string()?; let is_lazy_initialize = flags & 1 != 0; + let domain = library.avm2_domain(); // The rest of the tag is an ABC file so we can take our SwfSlice now. let slice = self @@ -481,7 +482,7 @@ impl<'gc> MovieClip<'gc> { ) })?; - if let Err(e) = Avm2::load_abc(slice, &name, is_lazy_initialize, context) { + if let Err(e) = Avm2::load_abc(slice, &name, is_lazy_initialize, context, domain) { log::warn!("Error loading ABC file: {}", e); } @@ -508,9 +509,12 @@ impl<'gc> MovieClip<'gc> { if let Some(name) = Avm2QName::from_symbol_class(&class_name, activation.context.gc_context) { - //TODO: Store a domain per movie & grab symbols out of that - let globals = activation.context.avm2.global_domain(); - let proto = globals + let library = activation + .context + .library + .library_for_movie_mut(movie.clone()); + let domain = library.avm2_domain(); + let proto = domain .read() .get_defined_value(&mut activation, name.clone()) .and_then(|v| v.coerce_to_object(&mut activation)); diff --git a/core/src/library.rs b/core/src/library.rs index 0fd8a1331..c901f49a1 100644 --- a/core/src/library.rs +++ b/core/src/library.rs @@ -1,3 +1,4 @@ +use crate::avm2::Domain as Avm2Domain; use crate::backend::audio::SoundHandle; use crate::character::Character; use crate::display_object::TDisplayObject; @@ -5,7 +6,7 @@ use crate::font::{Font, FontDescriptor}; use crate::prelude::*; use crate::tag_utils::{SwfMovie, SwfSlice}; use crate::vminterface::AvmType; -use gc_arena::{Collect, MutationContext}; +use gc_arena::{Collect, GcCell, MutationContext}; use std::collections::HashMap; use std::sync::{Arc, Weak}; use swf::{CharacterId, TagCode}; @@ -24,6 +25,7 @@ pub struct MovieLibrary<'gc> { device_font: Option>, fonts: HashMap>, avm_type: AvmType, + avm2_domain: Option>>, } impl<'gc> MovieLibrary<'gc> { @@ -35,6 +37,7 @@ impl<'gc> MovieLibrary<'gc> { device_font: None, fonts: HashMap::new(), avm_type, + avm2_domain: None, } } @@ -220,6 +223,20 @@ impl<'gc> MovieLibrary<'gc> { pub fn avm_type(&self) -> AvmType { self.avm_type } + + pub fn set_avm2_domain(&mut self, avm2_domain: GcCell<'gc, Avm2Domain<'gc>>) { + self.avm2_domain = Some(avm2_domain); + } + + /// Get the AVM2 domain this movie runs under. + /// + /// Note that the presence of an AVM2 domain does *not* indicate that this + /// movie provides AVM2 code. For example, a movie may have been loaded by + /// AVM2 code into a particular domain, even though it turned out to be + /// an AVM1 movie, and thus this domain is unused. + pub fn avm2_domain(&self) -> GcCell<'gc, Avm2Domain<'gc>> { + self.avm2_domain.unwrap() + } } /// Symbol library for multiple movies. diff --git a/core/src/loader.rs b/core/src/loader.rs index 94e3961cb..9b65aa046 100644 --- a/core/src/loader.rs +++ b/core/src/loader.rs @@ -2,6 +2,7 @@ use crate::avm1::activation::{Activation, ActivationIdentifier}; use crate::avm1::{Avm1, AvmString, Object, TObject, Value}; +use crate::avm2::Domain as Avm2Domain; use crate::backend::navigator::OwnedFuture; use crate::context::{ActionQueue, ActionType}; use crate::display_object::{DisplayObject, MorphShape, TDisplayObject}; @@ -467,7 +468,11 @@ impl<'gc> Loader<'gc> { .lock() .expect("Could not lock player!!") .update(|uc| { - uc.library.library_for_movie_mut(movie.clone()); + let domain = + Avm2Domain::movie_domain(uc.gc_context, uc.avm2.global_domain()); + uc.library + .library_for_movie_mut(movie.clone()) + .set_avm2_domain(domain); let (clip, broadcaster) = match uc.load_manager.get_loader(handle) { Some(Loader::Movie { diff --git a/core/src/player.rs b/core/src/player.rs index 8864e1297..aa1fa76ba 100644 --- a/core/src/player.rs +++ b/core/src/player.rs @@ -3,7 +3,7 @@ use crate::avm1::debug::VariableDumper; use crate::avm1::globals::system::SystemProperties; use crate::avm1::object::Object; use crate::avm1::{Avm1, AvmString, ScriptObject, TObject, Timers, Value}; -use crate::avm2::Avm2; +use crate::avm2::{Avm2, Domain as Avm2Domain}; use crate::backend::input::{InputBackend, MouseCursor}; use crate::backend::locale::LocaleBackend; use crate::backend::navigator::{NavigatorBackend, RequestOptions}; @@ -347,7 +347,11 @@ impl Player { self.instance_counter = 0; self.mutate_with_update_context(|context| { - context.library.library_for_movie_mut(context.swf.clone()); + let domain = Avm2Domain::movie_domain(context.gc_context, context.avm2.global_domain()); + context + .library + .library_for_movie_mut(context.swf.clone()) + .set_avm2_domain(domain); let root: DisplayObject = MovieClip::from_movie(context.gc_context, context.swf.clone()).into();