Commit Graph

345 Commits

Author SHA1 Message Date
David Wendt bb19699739 avm2: Add convenience method for converting a `Value` into an `EnumSet`. 2020-09-15 02:20:11 -07:00
David Wendt a653a62a93 avm2: Add array sorting constants. 2020-09-15 02:20:11 -07:00
David Wendt ca4982029b avm2: Impl `Array.toLocaleString`. 2020-09-15 02:20:11 -07:00
David Wendt 2ae3b6445b avm2: Partially implement `toLocaleString` insamuch as is necessary to run Array tests on it.
This appears to work almost like it's own TObject method; you can run `Object.prototype.toLocaleString` on all sorts of things and it has separate behavior to what the class method for it might be. I have attempted to match Flash Player as best as I can.
2020-09-15 02:20:11 -07:00
David Wendt dbaef812fa avm2: Impl `Array.splice`. 2020-09-15 02:20:11 -07:00
David Wendt 53b564bb52 avm2: Implement `Array.slice`. 2020-09-15 02:20:11 -07:00
David Wendt 036f7cbb90 avm2: Implement `Array.shift` and `Array.unshift`.
This also updates `Array.push` to support it's ability to push multiple arguments at once.
2020-09-15 02:20:11 -07:00
David Wendt 879aff3669 avm2: Implement `Array.reverse` 2020-09-15 02:20:11 -07:00
David Wendt 1ce78388a3 avm2: Implement `Array.push` and `Array.pop` 2020-09-15 02:20:11 -07:00
David Wendt 0ece924877 avm2: Implement `indexOf` and `lastIndexOf` 2020-09-15 02:20:11 -07:00
David Wendt 7aa1ab82e4 avm2: Avoid locking the array when running user code.
The array being iterated is explicitly handed to all callbacks, and it is legal for the callback to mutate the array. Hence, we can't actually hold a `Ref` to the array storage when we call user code. Instead, we implement a custom `Iterator` which iterates over the object like user code would.

