avm2: Implement `uint`, `Number`, and `Boolean`'s constructors, too.

This commit is contained in:
David Wendt 2021-11-10 22:38:41 -05:00 committed by kmeisthax
parent e89d85c3f6
commit 7dd9776d40
3 changed files with 54 additions and 24 deletions

View File

@ -4,18 +4,31 @@ use crate::avm2::activation::Activation;
use crate::avm2::class::Class;
use crate::avm2::method::Method;
use crate::avm2::names::{Namespace, QName};
use crate::avm2::object::{primitive_allocator, Object};
use crate::avm2::object::{primitive_allocator, Object, TObject};
use crate::avm2::value::Value;
use crate::avm2::Error;
use gc_arena::{GcCell, MutationContext};
/// Implements `Boolean`'s instance initializer.
pub fn instance_init<'gc>(
_activation: &mut Activation<'_, 'gc, '_>,
_this: Option<Object<'gc>>,
_args: &[Value<'gc>],
activation: &mut Activation<'_, 'gc, '_>,
this: Option<Object<'gc>>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
Err("Boolean constructor is a stub.".into())
if let Some(this) = this {
if let Some(mut prim) = this.as_primitive_mut(activation.context.gc_context) {
if matches!(*prim, Value::Undefined | Value::Null) {
*prim = args
.get(0)
.cloned()
.unwrap_or(Value::Bool(false))
.coerce_to_boolean()
.into();
}
}
}
Ok(Value::Undefined)
}
/// Implements `Boolean`'s native instance initializer.

View File

@ -11,11 +11,24 @@ use gc_arena::{GcCell, MutationContext};
/// Implements `Number`'s instance initializer.
pub fn instance_init<'gc>(
_activation: &mut Activation<'_, 'gc, '_>,
_this: Option<Object<'gc>>,
_args: &[Value<'gc>],
activation: &mut Activation<'_, 'gc, '_>,
this: Option<Object<'gc>>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
Err("Number constructor is a stub.".into())
if let Some(this) = this {
if let Some(mut prim) = this.as_primitive_mut(activation.context.gc_context) {
if matches!(*prim, Value::Undefined | Value::Null) {
*prim = args
.get(0)
.cloned()
.unwrap_or(Value::Number(0.0))
.coerce_to_number(activation)?
.into();
}
}
}
Ok(Value::Undefined)
}
/// Implements `Number`'s native instance initializer.

View File

@ -4,18 +4,31 @@ use crate::avm2::activation::Activation;
use crate::avm2::class::Class;
use crate::avm2::method::{Method, ParamConfig};
use crate::avm2::names::{Namespace, QName};
use crate::avm2::object::{primitive_allocator, Object};
use crate::avm2::object::{primitive_allocator, Object, TObject};
use crate::avm2::value::Value;
use crate::avm2::Error;
use gc_arena::{GcCell, MutationContext};
/// Implements `uint`'s instance initializer.
pub fn instance_init<'gc>(
_activation: &mut Activation<'_, 'gc, '_>,
_this: Option<Object<'gc>>,
_args: &[Value<'gc>],
activation: &mut Activation<'_, 'gc, '_>,
this: Option<Object<'gc>>,
args: &[Value<'gc>],
) -> Result<Value<'gc>, Error> {
Err("uint constructor is a stub.".into())
if let Some(this) = this {
if let Some(mut prim) = this.as_primitive_mut(activation.context.gc_context) {
if matches!(*prim, Value::Undefined | Value::Null) {
*prim = args
.get(0)
.cloned()
.unwrap_or(Value::Undefined)
.coerce_to_u32(activation)?
.into();
}
}
}
Ok(Value::Undefined)
}
/// Implements `uint`'s native instance initializer.
@ -45,16 +58,7 @@ pub fn create_class<'gc>(mc: MutationContext<'gc, '_>) -> GcCell<'gc, Class<'gc>
let class = Class::new(
QName::new(Namespace::public(), "uint"),
Some(QName::new(Namespace::public(), "Object").into()),
Method::from_builtin_and_params(
instance_init,
"<uint instance initializer>",
vec![ParamConfig::of_type(
"num",
QName::new(Namespace::public(), "Object").into(),
)],
false,
mc,
),
Method::from_builtin(instance_init, "<uint instance initializer>", mc),
Method::from_builtin(class_init, "<uint class initializer>", mc),
mc,
);