Clang was failing because because it rightfully saw we were attempting
to call a deleted constructor of `MarkedValueList`. If you explicitly
called move(list) then GCC would complain that the move was unnecessary.
For what ever reason both tool chains accept when we construct the
ThrowCompletionOr explicitly that we move the list into and return that.
This is much more common across the whole codebase and even these two
files. The same is used to return an empty JS::Value in an exception
check, for example.
This is where the spec wants to have it. Requires a couple of hacks as
currently everything that needs a Realm actually has a GlobalObject, so
we need to go via the Interpreter.
The primary themes here are invoking js_string() with existing instances
of Utf16String when possible, and not creating entire UTF-8 copies when
not needed.
This commit does not go out of its way to reduce copying of the string
data yet, but is a minimum set of changes to compile LibJS after making
PrimitiveString hold a Utf16String.
This also converts the GetSubstitution abstract operation take its input
strings as UTF-16 now that all callers are UTF-16 capable. This means
String.prototype.replace (and replaceAll) no longer needs UTF-8 and
UTF-16 copies of these strings.
- Fix evaluation order: IsArray(O) should always be called and before
Get(O, @@toStringTag), previously it was the other way around and
IsArray would only be called if @@toStringTag is not a string
- Add missing exception checks to both function calls
- Add missing builtin tag for arguments object
Also, while we're here:
- Update variable names to match spec
- Add spec step comments
Now that the Object rewrite is in place, we have enough tools to
implement the mapped `arguments` propreties according to spec.
The basic mechanism is that the `arguments` object installs a hidden
parameter mapping object that property accesses get filtered through.
This is how accessing numeric properties on `arguments` are proxied
to the named identifier in the function scope.
When `arguments` is instantiated, getters and setters are created
for all the numeric properties on the object that correspond to
function arguments. These getters and setters can be deleted from the
object. This is all pretty intricate, so refer to the spec for details.
Note that the `arguments` object itself is still lazily instantiated
on first access within a function. This is non-conforming, and we'll
have to revisit this once we get around to improving function calls.
This is a huge patch, I know. In hindsight this perhaps could've been
done slightly more incremental, but I started and then fixed everything
until it worked, and here we are. I tried splitting of some completely
unrelated changes into separate commits, however. Anyway.
This is a rewrite of most of Object, and by extension large parts of
Array, Proxy, Reflect, String, TypedArray, and some other things.
What we already had worked fine for about 90% of things, but getting the
last 10% right proved to be increasingly difficult with the current code
that sort of grew organically and is only very loosely based on the
spec - this became especially obvious when we started fixing a large
number of test262 failures.
Key changes include:
- 1:1 matching function names and parameters of all object-related
functions, to avoid ambiguity. Previously we had things like put(),
which the spec doesn't have - as a result it wasn't always clear which
need to be used.
- Better separation between object abstract operations and internal
methods - the former are always the same, the latter can be overridden
(and are therefore virtual). The internal methods (i.e. [[Foo]] in the
spec) are now prefixed with 'internal_' for clarity - again, it was
previously not always clear which AO a certain method represents,
get() could've been both Get and [[Get]] (I don't know which one it
was closer to right now).
Note that some of the old names have been kept until all code relying
on them is updated, but they are now simple wrappers around the
closest matching standard abstract operation.
- Simplifications of the storage layer: functions that write values to
storage are now prefixed with 'storage_' to make their purpose clear,
and as they are not part of the spec they should not contain any steps
specified by it. Much functionality is now covered by the layers above
it and was removed (e.g. handling of accessors, attribute checks).
- PropertyAttributes has been greatly simplified, and is being replaced
by PropertyDescriptor - a concept similar to the current
implementation, but more aligned with the actual spec. See the commit
message of the previous commit where it was introduced for details.
- As a bonus, and since I had to look at the spec a whole lot anyway, I
introduced more inline comments with the exact steps from the spec -
this makes it super easy to verify correctness.
- East-const all the things.
As a result of all of this, things are much more correct but a bit
slower now. Retaining speed wasn't a consideration at all, I have done
no profiling of the new code - there might be low hanging fruits, which
we can then harvest separately.
Special thanks to Idan for helping me with this by tracking down bugs,
updating everything outside of LibJS to work with these changes (LibWeb,
Spreadsheet, HackStudio), as well as providing countless patches to fix
regressions I introduced - there still are very few (we got it down to
5), but we also get many new passing test262 tests in return. :^)
Co-authored-by: Idan Horowitz <idan.horowitz@gmail.com>
This patch implements spec-compliant runtime semantics for the following
constructs:
- super.property
- super[property]
The MakeSuperPropertyReference AO is added to support this. :^)
This patch adds a new ArgumentsObject class to represent what the spec
calls "Arguments Exotic Objects"
These are constructed by the new CreateMappedArgumentsObject when the
`arguments` identifier is resolved in a callee context.
The implementation is incomplete and doesn't yet support mapping of
the parameter variables to the indexed properties of `arguments`.
This was a standalone function previously (get_method()), but instead of
passing a Value to it, we can just make it a method.
Also add spec step comments and fix the receiver value by using GetV().
Requires a bunch of find-and-replace updates across LibJS, but
constructing a PropertyName from a nullptr Symbol* should not be
possible - let's enforce this at the compiler level instead of using
VERIFY() (and already dereference Symbol pointers at the call site).
This is true for environments created by `with` statements, and false
for other (global) object environments.
Also add the WithBaseObject abstract operation while we're here.
To better follow the spec, we need to distinguish between the current
execution context's lexical environment and variable environment.
This patch moves us to having two record pointers, although both of
them point at the same environment records for now.
This patch adds FunctionEnvironmentRecord as a subclass of the existing
DeclarativeEnvironmentRecord. Things that are specific to function
environment records move into there, simplifying the base.
Most of the abstract operations related to function environment records
are rewritten to match the spec exactly. I also had to implement
GetThisEnvironment() and GetSuperConstructor() to keep tests working
after the changes, so that's nice as well. :^)