Commit Graph

1674 Commits

Author SHA1 Message Date
David Wendt 4a2a456666 `Class::new` should also take the superclass name. 2020-08-10 23:09:13 -04:00
David Wendt d96596fd8a Add a function to manually change attributes. 2020-08-10 23:07:16 -04:00
David Wendt 44b8e5d9c7 Wrap up the existing sealed/final/interface bits in a `ClassAttributes` enumset. 2020-08-10 23:07:13 -04:00
David Wendt bf6ccfeee1 Add some convenience functions for defining native classes. 2020-08-10 23:02:42 -04:00
David Wendt c2cdc302c3 Remove further unnecessary primitive comparison checks 2020-08-10 16:38:04 -07:00
David Wendt 993f56798e Extract all of the numerical conversions into a separate module and leverage them where appropriate in AVM2 2020-08-10 16:38:04 -07:00
David Wendt 566b262d60 Move all our custom object implementations into a separate module, and use a macro to implement them. 2020-08-10 16:38:04 -07:00
David Wendt 5bcd1be270 Remove another instance of `abs` for zero-checks. 2020-08-10 16:38:04 -07:00
David Wendt 2f55c08e37 `pushbyte` should generate signed integers rather than `Number`s. 2020-08-10 16:38:04 -07:00
David Wendt 7f479f24b9 Adjust `coerce_to_string` to be less silly. 2020-08-10 16:38:04 -07:00
David Wendt a12f51903f Non-finite covers everything here. 2020-08-10 16:38:04 -07:00
David Wendt 2e8acfe6f7 Apparantly, Rust already does not care about negative zero, so we don't need to, either. 2020-08-10 16:38:04 -07:00
David Wendt 1bb6f84beb Avoid hitting `coerce_to_number` for integer comparison cases. 2020-08-10 16:38:04 -07:00
David Wendt 4e92352813 Don't promote to `f64` in strict-equality comparisons if we can promote to `i64` instead. 2020-08-10 16:38:04 -07:00
David Wendt a211698464 Handle strict and abstract equality of our various number subtypes as if they were all the same type.
ECMA-262 3rd ed. doesn't mention anything about different number types, so the standard as-if rule applies. If we are going to distinguish number types, we have to treat them as if they were the same type, promoting to `f64` as necessary to facilitate the conversion. I took a cursory look at an ECMA-262 4th ed. draft and it appears to do the same, although it calls everything `GeneralNumber` and has some really confusing psuedo-Pascal syntax for some reason.

I am extremely glad AVM2 does not provide access to 64-bit integer types (for now, at least).
2020-08-10 16:38:04 -07:00
David Wendt f3e47cb596 Further adjustments due to the massive refactor of `Activation`, `AvmX`, and `UpdateContext`. 2020-08-10 16:38:04 -07:00
David Wendt ea4c42a6d1 Split `Value::Number` into separate floating-point, integer, and unsigned representations to match the three numerical classes provided by AS3. 2020-08-10 16:38:04 -07:00
David Wendt a0895e843c Fix `matches!` lint in nightly Rust being tripped. 2020-08-10 16:38:04 -07:00
David Wendt b779dccdc1 Allow objects to provide a coercion hint for cases where a more obvious one is not available. 2020-08-10 16:38:04 -07:00
David Wendt d14fa845c2 Remove `Value::Namespace`.
Namespaces as values adds a bunch of extra special cases to the coercion and equality rules that don't really belong there. Namespace itself just returns it's URI as a string, so we can just make `NamespaceObject` do that and then treat it the same way we treat boxed primitives.
2020-08-10 16:38:04 -07:00
David Wendt e6aac48ae2 Add `NamespaceObject` to hold `Namespace`s.
The reason for this will become very apparent, very shortly.
2020-08-10 16:38:04 -07:00
David Wendt aeb1752d0f `PrimitiveObject`'s `toString` and `valueOf` should always yield their boxed values. 2020-08-10 16:38:04 -07:00
David Wendt 65b4392642 Remove `as_number`.
The only code that used it was the enumeration operations in AVM2.
2020-08-10 16:38:04 -07:00
David Wendt 4906c5a3f1 Remove uses of `as_string` in various places.
These include:

 * Name resolution in `newobject`
 * All runtime & late-bound multinames
 * `Object.hasOwnProperty`
 * `Object.propertyIsEnumerable`
 * `Object.setPropertyIsEnumerable`
