- 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
Now ExecutionContext has vector of values that will represent values
of local variables.
This vector is initialized in ECMAScriptFunctionObject::internal_call()
or ECMAScriptFunctionObject::internal_const() using number of local
variables provided to ECMAScriptFunctionObject by the parser.
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.
This modification enables the parser to determine whether an identifier
used within a function refers to a local variable or not. In this
context, a local identifier means that it is not captured by any nested
function declaration which means it modified only from inside a
function.
The information about whether identifier is local is stored inside
Identifier AST node and also contains information about the index of
local variable inside a function and information about total number
of local variables used by a function is stored in function nodes.
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.
The flag indicating the presence of an await expression should be
passed up to the parent scope until the nearest function scope is
reached. This resolves several problems related to identifying
top-level awaits, which are currently not recognized correctly
when used within a nested scope.
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.
ECMA-262 implies that `MIN_VALUE` should be a denormalized value if
denormal arithmetic is supported. This is the case on x86-64 and AArch64
using standard GCC/Clang compilation settings.
test262 checks whether `Number.MIN_VALUE / 2.0` is equal to 0, which
only holds if `MIN_VALUE` is the smallest denormalized value.
This commit renames the existing `NumericLimits<FloatingPoint>::min()`
to `min_normal()` and adds a `min_denormal()` method to force users to
explicitly think about which one is appropriate for their use case. We
shouldn't follow the STL's confusingly designed interface in this
regard.
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 is a similar strategy to what v8 does. Use the ASAN API function
__asan_addr_is_in_fake_stack to check any fake stack frames associated
with each stack address we scan. This fully allows running test-js -g
with the option detect_stack_use_after_return turned on.
The valid range for temporal values (`nsMinInstant`/`nsMaxInstant`)
means performing nanosecond-valued integers could lead to an overflow.
NB: Only the `roundingMode: "day"` case was affected, as all others were
already performing the division on floating-point `fractional_second`
values. I'm adding `.0` suffixes everywhere to make this fact clearer.
This adds a few local tests as well, as those are tested with sanitizers
enabled by default, unlike 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.
See 874ecf9
After this refactoring, we now correctly handle non-function /
non-undefined objects being passed multiple times: instead of skipping
assignment to promiseCapability altogether and failing with a
NotAFunction error in the end; on the second time the executor closure
is called, we return GetCapabilitiesExecutorCalledMultipleTimes.
This fixes the 7 `capability-executor-called-twice.js` test262 tests.
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