Commit Graph

241 Commits

Author SHA1 Message Date
relrelb 95de87ad0a avm2: Throw `VerifyError` for invalid ABC files 2022-09-26 19:51:38 +03:00
relrelb c9ca7e2095 avm2: Port `flash.ui.Mouse` to ActionScript 2022-09-25 16:50:03 +03:00
relrelb c532d70844 avm2: Port `flash.net.ObjectEncoding` to ActionScript
Along with the `flash.net.IDynamicPropertyOutput` and `flash.net.IDynamicPropertyWriter`
interfaces.
2022-09-25 00:36:31 +03:00
EmperorBale a17352a01a avm2: Switch XML & XMLList to actionscript 2022-09-22 15:18:23 -07:00
EmperorBale 6dea1fa264 avm2: Implement TypeError 2022-09-22 15:18:23 -07:00
Aaron Hill 93b7de2fe6 avm2: Use custom Error instead of std::error::Error 2022-09-21 12:37:37 -05:00
EmperorBale e1eaa9770a avm2: Switch ByteArray to AS
avm2: Fix ByteArray

avm2: Implement ByteArray.defaultObjectEncoding

avm2: Rename ByteArray allocator
2022-09-17 12:31:43 -07:00
David Wendt 85cf383c84 core: Allow callers of `decode_tags` to flag when they would like decoding to stop 2022-09-15 19:14:41 -06:00
David Wendt 4e9bb3a173 core: Implement chunked decoding infrastructure.
We currently do not actually enforce a decoding limit; just add the functionality necessary to do so.
2022-09-15 19:14:41 -06:00
Aaron Hill 3e65a554fa avm2: Add 'gc lifetime parameter to avm2::Error 2022-09-13 18:55:08 -05:00
Adrian Wielgosik 1c940009a1 avm2: Convert Capabilities, System to AS 2022-09-12 02:03:34 +02:00
Adrian Wielgosik 4421fbff6a
avm2: Convert all Qname::new(...).into() to Multiname::new() (#7930) 2022-09-09 23:33:30 +02:00
Aaron Hill bb138d9082 avm2: Implement some of SharedObject
Our AVM2 `SharedObject` support is now *almost* equivalent
to our avm1 `SharedObject` support. We implement serialization
and deserialization for primitives, arrays, and `Object` instances
with local properties. We also implement serialization for `Date`,
but not `Xml` (since our AVM2 `Xml` class is just a stub at the moment).

This is enough to make 'This is the only level too' save level
progress to disk.

Currently, we always serialize to AMF3. When we implement
the `defaultObjectEncoding` and `objectEncoding`, we'll need
to adjust this.
2022-09-08 21:22:05 -05:00
EmperorBale 7fa19c2ea3 avm2: Store stack trace in Error objects 2022-09-07 13:54:33 -07:00
Aaron Hill 1a7c5339a7 avm2: Implement DisplayObject.localToGlobal and DisplayObject.globalToLocal
While writing tests for these methods, I discovered and fixed some
issues with how 'scrollRect' interacted with 'dobj.transform.matrix'
2022-08-29 23:12:40 -05:00
Aaron Hill c531994b1c avm2: Fire KeyboardEvent.KEY_UP and KeyboardEvent.KEY_DOWN
The 'charCode' and 'keyCode' properties are now implemented
on `KeyboardEvent`

The input injection code we use does not support keyboard events,
so we can't yet write a regression test for this. However,
both 'You need to burn the rope' and 'This is the Only Level TOO'
now properly handle keyboard events with this PR.
2022-08-28 14:15:57 -05:00
relrelb 2f106da04c avm2: Port toplevel constants to ActionScript
Declare `NaN`, `Infinity` and `undefined` in ActionScript, similarly
to how `avmplus` does in its `actionscript.lang.as`.

Note that `null` is only removed, without an ActionScript declaration,
as it seems like `avmplus` neither declares it. Probably `null` is
only usable as a compile-time constant.
2022-08-26 15:45:36 -07:00
Aaron Hill fa0c843a4d avm2: Implement DisplayObject.scrollRect
This property causes a DisplayObject to be both translated
and cropped.
2022-08-26 13:04:01 -07:00
relrelb ad84c2bbcb avm2: Rename `Avm2::load_abc` to `Avm2::do_abc`
This aligns with the name of `DoAbc` tags.
2022-08-26 11:37:04 -07:00
relrelb ad91992cb5 swf: Simplify `DoAbc` tag handling
Extract `swf::Reader::read_do_abc()` which, as the name suggests,
reads a `DoAbc` tag, and use it before calling to `Avm2::load_abc`.
Finally, introduce `DoAbcFlag` using `bitflags`.
This greatly simplifies the ABC loading code.
2022-08-26 11:37:04 -07:00
relrelb d152cc3e64 avm2: Port `Math` to ActionScript 2022-08-25 16:03:08 -07:00
onkrot 14abd01e91 avm2: Pull flash.crypto package method from globals to crypto.as 2022-08-23 09:58:19 -05:00
onkrot db22992b86 avm2: Pull flash.utils package methods from globals to utils.as 2022-08-23 09:58:19 -05:00
Aaron Hill 86e6983943 avm2: Partially implement Loader.load
This PR implements the `Loader.load` method, as well as
the associated `LoaderInfo` properties and events.

We can now load in an external AVM2 SWf: it will be added
as a child of `Loader` object, and will render properly
to the screen.

Limitations:
* The only supported `URLRequest` property is `url`
* `LoaderContext` is not supported at all - we always use the default
  behavior
* Only `Loader.load` is implemented - we do not yet support unloading.
* We fire a plain 'Event' for the 'progress' event, instead of using
  the (not yet implemented) 'ProgressEvent' class

The main changes in this PR are:
* The AVM2 `Loader` class now has an associated display object,
  `LoaderDisplay`. This is basically a stub, and just renders
  its single child (if it exists).
* `LoaderStream::Stage` is renamed to `LoaderStream::NotYetLoaded`.
  This is used for both the `Stage` and an 'uninitialized'
  `Loader.contentLoaderInfo`. In both cases, certain properties throw
  errors, while others return actual values.
* The rust `Loader` manager now handles both AVM1 and AVM2 movie loads.
2022-08-22 19:36:29 -07:00
Aaron Hill 1e18fc2227 avm2: Convert filters to ActionScript
We still don't implement the actual filter logic for `DisplayObject`,
but the classes themselves are fully implemented.
2022-08-17 12:55:03 -07:00
Aaron Hill 6f20e8882d avm2: Implement DisplayObject.transform and most of Transform
This PR implements the 'DisplayObject.transform' getters/setters,
and most of the getters/setters in the `Transform` class

From testing in FP, it appears that each call to the
'DisplayObject.transform' property produces a new
'Transform' instance, which is permanently tied to the
owner 'DisplayObject'. All of the getters/setters in
`Transform` operate directly on owner `DisplayObject`.
However, note that the `Matrix` and `ColorTransform`
valuse *produced* the getter are plain ActionScript objects,
and have no further tie to the `DisplayObject`.

Using the `DisplayObject.transform` setter results in
values being *copied* from the input `Transform` object.
The input object retains its original owner `DisplayObject`.

Not implemented:
* Transform.concatenatedColorTransform
* Transform.pixelBounds

When a DisplayObject is not a descendant of the stage,
the `concatenatedMatrix` property produces a bizarre matrix:
a scale matrix that the depends on the global state quality.
Any DisplayObject that *is* a descendant of the stage has
a `concatenatedMatrix` that does not depend on the stage quality.
I'm not sure why the behavior occurs - for now, I just manually
mimic the values prdduced by FP. However, these values may indicate
that we need to do some internal scaling based on stage quality values,
and then 'undo' this in certain circumstances when constructing
an ActionScript matrix.

Unfortunately, some of the computed 'concatenatedMatrix' values
are off by f32::EPSILON. This is likely due to us storing some
internal values in pixels rather than twips (the rounding introduced
by round-trip twips conversions could cause this slight difference0.
For now, I've opted to mark these tests as 'approximate'.

To support this, I've extended our test framework to support providing
a regex that matches floating-point values in the output. This allows
us to print out 'Matrix.toString()' and still perform approximate
comparisons between strings of the format
'(a=0, b=0, c=0, d=0, tx=0, ty=0)'
2022-08-14 19:12:25 -07:00
relrelb 8a7e96b0d5 avm2: Split `names.rs`
Into `namespace.rs`, `multiname.rs` and `qname.rs`, for better code
organization.
2022-08-13 02:12:53 +03:00
Adrian Wielgosik 5be7f425f0 avm2: Migrate all Events to AS, remove EventData. 2022-07-30 12:34:12 -07:00
Aaron Hill b4f98190e9 avm2: Implement flash.utils.Timer and associated events
The current 'setInterval/setTimeout' implementation is
moved to 'core/src/timers.rs', and now works with both
AVM1 and AVM2 objects. The `flash.utils.Timer` class is implemented
mostly in ActionScript, with minimal modifications to the actual
Ruffle timer code.
2022-07-24 20:43:00 -07:00
Aaron Hill bb6f07ee1a
avm2: Add support for playerglobal instance allocators
This commit adds support for combining instance allocators with
ActionScript playerglobal class definitions. This is activated
by defining the metadata `[Ruffle(InstanceAllocator = "true")]`
on the ActionScript class definition.

The implementation of this feature is very similar to native methods:
`build_playerglobal` checks for the metadata described above,
and defines a const `NATIVE_INSTANCE_ALLOCATOR_TABLE` mapping
class ids to function pointers.

To demonstrate this feature, I've converted `Event` to ActionScript
(keeping the existing instance allocator function).
I've also converted `ActivityEvent` and `ContextMenuEvent` to
`ActionScript`, to demonstrate how this simplifies inheritance.
In a future PR, we can convert the remaining events to ActionScript,
and remove the `EventData` enum entirely.

Unfortunately, `flex-sdk`'s `asc.jar` compiler strips out all metadata
when the `-optimize` option is passed. As a result, I forked
`flex-sdk` and disabled this behavior:
https://github.com/ruffle-rs/flex-sdk/releases/tag/ruffle-1.0.0

The modified `asc.jar` (built from the forked repository)
is included in this PR, and replaces the our previous 'asc.jar'
downloaded from the official Flex SDK release.

* Change metadata to `[Ruffle(InstanceAllocator)]`

* Strip out metadata before saving bytecode
2022-07-20 23:11:46 -07:00
Adrian Wielgosik 22d2810ef9 avm2: Migrate ContextMenu-related classes to AS 2022-07-17 11:05:37 -07:00
Aaron Hill af4f181856 avm2: Implement support for native methods in `playerglobal`
This commit adds support for marking methods as `native`
in ActionScript classes defined in playerglobal. The
`build_playerglobal` now checks for native methods, and
generates Rust code linking them to a corresponding Rust
function definition in the codebase.

To test this functionality, I've reimplemented several
functions as native methods (and moved related code to
pure ActionScript).
2022-07-15 11:43:49 -05:00
Aaron Hill b56eace008
avm2: Implement property type coercions
Properties can be declared with a type
(e.g. `var foo:MyClass = new MyClass();`). When
`set_property`/`init_property` is invoked for that property,
the VM will attempt to coerce the value to the provided type,
throwing an error if this fails. This can have observable behavior
consequences - if a property has type `integer`, for example, then
storing a floating point `Number` to that property will cause the
value to be coerced to an integer. Some SWFs (e.g. 'Solarmax') rely
on this behavior in order to implicitly coerce a floating point value
that's later used for array indexing.

This PR implements property type coercions in Ruffle. There are several
important considerations:

* The class lookup for property types needs to be done lazily, since
we can have a cycle between two classes (e.g. `var prop1:Class2;`
and `var prop2:Class1` in two different classes).
* The class lookup uses special rules (different from
  `resolve_definition`), and does *not* use `ScopeStack/`ScopeTree`
This means that a private class can specified as a property name -
the lookup will succeed without using a scope, even though
`flash.utils.getDefinitionByName` would fail with the same name
* The specialized 'Vector' classes (e.g "Vector$int") can be used
as property types, even though they cannot be lookup up normally.

Some Ruffle class definitions were previously using nonexistent
classes as property types (e.g. "BareObject") - these are fixed
in this PR.
2022-06-30 21:34:26 -07:00
Adrian Wielgosik 4d1bf7e00c avm2: Refactor AVM2 bare object creation 2022-06-29 15:12:39 -07:00
Adrian Wielgosik f31d4c2498 avm2: Remove SystemPrototypes. 2022-06-29 15:12:39 -07:00
Aaron Hill 53cdba96d3 avm2: Convert flash.geom.Matrix to ActionScript
I've kept the rust `flash.geom` module, even though it's now empty,
since we'll need to add things like `flash.geom.Transform` native
methods in the future.
2022-06-24 12:34:12 -05:00
relrelb 8398dc4ae8 avm2: Port `flash.net.URLLoaderDataFormat` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb 32df3b762c avm2: Port `flash.display.StageScaleMode` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb 29692b4a49 avm2: Port `flash.display.StageQuality` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb 121d17dd94 avm2: Port `flash.display.StageDisplayState` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb 1f1c2b91cd avm2: Port `flash.display.StageAlign` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb 1a8f6ef6aa avm2: Port `flash.display.SpreadMethod` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb 790880a508 avm2: Port `flash.display.Scene` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb 3745ab57db avm2: Port `flash.display.SWFVersion` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb 14830adb54 avm2: Port `flash.display.PixelSnapping` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb f0a8ba9b87 avm2: Port `flash.display.LineScaleMode` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb 8b8b320064 avm2: Port `flash.display.JointStyle` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb 6779e406ce avm2: Port `flash.display.InterpolationMethod` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb ad4b06917b avm2: Port `flash.display.GradientType` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb 1ad020566e avm2: Port `flash.display.CapsStyle` to ActionScript 2022-06-24 18:28:33 +03:00