1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-20 13:25:08 +00:00

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
16 changed files with 392 additions and 174 deletions

View file

@ -4,9 +4,8 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/OwnPtr.h>
#include <LibJS/AST.h>
#include <LibJS/Bytecode/Block.h>
#include <LibJS/Bytecode/BasicBlock.h>
#include <LibJS/Bytecode/Generator.h>
#include <LibJS/Bytecode/Instruction.h>
#include <LibJS/Bytecode/Register.h>
@ -16,30 +15,30 @@ namespace JS::Bytecode {
Generator::Generator()
{
m_block = Block::create();
}
Generator::~Generator()
{
}
OwnPtr<Block> Generator::generate(ASTNode const& node)
ExecutionUnit Generator::generate(ASTNode const& node)
{
Generator generator;
generator.switch_to_basic_block(generator.make_block());
node.generate_bytecode(generator);
generator.m_block->set_register_count({}, generator.m_next_register);
generator.m_block->seal();
return move(generator.m_block);
return { move(generator.m_root_basic_blocks), generator.m_next_register };
}
void Generator::grow(size_t additional_size)
{
m_block->grow(additional_size);
VERIFY(m_current_basic_block);
m_current_basic_block->grow(additional_size);
}
void* Generator::next_slot()
{
return m_block->next_slot();
VERIFY(m_current_basic_block);
return m_current_basic_block->next_slot();
}
Register Generator::allocate_register()
@ -48,19 +47,14 @@ Register Generator::allocate_register()
return Register { m_next_register++ };
}
Label Generator::make_label() const
{
return Label { m_block->instruction_stream().size() };
}
Label Generator::nearest_continuable_scope() const
{
return m_continuable_scopes.last();
}
void Generator::begin_continuable_scope()
void Generator::begin_continuable_scope(Label continue_target)
{
m_continuable_scopes.append(make_label());
m_continuable_scopes.append(continue_target);
}
void Generator::end_continuable_scope()