This actually can't be an `Iterator` impl due to limitations of the underlying trait. Hence, we have to `while let` instead of `for`.
2020-09-15 02:20:11 -07:00
David Wendt 832bbdd711 avm2: Implement `forEach`, `map`, `filter`, `every`, and `some` on `Array`.
This also comes with some refactoring: building the resulting array object and resolving holes is now done in helper methods.
2020-09-15 02:20:11 -07:00
David Wendt 0eeee72be6 avm2: Implement `Array.join`, `Array.toString`, and `Array.valueOf` (w/tests) 2020-09-15 02:20:11 -07:00
David Wendt 505018c3b8 avm2: Implement `newarray`. 2020-09-15 02:20:11 -07:00
David Wendt 04828663e8 avm2: `deleteproperty` should only ever yield `false` when attempting to delete unknown properties on a sealed class object. 2020-09-15 02:20:11 -07:00
David Wendt 6d9b9c9218 avm2: Attempts to get unknown properties on dynamic objects should yield `undefined`. 2020-09-15 02:20:11 -07:00
David Wendt 966dfc3902 avm2: Add method to get at the `Class` of non-class objects with a prototype.
The only unclassed objects should be bare objects, which are hard to get at.
2020-09-15 02:20:11 -07:00
David Wendt cac1717780 avm2: Add utility method `is_sealed` for `Class`. 2020-09-15 02:20:11 -07:00
David Wendt 5a29b781ec avm2: Ensure `ArrayObject` offers access to it's array properties for reading and writing. 2020-09-15 02:20:11 -07:00
David Wendt e054456286 avm2: Add method to check if a particular namespace is the public namespace. 2020-09-15 02:20:11 -07:00
David Wendt a09ba9d263 avm2: Implement `length`. 2020-09-15 02:20:11 -07:00
David Wendt aaf586e3a7 avm2: `define_instance_trait` should actually define instance traits. 2020-09-15 02:20:11 -07:00
David Wendt 45c95cae02 avm2: Impl `Array.concat` 2020-09-15 02:20:11 -07:00
David Wendt 1092bf2bc5 avm2: Add the ability to wrap an already-constructed array in an object. 2020-09-15 02:20:11 -07:00
David Wendt bd35ebb793 avm2: Impl `Array` constructor 2020-09-15 02:20:11 -07:00
David Wendt bedd5fa007 avm2: Add a method for mutating the array storage of an object. 2020-09-15 02:20:11 -07:00
David Wendt d92d3023e7 avm2: Restore `as_number`.
This is for the sake of methods that want to change behavior based on if they're working with a number or some other kind of value. It should not be used otherwise.
2020-09-15 02:20:11 -07:00
David Wendt 16e1a1bdf3 avm2: Add Array class.
This code also ensures that the prototypes of each system object are created in the appropriate `TObject` impl. This ensures that, for example, `new Array` hands you back an actual array.
2020-09-15 02:20:11 -07:00
David Wendt 88fc9b1538 avm2: Implement base types for array-shaped objects. 2020-09-15 02:20:11 -07:00
Nathan Adams 3ff399ca6b core: Trace only to the log backend, but have the default log backend trace to the log crate 2020-09-13 13:51:39 -07:00
Nathan Adams 319efabb47 tests: Make tests capture trace output through new backend 2020-09-13 13:51:39 -07:00
Nathan Adams e25e03a841 core: Log to new avm_trace method where we want things to show up 2020-09-13 13:51:39 -07:00
David Wendt 35b589b2ac avm2: `in` should only ever query non-namespaced/public properties. 2020-09-07 11:07:07 -07:00
David Wendt 3b5411547a avm2: Implement `in` 2020-09-07 11:07:07 -07:00
David Wendt 11b8354905 avm2: `resolve_any` should resolve prototype properties. 2020-09-07 11:07:07 -07:00
kmeisthax 559bc05b6a
avm2: Implement avm2 math opcodes (merge #1037)
* Implement `add`, with tests.

* Implement `add_i`.

There's no test, because for whatever reason, I can't figure out how to emit this from Animate CC 2020.

* avm2: Implement `bitand` with tests.

* Implement `bitnot` with tests.

* Implement `bitor` with tests.

* avm2: Implement `bitxor`

* avm2: Implement `declocal`, `declocal_i`, `decrement`, and `decrement_i`.

* tests: `swf_approx` tests should be allowed to print NaNs.

* avm2: Implement `divide`.

* avm2: Implement `inclocal`, `inclocal_i`, `increment`, and `increment_i`.

* avm2: Implement `lshift`.

* Implement `modulo`.

* avm2: Implement `multiply` and `multiply_i` (no tests for the latter)

* avm2: Implement `negate` and `negate_i` (no tests for the latter)

* avm2: Implement `rshift`

* avm2: Implement `subtract` and `subtract_i` (the latter without tests)

* avm2: Implement `urshift`.
2020-08-23 13:38:38 -07:00
David Wendt 4c824fcefe Rename `trait.rs` to `traits.rs` to avoid the use of reserved keyword syntax. 2020-08-14 21:20:41 -04:00
David Wendt 7b7f0b20e6 Consolidate all of our copied `CollectWrapper`s. 2020-08-14 20:52:09 -04:00
David Wendt 32aad6176b `FunctionObject::from_builtin_constr` should pull the scope and class off of it's given prototype and copy it onto the constructor function it returns. 2020-08-11 00:04:13 -04:00
David Wendt 11ddccfa6a Remove the two-step initialization process and construct an ES4 class for `Object`, `Function`, and `Class`.
This has some particularly annoying consequences for initialization order: notably, we can't actually create any ES4 classes using the standard machinery until after the three objects I just mentioned get created. Ergo, we have to create them through lower-level means, handing prototypes around, and then initialize AVM2's system prototypes list for it.

When we start adding more system prototypes, we'll also have to fill the extras with blank objects and then slot them in as we create them.
2020-08-11 00:02:12 -04:00
David Wendt b1bcceaa78 Allow accessing the `Class` off of a constructor or prototype that references it. 2020-08-10 23:35:33 -04:00
David Wendt 22ec96b85e `install_trait` and `install_foreign_trait` should return the value of the thing they installed. 2020-08-10 23:23:35 -04:00
David Wendt df95482eb1 Allow setting `slot_id` or `disp_id` (depending on kind). 2020-08-10 23:23:34 -04:00
David Wendt 4ed5050f56 Add function to change trait attributes. 2020-08-10 23:23:34 -04:00
David Wendt a5b62e833e Add trait attributes, similar to that of class attributes 2020-08-10 23:23:31 -04:00
David Wendt 60d42fa558 Allow creating slot/const traits. 2020-08-10 23:19:22 -04:00
David Wendt 3ca8dfd21a Allow constructing traits for getters, setters, and unbound free functions. 2020-08-10 23:19:22 -04:00
David Wendt d366ceab0e Allow setting the protected namespace of a builtin class. 2020-08-10 23:19:21 -04:00
David Wendt 9dc6cbe1ce Allow creating builtin traits from methods. 2020-08-10 23:19:21 -04:00
David Wendt 5e932bcb75 Allow implementing interfaces in built-in classes. 2020-08-10 23:19:20 -04:00
David Wendt 94d5170277 When manually instantiating classes for globals, make sure that the classes get the global scope object when instantiated. 2020-08-10 23:19:15 -04:00
David Wendt 3585cf983b Convert our stub implementations of all non-ECMA classes into `Class`es.
This was surprisingly tricky - due to the need to look up superclasses, class trait instantiation requires an active `Activation` and `UpdateContext`. We can't get those during VM instance creation, since the player needs the VM first before it can give it a context to work with. Ergo, we have to tear the global scope initialization in two. At the first possible moment, the player calls a new `load_player_globals` method that initializes all class traits in global scope.
2020-08-10 23:16:07 -04:00
David Wendt 6f284f60eb Allow constructing a trait from a class. 2020-08-10 23:09:16 -04:00
David Wendt b0b6cec117 Allow expanding a `QName` into a `Multiname` that selects exactly the `QName` and no more. 2020-08-10 23:09:15 -04:00
David Wendt f09c35c4b9 `From<NativeMethod<'gc>>` doesn't always work, but using an explicit non-trait method sometimes does.
I have no idea why this is necessary - I was in a context where what *should* have been a `NativeMethod<'gc>` was instead being interpreted as some different function type with all the same lifetimes, but with an extra `'gc` lifetime as well. Funneling this through a non-trait method bypasses whatever is going on with the trait solver, and then at that point the trait solver knows what to do. Consider this an extra level of conversion.
2020-08-10 23:09:15 -04:00
David Wendt 4a2a456666 `Class::new` should also take the superclass name. 2020-08-10 23:09:13 -04:00
David Wendt d96596fd8a Add a function to manually change attributes. 2020-08-10 23:07:16 -04:00
David Wendt 44b8e5d9c7 Wrap up the existing sealed/final/interface bits in a `ClassAttributes` enumset. 2020-08-10 23:07:13 -04:00
David Wendt bf6ccfeee1 Add some convenience functions for defining native classes. 2020-08-10 23:02:42 -04:00
David Wendt c2cdc302c3 Remove further unnecessary primitive comparison checks 2020-08-10 16:38:04 -07:00
David Wendt 993f56798e Extract all of the numerical conversions into a separate module and leverage them where appropriate in AVM2 2020-08-10 16:38:04 -07:00
David Wendt 566b262d60 Move all our custom object implementations into a separate module, and use a macro to implement them. 2020-08-10 16:38:04 -07:00
David Wendt 5bcd1be270 Remove another instance of `abs` for zero-checks. 2020-08-10 16:38:04 -07:00
David Wendt 2f55c08e37 `pushbyte` should generate signed integers rather than `Number`s. 2020-08-10 16:38:04 -07:00
David Wendt 7f479f24b9 Adjust `coerce_to_string` to be less silly. 2020-08-10 16:38:04 -07:00
David Wendt a12f51903f Non-finite covers everything here. 2020-08-10 16:38:04 -07:00
David Wendt 2e8acfe6f7 Apparantly, Rust already does not care about negative zero, so we don't need to, either. 2020-08-10 16:38:04 -07:00
David Wendt 1bb6f84beb Avoid hitting `coerce_to_number` for integer comparison cases. 2020-08-10 16:38:04 -07:00
David Wendt 4e92352813 Don't promote to `f64` in strict-equality comparisons if we can promote to `i64` instead. 2020-08-10 16:38:04 -07:00
David Wendt a211698464 Handle strict and abstract equality of our various number subtypes as if they were all the same type.
ECMA-262 3rd ed. doesn't mention anything about different number types, so the standard as-if rule applies. If we are going to distinguish number types, we have to treat them as if they were the same type, promoting to `f64` as necessary to facilitate the conversion. I took a cursory look at an ECMA-262 4th ed. draft and it appears to do the same, although it calls everything `GeneralNumber` and has some really confusing psuedo-Pascal syntax for some reason.

I am extremely glad AVM2 does not provide access to 64-bit integer types (for now, at least).
2020-08-10 16:38:04 -07:00
David Wendt f3e47cb596 Further adjustments due to the massive refactor of `Activation`, `AvmX`, and `UpdateContext`. 2020-08-10 16:38:04 -07:00
David Wendt ea4c42a6d1 Split `Value::Number` into separate floating-point, integer, and unsigned representations to match the three numerical classes provided by AS3. 2020-08-10 16:38:04 -07:00
David Wendt a0895e843c Fix `matches!` lint in nightly Rust being tripped. 2020-08-10 16:38:04 -07:00
David Wendt b779dccdc1 Allow objects to provide a coercion hint for cases where a more obvious one is not available. 2020-08-10 16:38:04 -07:00
David Wendt d14fa845c2 Remove `Value::Namespace`.
Namespaces as values adds a bunch of extra special cases to the coercion and equality rules that don't really belong there. Namespace itself just returns it's URI as a string, so we can just make `NamespaceObject` do that and then treat it the same way we treat boxed primitives.
2020-08-10 16:38:04 -07:00
David Wendt e6aac48ae2 Add `NamespaceObject` to hold `Namespace`s.
The reason for this will become very apparent, very shortly.
2020-08-10 16:38:04 -07:00
David Wendt aeb1752d0f `PrimitiveObject`'s `toString` and `valueOf` should always yield their boxed values. 2020-08-10 16:38:04 -07:00
David Wendt 65b4392642 Remove `as_number`.
The only code that used it was the enumeration operations in AVM2.
2020-08-10 16:38:04 -07:00
David Wendt 4906c5a3f1 Remove uses of `as_string` in various places.
These include:

 * Name resolution in `newobject`
 * All runtime & late-bound multinames
 * `Object.hasOwnProperty`
 * `Object.propertyIsEnumerable`
 * `Object.setPropertyIsEnumerable`
2020-08-10 16:38:04 -07:00
David Wendt c040997be2 *Actually* fix the conversion.
So, I overlooked this reading the 1.45 documentation, but the first thing they did is completely change f64 conversions. Apparantly, what I was doing (and what JavaScript spec dictates) is actually considered UB in LLVM, and my ability to actually write a concise wrapping u32 conversion is actually a soundness hole in Rust. Ergo, I'm now emulating the wrapping and sign calculation, which makes this both passing it's tests again and free of soundness holes and UB.
2020-08-10 16:38:04 -07:00
David Wendt 473414e167 Explicitly request `u64` be involved with `u32` coercions.
I don't know why I'm doing this - tests are failing in CI but not locally, and I can only assume that the most obvious conversion is broken in some way on whatever other architecture GitHub Actions uses. This will explicitly mask the integer result as a u64, and then convert it down to u32. A not-broken compiler should treat this code identically.
2020-08-10 16:38:04 -07:00
David Wendt 962f6aa54c Remove `as_object`.
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.
2020-08-10 16:38:04 -07:00
David Wendt 8de063a916 Implement automatic primitive boxing via `coerce_to_object`. 2020-08-10 16:38:04 -07:00
David Wendt f12f67650b Stub all primitive type classes. 2020-08-10 16:38:04 -07:00
David Wendt cb0f1e9099 Add a new object variant for boxed primitives. 2020-08-10 16:38:04 -07:00
David Wendt b7dfce51b8 Implement `greaterequals`, `greaterthan`, `lessequals`, and `lessthan`. 2020-08-10 16:38:04 -07:00
David Wendt 730c47cf29 Implement `ifge`, `ifgt`, `ifle`, `iflt`, `ifnge`, `ifngt`, `ifnle`, and `ifnlt`. 2020-08-10 16:38:04 -07:00
David Wendt 70a27ccb81 Implement ECMA abstract relational comparison 2020-08-10 16:38:04 -07:00
David Wendt 2ef03c6019 Allow no-hint primitive coercion 2020-08-10 16:38:04 -07:00
David Wendt 76ab8570e4 Implement and test `equals`.
The test is also far more in-depth than the `if_eq`/`if_ne` tests, which use the same set of vectors as the strict-equality tests from a while ago. Interestingly, this test passed on first run
2020-08-10 16:38:04 -07:00
David Wendt 29d5ae9989 Implement `ifeq` and `ifne`. 2020-08-10 16:38:04 -07:00
David Wendt ccc478e7dd Implement ECMA-262 abstract equality. 2020-08-10 16:38:04 -07:00
David Wendt 0125a14d1f Partially implement `ToObject` coercion.
Implementation is limited to generating exceptions on `null` or `undefined`. I'm not sure if primitive values don't exist in AVM2 or if this is supposed to box them like ES3, so I have decided to handle neither at this time.
2020-08-10 16:38:04 -07:00
David Wendt 0138300b5a Implement `coerce_s` and `convert_s`. 2020-08-10 16:38:04 -07:00
David Wendt 90d2964adf Properly handle all cases of ECMA-262 string coercions.
This code is slightly over/under-precise compared to AVM2. This is because we handle precision limiting in binary floats rather than as part of the float printing process. Flash Player may also be rounding differently than us. However, I'm pretty sure ECMA-262 allows us to slightly differ here.
2020-08-10 16:38:04 -07:00
David Wendt 35f939cb15 Add and test for `convert_u` using `ToUint32` from ECMA-262 2020-08-10 16:38:04 -07:00
David Wendt 6eb41035cf Add & test ECMA-262 ToInt32 and `convert_i` opcode.
The ECMA-262 documentation is awfully overwrought for something that boils down to "chop off the non-whole part, wrap to 32 bits, then reinterpret as signed". Bitwise operations are *hell* to describe mathematically, and such descriptions are even harder to understand.
2020-08-10 16:38:04 -07:00
David Wendt 4c1489a814 Promote bytes to signed representation before pushing.
For whatever reason, `pushbyte` appears to be processed as a *signed* byte, despite the clear wording of "*byte_value* is an unsigned byte" in avm2overview.pdf. I guess it's supposed to be manually converted and promoted in this manner.
2020-08-10 16:38:04 -07:00
David Wendt 736a94a244 Implement numerical coercions according to ECMA-262 3rd Edition spec. 2020-08-10 16:38:04 -07:00
David Wendt 24fd30652d Allow tracing numbers to the console. 2020-08-10 16:38:04 -07:00
David Wendt 60f9613365 Implement and test for `convert_b`. 2020-08-10 16:38:04 -07:00
David Wendt 6cf48eb543 Implement and test `not`. 2020-08-10 16:38:04 -07:00
David Wendt e5c8c5b340 Expose `Infinity` to AS3. 2020-08-10 16:38:04 -07:00
David Wendt 5bb8c1836f Replace `as_bool` with `coerce_to_bool`.
Functions that need to assert Boolness without coercion should either:

1. Ensure their function declaration requires a Boolean. (We don't enforce type errors on ES4 typehints yet, but we should.)
2. Check the value type themselves and raise their own errors if necessary.

As it stands the only users of `as_bool` either needed to check the type themselves or use `coerce_to_bool`. Notably, `setPropertyIsEnumerable` doesn't appear to coerce *or* throw an error: it instead fails silently if you hand it a non-`Boolean` value.
2020-08-10 16:38:04 -07:00
David Wendt 8ebf5405e2 Move AVM2 into the UpdateContext. 2020-08-01 15:49:29 -04:00
Mike Welsh e5480ee9b2 chore: Use matches! to fix clippy lint 2020-07-27 04:13:11 -07:00
Nathan Adams 7f7281493f core: Allow toggling avm_debug output on and off with ctrl+alt+d, defaults to off 2020-07-23 19:14:32 -07:00
David Wendt 7adabc8166 Use `unwrap_or_default` 2020-07-18 17:28:07 -04:00
David Wendt 44b924d7b4 `Script` should not hold write locks when probing it's internal caches. 2020-07-18 17:26:11 -04:00
David Wendt 575a9b091a Use FnvHashMap for the translation unit pools. 2020-07-18 17:02:52 -04:00
David Wendt 262bb148f1 Rename `a2me` to `entry` (or `method` in one case where it lets me simplify a struct declaration) 2020-07-18 17:02:32 -04:00
David Wendt c415190376 Zero-index multinames should generate a validation error in `QName::from_abc_multiname`. 2020-07-18 16:48:10 -04:00
David Wendt dc962f2abd Add AVM2 equivalent of `PropertyMap` for further expansion. 2020-07-18 16:41:35 -04:00
David Wendt 37b6b89d26 Add a stub AVM2 string representation to allow for both VMs' strings to diverge. 2020-07-18 16:20:58 -04:00
David Wendt ccacc540bf Remove dead code on all now-in-use structs and methods. 2020-07-18 16:12:24 -04:00
David Wendt e354c53075 Remove any remaining uses of `abc_ref`.
Holding a `Ref` on a garbage-collected object inherently extends any borrow locks on that object. Since ABC files are references already, taking a `Ref` to them only helps to skip the refcount update. This is less useful than expected: in most situations, using `abc_ref` causes double-borrow panics. The few methods that can use it are going to be fragile in the face of future refactors, so I'm nipping the problem in the bud now.
2020-07-14 20:14:23 -04:00
David Wendt f4c5075086 Run all string constant retrieval through the `TranslationUnit`, preventing us from making multiple copies of the same string.
For good measure, most of the other methods in `value` for retrieving pool primitives now also use `TranslationUnit` instead of `AbcFile`. This is the result of a handful of cascading changes throughout the project, and itself caused a few more.
2020-07-14 20:05:25 -04:00
David Wendt 70e9e7e9e9 Add support for cached/interned pool strings in the `TranslationUnit`. 2020-07-13 23:42:07 -04:00
David Wendt e1b9b823fc Remove `abc_string` and replace it with `abc_string_copy`. All code that pulls strings from the ABC file now uses `AvmString`s. 2020-07-13 23:41:46 -04:00
David Wendt 61a3ff8ae6 Replace `String` or `&str` references with `AvmString` everywhere in the AVM2 runtime. 2020-07-13 22:21:18 -04:00
David Wendt 508fcd6e9e `pool_string` should return a `Ref<str>` just like `value::abc_string`. 2020-07-13 17:45:12 -04:00
David Wendt a406bdada2 Don't attempt to log debugging information if we're not in a debug build. 2020-07-13 17:45:12 -04:00
David Wendt ae26615bb4 `coerce_string` may return a static string, which we shouldn't clone. 2020-07-13 17:45:12 -04:00
David Wendt f0c633fe81 Allow borrowing string values from an ABC file instead of cloning everything. 2020-07-13 17:45:11 -04:00
David Wendt 39a4566f20 Instances should be listed as their prototypes (empty as they are) 2020-07-13 17:45:10 -04:00
David Wendt c917b3d411 Implement `istype`, `istypelate`, and `instanceof`. 2020-07-13 17:45:10 -04:00
David Wendt a0cb052795 Add `is_instance_of` trait method to `TObject` 2020-07-13 17:45:09 -04:00
David Wendt 3fae8b3832 Read the interface list when instantiating classes, resolve them, and stick them in the prototype for later use. 2020-07-13 17:45:09 -04:00
David Wendt cce68dbc21 Add trait methods for getting and setting the interfaces list. 2020-07-13 17:45:08 -04:00
David Wendt 8f2d3315f3 Allow the construction of classes with no base class.
This is primarily used for interfaces, in case you can't guess by the previous commit.
2020-07-13 17:45:07 -04:00
David Wendt 5d89d4ed85 Allow methods to not hold a body.
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.
2020-07-13 17:45:07 -04:00
David Wendt 090fe56bd3 Wrap `BytecodeMethod` (and the bytecode half of `Executable`) in a `Gc`.
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.
2020-07-13 17:45:06 -04:00
David Wendt 97e005622b Invert the role of `Avm2` and it's `Activation`, similar to what was done with `Avm1` and it's `Activation`.
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.
2020-07-13 17:45:06 -04:00
David Wendt 5b5bf0719e Remove `Avm2Function` as it is no longer used. 2020-07-13 17:45:05 -04:00
David Wendt 098b034de0 Refactor method-related structs into a separate method module.
This also renames `NativeFunction` and `Avm2MethodEntry` to `NativeMethod` and `BytecodeMethod`, respectively.
2020-07-13 17:45:05 -04:00
David Wendt b6e05519cd Remove `Avm2ClassEntry`. It is no longer used. 2020-07-13 17:45:05 -04:00
David Wendt 12fc13da7f Clippy compliance for the last batch of commits. 2020-07-13 17:45:05 -04:00
David Wendt 041cb0b5c3 Resolve multiname constant zero as an error rather than a panic.
While some code that references pool multinames has zero as a valid index, we cannot validate exactly what the zero index is for a given index. Hence, callers instantiating multinames must check for zero and substitute the correct zero-value interpretation for their given type. If zero is an invalid value, it should ideally throw a different error than what's provided here.
2020-07-13 17:45:04 -04:00
David Wendt 0d2235d2e0 Resolve all remaining compilation issues with this refactor. 2020-07-13 17:45:04 -04:00
David Wendt eaebd3c63c Make `Avm2MethodEntry` hold it's `TranslationUnit` rather than an `AbcFile`. 2020-07-13 17:45:03 -04:00
David Wendt 4467bc3193 Make `TranslationUnit` a GC-mandatory type (only referred to by `GcCell`). 2020-07-13 17:45:03 -04:00
David Wendt 60f3ae3ba7 Remove `Avm2ScriptEntry`. It is now obsolete and unused. 2020-07-13 17:45:02 -04:00
David Wendt f549d0146e Fix compilation bugs involved with automatic script initializer execution. 2020-07-13 17:45:02 -04:00
David Wendt b4f944b37b Wrap ABC loading inside of a `TranslationUnit`. 2020-07-13 17:45:01 -04:00
David Wendt 70e9030072 Decouple the entire trait machinery from ABC-provided traits.
This commit breaks the build: we still need to tell `Avm2` how to turn ABC traits into our own internal `Trait<'gc>`, `Class<'gc>`, and `Method<'gc>` types. We also need something to track which traits have already been instantiated, because `callstatic` would otherwise reinstantiate the trait in a different scope. (In fact, I think it *does* do exactly that right now...)
2020-07-13 17:45:01 -04:00
David Wendt 15a62d31cb Add an internal representation of `Trait`, separate from `swf::avm2::types::Trait`, which is specific to the ABC file format.
The intention is to completely replace all usage of `Avm2XYZEntry` with `Class`, `Trait`, and `Method`. This will allow runtime-provided global class traits to coexist with those provided by user code.
2020-07-13 17:45:01 -04:00
David Wendt 4cd30455de Excise `ReturnValue<'gc>` from all `TObject` methods.
Inspired by Dinnerbone's PR doing the exact same thing to AVM1.

On AVM2 we have a bit of a subtle issue: the base implementation of `set_property_local` and `init_property_local` *must* return `ReturnValue`s to avoid double-borrows. Each implementation of `TObject` must resolve them before returning.
2020-07-13 17:45:00 -04:00
David Wendt fe283e6770 Silence this warning about occupied slots being an unused variant.
I don't know if I'm missing something, but I'm pretty sure this variant is reachable via `TObject::install_slot`.
2020-07-13 17:45:00 -04:00
David Wendt 34ab8c8ce6 `NaN` is not special-cased in AS3. 2020-07-13 17:44:59 -04:00
David Wendt ecfd16cec9 Add global constants `undefined`, `null`, and `NaN`. 2020-07-13 17:44:58 -04:00