* avm2: Properly make all classes an instance of `Class`.
Also, does this technically mean that `Class` is a metaclass?
* avm2: Remove `Function::from_method_and_proto` as it will no longer be needed
* avm2: Ensure builtin classes are also instances of `Class`.
This requires tying a veritable gordian knot of classes; everything needs to be allocated up-front, linked together, and then properly initialized later on. This necessitated splitting the whole class construction process up into three steps:
1. Allocation via `from_class_partial`, which does everything that can be done without any other classes
2. Weaving via `link_prototype` and `link_type`, which links all of the allocated parts together correctly. This also includes initializing `SystemClasses` and `SystemPrototypes`.
3. Initialization via `into_finished_class`, which must be done *after* the weave has finished.
Once complete you have core classes that are all instances of `Class`, along with prototypes that have their usual legacy quirks.
Note that this does *not* make prototypes instances of their class. We do need to do that, but doing so breaks ES3 legacy support. This is because we currently only work with bound methods, but need to be able to call unbound methods in `callproperty`.
* tests: Add a test for all core classes' instance-of relationships
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 is very wrong: Strictly speaking, we should not be instantiating anything that needs a scope when we install the trait. We just create a slot for it to go into. Script initializers are responsible for providing a scope stack to instantiate traits into.
Because we have stuff running in early globals, we stlil need a more elaborate version of this function that *does* take `fn_proto`. We also can't pull `scope` from the activation since this gets called to install traits.
This also makes it more difficult to accidentally build a class without calling it's initializer. Native/builtin class initializers should also be running now, too.
The only minor bit of jank is that we need a class initialized bit to flag classes we've already run, because our current lazy-init design for traits causes classes to be constructed twice. This is temporary and I intend to remove it along with lazy-init traits.
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.
This entirely abolishes the "global scope object" in AVM2. I even had to redefine several global object functions to work with the bottom of the scope stack, which seems to be where ASC likes to stick the script scope.