avm2: Create a separate domain for each loaded movie and pull symbols out of each.
This commit is contained in:
parent
cdab885979
commit
0d1676afda
|
@ -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() {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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<Font<'gc>>,
|
||||
fonts: HashMap<FontDescriptor, Font<'gc>>,
|
||||
avm_type: AvmType,
|
||||
avm2_domain: Option<GcCell<'gc, Avm2Domain<'gc>>>,
|
||||
}
|
||||
|
||||
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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue