Commit Graph

209 Commits

Author SHA1 Message Date
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
relrelb 761d746c38 avm2: Port `flash.display.ActionScriptVersion` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb d24c03349e avm2: Port `flash.text.TextFormatAlign` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb 6108be135e avm2: Port `flash.text.TextFieldType` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb 976cf2da39 avm2: Port `flash.text.TextFieldAutoSize` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb 3abfac8ea6 avm2: Port `flash.utils.Endian` to ActionScript 2022-06-24 18:28:33 +03:00
relrelb 8228f7af6c avm2: Port `flash.utils.CompressionAlgorithm` to ActionScript 2022-06-24 18:28:33 +03:00
Callum Thomson 1310f433f2
avm2: Implement escape() toplevel (#7281)
* AVM2: Implement escape()

* chore: Fix formatting

* avm2: Escape resolves non strings to null and use push to append

* chore: Fix nits

* avm2: Escape should coerce objects, add early returns
2022-06-22 08:43:22 +03:00
relrelb 754579eb07 avm2: Port `AccessibilityProperties` to ActionScript 2022-06-18 20:00:56 +03:00
relrelb f9596543c6 avm2: Remove unused `Rectangle` and `Point` classes/prototypes
They are now both implemented in pure ActionScript, and no Rust code
ever references them.
2022-06-16 22:42:50 +03:00
relrelb a9915c71bc avm2: Port `flash.geom.Rectangle` to ActionScript
`flash.geom.Rectangle` is a good candidate, since it doesn't have
any native function, and it depends only on `flash.geom.Point`,
which was already been ported to ActionScript in #7071.
2022-06-16 22:42:50 +03:00
Aaron Hill f629a91e53
avm2: Allow implementing classes in ActionScript in custom `playerglobal`
This PR adds support for building a custom `playerglobal.swf`, which can be used
to implement builtin Flash classes in ActionScript. This file is embedded into Ruffle
using `include_bytes!`, and loaded during initialization.
As an example, the `Point` class is reimplemented
in ActionScript, and `flash.text.AntiAliasType` is added.

The ActionScript compilation process is performed by `core/build.rs`.
See that file, along with `core/src/avm2/globals/README.md`, for
more details.
2022-06-15 22:00:17 +03:00
Aaron Hill cc90796d8a avm2: More filter-related stubs
This stubs out BlurFilter, adds properties to GlowFilter,
and make the getter for  DisplayObject.filters return
an empty array instead of Undefined.

This is all of the filter-related code that 'Solarmax'
needs in order to reach the main screen (combined with
other unrelated changes I have yet to submit)
2022-06-10 19:35:48 +03:00
Daniel Jacobs cddf5796a3 avm2: Add more Event classes' methods and properties 2022-05-20 18:42:07 -07:00
Aaron Hill 8d8a7600d8 avm2: Partially implement `URLLoader` and related classes
This PR implements the `URLLoader` class, allowing AVM2 scripts
to load data from a URL. This requires several other related
classes (`URLLoaderDataFormat`, `URLRequest`, `IOError`) to be
implemented as well.

Currently implemented:
* Fetching from URLs using the 'navigator' backend
* The `text` and `binary` data formats (which store data
in a `String` or `ByteArray` respectively)
* The `open`, `complete`, and `ioError` events
* The `bytesLoaded`, `bytesTotal`, and `data` properties

Not yet implemented:
* The HTTP and security events
* All of the properties of `IOError`
* The properties on `URLRequest` (besides `url`)
* The "variables" data format

This should be enough to get some basic uses of `URLLoader` working
(e.g. simple GET requests to a particular website).

Note that in Flash's `playerglobal`, the `URLLoader` class is just
a think wrapper around the more general `URLStream`. However,
implementing `URLStream` will require changes to `Navigator``
to support notifications when data arrives in the stream. When
that happens, we should be able to re-use a large amount of the
code in this PR.
2022-05-20 11:41:17 -07:00
TÖRÖK Attila 81749f900b avm2: Implement GradientType, InterpolationMethod, SpreadMethod in flash.display 2022-05-19 23:47:55 +02:00
David Wendt 1383901a94 avm2: Remove unnecessary usage of `coerce_to_object` in `avm2::globals`. 2022-04-24 16:54:19 -07:00
TÖRÖK Attila 7cbba5bc8f avm2: Stub flash.accessibility.AccessibilityProperties 2022-04-19 09:55:09 -07:00
Aaron Hill d7532ae654 avm2: Add stubs for `BitmapFilter`, `GlowFilter`, and `DisplayObject.filters`
This gets 'Rolling Hero' further in the startup process,
since it just tries to set a filter on an object.
2022-04-08 16:53:16 -07:00
Aaron Hill 4f23500779 avm2: Implement most of `flash.external.ExternalInterface`
This re-uses the logic we have for handling AVM1's `ExternalInterface`.
For now, serialization/deserialization of non-array objects is
left unimplemented.
2022-03-31 22:40:09 -07:00
Adrian Wielgosik 7e8738d82e avm2: Add ContextMenuEvent stub 2022-03-30 21:42:48 +02:00
Adrian Wielgosik ea56902d80 chore: cargo fmt 2022-03-30 21:42:48 +02:00
Adrian Wielgosik 90b1d4722c avm2: Add ContextMenuItem stub 2022-03-30 21:42:48 +02:00
Adrian Wielgosik 2389422c99 avm2: Add ioErrorEvent stub 2022-03-30 21:42:48 +02:00
Aaron Hill a281db3af6 Add `define_indirect_properties` helper macro for property/slot pairs
In both `FrameLabel` and `Scene`, we define multiple
'public property / private slot' pairs.
The public property has a getter which delegates to the private
property. There is no setter for the property, ensuring that
the private slot can only be modified from within Ruffle itself.

This PR adds a macro `define_indirect_properties` to abstract over
this pattern. Currently, it only supports the read-only property
pattern - however, it could be extended in the future to generate
a setter that invokes a caller-provided callback function.

This needs to be a macro (rather than a method) so that we can
generate a function with the property name hard-coded into it.
Using a closure that references an upvar will not work, since
`Method::from_builtin` requires a function pointer.
2022-03-21 19:00:25 -07:00
Aaron Hill e87ad52deb avm2: Add initial implementation of `Matrix`
This implements the `a, b, c, d, tx, ty` properties,
as well as the constructor, `identity`, and `scale` methods.
2022-03-16 13:52:58 +02:00
Aaron Hill 3bcb409bd8 Add more AVM2 'flash.' class stubs
This PR adds the following class stubs:

* 'flash.display.Loader'
* 'flash.net.URLRequest'
* 'flash.ui.Keyboard'
* 'flash.utils.Timer'

These are needed for 'This is the Only Level TOO' (though we'll need
actual implementations to get this game past the loading screen).
2022-03-12 15:09:41 +01:00
David Wendt 7b6f8aef06 avm2: Implement `flash.events.EventPhase`. 2022-01-22 19:58:32 -08:00
David Wendt ada093938e avm2: Expose `MouseEvent` as a system class. 2022-01-22 19:58:32 -08:00
Adrian Wielgosik 4230d1f19f avm2: Add Mouse.hide(), Mouse.show() 2021-12-21 17:32:57 +01:00
Adrian Wielgosik 11534a4b34 avm2: Implement parseInt, parseFloat 2021-12-15 22:16:49 +01:00
Adrian Wielgosik 49feb23649 avm2: Move toplevel functions to separate file 2021-12-15 22:16:49 +01:00
EmperorBale 30f2e0f8b1
avm2: Implement JSON (#5172)
* avm2: Implement JSON.parse

* avm2: Add AvmSerializer for serializing AVM values to JSON

* avm2: Add support for replacer objects

* avm2: use *const ObjectPtr for object stack

* avm2: Add support for space parameter is JSON.stringify

* avm2: Refactor AvmSerializer design

* avm2: Restrict spaces to a maximum of 10

* avm2: Refactor map_value

* tests: Add JSON.parse test

* chore: Appease clippy

* avm2: Check if value is undefined before inserting

* tests: Add test for JSON.stringify

* tests: Improve JSON.stringify test

* chore: Replace map_or with explicit match statements

* chore: Use QName::dynamic_name

* avm2: Use Object<'gc> instead of ObjectPtr

* chore: Use explicit match in deserialize_value

* Rebase fixes

Co-authored-by: Adrian Wielgosik <adrian.wielgosik@gmail.com>
2021-12-13 18:32:04 +01:00