Skip to content

Commit 34a4bd5

Browse files
committed
avm1: Add super basic 'ASnative' implementation
1 parent 6a167aa commit 34a4bd5

File tree

8 files changed

+99
-1
lines changed

8 files changed

+99
-1
lines changed

core/src/avm1/globals.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::avm1::activation::Activation;
22
use crate::avm1::error::Error;
3+
use crate::avm1::function::NativeFunction;
34
use crate::avm1::property::Attribute;
45
use crate::avm1::property_decl::{DeclContext, Declaration};
56
use crate::avm1::{Object, Value};
@@ -11,6 +12,7 @@ use std::str;
1112
mod accessibility;
1213
pub(super) mod array;
1314
pub(crate) mod as_broadcaster;
15+
mod asnative;
1416
pub(crate) mod bevel_filter;
1517
mod bitmap_data;
1618
mod bitmap_filter;
@@ -77,6 +79,7 @@ const GLOBAL_DECLS: &[Declaration] = declare_properties! {
7779
"parseInt" => method(parse_int; DONT_ENUM);
7880
"parseFloat" => method(parse_float; DONT_ENUM);
7981
"ASSetPropFlags" => method(object::as_set_prop_flags; DONT_ENUM);
82+
"ASnative" => method(asnative::asnative; DONT_ENUM);
8083
"clearInterval" => method(clear_interval; DONT_ENUM);
8184
"setInterval" => method(set_interval; DONT_ENUM);
8285
"clearTimeout" => method(clear_timeout; DONT_ENUM);
@@ -88,6 +91,17 @@ const GLOBAL_DECLS: &[Declaration] = declare_properties! {
8891
"Infinity" => property(get_infinity; DONT_ENUM);
8992
};
9093

94+
pub fn get_native_function(id: u32) -> Option<NativeFunction> {
95+
Some(match id {
96+
0 => escape,
97+
1 => unescape,
98+
2 => parse_int,
99+
3 => parse_float,
100+
4 => trace,
101+
_ => return None,
102+
})
103+
}
104+
91105
pub fn trace<'gc>(
92106
activation: &mut Activation<'_, 'gc>,
93107
_this: Object<'gc>,

core/src/avm1/globals/asnative.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use crate::avm1::activation::Activation;
2+
use crate::avm1::error::Error;
3+
use crate::avm1::function::{FunctionObject, NativeFunction};
4+
use crate::avm1::{Object, Value};
5+
6+
pub fn asnative<'gc>(
7+
activation: &mut Activation<'_, 'gc>,
8+
_this: Object<'gc>,
9+
args: &[Value<'gc>],
10+
) -> Result<Value<'gc>, Error<'gc>> {
11+
if args.len() != 2 {
12+
return Ok(Value::Undefined);
13+
}
14+
let Ok(category) = args[0].coerce_to_u32(activation) else {
15+
return Ok(Value::Undefined);
16+
};
17+
let Ok(index) = args[1].coerce_to_u32(activation) else {
18+
return Ok(Value::Undefined);
19+
};
20+
21+
let category_lookup: Option<fn(u32) -> Option<NativeFunction>> = match category {
22+
100 => Some(crate::avm1::globals::get_native_function),
23+
101 => Some(crate::avm1::globals::object::get_native_function),
24+
_ => None,
25+
};
26+
27+
if let Some(lookup) = category_lookup {
28+
let function = lookup(index)
29+
.map(FunctionObject::native)
30+
.unwrap_or_else(|| FunctionObject::empty());
31+
return Ok(function
32+
.build(
33+
&activation.context.strings,
34+
activation.prototypes().function,
35+
None,
36+
)
37+
.into());
38+
}
39+
40+
Ok(Value::Undefined)
41+
}

core/src/avm1/globals/object.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use crate::avm1::activation::Activation;
44
use crate::avm1::error::Error;
5+
use crate::avm1::function::NativeFunction;
56
use crate::avm1::property::Attribute;
67
use crate::avm1::property_decl::{DeclContext, Declaration, SystemClass};
78
use crate::avm1::{Object, Value};
@@ -24,6 +25,13 @@ const OBJECT_DECLS: &[Declaration] = declare_properties! {
2425
"registerClass" => method(register_class; DONT_ENUM | DONT_DELETE | READ_ONLY);
2526
};
2627

28+
pub fn get_native_function(id: u32) -> Option<NativeFunction> {
29+
Some(match id {
30+
5 => has_own_property,
31+
_ => return None,
32+
})
33+
}
34+
2735
/// Constructs the `Object` class.
2836
///
2937
/// Since Object and Function are so heavily intertwined, this function does
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// ASnative(100)
2+
undefined
3+
4+
// ASnative(100, 0)
5+
[type Function]
6+
7+
// ASnative(100, "string")
8+
[type Function]
9+
10+
// ASnative(100, 0, 0)
11+
undefined
12+
13+
// ASnative("100", "0")
14+
[type Function]
15+
16+
// ASnative("onehundred", 0)
17+
undefined
18+
19+
// ASnative(100, {valueOf: function() {return 4;}})("success")
20+
success
21+
22+
// ASnative(100, 4.5)("success")
23+
success
24+
25+
// ASnative(100, 0x10000 + 4)("success")
26+
27+
// ASnative(100, 0x100000000 + 4)("success")
28+
success
29+
30+
// ASnative(100, 0)("&")
31+
%26
32+
33+
// ASnative(100, 1)("%26")
34+
&
35+
4.88 KB
Binary file not shown.
871 Bytes
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
num_frames = 1
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
num_frames = 30
2-
known_failure = true

0 commit comments

Comments
 (0)