mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 05:17:35 +00:00
LibJS: Start fleshing out a bytecode for the JavaScript engine :^)
This patch begins the work of implementing JavaScript execution in a bytecode VM instead of an AST tree-walk interpreter. It's probably quite naive, but we have to start somewhere. The basic idea is that you call Bytecode::Generator::generate() on an AST node and it hands you back a Bytecode::Block filled with instructions that can then be interpreted by a Bytecode::Interpreter. This first version only implements two instructions: Load and Add. :^) Each bytecode block has infinity registers, and the interpreter resizes its register file to fit the block being executed. Two new `js` options are added in this patch as well: `-d` will dump the generated bytecode `-b` will execute the generated bytecode Note that unless `-d` and/or `-b` are specified, none of the bytecode related stuff in LibJS runs at all. This is implemented in parallel with the existing AST interpreter. :^)
This commit is contained in:
parent
f9395efaac
commit
69dddd4ef5
16 changed files with 487 additions and 24 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2020-2021, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
|
@ -14,6 +14,9 @@
|
|||
#include <LibCore/File.h>
|
||||
#include <LibCore/StandardPaths.h>
|
||||
#include <LibJS/AST.h>
|
||||
#include <LibJS/Bytecode/Block.h>
|
||||
#include <LibJS/Bytecode/Generator.h>
|
||||
#include <LibJS/Bytecode/Interpreter.h>
|
||||
#include <LibJS/Console.h>
|
||||
#include <LibJS/Interpreter.h>
|
||||
#include <LibJS/Parser.h>
|
||||
|
@ -73,6 +76,8 @@ private:
|
|||
};
|
||||
|
||||
static bool s_dump_ast = false;
|
||||
static bool s_dump_bytecode = false;
|
||||
static bool s_run_bytecode = false;
|
||||
static bool s_print_last_result = false;
|
||||
static RefPtr<Line::Editor> s_editor;
|
||||
static String s_history_path = String::formatted("{}/.js-history", Core::StandardPaths::home_directory());
|
||||
|
@ -489,6 +494,19 @@ static bool parse_and_run(JS::Interpreter& interpreter, const StringView& source
|
|||
if (s_dump_ast)
|
||||
program->dump(0);
|
||||
|
||||
if (s_dump_bytecode || s_run_bytecode) {
|
||||
auto block = JS::Bytecode::Generator::generate(*program);
|
||||
VERIFY(block);
|
||||
|
||||
if (s_dump_bytecode)
|
||||
block->dump();
|
||||
|
||||
if (s_run_bytecode) {
|
||||
JS::Bytecode::Interpreter bytecode_interpreter(interpreter.global_object());
|
||||
bytecode_interpreter.run(*block);
|
||||
}
|
||||
}
|
||||
|
||||
if (parser.has_errors()) {
|
||||
auto error = parser.errors()[0];
|
||||
auto hint = error.source_location_hint(source);
|
||||
|
@ -744,6 +762,8 @@ int main(int argc, char** argv)
|
|||
Core::ArgsParser args_parser;
|
||||
args_parser.set_general_help("This is a JavaScript interpreter.");
|
||||
args_parser.add_option(s_dump_ast, "Dump the AST", "dump-ast", 'A');
|
||||
args_parser.add_option(s_dump_bytecode, "Dump the bytecode", "dump-bytecode", 'd');
|
||||
args_parser.add_option(s_run_bytecode, "Run the bytecode", "run-bytecode", 'b');
|
||||
args_parser.add_option(s_print_last_result, "Print last result", "print-last-result", 'l');
|
||||
args_parser.add_option(gc_on_every_allocation, "GC on every allocation", "gc-on-every-allocation", 'g');
|
||||
args_parser.add_option(disable_syntax_highlight, "Disable live syntax highlighting", "no-syntax-highlight", 's');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue