1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-20 11:45:06 +00:00
Commit graph

4609 commits

Author SHA1 Message Date
Aliaksandr Kalenik
ae3a7fd4b8 LibJS: Update bytecode generator to use local variables
- 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
2023-07-05 21:03:01 +02:00
Aliaksandr Kalenik
0daff637e2 LibJS: Add vector of local variables in ExecutionContext
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.
2023-07-05 21:03:01 +02:00
Aliaksandr Kalenik
7765ebb5f2 LibJS+LibWeb: Plumb local variables names to ECMAScriptFunctionObject
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.
2023-07-05 21:03:01 +02:00
Aliaksandr Kalenik
401d97c45c LibJS: Add ScopeNode::for_each_var_declared_identifier()
The same as for_each_var_declared_name but for identifiers.
2023-07-05 21:03:01 +02:00
Aliaksandr Kalenik
7f0074ac23 LibJS: Add for_each_bound_identifier for AST::Declaration
The same as for_each_bound_name but for identifiers.
2023-07-05 21:03:01 +02:00
Aliaksandr Kalenik
a6cdb1655b LibJS: Use Identifier to represent name of FunctionNode 2023-07-05 21:03:01 +02:00
Aliaksandr Kalenik
380abddf3c LibJS: Update parser to detect if identifier refer a "local" variable
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.
2023-07-05 21:03:01 +02:00
Aliaksandr Kalenik
c734f2b5e6 LibJS: Use Identifier to represent name of ClassExpression
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.
2023-07-05 21:03:01 +02:00
Andreas Kling
dfd0942e41 LibJS/Bytecode: Clear accumulator before entering for body
2 new passes on test262. :^)
2023-07-05 15:39:25 +02:00
Andreas Kling
24b815d4a0 LibJS/Bytecode: Clear accumulator before entering while body
2 new passes on test262. :^)
2023-07-05 15:39:25 +02:00
Andreas Kling
b14032bbfa LibJS/Bytecode: Leave for in and for of with right completion value
14 new passes on test262. :^)
2023-07-05 15:39:25 +02:00
Andreas Kling
7430dee5cf LibJS/Bytecode: Make ClassDeclaration not clobber the accumulator
2 new passes on test262. :^)
2023-07-05 15:39:25 +02:00
Andreas Kling
e87d84f883 LibJS/Bytecode: Support in binary operator for private fields
11 new passes on test262. :^)
2023-07-05 15:39:25 +02:00
Aliaksandr Kalenik
75ae368896 LibJS: Propagate "contains await" flag to parent scope in ScopePusher
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.
2023-07-05 06:05:22 +02:00
Hendiadyoin1
b26dad3d62 LibJS: Handle Calls argument range during EliminateLoads pass
Otherwise we could forget to emit stores those registers, thinking that
they are only directly accessed.
2023-07-03 16:55:13 +02:00
Daniel Bertalan
d165590809 LibJS/Bytecode: Do not coerce the receiver to Object for internal_set
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.
2023-07-02 22:08:48 +01:00
Daniel Bertalan
0cd85ab0fc AK+LibJS: Make Number.MIN_VALUE a denormal
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.
2023-07-02 21:19:09 +01:00
Andreas Kling
c37b204ce1 LibJS/Bytecode: Add Call opcode for fixed-argument-count calls
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
2023-07-02 18:30:02 +02:00
Andreas Kling
7eb87dec9f LibJS/Bytecode: Rename Call and SuperCall to &WithArgumentArray
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.
2023-07-02 18:30:02 +02:00
Andreas Kling
dc884aa0d3 LibJS/Bytecode: Remove unnecessary variable environment stack
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.
2023-07-02 18:30:02 +02:00
Andreas Kling
fb979dcf34 LibJS/Bytecode: Make Bytecode::Interpreter participate in GC marking
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 :^)
2023-07-02 14:50:02 +02:00
Andreas Kling
cea2071349 LibJS/Bytecode: Infer name of anonymous exported classes when possible
5 new passes on test262. :^)
2023-07-02 12:18:25 +02:00
Andreas Kling
b0ae1e80fb LibJS/Bytecode: Support using MemberExpression as rest property
Also, don't assert while dumping an AST with this construct.

7 new passes on test262. :^)
2023-07-02 11:53:10 +02:00
Daniel Bertalan
0df7255fe7 LibJS/Bytecode: Do not clobber completion value with VariableDeclaration
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.
2023-07-02 10:54:35 +02:00
Andreas Kling
bd2c3ace68 LibJS/Bytecode: Make sure empty with statement results in undefined
2 new passes on test262. :^)
2023-07-02 10:54:28 +02:00
Andreas Kling
0cb9c9e81e LibJS: Add fast paths for bitwise ops on 2x Int32 JS::Value
~9% speed-up on Kraken/stanford-crypto-aes.js :^)
2023-07-01 20:29:12 +01:00
Andreas Kling
1efe4b58aa LibJS/Bytecode: Store current interpreter register window as a Span
This avoids a bunch of indirections on every single register access.