2020-08-10 16:38:04 -07:00
David Wendt c040997be2 *Actually* fix the conversion.
So, I overlooked this reading the 1.45 documentation, but the first thing they did is completely change f64 conversions. Apparantly, what I was doing (and what JavaScript spec dictates) is actually considered UB in LLVM, and my ability to actually write a concise wrapping u32 conversion is actually a soundness hole in Rust. Ergo, I'm now emulating the wrapping and sign calculation, which makes this both passing it's tests again and free of soundness holes and UB.
2020-08-10 16:38:04 -07:00
David Wendt 473414e167 Explicitly request `u64` be involved with `u32` coercions.
I don't know why I'm doing this - tests are failing in CI but not locally, and I can only assume that the most obvious conversion is broken in some way on whatever other architecture GitHub Actions uses. This will explicitly mask the integer result as a u64, and then convert it down to u32. A not-broken compiler should treat this code identically.
2020-08-10 16:38:04 -07:00
David Wendt 962f6aa54c Remove `as_object`.
AVM2 is based on ES4, which as far as I'm aware, does not distinguish between "primitive values" and "objects". Thus, it is expedient to interpret any statement requiring something to be an Object to mean "not null or undefined".

Since we internally represent register values with primitive types, it is important that the VM always coerces to object before doing any other sort of type checking. Hence, something like `as_object` is unhelpful as it accidentally enforces a primitive/object distinction that ES4 attempted to remove.
2020-08-10 16:38:04 -07:00
David Wendt 8de063a916 Implement automatic primitive boxing via `coerce_to_object`. 2020-08-10 16:38:04 -07:00
David Wendt f12f67650b Stub all primitive type classes. 2020-08-10 16:38:04 -07:00
David Wendt cb0f1e9099 Add a new object variant for boxed primitives. 2020-08-10 16:38:04 -07:00
David Wendt 6ec1d453b8 Add tests for `greaterequals`, `greaterthan`, `lessequals`, and `lessthan`. 2020-08-10 16:38:04 -07:00
David Wendt b7dfce51b8 Implement `greaterequals`, `greaterthan`, `lessequals`, and `lessthan`. 2020-08-10 16:38:04 -07:00
David Wendt f88f2e225a Add tests for `>`, `<`, `<=`, and `>=`.
Note that this does NOT completely test the full range of if instructions for abstract relational comparison. Notably, the Adobe Animate CC compiler compiles each operator into it's negated equivalent, e.g. `<` becomes `ifnlt`.

