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
|
//! ActionScript Virtual Machine 2 (AS3) support
|
||||||
|
|
||||||
use crate::avm2::domain::Domain;
|
|
||||||
use crate::avm2::globals::SystemPrototypes;
|
use crate::avm2::globals::SystemPrototypes;
|
||||||
use crate::avm2::scope::Scope;
|
use crate::avm2::scope::Scope;
|
||||||
use crate::avm2::script::{Script, TranslationUnit};
|
use crate::avm2::script::{Script, TranslationUnit};
|
||||||
|
@ -39,6 +38,7 @@ mod traits;
|
||||||
mod value;
|
mod value;
|
||||||
|
|
||||||
pub use crate::avm2::activation::Activation;
|
pub use crate::avm2::activation::Activation;
|
||||||
|
pub use crate::avm2::domain::Domain;
|
||||||
pub use crate::avm2::names::{Namespace, QName};
|
pub use crate::avm2::names::{Namespace, QName};
|
||||||
pub use crate::avm2::object::{Object, StageObject, TObject};
|
pub use crate::avm2::object::{Object, StageObject, TObject};
|
||||||
pub use crate::avm2::value::Value;
|
pub use crate::avm2::value::Value;
|
||||||
|
@ -129,11 +129,11 @@ impl<'gc> Avm2<'gc> {
|
||||||
_abc_name: &str,
|
_abc_name: &str,
|
||||||
_lazy_init: bool,
|
_lazy_init: bool,
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
|
domain: GcCell<'gc, Domain<'gc>>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
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 domain = Domain::movie_domain(context.gc_context, context.avm2.globals);
|
|
||||||
let tunit = TranslationUnit::from_abc(abc_file.clone(), domain, context.gc_context);
|
let tunit = TranslationUnit::from_abc(abc_file.clone(), domain, context.gc_context);
|
||||||
|
|
||||||
for i in (0..abc_file.scripts.len()).rev() {
|
for i in (0..abc_file.scripts.len()).rev() {
|
||||||
|
|
|
@ -466,6 +466,7 @@ impl<'gc> MovieClip<'gc> {
|
||||||
let flags = reader.read_u32()?;
|
let flags = reader.read_u32()?;
|
||||||
let name = reader.read_c_string()?;
|
let name = reader.read_c_string()?;
|
||||||
let is_lazy_initialize = flags & 1 != 0;
|
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.
|
// The rest of the tag is an ABC file so we can take our SwfSlice now.
|
||||||
let slice = self
|
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);
|
log::warn!("Error loading ABC file: {}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,9 +509,12 @@ impl<'gc> MovieClip<'gc> {
|
||||||
if let Some(name) =
|
if let Some(name) =
|
||||||
Avm2QName::from_symbol_class(&class_name, activation.context.gc_context)
|
Avm2QName::from_symbol_class(&class_name, activation.context.gc_context)
|
||||||
{
|
{
|
||||||
//TODO: Store a domain per movie & grab symbols out of that
|
let library = activation
|
||||||
let globals = activation.context.avm2.global_domain();
|
.context
|
||||||
let proto = globals
|
.library
|
||||||
|
.library_for_movie_mut(movie.clone());
|
||||||
|
let domain = library.avm2_domain();
|
||||||
|
let proto = domain
|
||||||
.read()
|
.read()
|
||||||
.get_defined_value(&mut activation, name.clone())
|
.get_defined_value(&mut activation, name.clone())
|
||||||
.and_then(|v| v.coerce_to_object(&mut activation));
|
.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::backend::audio::SoundHandle;
|
||||||
use crate::character::Character;
|
use crate::character::Character;
|
||||||
use crate::display_object::TDisplayObject;
|
use crate::display_object::TDisplayObject;
|
||||||
|
@ -5,7 +6,7 @@ use crate::font::{Font, FontDescriptor};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::tag_utils::{SwfMovie, SwfSlice};
|
use crate::tag_utils::{SwfMovie, SwfSlice};
|
||||||
use crate::vminterface::AvmType;
|
use crate::vminterface::AvmType;
|
||||||
use gc_arena::{Collect, MutationContext};
|
use gc_arena::{Collect, GcCell, MutationContext};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use swf::{CharacterId, TagCode};
|
use swf::{CharacterId, TagCode};
|
||||||
|
@ -24,6 +25,7 @@ pub struct MovieLibrary<'gc> {
|
||||||
device_font: Option<Font<'gc>>,
|
device_font: Option<Font<'gc>>,
|
||||||
fonts: HashMap<FontDescriptor, Font<'gc>>,
|
fonts: HashMap<FontDescriptor, Font<'gc>>,
|
||||||
avm_type: AvmType,
|
avm_type: AvmType,
|
||||||
|
avm2_domain: Option<GcCell<'gc, Avm2Domain<'gc>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'gc> MovieLibrary<'gc> {
|
impl<'gc> MovieLibrary<'gc> {
|
||||||
|
@ -35,6 +37,7 @@ impl<'gc> MovieLibrary<'gc> {
|
||||||
device_font: None,
|
device_font: None,
|
||||||
fonts: HashMap::new(),
|
fonts: HashMap::new(),
|
||||||
avm_type,
|
avm_type,
|
||||||
|
avm2_domain: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,6 +223,20 @@ impl<'gc> MovieLibrary<'gc> {
|
||||||
pub fn avm_type(&self) -> AvmType {
|
pub fn avm_type(&self) -> AvmType {
|
||||||
self.avm_type
|
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.
|
/// Symbol library for multiple movies.
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use crate::avm1::activation::{Activation, ActivationIdentifier};
|
use crate::avm1::activation::{Activation, ActivationIdentifier};
|
||||||
use crate::avm1::{Avm1, AvmString, Object, TObject, Value};
|
use crate::avm1::{Avm1, AvmString, Object, TObject, Value};
|
||||||
|
use crate::avm2::Domain as Avm2Domain;
|
||||||
use crate::backend::navigator::OwnedFuture;
|
use crate::backend::navigator::OwnedFuture;
|
||||||
use crate::context::{ActionQueue, ActionType};
|
use crate::context::{ActionQueue, ActionType};
|
||||||
use crate::display_object::{DisplayObject, MorphShape, TDisplayObject};
|
use crate::display_object::{DisplayObject, MorphShape, TDisplayObject};
|
||||||
|
@ -467,7 +468,11 @@ impl<'gc> Loader<'gc> {
|
||||||
.lock()
|
.lock()
|
||||||
.expect("Could not lock player!!")
|
.expect("Could not lock player!!")
|
||||||
.update(|uc| {
|
.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) {
|
let (clip, broadcaster) = match uc.load_manager.get_loader(handle) {
|
||||||
Some(Loader::Movie {
|
Some(Loader::Movie {
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::avm1::debug::VariableDumper;
|
||||||
use crate::avm1::globals::system::SystemProperties;
|
use crate::avm1::globals::system::SystemProperties;
|
||||||
use crate::avm1::object::Object;
|
use crate::avm1::object::Object;
|
||||||
use crate::avm1::{Avm1, AvmString, ScriptObject, TObject, Timers, Value};
|
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::input::{InputBackend, MouseCursor};
|
||||||
use crate::backend::locale::LocaleBackend;
|
use crate::backend::locale::LocaleBackend;
|
||||||
use crate::backend::navigator::{NavigatorBackend, RequestOptions};
|
use crate::backend::navigator::{NavigatorBackend, RequestOptions};
|
||||||
|
@ -347,7 +347,11 @@ impl Player {
|
||||||
self.instance_counter = 0;
|
self.instance_counter = 0;
|
||||||
|
|
||||||
self.mutate_with_update_context(|context| {
|
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 =
|
let root: DisplayObject =
|
||||||
MovieClip::from_movie(context.gc_context, context.swf.clone()).into();
|
MovieClip::from_movie(context.gc_context, context.swf.clone()).into();
|
||||||
|
|
Loading…
Reference in New Issue