* avm2: Implement call stack
* avm2: Class traits should have a special prefix
* avm2: Stack tracebacks should also contain error message
* avm2: Move method naming to Executable
* avm2: Handle getter and setter methods in tracebacks
* chore: Formatting
* chore: Add comments
* avm2: Make full_name write to a string, instead of creating a new one
* core: Make GcArena publicly accessible
* core: Add Deref impl for Either type
* desktop: Add AVM2 call stack to panic message
* avm2: Prefix native methods with a `/`
* chore: Appease clippy
* avm2: Check if method actually contains bytecode instead of unwrapping
* web: Add AVM2 stack trace to panic message
* chore: Formatting
* chore: Clippy
* avm2: Fix stack traces for free standing functions
* core: Remove global data from context
* core: Rename GcGlobalData to GcCallstack
* core: Introduce StaticCallstack, make GcArena private again
Co-authored-by: Adrian Wielgosik <4729533+adrian17@users.noreply.github.com>
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).
Instead, the following terms are used:
* Static classes, to refer to `Class<'gc>`. Shortened to "class" in contexts where this is not ambiguous.
* Class objects, to refer to objects that represent a particular class. Also shortened to "class" in non-ambiguous contexts.
Downstream of this, the `base_constr` (referring to the class that a currently called trait has been pulled from) is now called `subclass_object` and several `TObject` methods have also been renamed.
This is limited by the fact that we currently cannot store type metadata in static tables. I don't think it's necessary to do so as of yet as pretty much every actual parameter type I *could* shove in here turned out to be optional and broke tests if it wasn't. Still, it's probably useful enough for new classes to include.
This also incurred a large number of ancillary changes, as it turns out nearly every native object is currently pulling a prototype and sticking it into an object. Right now, I have it instead pulling the constructor out of the prototype, but a future PR will also remove `system_prototypes` as well.
Other ancillary changes include:
* `Domain` now supports partial initialization to avoid an order-of-events issue. Accessing domain memory on a partially-initialized `Domain` will panic.
* `Domain` construction requires a full `activation` now, except for `global_scope` which needs to be initialized later with valid domain memory before user code runs.
* Pretty much every native object constructor now takes a proto/constr pair
* Trait lookup was rewritten to handle this. It's still buggy - seven tests don't work
* `TObject.construct` now actually does the full object construction dance. This allows `ClassObject` to implement the ES4 object construction pathway directly while `FunctionObject` maintains ES3 compatibility.
This is a tentative commit; there are still seven failing tests that I need to fix.
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.
Interface methods are specifically not allowed to be called: as a result, they don't get a method body. Existing code assumed a 1:1 relationship between methods and bodies, which causes spurious errors.
This is inspired by Dinnerbone's similar PR on the AVM1 side, where the Action half of that VM's `Executable` was reduced from 128 bytes to 16 by shoving it in a `Gc`. This won't be as dramatic but should still save some memory.
In fact, it should save a *lot* of memory in bytecode execution, where thanks to the previous commit's rebase, we now need to clone the current method once *for each instruction executed*. That is terrible, but should stop now.
This also results in a far reduced role for `ReturnValue`, since I also took the liberty of removing most of it's use. Furthermore, I also made it apply equally to native and AVM2 code, which ensures all native implementations of methods don't double-borrow.
In AVM1, `ReturnValue` was actually removed entirely, because it's not needed. I attempted to do the same, but the fact that we're currently embedding `ScriptObjectData` in native objects means that we need it for virtual properties. Otherwise, virtual property implementations will see locked objects, which is bad.