Commit graph

20 commits

Author SHA1 Message Date
Andreas Kling
2ca7dfa649 LibJS: Move bytecode interpreter state to VM
The bytecode interpreter only needed the running execution context,
but still threaded a separate Interpreter object through both the C++
and asm entry points. Move that state and the bytecode execution
helpers onto VM instead, and teach the asm generator and slow paths to
use VM directly.
2026-04-13 18:29:43 +02:00
Johan Dahlin
1179e40d3f LibJS: Eliminate GeneratorResult GC cell allocation on yield/await
Store yield_continuation and yield_is_await directly in
ExecutionContext instead of allocating a GeneratorResult GC cell.
This removes a heap allocation per yield/await and fixes a latent
bug where continuation addresses stored as doubles could lose
precision.
2026-03-20 15:57:23 -05:00
Andreas Kling
272562ddc5 LibJS: Remove dead C++ bytecode compilation functions
Remove Bytecode::compile() and the old create() overloads on
ECMAScriptFunctionObject that accepted C++ AST nodes. These
have no remaining callers now that all compilation goes through
the Rust pipeline.

Also remove the if-constexpr Parse Node branch from
async_block_start, since the Statement template instantiation
was already removed.

Fix transitive include dependencies on Generator.h by adding
explicit includes for headers that were previously pulled in
transitively.
2026-03-19 21:55:10 -05:00
Andreas Kling
fe48e27a05 LibJS: Replace GC::Weak with GC::RawPtr in inline cache entries
Property lookup cache entries previously used GC::Weak<T> for shape,
prototype, and prototype_chain_validity pointers. Each GC::Weak
requires a ref-counted WeakImpl allocation and an extra indirection
on every access.

Replace these with GC::RawPtr<T> and make Executable a WeakContainer
so the GC can clear stale pointers during sweep via remove_dead_cells.

For static PropertyLookupCache instances (used throughout the runtime
for well-known property lookups), introduce StaticPropertyLookupCache
which registers itself in a global list that also gets swept.

Now that inline cache entries use GC::RawPtr instead of GC::Weak,
we can compare shape/prototype pointers directly without going
through the WeakImpl indirection. This removes one dependent load
from each IC check in GetById, PutById, GetLength, GetGlobal, and
SetGlobal handlers.
2026-03-08 10:27:13 +01:00
Luke Wilde
a63b0cfaba LibJS: Introduce NativeJavaScriptBackedFunction
This hosts the ability to compile and run JavaScript to implement
native functions. This is particularly useful for any native function
that is not a normal function, for example async functions such as
Array.fromAsync, which require yielding.

These functions are not allowed to observe anything from outside their
environment. Any global identifiers will instead be assumed to be a
reference to an abstract operation or a constant. The generator will
inject the appropriate bytecode if the name of the global identifier
matches a known name. Anything else will cause a code generation error.
2025-11-30 11:54:54 +01:00
Rocco Corsi
5fb78ae455 LibJS: Correct completion_cell typo in GeneratorObject 2025-11-17 23:43:04 +01:00
Andreas Kling
04238d0f3f LibJS: Make AsyncGenerator and GeneratorObject factories infallible
These should never fail.
2025-11-17 23:42:51 +01:00
Andreas Kling
d8f5971ddf LibJS: Allow constructing generator from function with null "prototype"
Fixes 4 test262 tests and simplifies some upcoming stuff.
2025-11-17 23:42:51 +01:00
Andreas Kling
5706831328 LibJS: Make run_executable() return simple ThrowCompletionOr<Value>
We don't need to return two values; running an executable only ever
produces a throw completion, or a normal completion, i.e a Value.

This necessitated a few minor changes, such as adding a way to check
if a JS::Cell is a GeneratorResult.
2025-10-31 08:56:02 +01:00
Andreas Kling
9dae1acc31 LibJS: Pass ExecutionContext to Interpreter::run_executable()
This avoids having to get it from the VM's context stack, since most
callers already have it on hand.
2025-10-29 21:20:10 +01:00
Andreas Kling
d065171791 LibJS: Use property lookup caches for some of our hot C++ gets
We can use caching in a million more places. This is just me running JS
benchmarks and looking at which get() call sites were hot and putting
caches there.

