Commit Graph

66 Commits

Author SHA1 Message Date
Mike Welsh d87be39e3c avm2: Don't parse "inf" as Infinity 2021-04-14 21:51:48 -07:00
relrelb bb89391f3a chore: Avoid deprecated constants
The Rust documentation considers numeric constants prefixed with std::
as deprecated.
For example: https://doc.rust-lang.org/std/u16/constant.MAX.html.
2021-02-12 06:36:17 -08:00
relrelb b05c6540e1
chore: Migrate from enumset to bitflags 2021-01-21 16:35:46 -08:00
Mike Welsh da1e2801a2 chore: Appease clippy 2021-01-18 21:23:50 -08:00
David Wendt 8b9a804ae9 avm2: Implement `Event.formatToString`. 2020-12-14 16:46:33 -08:00
relrelb 2e0509694c docs: Miscellaneous spelling corrections 2020-11-12 13:34:05 -08:00
Mike Welsh 316bc4e920 chore: Appease clippy 2020-11-09 01:52:57 -08:00
Mike Welsh ead845ff33 chore: Appease clippy 2020-09-26 18:19:37 -07:00
Luca Weiss d5cb396331 *: fix spelling mistakes 2020-09-19 16:17:58 -07:00
David Wendt bb19699739 avm2: Add convenience method for converting a `Value` into an `EnumSet`. 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 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 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 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 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 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 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 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
Mike Welsh e5480ee9b2 chore: Use matches! to fix clippy lint 2020-07-27 04:13:11 -07: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 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 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