Commit Graph

497 Commits

Author SHA1 Message Date
David Wendt 854526923e Calls to `super` inherently bind to itself.
This requires some subclassing nonsense to be able to smuggle a self-reference into `SuperObject`s. When successfully smuggled, all calls to `call` will be invoked with the `super` object as `this`. This allows constructor chaining to work.

Note that not all `Object` trait methods are implemented on `SuperObject`, so things like `delete this.x` in super constructors will randomly fail. This should be fixed.
2019-12-15 13:32:04 -08:00
David Wendt 548f19ffbb `ActionExtends` uses the class's explicit prototype, not it's implicit prototype which should almost always be `Function.prototype`. 2019-12-15 13:32:04 -08:00
David Wendt eb06501492 Since `get_local` doesn't scale the prototype chain anymore, we don't need to change the prototype chain traversal anymore. 2019-12-15 13:32:04 -08:00
David Wendt e08cfcd288 Enable the `as2-oop` test since it now passes. 2019-12-15 13:32:04 -08:00
David Wendt 5c1ac19c1b Implement `super`, mostly.
We implement `super` by way of a new `Object` impl which wraps arbitrary objects with a modified prototype chain. Specifically, the lowest layer of the prototype chain is omitted. This new `SuperObject` script is composable: a chain of two `SuperObject`s will go two levels of inheritance upwards while still maintaining non-prototype property access.
2019-12-15 13:32:04 -08:00
David Wendt 681b4adfa4 Functions close over the constant pool they were defined with. 2019-12-15 13:17:41 -08:00
David Wendt 71d9655f6d Implement `ASSetPropFlags` 2019-12-15 13:17:41 -08:00
David Wendt d173e91de6 AS2 OOP test. This won't actually pass until we have interfaces, init actions, and constant pool closures merged in. Hence, it's ignored. 2019-12-15 13:17:41 -08:00
David Wendt 213b3cfca1 Store implemented interfaces on the prototype, not the constructor, so that InstanceOf can get at them. 2019-12-15 13:17:41 -08:00
David Wendt fcb37bd273 Implement `ActionCastOp`. 2019-12-15 13:17:41 -08:00
David Wendt 1b459f522d Implement `ActionImplementsOp`.
This commit title has won the "World's Lowest-Entropy Commit Title" award for 2019.
2019-12-15 13:17:41 -08:00
David Wendt ee4b47d062 Add interface support, and add interface checking to `ActionInstanceOf`. 2019-12-15 13:17:41 -08:00
David Wendt ca93bba5c1 Implement ActionExtends. 2019-12-15 13:14:21 -08:00
Mike Welsh 81e5c7ba1d core: Rename get_length etc. -> length 2019-12-15 12:33:24 -08:00
Mike Welsh bc42004db5 core: Implement From for Object variants to Value/ReturnValue 2019-12-15 12:33:24 -08:00
Nathan Adams 133a1c3c91 core: Interacting with memebers on something that isn't an object isn't a hard error 2019-12-15 12:33:24 -08:00
Nathan Adams aca746eee7 core: Implemented Array.splice with tests 2019-12-15 12:33:24 -08:00
Nathan Adams 31b84c5f19 core: Made arrays a storage property of objects, not a unique object type. Added more corner case tests. 2019-12-15 12:33:24 -08:00
Nathan Adams 3bdf710af6 core: Add another array.concat test 2019-12-15 12:33:24 -08:00
Nathan Adams 32a1eda080 core: Implement Arrays & array prototype 2019-12-15 12:33:24 -08:00
Nathan Adams 46b6ce570b core: Added array tests 2019-12-15 12:33:24 -08:00
Mike Welsh 3c83d9ac9d docs: Shuffle some docs in DisplayObject 2019-12-15 10:17:33 -08:00
Mike Welsh 95755b5fb3 tests: Add test for TransformedByScript flag 2019-12-15 10:17:33 -08:00
Mike Welsh d7393dc81d core: Add DisplayObjectFlags::TransformedByScript
This is set when a DisplayObject is dynamically moved by AS code,
which causes further modification from PlaceObject tags to be
ignored.
2019-12-15 10:17:33 -08:00
Mike Welsh f6c50efe5a tests: Clean up stage_object_propreties and add _name and _target 2019-12-15 10:17:33 -08:00
Mike Welsh 8c27097240 core: Implement _target property
Add DisplayObject::slash_path to get the Flash 4-style slash path
to the clip. This fixes the tellTarget regression test and removes
the superfluous `target_path` from `UpdateContext`.
2019-12-15 10:17:33 -08:00
Mike Welsh d5f7521061 core: Ignore NaN in StageObject setters 2019-12-15 10:17:33 -08:00
Mike Welsh e36dbad7d2 tests: Add stage_object_properties test 2019-12-15 10:17:33 -08:00
Mike Welsh c9864eb557 core: Add StageObject properties 2019-12-15 10:17:33 -08:00
Mike Welsh 3986a8dc4a tests: Add regression test for display object properties 2019-12-15 08:54:26 -08:00
Mike Welsh d30506dc59 tests: Add test for enumerating child instances 2019-12-15 08:54:26 -08:00
Mike Welsh f2422a2c9f avm1: Add attributes for _global/_root/_parent 2019-12-15 08:54:26 -08:00
Mike Welsh 11f2b46b6a tests: Add test for stage instances 2019-12-15 08:54:26 -08:00
Mike Welsh c29b042f5e avm1: Get child clip instances in StageObject
Add the logic to get children display objects as properties in
`StageObject`.
2019-12-15 08:54:26 -08:00
Mike Welsh 783ede6f79 core: Add DisplayObject::path 2019-12-15 08:54:26 -08:00
Mike Welsh 73604a891e core: Move get_child_by_name to DisplayObject 2019-12-15 08:54:26 -08:00
David Wendt 724f845037 Remove the `DisplayNode` slot from `ScriptObject`, since all display node objects should be `StageObject`s now. 2019-12-15 08:54:26 -08:00
David Wendt fa9329df68 Instantiate all MovieClips as StageObjects. 2019-12-15 08:54:26 -08:00
David Wendt 3df6c7eeef Always post-instantiate display objects when running tests. 2019-12-15 08:54:26 -08:00
David Wendt 73655c0c88 Add a separate native object type for objects tied to the stage. 2019-12-15 08:54:26 -08:00
Mike Welsh f0c6b2d8d8 core: Remove this from Object::get/set 2019-12-15 08:54:26 -08:00
dependabot-preview[bot] 251fb01572 build(deps): bump jpeg-decoder from 0.1.17 to 0.1.18
Bumps [jpeg-decoder](https://github.com/image-rs/jpeg-decoder) from 0.1.17 to 0.1.18.
- [Release notes](https://github.com/image-rs/jpeg-decoder/releases)
- [Changelog](https://github.com/image-rs/jpeg-decoder/blob/master/CHANGELOG.md)
- [Commits](https://github.com/image-rs/jpeg-decoder/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-11 18:21:42 +00:00
Mike Welsh b59bf40c78 core: Remove this from Object::get/set 2019-12-10 01:36:02 -08:00
Mike Welsh f7822141b7 core: Rename display_node methods to display_object 2019-12-10 01:36:02 -08:00
Mike Welsh 71e4eb87d7 core: Remove as_*_mut methods on DisplayObject/Object 2019-12-10 01:36:02 -08:00
Mike Welsh d7740bc3ad core: Don't touch UpdateContext::active_clip in DisplayObjects
DisplayObject code no longer has to manage
UpdateContext::active_clip before calling out to children, because
each child still has access to its Gc pointer.
2019-12-10 01:36:02 -08:00
Mike Welsh 25b86c14ae core: Move method impls from Button to ButtonData 2019-12-10 01:36:02 -08:00
Mike Welsh 78e65a01df core: Move method impls from MovieClip to MovieClipData 2019-12-10 01:36:01 -08:00
Mike Welsh 12c1bf7cf1 core: Clean up UpdateContext creation
Added Player::mutate_with_update_context, which takes a closure
and passes it an UpdateContext.
2019-12-10 01:36:01 -08:00
Mike Welsh 30ecbd0ecc core: Use enum_trait_object for DisplayObject 2019-12-10 01:36:01 -08:00
Mike Welsh 23ca66a7e3 avm1: Use enum_trait_object for avm1::Object 2019-12-10 01:36:01 -08:00
Mike Welsh b27bc578e0 core: Add enum_trait_object proc macro
The enum_trait_object attribute macro can be used to define an enum where
each variant holds an implementor of a trait. It implements all
methods to forward to the underlying object, as well as `From` impls.

This an aliternative to using trait objects that gets along nicer
with `gc-arena`.
2019-12-10 01:36:01 -08:00
dependabot-preview[bot] 86c0fa327b build(deps): bump jpeg-decoder from 0.1.16 to 0.1.17
Bumps [jpeg-decoder](https://github.com/image-rs/jpeg-decoder) from 0.1.16 to 0.1.17.
- [Release notes](https://github.com/image-rs/jpeg-decoder/releases)
- [Changelog](https://github.com/image-rs/jpeg-decoder/blob/master/CHANGELOG.md)
- [Commits](https://github.com/image-rs/jpeg-decoder/commits)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2019-12-09 17:39:42 +00:00
Mike Welsh cbe0f873af tests: Add test for Object.addProperty 2019-12-03 15:01:39 -08:00
Mike Welsh 90b6858bb2 avm1: Fix return value of `Object.addProperty` 2019-12-03 14:59:37 -08:00
Mike Welsh 28364f7d00 avm1: Fix `this` object in GetMember/SetMember 2019-12-03 14:59:01 -08:00
Mike Welsh 1a1cdfa757 desktop: Allow audio creation to fail
Switch to NullAudioBackend if CpalAudioBackend fails to initialize.
(This happens on my laptop which doesn't have an audio device!)
2019-11-30 20:08:34 -08:00
Nathan Adams eb185982cd Add more Number(x) tests, and corrected primitive_as_number to match 2019-11-29 16:07:35 -08:00
Nathan Adams 85b9ffe102 core: Merge both test macros into a generic test_method 2019-11-29 13:12:00 -08:00
Nathan Adams 1f4405189a core: Make math test_std also take in versions 2019-11-29 13:12:00 -08:00
Nathan Adams 999bb128de core: Allow global test_std to test multiple swf versions 2019-11-29 13:12:00 -08:00
Nathan Adams 4c7d37c498 core: Added `avm_debug!` macro 2019-11-29 12:59:45 -08:00
Nathan Adams d1b73582ce core: Add feature `avm_debug` that toggles tracing avm actions and stack history 2019-11-29 12:59:45 -08:00
David Wendt 9ec85c3892 Add tests for SWF6 numerical coercions. 2019-11-28 21:32:10 -05:00
David Wendt f856243247 Primitive coercions should not yield an object just because valueOf is undefined. 2019-11-28 20:53:32 -05:00
David Wendt ec3ac4e5d6 `undefined` coerces to `0.0` on SWF6 2019-11-28 20:53:32 -05:00
David Wendt 89e060be4e Add a regression test for `_global` being a bare object 2019-11-28 20:53:31 -05:00
David Wendt 16259ad74a Calling uncallable values does not actually cause a runtime error in Flash; it just returns null.
This was discovered almost by accident: @Dinnerbone noticed that `_global == null`, and surmised that `valueOf` was the culprit. However, this doesn't really make sense: `_global` is a bare object, so it shouldn't have a `valueOf` (and in practice, it doesn't).

The ultimate cause of such an odd comparison is as such:

1. Flash coerces the `_global` object to a numerical primitive by calling `valueOf`.
2. `_global.valueOf` is undefined. Flash handles calls to any uncallable value by literally just having it return `undefined`. In other words, all values are implicitly callable as empty functions.
3. `undefined` is then compared to `null`. These two values *are* equal under abstract equality (`==`). Hence, `_global == null`.

For comparison, modern ECMAScript engines throw errors on calls to uncallable values; and won't attempt to use an invalid `valueOf` to coerce objects. So none of this applies to, say, standard JavaScript in your browser.
2019-11-28 20:53:31 -05:00
Nathan Adams 68760007fc Lessthan can return `undefined`, not just booleans 2019-11-28 20:53:30 -05:00
Nathan Adams 638231e7fb swf4 doesn't have NaN or Infinity 2019-11-28 20:53:20 -05:00
Nathan Adams 581d0940b2 NaN == NaN without coercion 2019-11-28 20:43:59 -05:00
Nathan Adams f33229a2a1 `_global` == null && `_global` == undefined 2019-11-28 20:43:58 -05:00
Nathan Adams ec5ed4f140 Change regression_test to use `actual, expected` so tools (like intelliJ) diff it correctly 2019-11-28 20:43:54 -05:00
Nathan Adams f5b78f6fb0 Typo in test filename 2019-11-28 20:41:26 -05:00
Nathan Adams bda72728ac Assume that NaN == NaN for ruffle 2019-11-28 20:41:25 -05:00
Nathan Adams c9c4749bb0 core: Added battery of tests for lessthan, greaterthan, equals and strictequals between swf4-swf7 2019-11-28 20:41:23 -05:00
Nathan Adams 3f4597f081 Add tests for lessthan 2019-11-28 20:31:02 -05:00
David Wendt 504f962256 Add a test for every string coercion I could find. 2019-11-28 20:28:46 -05:00
David Wendt 129d50bfa6 Implement ECMAScript compliant type coercions.
This includes ECMA-262 2ed `ToNumber`, `ToPrimitive` (Number), `ToString`, and abstract equality and less-than implementations. Note that `ToPrimitive` is only the "number hint" variant, and Flash specifically *never* calls `toString` like how ECMA-262 specifies.

Several builtins inherit numerical coercion - I'm not 100% sure if that's correct.

The following ActionScript opcodes now perform ECMA-262 style coercions:

`ActionAdd2` (uses `valueOf` / "ToPrimitive hint Number")
`ActionDecrement` (uses `valueOf`)
`ActionEquals2` (uses `valueOf`)
`ActionGetMember` (member names, uses `toString`)
`ActionIncrement` (uses `valueOf`)
`ActionLess2` (uses `valueOf`)
`ActionGreater` (uses `valueOf`)
`ActionSetMember` (member names, uses `toString`)
`ActionStringEquals` (uses `toString`)
`ActionStringGreater` (uses `toString`)
`ActionStringLess` (uses `toString`)
`ActionToNumber` (uses `valueOf`)
`ActionToString` (uses `toString`)
`ActionTrace` (uses `toString`)

The following functions now gained user-specified coercions via `toString`:
`_global.number` (uses `valueOf`)
`_global.is_nan` (uses `valueOf`)
Every function in `Math` (uses `valueOf`)
2019-11-28 20:23:39 -05:00
Nathan Adams 2650433271 Fixed get_keys with prototypes 2019-11-27 22:30:31 +01:00
Nathan Adams 585c520b87 Added prototype_enumerate test, `for (key in obj)` 2019-11-27 21:46:21 +01:00
Nathan Adams fdbd16a5d9 Ignore extends_chain, that's NYI 2019-11-27 21:11:03 +01:00
Nathan Adams 57d8469e3b Added a test for isPrototypeOf 2019-11-27 21:09:14 +01:00
David Wendt 1eb4dfa696 Merge remote-tracking branch 'dinnerbone/feature/extends_test' into feature/prototyping 2019-11-27 14:58:47 -05:00
David Wendt 5999aded7a Merge remote-tracking branch 'dinnerbone/feature/prototype_tests' into feature/prototyping 2019-11-27 14:56:39 -05:00
David Wendt 46e58c3ecd Remove `ReturnValue.ignore` entirely, since you really *do* need to resolve `ReturnValue`s, even if you don't want the result. 2019-11-27 14:52:07 -05:00
Nathan Adams b0f0008596 Added test for hasOwnProperty 2019-11-27 20:51:40 +01:00
Nathan Adams 03713f32e9 Correct fla for object_prototypes 2019-11-27 20:46:09 +01:00
Nathan Adams b43436bdd2 Enable recursive_prototypes test as it now passes 2019-11-27 20:31:33 +01:00
David Wendt 2c87888e28 Implement prototype chain recursion limit of 255 prototypes.
In Flash, this also at least claims to halt ActionScript execution on the movie. No such implementation of AVM poisoning currently exists in Ruffle, primarily because it's unclear what gets poisoned and implementing some of these options isn't yet possible:

1. AVM (e.g. all movies) - we would need to make the AVM fail silently in this case. This is the most straightforward way to poison the movie, but I'm not sure if this is how Flash actually does it, or if it poisons...
2. Movie - the current structure of movies is incompatible with adding arbitrary data to them. We need to merge `moviefetch` in before we can attach data to loaded movies.
3. MovieClip - this would also be implementable but has problems. How do child MovieClips know that their parent has been poisoned, or vice versa? What if a movie clip is loaded from one movie and moved into another?

As a result, I have decided to hold off on implementing recursion poisoning until I know where it's supposed to go and how to implement that.
2019-11-27 08:59:16 -05:00
Nathan Adams e9ad733e68 Add a test to see if the avm crashes with recursive prototypes.
Spoilers: it does.
2019-11-26 23:38:34 +01:00
Nathan Adams de1f5417ec Added test for extending MovieClip prototype 2019-11-26 23:22:07 +01:00
Nathan Adams ffaf10b604 Add test for prototyping 2019-11-26 23:22:07 +01:00
Nathan Adams 3bcd9ed71b Added test for class & interface hierarchy 2019-11-26 22:42:11 +01:00
David Wendt 4655ebe73f Always push the constructed object on the stack. 2019-11-26 15:07:59 -05:00
David Wendt b9f02c290c Functions should be traceable. 2019-11-26 15:07:03 -05:00
David Wendt 0b1afcf8be Implement `ActionInstanceOf` (for non-interface types) 2019-11-26 14:51:06 -05:00
David Wendt 3c8d9b9c1c `new` should be called on the prototype - not the constructor function. This will allow different host object impls to subclass correctly. 2019-11-26 14:51:06 -05:00
David Wendt e8632bbcaa Implement `valueOf` for `Object` and fix the `toString` impl. 2019-11-26 14:51:06 -05:00
David Wendt 73c3b42cd4 Move `force_set` and `force_set_virtual` into the `Object` trait. They are now called `define_value` and `add_property`, respectively.
While I don't expect every host object to implement it correctly, this also gets rid of a lot of unnecessary `unwrap` calls that would allow a poorly-written Flash file to kill the interpreter.
2019-11-26 14:51:06 -05:00