I do not know how to get it to emit `ifge` or the like, which differ only by how they handle `NaN`s.
2020-08-10 16:38:04 -07:00
David Wendt 730c47cf29 Implement `ifge`, `ifgt`, `ifle`, `iflt`, `ifnge`, `ifngt`, `ifnle`, and `ifnlt`. 2020-08-10 16:38:04 -07:00
David Wendt 70a27ccb81 Implement ECMA abstract relational comparison 2020-08-10 16:38:04 -07:00
David Wendt 2ef03c6019 Allow no-hint primitive coercion 2020-08-10 16:38:04 -07:00
David Wendt 76ab8570e4 Implement and test `equals`.
The test is also far more in-depth than the `if_eq`/`if_ne` tests, which use the same set of vectors as the strict-equality tests from a while ago. Interestingly, this test passed on first run
2020-08-10 16:38:04 -07:00
David Wendt 5da4e2f118 Test for `iseq` and `isne` 2020-08-10 16:38:04 -07:00
David Wendt 29d5ae9989 Implement `ifeq` and `ifne`. 2020-08-10 16:38:04 -07:00
David Wendt ccc478e7dd Implement ECMA-262 abstract equality. 2020-08-10 16:38:04 -07:00
David Wendt 0125a14d1f Partially implement `ToObject` coercion.
Implementation is limited to generating exceptions on `null` or `undefined`. I'm not sure if primitive values don't exist in AVM2 or if this is supposed to box them like ES3, so I have decided to handle neither at this time.
2020-08-10 16:38:04 -07:00
David Wendt 86965eb674 Test for `coerce_s`.
I cannot yet figure out how to generate tests that use `convert_s`, so it's not covered.
2020-08-10 16:38:04 -07:00
David Wendt 0138300b5a Implement `coerce_s` and `convert_s`. 2020-08-10 16:38:04 -07:00
David Wendt 90d2964adf Properly handle all cases of ECMA-262 string coercions.
This code is slightly over/under-precise compared to AVM2. This is because we handle precision limiting in binary floats rather than as part of the float printing process. Flash Player may also be rounding differently than us. However, I'm pretty sure ECMA-262 allows us to slightly differ here.
2020-08-10 16:38:04 -07:00
David Wendt 35f939cb15 Add and test for `convert_u` using `ToUint32` from ECMA-262 2020-08-10 16:38:04 -07:00
David Wendt 6eb41035cf Add & test ECMA-262 ToInt32 and `convert_i` opcode.
The ECMA-262 documentation is awfully overwrought for something that boils down to "chop off the non-whole part, wrap to 32 bits, then reinterpret as signed". Bitwise operations are *hell* to describe mathematically, and such descriptions are even harder to understand.
2020-08-10 16:38:04 -07:00
David Wendt 351fe026e9 Add a test for all the above numerical coercions. 2020-08-10 16:38:04 -07:00
David Wendt 4c1489a814 Promote bytes to signed representation before pushing.
For whatever reason, `pushbyte` appears to be processed as a *signed* byte, despite the clear wording of "*byte_value* is an unsigned byte" in avm2overview.pdf. I guess it's supposed to be manually converted and promoted in this manner.
2020-08-10 16:38:04 -07:00
David Wendt 736a94a244 Implement numerical coercions according to ECMA-262 3rd Edition spec. 2020-08-10 16:38:04 -07:00
David Wendt 24fd30652d Allow tracing numbers to the console. 2020-08-10 16:38:04 -07:00
David Wendt 60f9613365 Implement and test for `convert_b`. 2020-08-10 16:38:04 -07:00
David Wendt 6cf48eb543 Implement and test `not`. 2020-08-10 16:38:04 -07:00
David Wendt b972c24f7e Oh look, I figured out how to emit `istrue`, so that's tested, too. 2020-08-10 16:38:04 -07:00
David Wendt 850ebc88a2 Add test for truthiness.
As compiled by Adobe Animate CC 2020, this test appears to only use `iffalse`. However, both `op_is_false` and `op_is_true` coerce in the same manner, so I'm not entirely sure this is a problem for now.
2020-08-10 16:38:04 -07:00
David Wendt e5c8c5b340 Expose `Infinity` to AS3. 2020-08-10 16:38:04 -07:00
David Wendt 5bb8c1836f Replace `as_bool` with `coerce_to_bool`.
Functions that need to assert Boolness without coercion should either:

