avm1: Implement Error object (see #251)

This commit is contained in:
Jon Pacheco 2020-07-02 15:57:18 +01:00 committed by Mike Welsh
parent 301d696670
commit 48c65f02a1
2 changed files with 65 additions and 0 deletions

View File

@ -15,6 +15,7 @@ pub(crate) mod boolean;
pub(crate) mod button;
mod color;
pub(crate) mod display_object;
pub(crate) mod error;
mod function;
mod key;
mod math;
@ -201,6 +202,9 @@ pub fn create_globals<'gc>(
let array_proto: Object<'gc> = array::create_proto(gc_context, object_proto, function_proto);
let color_proto: Object<'gc> = color::create_proto(gc_context, object_proto, function_proto);
let error_proto: Object<'gc> = error::create_proto(gc_context, object_proto, function_proto);
let xmlnode_proto: Object<'gc> =
xml::create_xmlnode_proto(gc_context, object_proto, function_proto);
@ -230,6 +234,12 @@ pub fn create_globals<'gc>(
Some(function_proto),
Some(color_proto),
);
let error = FunctionObject::function(
gc_context,
Executable::Native(error::constructor),
Some(function_proto),
Some(error_proto),
);
let function = FunctionObject::function(
gc_context,
Executable::Native(function::constructor),
@ -304,6 +314,7 @@ pub fn create_globals<'gc>(
globals.define_value(gc_context, "Array", array.into(), EnumSet::empty());
globals.define_value(gc_context, "Button", button.into(), EnumSet::empty());
globals.define_value(gc_context, "Color", color.into(), EnumSet::empty());
globals.define_value(gc_context, "Error", error.into(), EnumSet::empty());
globals.define_value(gc_context, "Object", object.into(), EnumSet::empty());
globals.define_value(gc_context, "Function", function.into(), EnumSet::empty());
globals.define_value(gc_context, "MovieClip", movie_clip.into(), EnumSet::empty());

View File

@ -0,0 +1,54 @@
//! Error object
use crate::avm1::activation::Activation;
use crate::avm1::error::Error;
use crate::avm1::property::Attribute::*;
use crate::avm1::{Object, ScriptObject, TObject, UpdateContext, Value};
use enumset::EnumSet;
use gc_arena::MutationContext;
pub fn constructor<'gc>(
activation: &mut Activation<'_, 'gc>,
context: &mut UpdateContext<'_, 'gc, '_>,
this: Object<'gc>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
let message: Value<'gc> = args.get(0).cloned().unwrap_or(Value::Undefined);
if message != Value::Undefined {
this.set("message", message, activation, context)?;
}
Ok(Value::Undefined)
}
pub fn create_proto<'gc>(
gc_context: MutationContext<'gc, '_>,
proto: Object<'gc>,
fn_proto: Object<'gc>,
) -> Object<'gc> {
let mut object = ScriptObject::object(gc_context, Some(proto));
object.define_value(gc_context, "message", "Error".into(), EnumSet::empty());
object.define_value(gc_context, "name", "Error".into(), EnumSet::empty());
object.force_set_function(
"toString",
to_string,
gc_context,
DontDelete | ReadOnly | DontEnum,
Some(fn_proto),
);
object.into()
}
fn to_string<'gc>(
activation: &mut Activation<'_, 'gc>,
context: &mut UpdateContext<'_, 'gc, '_>,
this: Object<'gc>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
let message = this.get("message", activation, context)?;
Ok(message.coerce_to_string(activation, context)?.into())
}