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

LibJS: Store strings in a string table

Instead of using Strings in the bytecode ops this adds a global string
table to the Executable struct which individual operations can refer
to using indices. This brings bytecode ops one step closer to being
pointer free.
This commit is contained in:
Gunnar Beutner 2021-06-09 10:02:01 +02:00 committed by Andreas Kling
parent 4efccbd030
commit 6a0d1fa259
16 changed files with 173 additions and 82 deletions

View file

@ -16,11 +16,11 @@
namespace JS::Bytecode {
String Instruction::to_string() const
String Instruction::to_string(Bytecode::Executable const& executable) const
{
#define __BYTECODE_OP(op) \
case Instruction::Type::op: \
return static_cast<Bytecode::Op::op const&>(*this).to_string();
return static_cast<Bytecode::Op::op const&>(*this).to_string(executable);
switch (type()) {
ENUMERATE_BYTECODE_OPS(__BYTECODE_OP)
@ -77,7 +77,7 @@ static Value typed_equals(GlobalObject&, Value src1, Value src2)
auto rhs = interpreter.accumulator(); \
interpreter.accumulator() = op_snake_case(interpreter.global_object(), lhs, rhs); \
} \
String OpTitleCase::to_string() const \
String OpTitleCase::to_string(Bytecode::Executable const&) const \
{ \
return String::formatted(#OpTitleCase " {}", m_lhs_reg); \
}
@ -99,7 +99,7 @@ static Value typeof_(GlobalObject& global_object, Value value)
{ \
interpreter.accumulator() = op_snake_case(interpreter.global_object(), interpreter.accumulator()); \
} \
String OpTitleCase::to_string() const \
String OpTitleCase::to_string(Bytecode::Executable const&) const \
{ \
return #OpTitleCase; \
}
@ -122,7 +122,7 @@ void NewArray::execute(Bytecode::Interpreter& interpreter) const
void NewString::execute(Bytecode::Interpreter& interpreter) const
{
interpreter.accumulator() = js_string(interpreter.vm(), m_string);
interpreter.accumulator() = js_string(interpreter.vm(), interpreter.current_executable().get_string(m_string));
}
void NewObject::execute(Bytecode::Interpreter& interpreter) const
@ -137,24 +137,24 @@ void ConcatString::execute(Bytecode::Interpreter& interpreter) const
void GetVariable::execute(Bytecode::Interpreter& interpreter) const
{
interpreter.accumulator() = interpreter.vm().get_variable(m_identifier, interpreter.global_object());
interpreter.accumulator() = interpreter.vm().get_variable(interpreter.current_executable().get_string(m_identifier), interpreter.global_object());
}
void SetVariable::execute(Bytecode::Interpreter& interpreter) const
{
interpreter.vm().set_variable(m_identifier, interpreter.accumulator(), interpreter.global_object());
interpreter.vm().set_variable(interpreter.current_executable().get_string(m_identifier), interpreter.accumulator(), interpreter.global_object());
}
void GetById::execute(Bytecode::Interpreter& interpreter) const
{
if (auto* object = interpreter.accumulator().to_object(interpreter.global_object()))
interpreter.accumulator() = object->get(m_property);
interpreter.accumulator() = object->get(interpreter.current_executable().get_string(m_property));
}
void PutById::execute(Bytecode::Interpreter& interpreter) const
{
if (auto* object = interpreter.reg(m_base).to_object(interpreter.global_object()))
object->put(m_property, interpreter.accumulator());
object->put(interpreter.current_executable().get_string(m_property), interpreter.accumulator());
}
void Jump::execute(Bytecode::Interpreter& interpreter) const
@ -255,27 +255,27 @@ void Decrement::execute(Bytecode::Interpreter& interpreter) const
interpreter.accumulator() = js_bigint(interpreter.vm().heap(), old_value.as_bigint().big_integer().minus(Crypto::SignedBigInteger { 1 }));
}
String Load::to_string() const
String Load::to_string(Bytecode::Executable const&) const
{
return String::formatted("Load {}", m_src);
}
String LoadImmediate::to_string() const
String LoadImmediate::to_string(Bytecode::Executable const&) const
{
return String::formatted("LoadImmediate {}", m_value);
}
String Store::to_string() const
String Store::to_string(Bytecode::Executable const&) const
{
return String::formatted("Store {}", m_dst);
}
String NewBigInt::to_string() const
String NewBigInt::to_string(Bytecode::Executable const&) const
{
return String::formatted("NewBigInt \"{}\"", m_bigint.to_base10());
}
String NewArray::to_string() const
String NewArray::to_string(Bytecode::Executable const&) const
{
StringBuilder builder;
builder.append("NewArray");
@ -291,63 +291,63 @@ String NewArray::to_string() const
return builder.to_string();
}
String NewString::to_string() const
String NewString::to_string(Bytecode::Executable const& executable) const
{
return String::formatted("NewString \"{}\"", m_string);
return String::formatted("NewString {} (\"{}\")", m_string, executable.string_table->get(m_string));
}
String NewObject::to_string() const
String NewObject::to_string(Bytecode::Executable const&) const
{
return "NewObject";
}
String ConcatString::to_string() const
String ConcatString::to_string(Bytecode::Executable const&) const
{
return String::formatted("ConcatString {}", m_lhs);
}
String GetVariable::to_string() const
String GetVariable::to_string(Bytecode::Executable const& executable) const
{
return String::formatted("GetVariable {}", m_identifier);
return String::formatted("GetVariable {} ({})", m_identifier, executable.string_table->get(m_identifier));
}
String SetVariable::to_string() const
String SetVariable::to_string(Bytecode::Executable const& executable) const
{
return String::formatted("SetVariable {}", m_identifier);
return String::formatted("SetVariable {} ({})", m_identifier, executable.string_table->get(m_identifier));
}
String PutById::to_string() const
String PutById::to_string(Bytecode::Executable const& executable) const
{
return String::formatted("PutById base:{}, property:{}", m_base, m_property);
return String::formatted("PutById base:{}, property:{} ({})", m_base, m_property, executable.string_table->get(m_property));
}
String GetById::to_string() const
String GetById::to_string(Bytecode::Executable const& executable) const
{
return String::formatted("GetById {}", m_property);
return String::formatted("GetById {} ({})", m_property, executable.string_table->get(m_property));
}
String Jump::to_string() const
String Jump::to_string(Bytecode::Executable const&) const
{
if (m_true_target.has_value())
return String::formatted("Jump {}", *m_true_target);
return String::formatted("Jump <empty>");
}
String JumpConditional::to_string() const
String JumpConditional::to_string(Bytecode::Executable const&) const
{
auto true_string = m_true_target.has_value() ? String::formatted("{}", *m_true_target) : "<empty>";
auto false_string = m_false_target.has_value() ? String::formatted("{}", *m_false_target) : "<empty>";
return String::formatted("JumpConditional true:{} false:{}", true_string, false_string);
}
String JumpNullish::to_string() const
String JumpNullish::to_string(Bytecode::Executable const&) const
{
auto true_string = m_true_target.has_value() ? String::formatted("{}", *m_true_target) : "<empty>";
auto false_string = m_false_target.has_value() ? String::formatted("{}", *m_false_target) : "<empty>";
return String::formatted("JumpNullish null:{} nonnull:{}", true_string, false_string);
}
String Call::to_string() const
String Call::to_string(Bytecode::Executable const&) const
{
StringBuilder builder;
builder.appendff("Call callee:{}, this:{}", m_callee, m_this_value);
@ -363,22 +363,22 @@ String Call::to_string() const
return builder.to_string();
}
String EnterScope::to_string() const
String EnterScope::to_string(Bytecode::Executable const&) const
{
return "EnterScope";
}
String Return::to_string() const
String Return::to_string(Bytecode::Executable const&) const
{
return "Return";
}
String Increment::to_string() const
String Increment::to_string(Bytecode::Executable const&) const
{
return "Increment";
}
String Decrement::to_string() const
String Decrement::to_string(Bytecode::Executable const&) const
{
return "Decrement";
}