Converting a base value to an Object is performed by Reference::delete_.
Doing this early in the bytecode operator could be observable, although
it would likely be the first observable step in Reference::delete_
anyways. This will just align these operators with upcoming operators
for super references, where doing this coercion first will be observable
(we need to throw an exception for deleting a super property before this
coercion).
Invariants 5 and 6 of the `EnumerateObjectProperties` AO mean that we
must not include an enumerate property if there is a non-enumerable
property higher up the prototype chain with the same name. The previous
implementation did not adhere to this, as `EnumerableOwnPropertyNames`
does not carry information about present but non-enumerable properties.
This is part of an old normative change that happened soon after
Andreas made `super` closer to spec in 1270df2.
See https://github.com/tc39/ecma262/pull/2267/
This was introduced into bytecode by virtue of copy and paste :^)
Bytecode results:
Summary:
Diff Tests:
+2 ✅ -2 ❌
- Update ECMAScriptFunctionObject::function_declaration_instantiation
to initialize local variables
- Introduce GetLocal, SetLocal, TypeofLocal that will be used to
operate on local variables.
- Update bytecode generator to emit instructions for local variables
Saving vector of local variables names in ECMAScriptFunctionObject
will allow to get a name by index in case message of ReferenceError
needs to contain a variable name.
By using Identifier class to represent the name of a class expression,
it becomes possible to consistently store information within the
identifier object, indicating whether the name refers to a local
variable or not.
This makes the behavior of `Symbol` correct in strict mode, wherein if
the receiver is a symbol primitive, assigning new properties should
throw a TypeError.
This avoids the overhead of allocating a new Array on every function
call, saving a substantial amount of time and avoiding GC thrash.
This patch only makes use of Op::Call in CallExpression. There are other
places we should codegen this op. We should also do the same for super
expression calls.
~5% speed-up on Kraken/stanford-crypto-ccm.js
Forcing every function call to allocate a new Array just to accommodate
spread parameters is not very nice, so let's start moving towards making
this a special case rather than the general (and only) case.
The var environments will unwind as needed with the ExecutionContext
and there's no need to include it in the unwind info.
We still need to do this for lexical environments though, since they
can have short local lifetimes inside a function.
Since the relationship between VM and Bytecode::Interpreter is now
clear, we can have VM ask the Interpreter for roots in the GC marking
pass. This avoids having to register and unregister handles and
MarkedVectors over and over.
Since GeneratorObject can also own a RegisterWindow, we share the code
in a RegisterWindow::visit_edges() helper.
~4% speed-up on Kraken/stanford-crypto-ccm.js :^)
While the completion value of a variable declaration is specified to be
empty, we might already have a completion value in the accumulator from
a previous statement. Preserve it so as to avoid clobbering it.
This fixes 6 tests on test262.
This makes them trivially copyable, which is an assumption multiple
optimizations use when rebuilding the instruction stream.
This fixes most optimized crashes in the test262 suite.
We do this by moving the `LoadImmediate undefined` instruction to a
separate basic block which jumps to the case's block unconditionally.
We enter a case initially using this wrapper, but when falling through,
we directly jump to the next case's block.
This adds support for exporting class expressions, which was previously
TODO'd.
We now correctly set the binding name of exports to `"*default*"` if
they are unnamed. I'm not sure what the difference between the
`InitializationMode` kinds is, but using `Initialize` fixes a bunch of
tests.
Note that some export tests (e.g. `eval-export-dflt-expr-cls-named.js`)
still fail, as we don't set the "name" property of exported classes
correctly.
176 new passes on test262
While this would be useful in the future for implementing a multi-tiered
optimization strategy, currently a binary on/off is enough for us. This
removes the confusingly on-by-default `OptimizationLevel::None` option
which made the optimization pipeline a no-op even if
`Bytecode::Interpreter::set_optimizations_enabled` had been called.
Fixes#15982
This is in preparation for an upcoming implementation of the Iterator
Helpers proposal. That proposal will require a JS::Object type named
"Iterator", so this rename is to avoid conflicts.
The fact that side effects clobbers the accumulator isn't just annoying
inside the instruction handler, but also really counter-intuitive in
the bytecode program itself.
17 new passes on test262. :^)
Instead of assuming that there's an active AST interpreter, this code
now takes VM& everywhere and invokes the appropriate interpreter.
92 new passes on test262. :^)