LibJS: Add alternative source-to-bytecode pipeline in Rust

Implement a complete Rust reimplementation of the LibJS frontend:
lexer, parser, AST, scope collector, and bytecode code generator.

The Rust pipeline is built via Corrosion (CMake-Cargo bridge) and
linked into LibJS as a static library. It is gated behind a build
flag (ENABLE_RUST, on by default except on Windows) and two runtime
environment variables:

- LIBJS_CPP: Use the C++ pipeline instead of Rust
- LIBJS_COMPARE_PIPELINES=1: Run both pipelines in lockstep,
  aborting on any difference in AST or bytecode generated.

The C++ side communicates with Rust through a C FFI layer
(RustIntegration.cpp/h) that passes source text to Rust and receives
a populated Executable back via a BytecodeFactory interface.
This commit is contained in:
Andreas Kling
2026-02-23 11:50:46 +01:00
committed by Andreas Kling
parent 8bf1d749a1
commit 6cdfbd01a6
Notes: github-actions[bot] 2026-02-24 08:41:00 +00:00
43 changed files with 28402 additions and 148 deletions

View File

@@ -128,11 +128,13 @@ ThrowCompletionOr<Value> Interpreter::run(Script& script_record, GC::Ptr<Environ
GC::Ptr<Executable> executable = script_record.cached_executable();
if (!executable && result.type() == Completion::Type::Normal) {
executable = JS::Bytecode::Generator::generate_from_ast_node(vm, *script_record.parse_node(), {});
script_record.cache_executable(*executable);
script_record.drop_ast();
if (g_dump_bytecode)
executable->dump();
if (executable) {
script_record.cache_executable(*executable);
script_record.drop_ast();
}
}
if (executable && g_dump_bytecode)
executable->dump();
u32 registers_and_locals_count = 0;
u32 constants_count = 0;