1. Ensure their function declaration requires a Boolean. (We don't enforce type errors on ES4 typehints yet, but we should.)
2. Check the value type themselves and raise their own errors if necessary.

As it stands the only users of `as_bool` either needed to check the type themselves or use `coerce_to_bool`. Notably, `setPropertyIsEnumerable` doesn't appear to coerce *or* throw an error: it instead fails silently if you hand it a non-`Boolean` value.
2020-08-10 16:38:04 -07:00
dependabot-preview[bot] 04b146ffc4 build(deps): bump enumset from 1.0.0 to 1.0.1
Bumps [enumset](https://github.com/Lymia/enumset) from 1.0.0 to 1.0.1.
- [Release notes](https://github.com/Lymia/enumset/releases)
- [Changelog](https://github.com/Lymia/enumset/blob/master/RELEASES.md)
- [Commits](https://github.com/Lymia/enumset/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-09 13:15:38 -07:00
dependabot-preview[bot] 178178d9dd build(deps): bump indexmap from 1.5.0 to 1.5.1
Bumps [indexmap](https://github.com/bluss/indexmap) from 1.5.0 to 1.5.1.
- [Release notes](https://github.com/bluss/indexmap/releases)
- [Commits](https://github.com/bluss/indexmap/compare/1.5.0...1.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-08 13:37:32 -07:00
dependabot-preview[bot] 53d32d4dac build(deps): bump num_enum from 0.5.0 to 0.5.1
Bumps [num_enum](https://github.com/illicitonion/num_enum) from 0.5.0 to 0.5.1.
- [Release notes](https://github.com/illicitonion/num_enum/releases)
- [Commits](https://github.com/illicitonion/num_enum/compare/0.5.0...0.5.1)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-05 16:00:27 -07:00
dependabot-preview[bot] 0c7edda6c2 build(deps): bump syn from 1.0.37 to 1.0.38
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.37 to 1.0.38.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.37...1.0.38)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-05 15:59:02 -07:00
unknown 47a8eb6f3e avm1: Copy broadcast functions for MovieClipLoader 2020-08-04 07:02:14 -07:00
dependabot-preview[bot] f8aa185c3e build(deps): bump syn from 1.0.36 to 1.0.37
Bumps [syn](https://github.com/dtolnay/syn) from 1.0.36 to 1.0.37.
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/1.0.36...1.0.37)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-08-03 16:57:45 -07:00
David Wendt 8cb6e4af39 Further adjustments that fell through before. 2020-08-01 16:11:11 -04:00
David Wendt 4dbd26807e Remove useless lifetime in `notify_system_listeners` 2020-08-01 15:49:29 -04:00
David Wendt 8ebf5405e2 Move AVM2 into the UpdateContext. 2020-08-01 15:49:29 -04:00
David Wendt bfa5f8ae35 Further compilation fixes necessary to get the refactor to compile again.
Notably, all of the `Avm1` "run stack frame" functions can no longer take a self parameter as the update context they will be getting also has that same parameter. Ergo, they're associated functions that get the moral equivalent of self from the update context.

This also introduces a new `Activation::from_stub` which creates a stub frame that runs everything on the main movie in layer 0. This significantly reduces boilerplate code elsewhere in the project.
2020-08-01 15:49:28 -04:00
David Wendt 9b089ae1d7 Convert `array.rs` to the new activation-only format.
This also removes the function parameter on `sort_compare_numeric`. As it was only being used for string comparisons, and it was causing unfixable lifetime issues, I have instead had it take the case-sensitivity flag and call the two functions it would have been passed anyway. This fixes the lifetime issue.
2020-08-01 15:49:26 -04:00
David Wendt a19595c8b4 Embed `UpdateContext` in `Activation` directly.
The process of constructing an `Activation` now involves calling `UpdateContext.reborrow`, which "sheds" a lifetime by copying all of the borrows into a new "owned" context with that lifetime.

Likewise, to call out to functions that don't need an `Activation`, just borrow the context out of the current activation. You can also construct child-frame activations by reborrowing the parent activation's context.
2020-08-01 15:49:19 -04:00
David Wendt 7c7b019087 Move AVM1 inside UpdateContext. 2020-08-01 13:44:04 -04:00
David Wendt 14bfbc358f wip: Move UpdateContext into Activation 2020-08-01 13:33:04 -04:00
David Wendt 9f76a7b964 Ensure that `Player` always has a movie in level zero, even if no movie has been queued up yet.
There is a race condition inadvertently caused by allowing movies to be fetched in slot 0: it is possible for the player to be caught mid-load without a root movie. A lot of code assumes level 0 always exists (e.g. `levels.get(0).unwrap()`), while our initialization methods assumed no Player methods would be called until the root movie is installed. This is an unreasonable assumption, as among other things users can trigger the race condition by just playing the movie too quickly.
2020-08-01 02:35:00 -07:00
Nathan Adams 26b14bd904 avm1: Undone some __constructor__ setting on objects that don't actually construct 2020-08-01 02:33:14 -07:00
Nathan Adams db4f5007f3 avm1: TObject::create_bare_object doesn't use or need args 2020-08-01 02:33:14 -07:00
Nathan Adams 79af3ffe44 avm1: Rename TObject::new to TObject::create_bare_object 2020-08-01 02:33:14 -07:00
Nathan Adams 2131f7860b avm1: Change Object::construct to create and return a new object, instead of requiring the caller to do that first 2020-08-01 02:33:14 -07:00
Nathan Adams e74d4f0abb avm1: Make FunctionObject::allocate_function require prototype, it's not optional 2020-08-01 02:33:14 -07:00
Nathan Adams fb7fb6f99a avm1: Make FunctionObject::functional require prototype, it's not optional 2020-08-01 02:33:14 -07:00
Nathan Adams 9123d92513 avm1: Make FunctionObject::constructor require prototype, it's not optional 2020-08-01 02:33:14 -07:00
Nathan Adams 691e3b6804 avm1: Make FunctionObject::function_and_constructor require prototype, it's not optional 2020-08-01 02:33:14 -07:00
Nathan Adams 88a31cc5a9 avm1: Ensure we call movie constructors through Function::construct, not manually, to set __constructor__ 2020-08-01 02:33:14 -07:00
Nathan Adams 69a4d10338 avm1: Replace manual constructor calling with Function::construct, to ensure we set __constructor__ 2020-08-01 02:33:14 -07:00
Nathan Adams 2faf35d43e avm1: Set __constructor__ in Function::construct 2020-08-01 02:33:14 -07:00
unknown d6eeb723dc avm1: Fix panic in broadcastMessage 2020-07-29 15:24:23 -07:00
unknown 1d17910b6d chore: Remove an unnecessary file 2020-07-29 15:24:23 -07:00
unknown ef4240e95d chore: Satisfy rustfmt and clippy 2020-07-29 15:24:23 -07:00
unknown a14f19e9e5 avm1: Call the respective listeners 2020-07-29 15:24:23 -07:00
unknown 795cd72dce avm1: Broadcasting functions are now copied from AsBroadcaster 2020-07-29 15:24:23 -07:00
unknown b72dbcae96 chore: Assert his inside of listeners 2020-07-29 15:24:23 -07:00
unknown df50cbb27f avm1: Fix the behavior of addListener and removeListener 2020-07-29 15:24:23 -07:00
unknown 20989ef03d avm1: Initialize now copies the functions from AsBroadcaster 2020-07-29 15:24:23 -07:00
unknown 3a0af11e34 chore: Run rustfmt 2020-07-29 15:24:23 -07:00
unknown 890dc0ea13 avm1: Implement AsBroadcaster 2020-07-29 15:24:23 -07:00
Nathan Adams 32be19da6d avm1: Allow gotoAndStop/gotoAndPlay with frame numbers in paths - #915 2020-07-29 13:53:57 -07:00
Mike Welsh 5d08956152 tests: Add typeof and labels for Object() test 2020-07-29 13:52:51 -07:00
CUB3D 0fe3a23fd6 core: Correct handling of Object function without args 2020-07-29 13:52:51 -07:00
CUB3D 49bee3fe5c core: Implement Object() function 2020-07-29 13:52:51 -07:00
CUB3D fa8b2bca8b chore: Fix formatting 2020-07-27 12:50:31 -07:00
CUB3D c1771d7d4e core: Split function and constructor, tests, fix bug with constructor 2020-07-27 12:50:31 -07:00
CUB3D 4217138d1a chore: Update comment 2020-07-27 12:50:31 -07:00
CUB3D 7792487181 chore: Fix clippy lints 2020-07-27 12:50:31 -07:00