LibJS: Generate bytecode in basic blocks instead of one big block

This limits the size of each block (currently set to 1K), and gets us
closer to a canonical, more easily analysable bytecode format.
As a result of this, "Labels" are now simply entries to basic blocks.
Since there is no more 'conditional' jump (as all jumps are always
taken), JumpIf{True,False} are unified to JumpConditional, and
JumpIfNullish is renamed to JumpNullish.
Also fixes #7914 as a result of reimplementing the loop logic.
This commit is contained in:
Ali Mohammad Pur 2021-06-09 06:49:58 +04:30 committed by Andreas Kling
parent d7a25cdb82
commit 01e8f0889a
Notes: sideshowbarker 2024-07-18 12:35:35 +09:00
16 changed files with 392 additions and 174 deletions

View file

@ -7,7 +7,7 @@
#include <AK/Debug.h>
#include <AK/Function.h>
#include <LibJS/AST.h>
#include <LibJS/Bytecode/Block.h>
#include <LibJS/Bytecode/BasicBlock.h>
#include <LibJS/Bytecode/Generator.h>
#include <LibJS/Bytecode/Interpreter.h>
#include <LibJS/Interpreter.h>
@ -151,15 +151,15 @@ Value ScriptFunction::execute_function_body()
if (bytecode_interpreter) {
prepare_arguments();
if (!m_bytecode_block) {
m_bytecode_block = Bytecode::Generator::generate(m_body);
VERIFY(m_bytecode_block);
if (!m_bytecode_execution_unit.has_value()) {
m_bytecode_execution_unit = Bytecode::Generator::generate(m_body);
if constexpr (JS_BYTECODE_DEBUG) {
dbgln("Compiled Bytecode::Block for function '{}':", m_name);
m_bytecode_block->dump();
for (auto& block : m_bytecode_execution_unit->basic_blocks)
block.dump();
}
}
return bytecode_interpreter->run(*m_bytecode_block);
return bytecode_interpreter->run(*m_bytecode_execution_unit);
} else {
OwnPtr<Interpreter> local_interpreter;
ast_interpreter = vm.interpreter_if_exists();