Lots of nice speedups all over the place, some examples:

1.19x speedup on Octane/raytrace.js
1.13x speedup on Octane/earley-boyer.js
1.12x speedup on Kraken/ai-astar.js
1.10x speedup on Octane/box2d.js
1.08x speedup on Octane/gbemu.js
1.05x speedup on Octane/regexp.js
2025-10-14 15:47:38 +02:00
Aliaksandr Kalenik
4c789ac689 LibJS: Skip iteration result allocation in AsyncFunctionDriverWrapper
- Create less GC pressure by making each `await` in async function skip
  iteration result object allocation.
- Skip uncached `Object::get()` calls to extract `value` and `done` from
  the iteration result object.

With this change, following function goes 30% faster on my computer:
```js
(async () => {
    const resolved = Promise.resolve();
    for (let i = 0; i < 5_000_000; i++) {
        await resolved;
    }
})();
```
2025-05-09 12:30:15 +02:00
Andreas Kling
3cf50539ec LibJS: Make Value() default-construct the undefined value
The special empty value (that we use for array holes, Optional<Value>
when empty and a few other other placeholder/sentinel tasks) still
exists, but you now create one via JS::js_special_empty_value() and
check for it with Value::is_special_empty_value().

The main idea here is to make it very unlikely to accidentally create an
unexpected special empty value.
2025-04-05 11:20:26 +02:00
Andreas Kling
de424d6879 LibJS: Make Completion.[[Value]] non-optional
Instead, just use js_undefined() whenever the [[Value]] field is unused.
This avoids a whole bunch of presence checks.
2025-04-05 11:20:26 +02:00
Andreas Kling
a0bb31f7a0 LibJS: Make async functions & generators faster with helper types
Instead of returning internal generator results as ordinary JS::Objects
with properties, we now use GeneratorResult and CompletionCell which
both inherit from Cell directly and allow efficient access to state.

1.59x speedup on JetStream3/lazy-collections.js :^)
2025-04-01 02:30:42 +02:00
Andreas Kling
53da8893ac LibJS: Replace PropertyKey(char[]) with PropertyKey(FlyString)
...and deal with the fallout.
2025-03-24 22:27:17 +00:00
Shannon Booth
d48a0aaa55 LibJS: Remove unneeded FIXMEs for suspending an execution context
From what I understand, the suspension steps are not required now,
or in the future for our implementation, or any other. The intent
is already implemented in the spec pushing on another execution
context to the stack and leaving the running execution context as-is.

The resume steps are a slightly different story as there is some subtle
behavior which the spec is trying to convey where some custom logic may
need to be done when one execution context changes from one to another.
It may be worth implementing those steps at a later point in time so
that this behavior is a bit easier to follow in those cases.

To make the situation more confusing - from what I can gather from the
spec, not all cases that the spec mentions resume actually means
anything normative. Resume is only _actually_ needed in a limited set
of locations.

For now, let's just remove the unneeded FIXMEs that indicate that there
is something to be done for the suspension steps, as there is not, and
leave the resume steps as is.
2025-01-02 11:30:04 +01:00
Shannon Booth
f87041bf3a LibGC+Everywhere: Factor out a LibGC from LibJS
Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:

 * JS::NonnullGCPtr -> GC::Ref
 * JS::GCPtr -> GC::Ptr
 * JS::HeapFunction -> GC::Function
 * JS::CellImpl -> GC::Cell
 * JS::Handle -> GC::Root
2024-11-15 14:49:20 +01:00
Shannon Booth
9b79a686eb LibJS+LibWeb: Use realm.create<T> instead of heap.allocate<T>
The main motivation behind this is to remove JS specifics of the Realm
from the implementation of the Heap.

As a side effect of this change, this is a bit nicer to read than the
previous approach, and in my opinion, also makes it a little more clear
that this method is specific to a JavaScript Realm.
2024-11-13 16:51:44 -05:00
Timothy Flynn
93712b24bf Everywhere: Hoist the Libraries folder to the top-level 2024-11-10 12:50:45 +01:00
Renamed from Userland/Libraries/LibJS/Runtime/GeneratorObject.cpp (Browse further)