avm2: Fix errors in LoaderInfo and stubbed remaining properties

This commit is contained in:
Nathan Adams 2023-03-27 19:22:19 +02:00
parent e19f63c3c6
commit 3a49870689
4 changed files with 101 additions and 18 deletions

View File

@ -210,6 +210,17 @@ pub fn eof_error<'gc>(
error_constructor(activation, class, message, code) error_constructor(activation, class, message, code)
} }
#[inline(never)]
#[cold]
pub fn error<'gc>(
activation: &mut Activation<'_, 'gc>,
message: &str,
code: u32,
) -> Result<Value<'gc>, Error<'gc>> {
let class = activation.avm2().classes().error;
error_constructor(activation, class, message, code)
}
fn error_constructor<'gc>( fn error_constructor<'gc>(
activation: &mut Activation<'_, 'gc>, activation: &mut Activation<'_, 'gc>,
class: ClassObject<'gc>, class: ClassObject<'gc>,

View File

@ -111,6 +111,7 @@ pub struct SystemClasses<'gc> {
pub verifyerror: ClassObject<'gc>, pub verifyerror: ClassObject<'gc>,
pub ioerror: ClassObject<'gc>, pub ioerror: ClassObject<'gc>,
pub eoferror: ClassObject<'gc>, pub eoferror: ClassObject<'gc>,
pub error: ClassObject<'gc>,
pub uncaughterrorevents: ClassObject<'gc>, pub uncaughterrorevents: ClassObject<'gc>,
pub statictext: ClassObject<'gc>, pub statictext: ClassObject<'gc>,
pub textlinemetrics: ClassObject<'gc>, pub textlinemetrics: ClassObject<'gc>,
@ -218,6 +219,7 @@ impl<'gc> SystemClasses<'gc> {
verifyerror: object, verifyerror: object,
ioerror: object, ioerror: object,
eoferror: object, eoferror: object,
error: object,
uncaughterrorevents: object, uncaughterrorevents: object,
statictext: object, statictext: object,
textlinemetrics: object, textlinemetrics: object,
@ -606,6 +608,7 @@ fn load_playerglobal<'gc>(
activation, activation,
script, script,
[ [
("", "Error", error),
("", "ArgumentError", argumenterror), ("", "ArgumentError", argumenterror),
("", "RangeError", rangeerror), ("", "RangeError", rangeerror),
("", "ReferenceError", referenceerror), ("", "ReferenceError", referenceerror),

View File

@ -30,5 +30,7 @@ package flash.display {
public native function get parameters():Object; public native function get parameters():Object;
public native function get sharedEvents():EventDispatcher; public native function get sharedEvents():EventDispatcher;
public native function get uncaughtErrorEvents():UncaughtErrorEvents; public native function get uncaughtErrorEvents():UncaughtErrorEvents;
public native function get sameDomain():Boolean;
public native function get childAllowsParent():Boolean;
} }
} }

View File

@ -2,6 +2,7 @@
use crate::avm2::activation::Activation; use crate::avm2::activation::Activation;
use crate::avm2::bytearray::Endian; use crate::avm2::bytearray::Endian;
use crate::avm2::error::error;
use crate::avm2::object::{DomainObject, LoaderStream, Object, TObject}; use crate::avm2::object::{DomainObject, LoaderStream, Object, TObject};
use crate::avm2::value::Value; use crate::avm2::value::Value;
use crate::avm2::{AvmString, Error}; use crate::avm2::{AvmString, Error};
@ -11,7 +12,6 @@ use swf::{write_swf, Compression};
pub use crate::avm2::object::loader_info_allocator; pub use crate::avm2::object::loader_info_allocator;
// FIXME - Throw an actual 'Error' with the proper code
const INSUFFICIENT: &str = const INSUFFICIENT: &str =
"Error #2099: The loading object is not sufficiently loaded to provide this information."; "Error #2099: The loading object is not sufficiently loaded to provide this information.";
@ -41,7 +41,7 @@ pub fn get_action_script_version<'gc>(
{ {
match &*loader_stream { match &*loader_stream {
LoaderStream::NotYetLoaded(_, _, _) => { LoaderStream::NotYetLoaded(_, _, _) => {
return Err(INSUFFICIENT.into()); return Err(Error::AvmError(error(_activation, INSUFFICIENT, 2099)?));
} }
LoaderStream::Swf(movie, _) => { LoaderStream::Swf(movie, _) => {
let version = if movie.is_action_script_3() { 3 } else { 2 }; let version = if movie.is_action_script_3() { 3 } else { 2 };
@ -195,7 +195,7 @@ pub fn get_frame_rate<'gc>(
{ {
match &*loader_stream { match &*loader_stream {
LoaderStream::NotYetLoaded(_, _, _) => { LoaderStream::NotYetLoaded(_, _, _) => {
return Err("Error: The stage's loader info does not have a frame rate".into()) return Err(Error::AvmError(error(_activation, INSUFFICIENT, 2099)?));
} }
LoaderStream::Swf(root, _) => { LoaderStream::Swf(root, _) => {
return Ok(root.frame_rate().to_f64().into()); return Ok(root.frame_rate().to_f64().into());
@ -220,7 +220,7 @@ pub fn get_height<'gc>(
{ {
match &*loader_stream { match &*loader_stream {
LoaderStream::NotYetLoaded(_, _, _) => { LoaderStream::NotYetLoaded(_, _, _) => {
return Err("Error: The stage's loader info does not have a height".into()) return Err(Error::AvmError(error(_activation, INSUFFICIENT, 2099)?));
} }
LoaderStream::Swf(root, _) => { LoaderStream::Swf(root, _) => {
return Ok(root.height().to_pixels().into()); return Ok(root.height().to_pixels().into());
@ -242,19 +242,9 @@ pub fn get_is_url_inaccessible<'gc>(
Ok(false.into()) Ok(false.into())
} }
/// `parentAllowsChild` getter /// `sameDomain` getter
pub fn get_parent_allows_child<'gc>( pub fn get_same_domain<'gc>(
activation: &mut Activation<'_, 'gc>, activation: &mut Activation<'_, 'gc>,
_this: Option<Object<'gc>>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
avm2_stub_getter!(activation, "flash.display.LoaderInfo", "parentAllowsChild");
Ok(false.into())
}
/// `swfVersion` getter
pub fn get_swf_version<'gc>(
_activation: &mut Activation<'_, 'gc>,
this: Option<Object<'gc>>, this: Option<Object<'gc>>,
_args: &[Value<'gc>], _args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> { ) -> Result<Value<'gc>, Error<'gc>> {
@ -265,7 +255,84 @@ pub fn get_swf_version<'gc>(
{ {
match &*loader_stream { match &*loader_stream {
LoaderStream::NotYetLoaded(_, _, _) => { LoaderStream::NotYetLoaded(_, _, _) => {
return Err("Error: The stage's loader info does not have a SWF version".into()) return Err(Error::AvmError(error(activation, INSUFFICIENT, 2099)?));
}
LoaderStream::Swf(_root, _) => {
avm2_stub_getter!(activation, "flash.display.LoaderInfo", "sameDomain");
return Ok(false.into());
}
}
}
}
Ok(Value::Undefined)
}
/// `childAllowsParent` getter
pub fn get_child_allows_parent<'gc>(
activation: &mut Activation<'_, 'gc>,
this: Option<Object<'gc>>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(this) = this {
if let Some(loader_stream) = this
.as_loader_info_object()
.and_then(|o| o.as_loader_stream())
{
match &*loader_stream {
LoaderStream::NotYetLoaded(_, _, _) => {
return Err(Error::AvmError(error(activation, INSUFFICIENT, 2099)?));
}
LoaderStream::Swf(_root, _) => {
avm2_stub_getter!(activation, "flash.display.LoaderInfo", "childAllowsParent");
return Ok(false.into());
}
}
}
}
Ok(Value::Undefined)
}
/// `parentAllowsChild` getter
pub fn get_parent_allows_child<'gc>(
activation: &mut Activation<'_, 'gc>,
this: Option<Object<'gc>>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(this) = this {
if let Some(loader_stream) = this
.as_loader_info_object()
.and_then(|o| o.as_loader_stream())
{
match &*loader_stream {
LoaderStream::NotYetLoaded(_, _, _) => {
return Err(Error::AvmError(error(activation, INSUFFICIENT, 2099)?));
}
LoaderStream::Swf(_root, _) => {
avm2_stub_getter!(activation, "flash.display.LoaderInfo", "parentAllowsChild");
return Ok(false.into());
}
}
}
}
Ok(Value::Undefined)
}
/// `swfVersion` getter
pub fn get_swf_version<'gc>(
activation: &mut Activation<'_, 'gc>,
this: Option<Object<'gc>>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
if let Some(this) = this {
if let Some(loader_stream) = this
.as_loader_info_object()
.and_then(|o| o.as_loader_stream())
{
match &*loader_stream {
LoaderStream::NotYetLoaded(_, _, _) => {
return Err(Error::AvmError(error(activation, INSUFFICIENT, 2099)?));
} }
LoaderStream::Swf(root, _) => { LoaderStream::Swf(root, _) => {
return Ok(root.version().into()); return Ok(root.version().into());
@ -312,7 +379,7 @@ pub fn get_width<'gc>(
{ {
match &*loader_stream { match &*loader_stream {
LoaderStream::NotYetLoaded(_, _, _) => { LoaderStream::NotYetLoaded(_, _, _) => {
return Err("Error: The stage's loader info does not have a width".into()) return Err(Error::AvmError(error(_activation, INSUFFICIENT, 2099)?));
} }
LoaderStream::Swf(root, _) => { LoaderStream::Swf(root, _) => {
return Ok(root.width().to_pixels().into()); return Ok(root.width().to_pixels().into());