A second root module in a failed cycle can call Evaluate after the
cycle root has already cached an evaluation error. In that case
InnerModuleEvaluation returns the cached error immediately and Evaluate
must reject the new top-level capability with that same error.
Remove the extra assertion that the module evaluation error is empty in
the abrupt completion path. Add text coverage for evaluating both roots
of a module cycle whose dependency throws during evaluation.
DateParser is a GenericLexer, which is not particularly UTF-8 aware.
Other engines do not accept ASCII input, so let's just reject non-ASCII
strings outright.
While we are here, let's avoid the std ctype header. It is explicitly
undefined behavior to provide code points to isspace, isalpha, etc. that
do not fit in an unsigned char. Although this isn't reachable any longer
let's just nip it in the bud and use our safe AK character types.
Just to demonstrate, the following returns different values for me on
different systems and with different compilers:
isdigit(0xff01)
isalpha(0xff01)
isspace(0xff01)
* Replace std::pair with a named struct, which we've always preferred.
* Remove needless use of std::ignore.
* Use concepts from AK instead of type traits from the STL.
This class was effectively upside-down compared to the way we typically
organize our classes.
* Put public section above private section
* Put methods above members
* Add newlines between methods
Resolve strict global-looking assignment targets before evaluating their
right-hand side instead of lowering them directly to SetGlobal. Preserve
the original unresolvable reference for PutValue so a RHS-created global
cannot hide the ReferenceError.
Add a runtime test for that ordering and update the bytecode expectation
for a strict top-level assignment that now uses SetResolvedBinding.
Parenthesized import calls are valid callees for new expressions. The
unparenthesized form remains a syntax error, but the grouped expression
must parse and then fail at runtime if the produced Promise is not a
constructor.
Add syntax coverage for both forms.
Store ExecutableBacking on Script and SourceTextModule, and make those
owners coordinate generated cache installation. Replacing executable
backing now clears non-cache compile inputs and verifies that mapped
cache-backed records no longer retain source or heap bytecode inputs.
Give scripts and modules an explicit list of their shared function data
records, and teach Rust materialization to populate that list directly.
This gives bytecode cache installation a stable set of functions to
update when replacing executable backing storage.
Allow a freshly materialized executable to inherit compatible runtime
caches from the executable it replaces. Store template object caches as
GC cells so they can be shared safely between executable instances.
Introduce ExecutableBacking as the state machine for how a Script or
SourceTextModule executable is backed. Keep construction and transitions
private to the owning record types so transient cache-generation states
cannot be created directly.
Store the spec's [[AsyncEvaluationOrder]] value instead of a boolean for
pending async module evaluation. This lets AsyncModuleExecutionFulfilled
sort available parent modules by the order assigned during module graph
evaluation before executing them.
This matches ECMA-262 module graph ordering and fixes TLA parent
completion order, including graphs where a dynamic import later reuses a
TLA dependency.
Avoid draining the Promise job queue from VM::run_executable while a
SourceTextModule is still executing its body. Dynamic import queues the
load/link/evaluate continuation as a Promise job, and running that job
before ModuleEvaluation unwinds can re-enter Link() while the entry
module is still evaluating.
Track module execution depth so standalone script execution still drains
jobs at the same boundary, but module jobs are drained by
VM::run(SourceTextModule) after Link/Evaluate returns. Add coverage for
an entry module dynamically importing itself during evaluation.
Only drain the standalone Promise job queue when unwinding the outermost
bytecode execution. Draining after every nested run_executable() return
let sibling Promise reactions run before current-job reactions.
Plain async function returns were relying on that extra drain because
return values were compiled as implicit awaits. Resolve completed async
functions through the Promise resolving function instead, while keeping
the async generator return-await path.
Add Promise ordering coverage and update the asm inline-call regression
to check the pre-drain state.
Resolve dynamic identifier assignment targets before evaluating the
right hand side, then store through that saved environment record. This
matches the ECMA-262 ordering for simple assignment and var initializers
when a with binding is deleted or direct eval creates a nearer var.
Add runtime coverage for with and direct-eval cases and refresh bytecode
expectations for dynamic assignments that now snapshot the binding
before storing.
Treat labelled FunctionDeclaration nodes as declaration-bearing items
when collecting block lexical and top-level var scoped declarations.
This lets Annex B declaration instantiation initialize them before
execution and copy block functions back to the var binding.
Add LibJS coverage for function bodies, direct eval, blocks, switch
cases, and duplicate labelled declarations.
Run deferred parameter validation whenever the surrounding context is
already strict, not only when a function body contains a Use Strict
Directive. Destructured parameter names are collected while parsing the
parameter list, so eval and arguments bindings in patterns otherwise
escaped the strict-mode early error for functions and methods.
Add parser coverage for sloppy destructuring remaining accepted, strict
source being rejected, and class methods applying their strict context.
Match ECMA-262's SuperCall evaluation order by resolving the super
constructor before evaluating the argument list. This preserves the
constructor across argument-side prototype mutations and still lets
abrupt argument evaluation happen before the constructor check.
Add LibJS coverage and update bytecode baselines for the new saved
super-constructor operand. The test262 superCallOrder staging test now
passes.
Reject parenthesized object and array literals when a destructuring
assignment element is refined into a nested assignment pattern. These
grouped forms do not cover AssignmentPattern, while parenthesized simple
assignment targets such as identifiers and member expressions remain
valid.
Add local syntax coverage for the invalid nested patterns and the valid
simple target cases.
Apply the `async of` grammar exclusion only to ordinary for-of
statements. The for-await-of production excludes `let` at the start of
the left-hand side, but does not exclude `async of`, so `async` remains
a valid assignment target there.
Add local parser coverage for async functions and async generators.
Parse await through the unary-expression path so the existing
exponentiation early error also applies to AwaitExpression. This keeps
parenthesized await expressions valid while rejecting await on the
left-hand side of **.
Add parser coverage for the async-function constructor case.
Reject labels whose string value is an unconditional ReservedWord,
while keeping await and yield on their contextual identifier paths.
This makes super labels a syntax error, matching ECMA-262 and V8.
Add coverage for the rejected super label form.
NamedEvaluation for assignment only applies when the left hand side is
an IdentifierRef. Parenthesized identifiers are still assignment
targets, but are not IdentifierRefs, so `(fn) = function () {}` must
leave the function anonymous.
Carry the parser's parenthesized-LHS bit into assignment codegen. Use
it when setting pending_lhs_name for plain and logical assignment, and
cover parenthesized assignment targets in the function-name tests.
The delete operator needs the Reference produced by an optional chain
when the chain ends in a property access. We evaluated the chain for
side effects and returned true, so delete object?.property reported
success without removing the property.
Emit delete-specific optional-chain bytecode. It short-circuits to true
for nullish optional hops, but performs DeleteById or DeleteByValue
when the final property reference is reached. Add runtime coverage for
named, computed, and short-circuited optional deletes.
Set.prototype.difference must call other.has for the entries in the
copied resultSetData, not for a live iteration over the receiver. If
other.has mutates the receiver, newly-added entries must not be visited.
Snapshot the copied result keys before calling user code so receiver
mutations cannot change which entries the operation tests. Add coverage
for the mutation case from the staging Set difference tests.
Normal functions create their prototype lazily. [[GetOwnProperty]]
already materialized it, but [[OwnPropertyKeys]] read the current shape
directly, so Object.getOwnPropertyNames(...) omitted "prototype".
Materialize the lazy prototype before enumerating own keys. This keeps
the fast path for functions whose keys are never observed while matching
the ordinary function property list expected by engines and test262.
InitializeTypedArrayFromArrayBuffer used Checked<u32> for view bounds.
Valid ToIndex values at 2**32 could wrap to zero before the
out-of-range check, so constructors accepted views that should throw.
Keep the bounds math in size_t until after the spec range checks. Narrow
only when storing the values in the current TypedArray slots. Add LibJS
coverage for ArrayBuffer byteOffset and length wraparound cases.
Accept single-digit minute and second components for space-separated
ISO-like dates. This matches other engines and the SpiderMonkey test.
Keep T-separated date-times stricter by rejecting bare hour offsets like
-07, while still allowing the non-standard space-separated form.
Return negative BigInts unchanged when their magnitude already fits in
the requested signed width. This matches BigInt.asIntN wrapping without
allocating the enormous modulo value first.
Update coverage to expect the result produced by other engines for these
large bit counts instead of an internal OOM.
Number.prototype.toFixed was using generic fixed-format double printing
after the spec steps. That loses the exact binary64 value for large
fractionDigits, so high precision output rounded from a nearby decimal.
Compute the scaled integer n with BigInteger arithmetic from the exact
binary decomposition of the double, then format that integer according
to the toFixed placement rules. Add coverage for high precision
fractional values and the signed Number.MIN_VALUE case.
`import * as ns; export { ns }` was being recorded as a local
export, so two star exports of matching namespace objects resolved
through different fixture modules and became ambiguous.
Emit the same indirect namespace export metadata used by `export * as`
for both normal compilation and bytecode-cache materialization. Add a
module test that merges two matching namespace re-exports.
Host-loaded modules are inserted into the VM module registry before
their dependencies are walked, but entry modules passed directly to
`VM::run()` were not. That made an entry module self-import parse a
second Module Record and observe the second copy after evaluation.
Register named entry modules in the same registry before dependency
loading runs, so self-imports and namespace access go through the
original Module Record. Add a test-js helper for running modules
directly and cover the self-import pre-evaluation binding state.
Sync yield* must suspend with the delegated IteratorResult object itself
on non-terminal steps. We were reading value and yielding that value,
causing Generator.prototype.next() to create a fresh result object.
Add a bytecode op for this path so ordinary yield keeps wrapping its
value, and teach generator resume to return the prebuilt result object.
This also avoids touching value before the delegated iterator is done.
Add regression coverage and update the yield* bytecode baseline.
Reset the legacy octal string marker at the start of each directive
prologue scan. Otherwise an octal string parsed later in an outer
function body can leak into a nested function and be treated as part of
that nested function's directive prologue.
Add coverage for a nested strict function following a non-directive
octal string in the outer function body.
Reject for-await loop heads that fall through to normal for-loop or
for-in parsing. ECMA-262 only defines for-await with for-of productions,
and V8 rejects these forms as syntax errors.
Add parser coverage for the valid for-await-of form and the invalid
C-style and for-in forms.
Mark binding-pattern identifiers with their declaration kind so local
destructuring assignments use the normal TDZ and const assignment path.
This makes local const destructuring match the environment-backed path.
Also teach GetById to expose primitive string virtual index properties
before boxing, matching StringGetOwnProperty and GetByValue. Together
these fix the SpiderMonkey for-in/of const declaration coverage and the
lexical destructuring TDZ test.
YieldExpression carries the surrounding In grammar parameter into its
operand. The parser was always parsing yield operands with In enabled,
accepting invalid generator for-loop heads containing `yield ... in`.
GeneratorExpression parses its optional binding identifier with the
Yield grammar parameter enabled, so `yield` is not a valid name for
a named generator expression. Reject it while still allowing sloppy
generator declarations named `yield`, and add syntax coverage for
both cases.
ArrowFunction carries the surrounding In grammar parameter into its
ConciseBody. The parser recognized arrows in for-loop init expressions,
but parsed expression bodies with In always enabled, so
`for (x => 0 in 1;;)` was accepted as a normal for loop.
Thread the existing forbidden-token state through arrow parsing so the
body leaves `in` for the for-head parser. That parser then rejects the
arrow as an invalid for-in left-hand side. Add coverage in the for-loop
no-In syntax test.
Annex B.3.2 suppresses the labelled FunctionDeclaration early error
in non-strict code when the host supports that compatibility feature.
Script and block statement lists already enabled that path, but function
bodies parsed their statement lists with it disabled.
Parse function-body statement lists with the same labelled-function
allowance while the existing strict and generator checks continue to
reject the invalid forms. Add coverage for all three cases.
Accessor cache entries can be reused by objects with the same shape even
when the accessor functions differ. Reusing a getter cache for a later
setter-only object tried to call null instead of returning undefined.
Route cached gets through the missing-getter behavior from OrdinaryGet,
and fall back to the slow set path when a cached accessor has no setter
so strict assignment failures still come from OrdinarySet.
Add IC coverage for the missing accessor half in both directions.
Record the generator's strictness for each emitted bytecode
instruction, instead of applying the executable's final strictness to
every instruction during assembly. This lets class heritage and
computed element names run with strict assignment semantics inside
sloppy scripts.
Also create the class self-binding as a strict immutable binding,
matching ClassDefinitionEvaluation, and cover strict class heritage and
computed names in the runtime tests.
SingleNameBinding default initializers use NamedEvaluation when the
argument value is undefined and the initializer is an anonymous function
or class definition.
Set the pending inferred name while evaluating default initializers for
identifier parameters, and add coverage for function, generator, async,
arrow, and class expressions.
ArraySetLength deletes array index properties in descending order. When
a non-configurable index cannot be deleted, the length is restored to
that index plus one, and lower indexes are not touched.
The dictionary indexed storage path already restored the final length,
but removed configurable entries below the failing index too. Keep those
entries when truncation stops early and add sparse array coverage.
WithStatement evaluation updates empty statement completions to
undefined. The bytecode generator reused the surrounding completion
register while compiling the with body, so an empty break or continue
could leak the enclosing loop's previous completion value.
Give the with body its own completion register initialized to undefined
and add regression coverage for abrupt exits from the body.
Keep the premade normal-function property layout when creating dynamic
functions with a custom [[Prototype]], but transition the shape to that
prototype instead of replacing it with %Function.prototype%.
Let Function subclasses and bound functions created from their instances
participate in instanceof checks, and keep bound super() construction
passing the derived new.target through.
Treat ordinary and generator function expressions inside class static
blocks as boundaries for await binding names, while still rejecting
await as an arrow parameter in the static block itself.
Parse field initializers without inheriting an enclosing async
function's await-expression context, so script field initializers can
resolve await as an identifier while computed field names still use the
enclosing expression context.
Cover static block function expressions, class field initializers, and
the AST shape for an await arrow inside a nested function.
Evaluate member targets in object destructuring before reading the
source property or copying rest properties. Convert computed source
property keys before evaluating the target reference so the generated
bytecode follows the spec ordering.
Cover plain, computed, defaulted, and rest object destructuring.
ClassHeritage parses an extends clause as a LeftHandSideExpression,
which excludes unparenthesized arrow functions. Reject arrows that start
at the heritage expression while still allowing parenthesized arrows and
arrows nested inside call arguments.
Add class inheritance coverage for declarations, expressions, and nested
arrow arguments.
Generator and async generator instances should use
OrdinaryCreateFromConstructor with %GeneratorPrototype% and
%AsyncGeneratorPrototype%. When `.prototype` was nullish, we created a
null-prototype object, and when it was a primitive, we boxed it with
ToObject.
Use GetPrototypeFromConstructor for the generating function and cover
fallbacks for nullish and primitive prototype values.
Formal parameter early errors depend on the final parameter-list shape.
A duplicate in `function(a, a, ...rest)` was accepted because the
duplicate appeared before the rest parameter was seen.
Track the final simple-parameter-list result before checking duplicate
names, and enforce `UniqueFormalParameters` for method definitions. Add
coverage for sloppy functions with a later rest parameter and sloppy
object methods.