~17% speed-up on Kraken/stanford-crypto-aes.js :^)
2023-07-01 20:29:12 +01:00
Shannon Booth
e7435d68b0 LibJS: Extract named vm variables in ArrayBufferPrototype::slice 2023-07-01 16:55:17 +01:00
Shannon Booth
3781948f0c LibJS: Add initial implementation for SharedArrayBuffer
None of the actual sharing is implemented yet, but this is enough for
most basic functionality.

Diff Tests:
    +260     -262    +2 💀
2023-07-01 16:55:17 +01:00
Andrew Kaster
31440687a3 LibJS: Check the ASAN fake stack for heap pointers when ASAN is enabled
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.
2023-07-01 07:03:11 +02:00
Daniel Bertalan
96b197ef46 LibJS/Temporal: Perform floating point arithmetic in RoundTime
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.
2023-07-01 06:51:25 +02:00
Daniel Bertalan
1dce1994eb LibJS: Make the options arg of InterpretTemporalDateTimeFields nullable
This fixes "reference binding to null pointer" UBSan warnings.
2023-07-01 06:51:25 +02:00
PrestonLTaylor
850c252b3e LibJS: Implement ArrayBuffer.prototype.transfer & transferToFixedLength 2023-06-30 23:23:15 +02:00
PrestonLTaylor
34c5d34b95 LibJS: Show when an ArrayBuffer is detached when printing 2023-06-30 23:23:15 +02:00
PrestonLTaylor
286bf307d2 LibJS: Don't crash when calling byte_length for a detached ArrayBuffer 2023-06-30 23:23:15 +02:00
PrestonLTaylor
bd0ccbe3c8 LibJS: Implement the ArrayBuffer.prototype.detached getter 2023-06-30 12:47:15 +01:00
Daniel Bertalan
18c735429f LibJS: Fix incorrect is_function() check in NewPromiseCapability
I introduced this copy-paste mistake in c21255d.

Gets rid of 7 assertion failures on test262.
2023-06-29 08:43:28 +02:00
Aliaksandr Kalenik
1550e7c421 LibJS: Stop using execute_ast_node in NewClass instruction
This change replaces usage of `execute_ast_node` to evaluate super
expression in NewClass by generating instructions instead.
2023-06-29 07:14:14 +02:00
Hendiadyoin1
37067cf3ca LibJS: Use the IdentifierTable for NewFunction and NewClass lhs names
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.
2023-06-29 05:32:08 +02:00
Daniel Bertalan
c21255da7f LibJS: Align NewPromiseCapability with spec changes
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.
2023-06-28 23:36:15 +01:00
Shannon Booth
0748e755d8 LibJS: Implement SetValueInBuffer closer to spec
No functional changes intended, mostly just adding spec comments, along
with some asserts.
2023-06-28 23:18:39 +01:00
Shannon Booth
fe479ffd66 LibJS: Add spec comment for [[ArrayBufferData]]
I have found myself needing to grep around for this one a bunch.
2023-06-28 23:18:39 +01:00
Shannon Booth
78d5c23c3a LibJS: Add spec comment for IsDetachedBuffer ( arrayBuffer ) 2023-06-28 23:18:39 +01:00
Daniel Bertalan
50d6b1ba19 LibJS/Bytecode: Keep completion value of switch case if falling through
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.
2023-06-28 12:30:23 +02:00
Shannon Booth
be280ff3e4 LibJS/Tests: Enable some now passing Array length tests
Now that serenity is 64 bit only these tests no longer need to be
skipped :^)
2023-06-28 10:48:15 +02:00
Daniel Bertalan
fda619c7c2 LibJS/Bytecode: Implement Annex B Initializers in ForIn Statement Heads 2023-06-28 10:42:32 +02:00
Daniel Bertalan
fc7de74b12 LibJS/Bytecode: Improve export statement handling
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
2023-06-28 05:13:52 +02:00
Daniel Bertalan
11a7014b4e LibJS/Bytecode: Handle ImportStatement in codegen
There is nothing to do here at runtime as imports are handled in
`Interpreter::run`.
2023-06-27 21:10:08 +02:00
Luke Wilde
363bf114c0 LibJS/Bytecode: Implement for await of
Summary:
    Diff Tests:
        +391    +15    +2 💥️    -408 📝
2023-06-27 21:04:22 +02:00
Andreas Kling
aec3d9d84e LibJS/Bytecode: Prefer alias over name in object pattern bindings
10 new passes on test262. :^)
2023-06-27 15:08:14 +02:00