This allows us to hide things like `MovieClip.isPlaying` from older
SWFs, which may define an `isPlaying` method without marking it
as an override.
This has the largest impact on public namespaces. There is no longer
just one public namespace - we now have a public namespace per API
version. Most callsites should use `Avm2.find_public_namespace()`,
which determines the public namespace based on the root SWF API version.
This ensures that explicit property access in Ruffle (e.g. calling
"toString") are able to see things defined in the user SWF.
This requires several changes other:
* A new `ApiVersion` enum is introduced, storing all of the api versions
defined in avmplus
* NamespaceData::Namespace now holds an `ApiVersion`. When we read a
namespace from a user-defined ABC file, we use the `ApiVersion` from
the root movie clip. This matches Flash Player's behavior - when a
child SWF is loaded through `Loader`, its API version gets overwritten
with the parent's API version, which affects definition visibility and
'override' requirements in the child SWF. Note that 'behavior changes'
in methods like `gotoAndPlay` are unaffected.
* The `PartialEq` impl for `Namespace` has been removed - each call site must now choose
to compare namespaces either by an exact version match, or by
'compatible' versions (a `<=` check) with `Namespace::matches_ns`
* `PropertyMap` now uses `Namespace::matches_ns` to check for a
compatible version when looking up a definition.
* When compiling our playerglobal, we pass in the `-apiversioning` flag,
which causes asc.jar to convert `[API]` metadata into a special
Unicode 'version mark' suffix in namespace URLs. We parse this
when loading namespaces to determine the API version to use for
playerglobal definitions (unmarked definitions use the lowest possible
version).
Unfortunately, this makes ffdec unable to decompile our
playerglobal.swc
I've going to file an upstream issue
Some SWFS (in particular, anything using Unity) call
avmplus.describeTypeJSON, and rely on the behavior of the various
flags.
This PR changes our internal implementation to implement
describeTypeJSON (producing an `Object` with dynamic fields).
We then convert this to XML in `describeType`, using an implementation
inspired by avmplus.
The existing describeType tests are passing - in a follow-up PR,
I'll add tests for describeTypeJSON
The XML call handler is implemented as 'new XML(arg)',
so we get all of the related string coercions for free.
Our various native tables are starting to get somewhat wasteful -
if we add any more, we might want to consider a more compact
representation.