avm1: Made avm1::Error an actual error type, and removed all calls that throw incorrect errors in avm1
This commit is contained in:
parent
ad07520af3
commit
a36e2105a3
|
@ -47,7 +47,7 @@ pub mod xml_object;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
use crate::avm1::error::ExecutionError;
|
use crate::avm1::error::{Error, ExecutionError};
|
||||||
use crate::avm1::listeners::SystemListener;
|
use crate::avm1::listeners::SystemListener;
|
||||||
use crate::avm1::value::f64_to_wrapping_u32;
|
use crate::avm1::value::f64_to_wrapping_u32;
|
||||||
pub use activation::Activation;
|
pub use activation::Activation;
|
||||||
|
@ -115,8 +115,6 @@ unsafe impl<'gc> gc_arena::Collect for Avm1<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Error = Box<dyn std::error::Error>;
|
|
||||||
|
|
||||||
impl<'gc> Avm1<'gc> {
|
impl<'gc> Avm1<'gc> {
|
||||||
pub fn new(gc_context: MutationContext<'gc, '_>, player_version: u8) -> Self {
|
pub fn new(gc_context: MutationContext<'gc, '_>, player_version: u8) -> Self {
|
||||||
let (prototypes, globals, system_listeners) = create_globals(gc_context);
|
let (prototypes, globals, system_listeners) = create_globals(gc_context);
|
||||||
|
@ -1066,7 +1064,7 @@ impl<'gc> Avm1<'gc> {
|
||||||
action: swf::avm1::types::Action,
|
action: swf::avm1::types::Action,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
log::error!("Unknown AVM1 opcode: {:?}", action);
|
log::error!("Unknown AVM1 opcode: {:?}", action);
|
||||||
Err("Unknown op".into())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action_add(&mut self, _context: &mut UpdateContext) -> Result<(), Error> {
|
fn action_add(&mut self, _context: &mut UpdateContext) -> Result<(), Error> {
|
||||||
|
@ -1300,11 +1298,11 @@ impl<'gc> Avm1<'gc> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(format!(
|
self.push(Value::Undefined);
|
||||||
|
log::warn!(
|
||||||
"Invalid method name, expected string but found {:?}",
|
"Invalid method name, expected string but found {:?}",
|
||||||
method_name
|
method_name
|
||||||
)
|
);
|
||||||
.into())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1700,7 +1698,8 @@ impl<'gc> Avm1<'gc> {
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
if target.starts_with("_level") && target.len() > 6 {
|
if target.starts_with("_level") && target.len() > 6 {
|
||||||
let url = url.to_string();
|
let url = url.to_string();
|
||||||
let level_id = target[6..].parse::<u32>()?;
|
match target[6..].parse::<u32>() {
|
||||||
|
Ok(level_id) => {
|
||||||
let fetch = context.navigator.fetch(&url, RequestOptions::get());
|
let fetch = context.navigator.fetch(&url, RequestOptions::get());
|
||||||
let level = self.resolve_level(level_id, context);
|
let level = self.resolve_level(level_id, context);
|
||||||
|
|
||||||
|
@ -1711,6 +1710,13 @@ impl<'gc> Avm1<'gc> {
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
context.navigator.spawn_future(process);
|
context.navigator.spawn_future(process);
|
||||||
|
}
|
||||||
|
Err(e) => log::warn!(
|
||||||
|
"Couldn't parse level id {} for action_get_url: {}",
|
||||||
|
target,
|
||||||
|
e
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -2015,8 +2021,11 @@ impl<'gc> Avm1<'gc> {
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
// TODO(Herschel): Results on incorrect operands?
|
// TODO(Herschel): Results on incorrect operands?
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
let val = char::try_from(self.pop().coerce_to_f64(self, context)? as u32)?;
|
let result = char::try_from(self.pop().coerce_to_f64(self, context)? as u32);
|
||||||
self.push(val.to_string());
|
match result {
|
||||||
|
Ok(val) => self.push(val.to_string()),
|
||||||
|
Err(e) => log::warn!("Couldn't parse char for action_mb_ascii_to_char: {}", e),
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2254,7 +2263,8 @@ impl<'gc> Avm1<'gc> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action_push_duplicate(&mut self, _context: &mut UpdateContext) -> Result<(), Error> {
|
fn action_push_duplicate(&mut self, _context: &mut UpdateContext) -> Result<(), Error> {
|
||||||
let val = self.stack.last().ok_or("Stack underflow")?.clone();
|
let val = self.pop();
|
||||||
|
self.push(val.clone());
|
||||||
self.push(val);
|
self.push(val);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -2290,7 +2300,9 @@ impl<'gc> Avm1<'gc> {
|
||||||
|
|
||||||
fn action_return(&mut self, context: &mut UpdateContext<'_, 'gc, '_>) -> Result<(), Error> {
|
fn action_return(&mut self, context: &mut UpdateContext<'_, 'gc, '_>) -> Result<(), Error> {
|
||||||
let return_value = self.pop();
|
let return_value = self.pop();
|
||||||
self.retire_stack_frame(context, return_value)?;
|
if let Err(e) = self.retire_stack_frame(context, return_value) {
|
||||||
|
log::warn!("Couldn't return from stack frame: {}", e);
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -2496,8 +2508,9 @@ impl<'gc> Avm1<'gc> {
|
||||||
context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
register: u8,
|
register: u8,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
// Does NOT pop the value from the stack.
|
// The value must remain on the stack.
|
||||||
let val = self.stack.last().ok_or("Stack underflow")?.clone();
|
let val = self.pop();
|
||||||
|
self.push(val.clone());
|
||||||
self.set_current_register(register, val, context);
|
self.set_current_register(register, val, context);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -2606,7 +2619,8 @@ impl<'gc> Avm1<'gc> {
|
||||||
// TODO(Herschel)
|
// TODO(Herschel)
|
||||||
let _clip = self.pop().coerce_to_object(self, context);
|
let _clip = self.pop().coerce_to_object(self, context);
|
||||||
self.push(Value::Undefined);
|
self.push(Value::Undefined);
|
||||||
Err("Unimplemented action: TargetPath".into())
|
log::warn!("Unimplemented action: TargetPath");
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toggle_quality(&mut self, _context: &mut UpdateContext) -> Result<(), Error> {
|
fn toggle_quality(&mut self, _context: &mut UpdateContext) -> Result<(), Error> {
|
||||||
|
@ -2664,7 +2678,7 @@ impl<'gc> Avm1<'gc> {
|
||||||
if !loaded {
|
if !loaded {
|
||||||
// Note that the offset is given in # of actions, NOT in bytes.
|
// Note that the offset is given in # of actions, NOT in bytes.
|
||||||
// Read the actions and toss them away.
|
// Read the actions and toss them away.
|
||||||
skip_actions(r, num_actions_to_skip)?;
|
skip_actions(r, num_actions_to_skip);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -2681,7 +2695,7 @@ impl<'gc> Avm1<'gc> {
|
||||||
if !loaded {
|
if !loaded {
|
||||||
// Note that the offset is given in # of actions, NOT in bytes.
|
// Note that the offset is given in # of actions, NOT in bytes.
|
||||||
// Read the actions and toss them away.
|
// Read the actions and toss them away.
|
||||||
skip_actions(r, num_actions_to_skip)?;
|
skip_actions(r, num_actions_to_skip);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -2723,12 +2737,12 @@ pub fn is_swf_case_sensitive(swf_version: u8) -> bool {
|
||||||
|
|
||||||
/// Utility function used by `Avm1::action_wait_for_frame` and
|
/// Utility function used by `Avm1::action_wait_for_frame` and
|
||||||
/// `Avm1::action_wait_for_frame_2`.
|
/// `Avm1::action_wait_for_frame_2`.
|
||||||
fn skip_actions(reader: &mut Reader<'_>, num_actions_to_skip: u8) -> Result<(), Error> {
|
fn skip_actions(reader: &mut Reader<'_>, num_actions_to_skip: u8) {
|
||||||
for _ in 0..num_actions_to_skip {
|
for _ in 0..num_actions_to_skip {
|
||||||
reader.read_action()?;
|
if let Err(e) = reader.read_action() {
|
||||||
|
log::warn!("Couldn't skip action: {}", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Starts draggining this display object, making it follow the cursor.
|
/// Starts draggining this display object, making it follow the cursor.
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
//! Activation records
|
//! Activation records
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::error::ExecutionError;
|
use crate::avm1::error::ExecutionError;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::scope::Scope;
|
use crate::avm1::scope::Scope;
|
||||||
use crate::avm1::{Avm1, Error, Object, Value};
|
use crate::avm1::{Avm1, Object, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use crate::display_object::DisplayObject;
|
use crate::display_object::DisplayObject;
|
||||||
use crate::tag_utils::SwfSlice;
|
use crate::tag_utils::SwfSlice;
|
||||||
|
|
|
@ -207,7 +207,7 @@ mod tests {
|
||||||
_this: Object<'gc>,
|
_this: Object<'gc>,
|
||||||
_args: &[Value<'gc>],
|
_args: &[Value<'gc>],
|
||||||
) -> Result<ReturnValue<'gc>, Error> {
|
) -> Result<ReturnValue<'gc>, Error> {
|
||||||
Err("Error message!".into())
|
Err(Error::PrototypeRecursionLimit)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -331,7 +331,7 @@ mod tests {
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
VariableDumper::dump(&object.into(), " ", avm, context),
|
VariableDumper::dump(&object.into(), " ", avm, context),
|
||||||
"[object #0] {\n broken_value: Error: \"Error message!\"\n}"
|
"[object #0] {\n broken_value: Error: \"Prototype recursion limit has been exceeded\"\n}"
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Prototype recursion limit has been exceeded")]
|
||||||
|
PrototypeRecursionLimit,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum ExecutionError {
|
pub enum ExecutionError {
|
||||||
#[error("Couldn't parse SWF")]
|
#[error("Couldn't parse SWF")]
|
||||||
|
@ -15,5 +21,5 @@ pub enum ExecutionError {
|
||||||
AlreadyExecutingFrame,
|
AlreadyExecutingFrame,
|
||||||
|
|
||||||
#[error("Script error")]
|
#[error("Script error")]
|
||||||
ScriptError(Box<dyn std::error::Error>),
|
ScriptError(#[from] Error),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
//! FSCommand handling
|
//! FSCommand handling
|
||||||
|
|
||||||
use crate::avm1::{Avm1, Error, UpdateContext};
|
use crate::avm1::error::Error;
|
||||||
|
use crate::avm1::{Avm1, UpdateContext};
|
||||||
|
|
||||||
/// Parse an FSCommand URL.
|
/// Parse an FSCommand URL.
|
||||||
pub fn parse(url: &str) -> Option<&str> {
|
pub fn parse(url: &str) -> Option<&str> {
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
//! Code relating to executable functions + calling conventions.
|
//! Code relating to executable functions + calling conventions.
|
||||||
|
|
||||||
use crate::avm1::activation::Activation;
|
use crate::avm1::activation::Activation;
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::property::{Attribute, Attribute::*};
|
use crate::avm1::property::{Attribute, Attribute::*};
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::scope::Scope;
|
use crate::avm1::scope::Scope;
|
||||||
use crate::avm1::super_object::SuperObject;
|
use crate::avm1::super_object::SuperObject;
|
||||||
use crate::avm1::value::Value;
|
use crate::avm1::value::Value;
|
||||||
use crate::avm1::{Avm1, Error, Object, ObjectPtr, ScriptObject, TObject, UpdateContext};
|
use crate::avm1::{Avm1, Object, ObjectPtr, ScriptObject, TObject, UpdateContext};
|
||||||
use crate::display_object::{DisplayObject, TDisplayObject};
|
use crate::display_object::{DisplayObject, TDisplayObject};
|
||||||
use crate::tag_utils::SwfSlice;
|
use crate::tag_utils::SwfSlice;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::fscommand;
|
use crate::avm1::fscommand;
|
||||||
use crate::avm1::function::{Executable, FunctionObject};
|
use crate::avm1::function::{Executable, FunctionObject};
|
||||||
use crate::avm1::listeners::SystemListeners;
|
use crate::avm1::listeners::SystemListeners;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, UpdateContext, Value};
|
||||||
use crate::backend::navigator::NavigationMethod;
|
use crate::backend::navigator::NavigationMethod;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
//! Array class
|
//! Array class
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::{Executable, FunctionObject};
|
use crate::avm1::function::{Executable, FunctionObject};
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, UpdateContext, Value};
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
use smallvec::alloc::borrow::Cow;
|
use smallvec::alloc::borrow::Cow;
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
//! `Boolean` class impl
|
//! `Boolean` class impl
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::{Executable, FunctionObject};
|
use crate::avm1::function::{Executable, FunctionObject};
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::value_object::ValueObject;
|
use crate::avm1::value_object::ValueObject;
|
||||||
use crate::avm1::{Avm1, Error, Object, TObject, Value};
|
use crate::avm1::{Avm1, Object, TObject, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
//! Button/SimpleButton prototype
|
//! Button/SimpleButton prototype
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::globals::display_object;
|
use crate::avm1::globals::display_object;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, UpdateContext, Value};
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
||||||
pub fn create_proto<'gc>(
|
pub fn create_proto<'gc>(
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
//! TODO: This should change when `ColorTransform` changes to match Flash's representation
|
//! TODO: This should change when `ColorTransform` changes to match Flash's representation
|
||||||
//! (See GitHub #193)
|
//! (See GitHub #193)
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::property::Attribute::*;
|
use crate::avm1::property::Attribute::*;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, UpdateContext, Value};
|
||||||
use crate::display_object::{DisplayObject, TDisplayObject};
|
use crate::display_object::{DisplayObject, TDisplayObject};
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
//! DisplayObject common methods
|
//! DisplayObject common methods
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::property::Attribute::*;
|
use crate::avm1::property::Attribute::*;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, UpdateContext, Value};
|
||||||
use crate::display_object::{DisplayObject, TDisplayObject};
|
use crate::display_object::{DisplayObject, TDisplayObject};
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
//! Function prototype
|
//! Function prototype
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, UpdateContext, Value};
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, UpdateContext, Value};
|
||||||
|
|
||||||
use crate::events::KeyCode;
|
use crate::events::KeyCode;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::object::Object;
|
use crate::avm1::object::Object;
|
||||||
use crate::avm1::property::Attribute::*;
|
use crate::avm1::property::Attribute::*;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, ScriptObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, ScriptObject, TObject, UpdateContext, Value};
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use std::f64::{INFINITY, NAN, NEG_INFINITY};
|
use std::f64::{INFINITY, NAN, NEG_INFINITY};
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
//! flash.geom.Matrix
|
//! flash.geom.Matrix
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::{Executable, FunctionObject};
|
use crate::avm1::function::{Executable, FunctionObject};
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::listeners::Listeners;
|
use crate::avm1::listeners::Listeners;
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, UpdateContext, Value};
|
||||||
|
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
//! MovieClip prototype
|
//! MovieClip prototype
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::globals::display_object::{self, AVM_DEPTH_BIAS, AVM_MAX_DEPTH};
|
use crate::avm1::globals::display_object::{self, AVM_DEPTH_BIAS, AVM_MAX_DEPTH};
|
||||||
use crate::avm1::globals::matrix::gradient_object_to_matrix;
|
use crate::avm1::globals::matrix::gradient_object_to_matrix;
|
||||||
use crate::avm1::property::Attribute::*;
|
use crate::avm1::property::Attribute::*;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, UpdateContext, Value};
|
||||||
use crate::backend::navigator::NavigationMethod;
|
use crate::backend::navigator::NavigationMethod;
|
||||||
use crate::display_object::{DisplayObject, EditText, MovieClip, TDisplayObject};
|
use crate::display_object::{DisplayObject, EditText, MovieClip, TDisplayObject};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
//! `MovieClipLoader` impl
|
//! `MovieClipLoader` impl
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::object::TObject;
|
use crate::avm1::object::TObject;
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::script_object::ScriptObject;
|
use crate::avm1::script_object::ScriptObject;
|
||||||
use crate::avm1::{Avm1, Error, Object, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, UpdateContext, Value};
|
||||||
use crate::backend::navigator::RequestOptions;
|
use crate::backend::navigator::RequestOptions;
|
||||||
use crate::display_object::{DisplayObject, TDisplayObject};
|
use crate::display_object::{DisplayObject, TDisplayObject};
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
//! `Number` class impl
|
//! `Number` class impl
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::{Executable, FunctionObject};
|
use crate::avm1::function::{Executable, FunctionObject};
|
||||||
use crate::avm1::property::Attribute::*;
|
use crate::avm1::property::Attribute::*;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::value_object::ValueObject;
|
use crate::avm1::value_object::ValueObject;
|
||||||
use crate::avm1::{Avm1, Error, Object, TObject, Value};
|
use crate::avm1::{Avm1, Object, TObject, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
//! Object prototype
|
//! Object prototype
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::{Executable, FunctionObject};
|
use crate::avm1::function::{Executable, FunctionObject};
|
||||||
use crate::avm1::property::Attribute::{self, *};
|
use crate::avm1::property::Attribute::{self, *};
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, TObject, UpdateContext, Value};
|
||||||
use crate::character::Character;
|
use crate::character::Character;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
@ -228,18 +229,15 @@ pub fn as_set_prop_flags<'gc>(
|
||||||
_: Object<'gc>,
|
_: Object<'gc>,
|
||||||
args: &[Value<'gc>],
|
args: &[Value<'gc>],
|
||||||
) -> Result<ReturnValue<'gc>, Error> {
|
) -> Result<ReturnValue<'gc>, Error> {
|
||||||
//This exists because `.into` won't work inline
|
let mut object = if let Some(object) = args.get(0).map(|v| v.coerce_to_object(avm, ac)) {
|
||||||
let my_error: Result<ReturnValue<'gc>, Error> =
|
object
|
||||||
Err("ASSetPropFlags called without object to apply to!".into());
|
} else {
|
||||||
let my_error_2: Result<ReturnValue<'gc>, Error> =
|
log::warn!("ASSetPropFlags called without object to apply to!");
|
||||||
Err("ASSetPropFlags called without object list!".into());
|
return Ok(Value::Undefined.into());
|
||||||
|
};
|
||||||
|
|
||||||
let mut object = args
|
let properties = match args.get(1) {
|
||||||
.get(0)
|
Some(Value::Object(ob)) => {
|
||||||
.ok_or_else(|| my_error.unwrap_err())?
|
|
||||||
.coerce_to_object(avm, ac);
|
|
||||||
let properties = match args.get(1).ok_or_else(|| my_error_2.unwrap_err())? {
|
|
||||||
Value::Object(ob) => {
|
|
||||||
//Convert to native array.
|
//Convert to native array.
|
||||||
//TODO: Can we make this an iterator?
|
//TODO: Can we make this an iterator?
|
||||||
let mut array = vec![];
|
let mut array = vec![];
|
||||||
|
@ -254,8 +252,12 @@ pub fn as_set_prop_flags<'gc>(
|
||||||
|
|
||||||
Some(array)
|
Some(array)
|
||||||
}
|
}
|
||||||
Value::String(s) => Some(s.split(',').map(String::from).collect()),
|
Some(Value::String(s)) => Some(s.split(',').map(String::from).collect()),
|
||||||
_ => None,
|
Some(_) => None,
|
||||||
|
None => {
|
||||||
|
log::warn!("ASSetPropFlags called without object list!");
|
||||||
|
return Ok(Value::Undefined.into());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let set_attributes = EnumSet::<Attribute>::from_u128(
|
let set_attributes = EnumSet::<Attribute>::from_u128(
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
//! flash.geom.Point
|
//! flash.geom.Point
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::{Executable, FunctionObject};
|
use crate::avm1::function::{Executable, FunctionObject};
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
//! flash.geom.Rectangle
|
//! flash.geom.Rectangle
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::{Executable, FunctionObject};
|
use crate::avm1::function::{Executable, FunctionObject};
|
||||||
use crate::avm1::globals::point::{construct_new_point, point_to_object, value_to_point};
|
use crate::avm1::globals::point::{construct_new_point, point_to_object, value_to_point};
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
//! AVM1 Sound object
|
//! AVM1 Sound object
|
||||||
//! TODO: Sound position, transform, loadSound
|
//! TODO: Sound position, transform, loadSound
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::property::Attribute::*;
|
use crate::avm1::property::Attribute::*;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, SoundObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, SoundObject, TObject, UpdateContext, Value};
|
||||||
use crate::character::Character;
|
use crate::character::Character;
|
||||||
use crate::display_object::TDisplayObject;
|
use crate::display_object::TDisplayObject;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
//! Stage object
|
//! Stage object
|
||||||
//!
|
//!
|
||||||
//! TODO: This is a very rough stub with not much implementation.
|
//! TODO: This is a very rough stub with not much implementation.
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, UpdateContext, Value};
|
||||||
|
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
//! `String` class impl
|
//! `String` class impl
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::{Executable, FunctionObject};
|
use crate::avm1::function::{Executable, FunctionObject};
|
||||||
use crate::avm1::property::Attribute::*;
|
use crate::avm1::property::Attribute::*;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::value_object::ValueObject;
|
use crate::avm1::value_object::ValueObject;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use crate::string_utils;
|
use crate::string_utils;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::object::Object;
|
use crate::avm1::object::Object;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, ScriptObject, TObject, Value};
|
use crate::avm1::{Avm1, ScriptObject, TObject, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use enumset::{EnumSet, EnumSetType};
|
use enumset::{EnumSet, EnumSetType};
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::globals::system::SystemCapabilities;
|
use crate::avm1::globals::system::SystemCapabilities;
|
||||||
use crate::avm1::object::Object;
|
use crate::avm1::object::Object;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, ScriptObject, TObject, Value};
|
use crate::avm1::{Avm1, ScriptObject, TObject, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::listeners::Listeners;
|
use crate::avm1::listeners::Listeners;
|
||||||
use crate::avm1::object::Object;
|
use crate::avm1::object::Object;
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::property::Attribute::{DontDelete, DontEnum, ReadOnly};
|
use crate::avm1::property::Attribute::{DontDelete, DontEnum, ReadOnly};
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, ScriptObject, TObject, Value};
|
use crate::avm1::{Avm1, ScriptObject, TObject, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
use std::convert::Into;
|
use std::convert::Into;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::object::Object;
|
use crate::avm1::object::Object;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, ScriptObject, TObject, Value};
|
use crate::avm1::{Avm1, ScriptObject, TObject, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::globals::display_object;
|
use crate::avm1::globals::display_object;
|
||||||
use crate::avm1::property::Attribute::*;
|
use crate::avm1::property::Attribute::*;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, UpdateContext, Value};
|
||||||
use crate::display_object::{EditText, TDisplayObject};
|
use crate::display_object::{EditText, TDisplayObject};
|
||||||
use crate::font::TextFormat;
|
use crate::font::TextFormat;
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
//! `TextFormat` impl
|
//! `TextFormat` impl
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, UpdateContext, Value};
|
||||||
use gc_arena::MutationContext;
|
use gc_arena::MutationContext;
|
||||||
|
|
||||||
fn map_defined_to_string<'gc>(
|
fn map_defined_to_string<'gc>(
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
//! XML/XMLNode global classes
|
//! XML/XMLNode global classes
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::property::Attribute::*;
|
use crate::avm1::property::Attribute::*;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::script_object::ScriptObject;
|
use crate::avm1::script_object::ScriptObject;
|
||||||
use crate::avm1::xml_object::XMLObject;
|
use crate::avm1::xml_object::XMLObject;
|
||||||
use crate::avm1::{Avm1, Error, Object, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, TObject, UpdateContext, Value};
|
||||||
use crate::backend::navigator::RequestOptions;
|
use crate::backend::navigator::RequestOptions;
|
||||||
use crate::xml;
|
use crate::xml;
|
||||||
use crate::xml::{XMLDocument, XMLNode};
|
use crate::xml::{XMLDocument, XMLNode};
|
||||||
|
@ -55,7 +56,7 @@ pub fn xmlnode_constructor<'gc>(
|
||||||
this.as_xml_node(),
|
this.as_xml_node(),
|
||||||
) {
|
) {
|
||||||
(Some(Ok(1)), Some(Ok(ref strval)), Some(ref mut this_node)) => {
|
(Some(Ok(1)), Some(Ok(ref strval)), Some(ref mut this_node)) => {
|
||||||
let mut xmlelement = XMLNode::new_element(ac.gc_context, strval, blank_document)?;
|
let mut xmlelement = XMLNode::new_element(ac.gc_context, strval, blank_document);
|
||||||
xmlelement.introduce_script_object(ac.gc_context, this);
|
xmlelement.introduce_script_object(ac.gc_context, this);
|
||||||
this_node.swap(ac.gc_context, xmlelement);
|
this_node.swap(ac.gc_context, xmlelement);
|
||||||
}
|
}
|
||||||
|
@ -84,7 +85,9 @@ pub fn xmlnode_append_child<'gc>(
|
||||||
) {
|
) {
|
||||||
if let Ok(None) = child_xmlnode.parent() {
|
if let Ok(None) = child_xmlnode.parent() {
|
||||||
let position = xmlnode.children_len();
|
let position = xmlnode.children_len();
|
||||||
xmlnode.insert_child(ac.gc_context, position, child_xmlnode)?;
|
if let Err(e) = xmlnode.insert_child(ac.gc_context, position, child_xmlnode) {
|
||||||
|
log::warn!("Couldn't insert_child inside of XMLNode.appendChild: {}", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +109,12 @@ pub fn xmlnode_insert_before<'gc>(
|
||||||
) {
|
) {
|
||||||
if let Ok(None) = child_xmlnode.parent() {
|
if let Ok(None) = child_xmlnode.parent() {
|
||||||
if let Some(position) = xmlnode.child_position(insertpoint_xmlnode) {
|
if let Some(position) = xmlnode.child_position(insertpoint_xmlnode) {
|
||||||
xmlnode.insert_child(ac.gc_context, position, child_xmlnode)?;
|
if let Err(e) = xmlnode.insert_child(ac.gc_context, position, child_xmlnode) {
|
||||||
|
log::warn!(
|
||||||
|
"Couldn't insert_child inside of XMLNode.insertBefore: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -691,7 +699,9 @@ pub fn xml_constructor<'gc>(
|
||||||
xmlnode.introduce_script_object(ac.gc_context, this);
|
xmlnode.introduce_script_object(ac.gc_context, this);
|
||||||
this_node.swap(ac.gc_context, xmlnode);
|
this_node.swap(ac.gc_context, xmlnode);
|
||||||
|
|
||||||
this_node.replace_with_str(ac.gc_context, string)?;
|
if let Err(e) = this_node.replace_with_str(ac.gc_context, string) {
|
||||||
|
log::warn!("Couldn't replace_with_str inside of XML constructor: {}", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(None, Some(ref mut this_node)) => {
|
(None, Some(ref mut this_node)) => {
|
||||||
let xmldoc = XMLDocument::new(ac.gc_context);
|
let xmldoc = XMLDocument::new(ac.gc_context);
|
||||||
|
@ -722,7 +732,7 @@ pub fn xml_create_element<'gc>(
|
||||||
.get(0)
|
.get(0)
|
||||||
.map(|v| v.coerce_to_string(avm, ac).unwrap_or_default())
|
.map(|v| v.coerce_to_string(avm, ac).unwrap_or_default())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let mut xml_node = XMLNode::new_element(ac.gc_context, &nodename, document)?;
|
let mut xml_node = XMLNode::new_element(ac.gc_context, &nodename, document);
|
||||||
let object = XMLObject::from_xml_node(ac.gc_context, xml_node, Some(avm.prototypes().xml_node));
|
let object = XMLObject::from_xml_node(ac.gc_context, xml_node, Some(avm.prototypes().xml_node));
|
||||||
|
|
||||||
xml_node.introduce_script_object(ac.gc_context, object);
|
xml_node.introduce_script_object(ac.gc_context, object);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, UpdateContext, Value};
|
||||||
|
|
||||||
use gc_arena::{Collect, MutationContext};
|
use gc_arena::{Collect, MutationContext};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
//! Object trait to expose objects to AVM
|
//! Object trait to expose objects to AVM
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::{Executable, FunctionObject};
|
use crate::avm1::function::{Executable, FunctionObject};
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
|
@ -8,7 +9,7 @@ use crate::avm1::value_object::ValueObject;
|
||||||
use crate::avm1::xml_attributes_object::XMLAttributesObject;
|
use crate::avm1::xml_attributes_object::XMLAttributesObject;
|
||||||
use crate::avm1::xml_idmap_object::XMLIDMapObject;
|
use crate::avm1::xml_idmap_object::XMLIDMapObject;
|
||||||
use crate::avm1::xml_object::XMLObject;
|
use crate::avm1::xml_object::XMLObject;
|
||||||
use crate::avm1::{Avm1, Error, ScriptObject, SoundObject, StageObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, ScriptObject, SoundObject, StageObject, UpdateContext, Value};
|
||||||
use crate::display_object::DisplayObject;
|
use crate::display_object::DisplayObject;
|
||||||
use crate::xml::XMLNode;
|
use crate::xml::XMLNode;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
|
@ -458,7 +459,7 @@ pub fn search_prototype<'gc>(
|
||||||
|
|
||||||
while proto.is_some() {
|
while proto.is_some() {
|
||||||
if depth == 255 {
|
if depth == 255 {
|
||||||
return Err("Encountered an excessively deep prototype chain.".into());
|
return Err(Error::PrototypeRecursionLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
if proto.unwrap().has_own_property(avm, context, name) {
|
if proto.unwrap().has_own_property(avm, context, name) {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
//! User-defined properties
|
//! User-defined properties
|
||||||
|
|
||||||
use self::Attribute::*;
|
use self::Attribute::*;
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, UpdateContext, Value};
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use enumset::{EnumSet, EnumSetType};
|
use enumset::{EnumSet, EnumSetType};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
//! Return value enum
|
//! Return value enum
|
||||||
|
|
||||||
use crate::avm1::activation::Activation;
|
use crate::avm1::activation::Activation;
|
||||||
use crate::avm1::{Avm1, Error, Object, Value};
|
use crate::avm1::error::Error;
|
||||||
|
use crate::avm1::error::ExecutionError;
|
||||||
|
use crate::avm1::{Avm1, Object, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use gc_arena::{Collect, GcCell};
|
use gc_arena::{Collect, GcCell};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -93,7 +95,18 @@ impl<'gc> ReturnValue<'gc> {
|
||||||
match self {
|
match self {
|
||||||
Immediate(val) => Ok(val),
|
Immediate(val) => Ok(val),
|
||||||
ResultOf(frame) => {
|
ResultOf(frame) => {
|
||||||
avm.run_current_frame(context, frame)?;
|
match avm.run_current_frame(context, frame) {
|
||||||
|
Err(ExecutionError::ScriptError(e)) => {
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
log::warn!(
|
||||||
|
"Couldn't resolve value, encountered an avm1 execution error: {}",
|
||||||
|
e
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(avm.pop())
|
Ok(avm.pop())
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
//! Represents AVM1 scope chain resolution.
|
//! Represents AVM1 scope chain resolution.
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, UpdateContext, Value};
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::{GcCell, MutationContext};
|
use gc_arena::{GcCell, MutationContext};
|
||||||
use std::cell::Ref;
|
use std::cell::Ref;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::{Executable, FunctionObject, NativeFunction};
|
use crate::avm1::function::{Executable, FunctionObject, NativeFunction};
|
||||||
use crate::avm1::property::{Attribute, Property};
|
use crate::avm1::property::{Attribute, Property};
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ObjectPtr, TObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ObjectPtr, TObject, UpdateContext, Value};
|
||||||
use crate::property_map::{Entry, PropertyMap};
|
use crate::property_map::{Entry, PropertyMap};
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
//! AVM1 object type to represent Sound objects.
|
//! AVM1 object type to represent Sound objects.
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ObjectPtr, ScriptObject, TObject, Value};
|
use crate::avm1::{Avm1, Object, ObjectPtr, ScriptObject, TObject, Value};
|
||||||
use crate::backend::audio::{SoundHandle, SoundInstanceHandle};
|
use crate::backend::audio::{SoundHandle, SoundInstanceHandle};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use crate::display_object::DisplayObject;
|
use crate::display_object::DisplayObject;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
//! AVM1 object type to represent objects on the stage.
|
//! AVM1 object type to represent objects on the stage.
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::object::search_prototype;
|
use crate::avm1::object::search_prototype;
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ObjectPtr, ScriptObject, TDisplayObject, TObject, Value};
|
use crate::avm1::{Avm1, Object, ObjectPtr, ScriptObject, TDisplayObject, TObject, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use crate::display_object::{DisplayObject, MovieClip};
|
use crate::display_object::{DisplayObject, MovieClip};
|
||||||
use crate::property_map::PropertyMap;
|
use crate::property_map::PropertyMap;
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
//! Special object that implements `super`
|
//! Special object that implements `super`
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::object::search_prototype;
|
use crate::avm1::object::search_prototype;
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::script_object::TYPE_OF_OBJECT;
|
use crate::avm1::script_object::TYPE_OF_OBJECT;
|
||||||
use crate::avm1::{Avm1, Error, Object, ObjectPtr, ScriptObject, TObject, Value};
|
use crate::avm1::{Avm1, Object, ObjectPtr, ScriptObject, TObject, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use crate::display_object::DisplayObject;
|
use crate::display_object::DisplayObject;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::value_object::ValueObject;
|
use crate::avm1::value_object::ValueObject;
|
||||||
use crate::avm1::{Avm1, Error, Object, TObject, UpdateContext};
|
use crate::avm1::{Avm1, Object, TObject, UpdateContext};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::f64::NAN;
|
use std::f64::NAN;
|
||||||
|
|
||||||
|
@ -591,13 +592,14 @@ pub fn f64_to_wrapping_i32(n: f64) -> i32 {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::{Executable, FunctionObject};
|
use crate::avm1::function::{Executable, FunctionObject};
|
||||||
use crate::avm1::globals::create_globals;
|
use crate::avm1::globals::create_globals;
|
||||||
use crate::avm1::object::{Object, TObject};
|
use crate::avm1::object::{Object, TObject};
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::script_object::ScriptObject;
|
use crate::avm1::script_object::ScriptObject;
|
||||||
use crate::avm1::test_utils::with_avm;
|
use crate::avm1::test_utils::with_avm;
|
||||||
use crate::avm1::{Avm1, Error, Value};
|
use crate::avm1::{Avm1, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use std::f64::{INFINITY, NAN, NEG_INFINITY};
|
use std::f64::{INFINITY, NAN, NEG_INFINITY};
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
//! Object impl for boxed values
|
//! Object impl for boxed values
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::object::{ObjectPtr, TObject};
|
use crate::avm1::object::{ObjectPtr, TObject};
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, UpdateContext, Value};
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::{Collect, GcCell, MutationContext};
|
use gc_arena::{Collect, GcCell, MutationContext};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
//! AVM1 object type to represent the attributes of XML nodes
|
//! AVM1 object type to represent the attributes of XML nodes
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::object::{ObjectPtr, TObject};
|
use crate::avm1::object::{ObjectPtr, TObject};
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, UpdateContext, Value};
|
||||||
use crate::xml::{XMLName, XMLNode};
|
use crate::xml::{XMLName, XMLNode};
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::{Collect, MutationContext};
|
use gc_arena::{Collect, MutationContext};
|
||||||
|
@ -110,13 +111,14 @@ impl<'gc> TObject<'gc> for XMLAttributesObject<'gc> {
|
||||||
#[allow(clippy::new_ret_no_self)]
|
#[allow(clippy::new_ret_no_self)]
|
||||||
fn new(
|
fn new(
|
||||||
&self,
|
&self,
|
||||||
_avm: &mut Avm1<'gc>,
|
avm: &mut Avm1<'gc>,
|
||||||
_context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
_this: Object<'gc>,
|
_this: Object<'gc>,
|
||||||
_args: &[Value<'gc>],
|
_args: &[Value<'gc>],
|
||||||
) -> Result<Object<'gc>, Error> {
|
) -> Result<Object<'gc>, Error> {
|
||||||
//TODO: `new xmlnode.attributes()` returns undefined, not an object
|
//TODO: `new xmlnode.attributes()` returns undefined, not an object
|
||||||
Err("Cannot create new XML Attributes object".into())
|
log::warn!("Cannot create new XML Attributes object");
|
||||||
|
Ok(Value::Undefined.coerce_to_object(avm, context))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete(
|
fn delete(
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
//! AVM1 object type to represent the attributes of XML nodes
|
//! AVM1 object type to represent the attributes of XML nodes
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::object::{ObjectPtr, TObject};
|
use crate::avm1::object::{ObjectPtr, TObject};
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, UpdateContext, Value};
|
||||||
use crate::xml::{XMLDocument, XMLNode};
|
use crate::xml::{XMLDocument, XMLNode};
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::{Collect, MutationContext};
|
use gc_arena::{Collect, MutationContext};
|
||||||
|
@ -107,13 +108,14 @@ impl<'gc> TObject<'gc> for XMLIDMapObject<'gc> {
|
||||||
#[allow(clippy::new_ret_no_self)]
|
#[allow(clippy::new_ret_no_self)]
|
||||||
fn new(
|
fn new(
|
||||||
&self,
|
&self,
|
||||||
_avm: &mut Avm1<'gc>,
|
avm: &mut Avm1<'gc>,
|
||||||
_context: &mut UpdateContext<'_, 'gc, '_>,
|
context: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
_this: Object<'gc>,
|
_this: Object<'gc>,
|
||||||
_args: &[Value<'gc>],
|
_args: &[Value<'gc>],
|
||||||
) -> Result<Object<'gc>, Error> {
|
) -> Result<Object<'gc>, Error> {
|
||||||
//TODO: `new xmlnode.attributes()` returns undefined, not an object
|
//TODO: `new xmlnode.attributes()` returns undefined, not an object
|
||||||
Err("Cannot create new XML Attributes object".into())
|
log::warn!("Cannot create new XML Attributes object");
|
||||||
|
Ok(Value::Undefined.coerce_to_object(avm, context))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn delete(
|
fn delete(
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
//! AVM1 object type to represent XML nodes
|
//! AVM1 object type to represent XML nodes
|
||||||
|
|
||||||
|
use crate::avm1::error::Error;
|
||||||
use crate::avm1::function::Executable;
|
use crate::avm1::function::Executable;
|
||||||
use crate::avm1::object::{ObjectPtr, TObject};
|
use crate::avm1::object::{ObjectPtr, TObject};
|
||||||
use crate::avm1::property::Attribute;
|
use crate::avm1::property::Attribute;
|
||||||
use crate::avm1::return_value::ReturnValue;
|
use crate::avm1::return_value::ReturnValue;
|
||||||
use crate::avm1::{Avm1, Error, Object, ScriptObject, UpdateContext, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, UpdateContext, Value};
|
||||||
use crate::xml::{XMLDocument, XMLNode};
|
use crate::xml::{XMLDocument, XMLNode};
|
||||||
use enumset::EnumSet;
|
use enumset::EnumSet;
|
||||||
use gc_arena::{Collect, MutationContext};
|
use gc_arena::{Collect, MutationContext};
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
use crate::avm1::{Avm1, Object, ScriptObject, TObject, Value};
|
use crate::avm1::{Avm1, Object, ScriptObject, TObject, Value};
|
||||||
use crate::context::UpdateContext;
|
use crate::context::UpdateContext;
|
||||||
|
|
||||||
type Error = Box<dyn std::error::Error>;
|
|
||||||
|
|
||||||
/// A set of text formatting options to be applied to some part, or the whole
|
/// A set of text formatting options to be applied to some part, or the whole
|
||||||
/// of, a given text field.
|
/// of, a given text field.
|
||||||
///
|
///
|
||||||
|
@ -65,7 +63,7 @@ fn getstr_from_avm1_object<'gc>(
|
||||||
name: &str,
|
name: &str,
|
||||||
avm1: &mut Avm1<'gc>,
|
avm1: &mut Avm1<'gc>,
|
||||||
uc: &mut UpdateContext<'_, 'gc, '_>,
|
uc: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
) -> Result<Option<String>, Error> {
|
) -> Result<Option<String>, crate::avm1::error::Error> {
|
||||||
Ok(match object.get(name, avm1, uc)? {
|
Ok(match object.get(name, avm1, uc)? {
|
||||||
Value::Undefined => None,
|
Value::Undefined => None,
|
||||||
Value::Null => None,
|
Value::Null => None,
|
||||||
|
@ -78,7 +76,7 @@ fn getfloat_from_avm1_object<'gc>(
|
||||||
name: &str,
|
name: &str,
|
||||||
avm1: &mut Avm1<'gc>,
|
avm1: &mut Avm1<'gc>,
|
||||||
uc: &mut UpdateContext<'_, 'gc, '_>,
|
uc: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
) -> Result<Option<f64>, Error> {
|
) -> Result<Option<f64>, crate::avm1::error::Error> {
|
||||||
Ok(match object.get(name, avm1, uc)? {
|
Ok(match object.get(name, avm1, uc)? {
|
||||||
Value::Undefined => None,
|
Value::Undefined => None,
|
||||||
Value::Null => None,
|
Value::Null => None,
|
||||||
|
@ -91,7 +89,7 @@ fn getbool_from_avm1_object<'gc>(
|
||||||
name: &str,
|
name: &str,
|
||||||
avm1: &mut Avm1<'gc>,
|
avm1: &mut Avm1<'gc>,
|
||||||
uc: &mut UpdateContext<'_, 'gc, '_>,
|
uc: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
) -> Result<Option<bool>, Error> {
|
) -> Result<Option<bool>, crate::avm1::error::Error> {
|
||||||
Ok(match object.get(name, avm1, uc)? {
|
Ok(match object.get(name, avm1, uc)? {
|
||||||
Value::Undefined => None,
|
Value::Undefined => None,
|
||||||
Value::Null => None,
|
Value::Null => None,
|
||||||
|
@ -105,7 +103,7 @@ impl TextFormat {
|
||||||
object1: Object<'gc>,
|
object1: Object<'gc>,
|
||||||
avm1: &mut Avm1<'gc>,
|
avm1: &mut Avm1<'gc>,
|
||||||
uc: &mut UpdateContext<'_, 'gc, '_>,
|
uc: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, crate::avm1::error::Error> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
font: getstr_from_avm1_object(object1, "font", avm1, uc)?,
|
font: getstr_from_avm1_object(object1, "font", avm1, uc)?,
|
||||||
size: getfloat_from_avm1_object(object1, "size", avm1, uc)?,
|
size: getfloat_from_avm1_object(object1, "size", avm1, uc)?,
|
||||||
|
@ -142,7 +140,7 @@ impl TextFormat {
|
||||||
&self,
|
&self,
|
||||||
avm1: &mut Avm1<'gc>,
|
avm1: &mut Avm1<'gc>,
|
||||||
uc: &mut UpdateContext<'_, 'gc, '_>,
|
uc: &mut UpdateContext<'_, 'gc, '_>,
|
||||||
) -> Result<Object<'gc>, Error> {
|
) -> Result<Object<'gc>, crate::avm1::error::Error> {
|
||||||
let object = ScriptObject::object(uc.gc_context, Some(avm1.prototypes().text_format));
|
let object = ScriptObject::object(uc.gc_context, Some(avm1.prototypes().text_format));
|
||||||
|
|
||||||
object.set(
|
object.set(
|
||||||
|
|
|
@ -164,8 +164,8 @@ impl<'gc> XMLNode<'gc> {
|
||||||
mc: MutationContext<'gc, '_>,
|
mc: MutationContext<'gc, '_>,
|
||||||
element_name: &str,
|
element_name: &str,
|
||||||
document: XMLDocument<'gc>,
|
document: XMLDocument<'gc>,
|
||||||
) -> Result<Self, Error> {
|
) -> Self {
|
||||||
Ok(XMLNode(GcCell::allocate(
|
XMLNode(GcCell::allocate(
|
||||||
mc,
|
mc,
|
||||||
XMLNodeData::Element {
|
XMLNodeData::Element {
|
||||||
script_object: None,
|
script_object: None,
|
||||||
|
@ -178,7 +178,7 @@ impl<'gc> XMLNode<'gc> {
|
||||||
attributes_script_object: None,
|
attributes_script_object: None,
|
||||||
children: Vec::new(),
|
children: Vec::new(),
|
||||||
},
|
},
|
||||||
)))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a new XML root node.
|
/// Construct a new XML root node.
|
||||||
|
|
Loading…
Reference in New Issue