LibJS: Join locals, constants and registers into single vector

Merging registers, constants and locals into single vector means:
- Better data locality
- No need to check type in Interpreter::get() and Interpreter::set()
  which are very hot functions

Performance improvement is visible in almost all Octane and Kraken
tests.
This commit is contained in:
Aliaksandr Kalenik
2024-05-12 18:49:03 +02:00
committed by Andreas Kling
parent 59cb7994c6
commit d79438a2a6
11 changed files with 478 additions and 57 deletions

View File

@@ -1624,7 +1624,10 @@ void ScopeNode::block_declaration_instantiation(VM& vm, Environment* environment
// iii. Perform ! env.InitializeBinding(fn, fo). NOTE: This step is replaced in section B.3.2.6. // iii. Perform ! env.InitializeBinding(fn, fo). NOTE: This step is replaced in section B.3.2.6.
if (function_declaration.name_identifier()->is_local()) { if (function_declaration.name_identifier()->is_local()) {
vm.running_execution_context().local(function_declaration.name_identifier()->local_variable_index()) = function; auto& running_execution_context = vm.running_execution_context();
auto number_of_registers = running_execution_context.executable->number_of_registers;
auto number_of_constants = running_execution_context.executable->constants.size();
running_execution_context.local(function_declaration.name_identifier()->local_variable_index() + number_of_registers + number_of_constants) = function;
} else { } else {
VERIFY(is<DeclarativeEnvironment>(*environment)); VERIFY(is<DeclarativeEnvironment>(*environment));
static_cast<DeclarativeEnvironment&>(*environment).initialize_or_set_mutable_binding({}, vm, function_declaration.name(), function); static_cast<DeclarativeEnvironment&>(*environment).initialize_or_set_mutable_binding({}, vm, function_declaration.name(), function);

View File

@@ -266,6 +266,19 @@ CodeGenerationErrorOr<NonnullGCPtr<Executable>> Generator::emit_function_body_by
HashMap<size_t, SourceRecord> source_map; HashMap<size_t, SourceRecord> source_map;
for (auto& block : generator.m_root_basic_blocks) {
if (!block->is_terminated()) {
// NOTE: We must ensure that the "undefined" constant, which will be used by the not yet
// emitted End instruction, is taken into account while shifting local operands by the
// number of constants.
(void)generator.add_constant(js_undefined());
break;
}
}
auto number_of_registers = generator.m_next_register;
auto number_of_constants = generator.m_constants.size();
for (auto& block : generator.m_root_basic_blocks) { for (auto& block : generator.m_root_basic_blocks) {
basic_block_start_offsets.append(bytecode.size()); basic_block_start_offsets.append(bytecode.size());
if (block->handler() || block->finalizer()) { if (block->handler() || block->finalizer()) {
@@ -287,6 +300,21 @@ CodeGenerationErrorOr<NonnullGCPtr<Executable>> Generator::emit_function_body_by
while (!it.at_end()) { while (!it.at_end()) {
auto& instruction = const_cast<Instruction&>(*it); auto& instruction = const_cast<Instruction&>(*it);
instruction.visit_operands([number_of_registers, number_of_constants](Operand& operand) {
switch (operand.type()) {
case Operand::Type::Register:
break;
case Operand::Type::Local:
operand.offset_index_by(number_of_registers + number_of_constants);
break;
case Operand::Type::Constant:
operand.offset_index_by(number_of_registers);
break;
default:
VERIFY_NOT_REACHED();
}
});
// OPTIMIZATION: Don't emit jumps that just jump to the next block. // OPTIMIZATION: Don't emit jumps that just jump to the next block.
if (instruction.type() == Instruction::Type::Jump) { if (instruction.type() == Instruction::Type::Jump) {
auto& jump = static_cast<Bytecode::Op::Jump&>(instruction); auto& jump = static_cast<Bytecode::Op::Jump&>(instruction);
@@ -333,6 +361,20 @@ CodeGenerationErrorOr<NonnullGCPtr<Executable>> Generator::emit_function_body_by
} }
if (!block->is_terminated()) { if (!block->is_terminated()) {
Op::End end(generator.add_constant(js_undefined())); Op::End end(generator.add_constant(js_undefined()));
end.visit_operands([number_of_registers, number_of_constants](Operand& operand) {
switch (operand.type()) {
case Operand::Type::Register:
break;
case Operand::Type::Local:
operand.offset_index_by(number_of_registers + number_of_constants);
break;
case Operand::Type::Constant:
operand.offset_index_by(number_of_registers);
break;
default:
VERIFY_NOT_REACHED();
}
});
bytecode.append(reinterpret_cast<u8 const*>(&end), end.length()); bytecode.append(reinterpret_cast<u8 const*>(&end), end.length());
} }
if (block->handler() || block->finalizer()) { if (block->handler() || block->finalizer()) {

View File

@@ -42,6 +42,22 @@ void Instruction::visit_labels(Function<void(JS::Bytecode::Label&)> visitor)
#undef __BYTECODE_OP #undef __BYTECODE_OP
} }
void Instruction::visit_operands(Function<void(JS::Bytecode::Operand&)> visitor)
{
#define __BYTECODE_OP(op) \
case Type::op: \
static_cast<Op::op&>(*this).visit_operands_impl(move(visitor)); \
return;
switch (type()) {
ENUMERATE_BYTECODE_OPS(__BYTECODE_OP)
default:
VERIFY_NOT_REACHED();
}
#undef __BYTECODE_OP
}
template<typename Op> template<typename Op>
concept HasVariableLength = Op::IsVariableLength; concept HasVariableLength = Op::IsVariableLength;

View File

@@ -157,6 +157,7 @@ public:
size_t length() const; size_t length() const;
ByteString to_byte_string(Bytecode::Executable const&) const; ByteString to_byte_string(Bytecode::Executable const&) const;
void visit_labels(Function<void(Label&)> visitor); void visit_labels(Function<void(Label&)> visitor);
void visit_operands(Function<void(Operand&)> visitor);
static void destroy(Instruction&); static void destroy(Instruction&);
protected: protected:
@@ -166,6 +167,7 @@ protected:
} }
void visit_labels_impl(Function<void(Label&)>) { } void visit_labels_impl(Function<void(Label&)>) { }
void visit_operands_impl(Function<void(Operand&)>) { }
private: private:
Type m_type {}; Type m_type {};

View File

@@ -54,7 +54,7 @@ static ByteString format_operand(StringView name, Operand operand, Bytecode::Exe
break; break;
case Operand::Type::Constant: { case Operand::Type::Constant: {
builder.append("\033[36m"sv); builder.append("\033[36m"sv);
auto value = executable.constants[operand.index()]; auto value = executable.constants[operand.index() - executable.number_of_registers];
if (value.is_empty()) if (value.is_empty())
builder.append("<Empty>"sv); builder.append("<Empty>"sv);
else if (value.is_boolean()) else if (value.is_boolean())
@@ -153,30 +153,12 @@ Interpreter::~Interpreter()
ALWAYS_INLINE Value Interpreter::get(Operand op) const ALWAYS_INLINE Value Interpreter::get(Operand op) const
{ {
switch (op.type()) { return m_registers_and_constants_and_locals.data()[op.index()];
case Operand::Type::Register:
return m_registers.data()[op.index()];
case Operand::Type::Local:
return m_locals.data()[op.index()];
case Operand::Type::Constant:
return m_constants.data()[op.index()];
}
__builtin_unreachable();
} }
ALWAYS_INLINE void Interpreter::set(Operand op, Value value) ALWAYS_INLINE void Interpreter::set(Operand op, Value value)
{ {
switch (op.type()) { m_registers_and_constants_and_locals.data()[op.index()] = value;
case Operand::Type::Register:
m_registers.data()[op.index()] = value;
return;
case Operand::Type::Local:
m_locals.data()[op.index()] = value;
return;
case Operand::Type::Constant:
break;
}
__builtin_unreachable();
} }
// 16.1.6 ScriptEvaluation ( scriptRecord ), https://tc39.es/ecma262/#sec-runtime-semantics-scriptevaluation // 16.1.6 ScriptEvaluation ( scriptRecord ), https://tc39.es/ecma262/#sec-runtime-semantics-scriptevaluation
@@ -346,7 +328,7 @@ FLATTEN_ON_CLANG void Interpreter::run_bytecode(size_t entry_point)
auto& running_execution_context = this->running_execution_context(); auto& running_execution_context = this->running_execution_context();
auto* arguments = running_execution_context.arguments.data(); auto* arguments = running_execution_context.arguments.data();
auto* locals = running_execution_context.locals.data(); auto* registers_and_constants_and_locals = running_execution_context.registers_and_constants_and_locals.data();
auto& accumulator = this->accumulator(); auto& accumulator = this->accumulator();
auto& executable = current_executable(); auto& executable = current_executable();
auto const* bytecode = executable.bytecode.data(); auto const* bytecode = executable.bytecode.data();
@@ -384,7 +366,7 @@ FLATTEN_ON_CLANG void Interpreter::run_bytecode(size_t entry_point)
handle_SetLocal: { handle_SetLocal: {
auto& instruction = *reinterpret_cast<Op::SetLocal const*>(&bytecode[program_counter]); auto& instruction = *reinterpret_cast<Op::SetLocal const*>(&bytecode[program_counter]);
locals[instruction.index()] = get(instruction.src()); registers_and_constants_and_locals[instruction.index()] = get(instruction.src());
DISPATCH_NEXT(SetLocal); DISPATCH_NEXT(SetLocal);
} }
@@ -715,31 +697,35 @@ Interpreter::ResultAndReturnRegister Interpreter::run_executable(Executable& exe
VERIFY(!vm().execution_context_stack().is_empty()); VERIFY(!vm().execution_context_stack().is_empty());
auto& running_execution_context = vm().running_execution_context(); auto& running_execution_context = vm().running_execution_context();
if (running_execution_context.registers.size() < executable.number_of_registers) u32 registers_and_contants_count = executable.number_of_registers + executable.constants.size();
running_execution_context.registers.resize(executable.number_of_registers); if (running_execution_context.registers_and_constants_and_locals.size() < registers_and_contants_count)
running_execution_context.registers_and_constants_and_locals.resize(registers_and_contants_count);
TemporaryChange restore_running_execution_context { m_running_execution_context, &running_execution_context }; TemporaryChange restore_running_execution_context { m_running_execution_context, &running_execution_context };
TemporaryChange restore_arguments { m_arguments, running_execution_context.arguments.span() }; TemporaryChange restore_arguments { m_arguments, running_execution_context.arguments.span() };
TemporaryChange restore_registers { m_registers, running_execution_context.registers.span() }; TemporaryChange restore_registers_and_constants_and_locals { m_registers_and_constants_and_locals, running_execution_context.registers_and_constants_and_locals.span() };
TemporaryChange restore_locals { m_locals, running_execution_context.locals.span() };
TemporaryChange restore_constants { m_constants, executable.constants.span() };
reg(Register::accumulator()) = initial_accumulator_value; reg(Register::accumulator()) = initial_accumulator_value;
reg(Register::return_value()) = {}; reg(Register::return_value()) = {};
running_execution_context.executable = &executable; running_execution_context.executable = &executable;
for (size_t i = 0; i < executable.constants.size(); ++i) {
running_execution_context.registers_and_constants_and_locals[executable.number_of_registers + i] = executable.constants[i];
}
run_bytecode(entry_point.value_or(0)); run_bytecode(entry_point.value_or(0));
dbgln_if(JS_BYTECODE_DEBUG, "Bytecode::Interpreter did run unit {:p}", &executable); dbgln_if(JS_BYTECODE_DEBUG, "Bytecode::Interpreter did run unit {:p}", &executable);
if constexpr (JS_BYTECODE_DEBUG) { if constexpr (JS_BYTECODE_DEBUG) {
for (size_t i = 0; i < registers().size(); ++i) { auto const& registers_and_constants_and_locals = running_execution_context.registers_and_constants_and_locals;
for (size_t i = 0; i < executable.number_of_registers; ++i) {
String value_string; String value_string;
if (registers()[i].is_empty()) if (registers_and_constants_and_locals[i].is_empty())
value_string = "(empty)"_string; value_string = "(empty)"_string;
else else
value_string = registers()[i].to_string_without_side_effects(); value_string = registers_and_constants_and_locals[i].to_string_without_side_effects();
dbgln("[{:3}] {}", i, value_string); dbgln("[{:3}] {}", i, value_string);
} }
} }
@@ -758,8 +744,8 @@ Interpreter::ResultAndReturnRegister Interpreter::run_executable(Executable& exe
vm().finish_execution_generation(); vm().finish_execution_generation();
if (!exception.is_empty()) if (!exception.is_empty())
return { throw_completion(exception), running_execution_context.registers[0] }; return { throw_completion(exception), running_execution_context.registers_and_constants_and_locals[0] };
return { return_value, running_execution_context.registers[0] }; return { return_value, running_execution_context.registers_and_constants_and_locals[0] };
} }
void Interpreter::enter_unwind_context() void Interpreter::enter_unwind_context()

View File

@@ -49,11 +49,11 @@ public:
ALWAYS_INLINE Value& saved_return_value() { return reg(Register::saved_return_value()); } ALWAYS_INLINE Value& saved_return_value() { return reg(Register::saved_return_value()); }
Value& reg(Register const& r) Value& reg(Register const& r)
{ {
return m_registers.data()[r.index()]; return m_registers_and_constants_and_locals.data()[r.index()];
} }
Value reg(Register const& r) const Value reg(Register const& r) const
{ {
return m_registers.data()[r.index()]; return m_registers_and_constants_and_locals.data()[r.index()];
} }
[[nodiscard]] Value get(Operand) const; [[nodiscard]] Value get(Operand) const;
@@ -77,9 +77,6 @@ public:
Executable const& current_executable() const { return *m_current_executable; } Executable const& current_executable() const { return *m_current_executable; }
Optional<size_t> program_counter() const { return m_program_counter; } Optional<size_t> program_counter() const { return m_program_counter; }
Vector<Value>& registers() { return vm().running_execution_context().registers; }
Vector<Value> const& registers() const { return vm().running_execution_context().registers; }
ExecutionContext& running_execution_context() { return *m_running_execution_context; } ExecutionContext& running_execution_context() { return *m_running_execution_context; }
private: private:
@@ -99,9 +96,7 @@ private:
GCPtr<DeclarativeEnvironment> m_global_declarative_environment { nullptr }; GCPtr<DeclarativeEnvironment> m_global_declarative_environment { nullptr };
Optional<size_t&> m_program_counter; Optional<size_t&> m_program_counter;
Span<Value> m_arguments; Span<Value> m_arguments;
Span<Value> m_registers; Span<Value> m_registers_and_constants_and_locals;
Span<Value> m_locals;
Span<Value> m_constants;
ExecutionContext* m_running_execution_context { nullptr }; ExecutionContext* m_running_execution_context { nullptr };
}; };

View File

@@ -43,6 +43,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
private: private:
Operand m_dst; Operand m_dst;
@@ -82,6 +86,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_src);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand src() const { return m_src; } Operand src() const { return m_src; }
@@ -130,6 +139,12 @@ private:
\ \
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; \ ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; \
ByteString to_byte_string_impl(Bytecode::Executable const&) const; \ ByteString to_byte_string_impl(Bytecode::Executable const&) const; \
void visit_operands_impl(Function<void(Operand&)> visitor) \
{ \
visitor(m_dst); \
visitor(m_lhs); \
visitor(m_rhs); \
} \
\ \
Operand dst() const { return m_dst; } \ Operand dst() const { return m_dst; } \
Operand lhs() const { return m_lhs; } \ Operand lhs() const { return m_lhs; } \
@@ -164,6 +179,11 @@ JS_ENUMERATE_COMMON_BINARY_OPS_WITH_FAST_PATH(JS_DECLARE_COMMON_BINARY_OP)
\ \
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; \ ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; \
ByteString to_byte_string_impl(Bytecode::Executable const&) const; \ ByteString to_byte_string_impl(Bytecode::Executable const&) const; \
void visit_operands_impl(Function<void(Operand&)> visitor) \
{ \
visitor(m_dst); \
visitor(m_src); \
} \
\ \
Operand dst() const { return m_dst; } \ Operand dst() const { return m_dst; } \
Operand src() const { return m_src; } \ Operand src() const { return m_src; } \
@@ -186,6 +206,10 @@ public:
void execute_impl(Bytecode::Interpreter&) const; void execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
@@ -206,6 +230,10 @@ public:
void execute_impl(Bytecode::Interpreter&) const; void execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
StringTableIndex source_index() const { return m_source_index; } StringTableIndex source_index() const { return m_source_index; }
@@ -234,6 +262,10 @@ private:
\ \
void execute_impl(Bytecode::Interpreter&) const; \ void execute_impl(Bytecode::Interpreter&) const; \
ByteString to_byte_string_impl(Bytecode::Executable const&) const; \ ByteString to_byte_string_impl(Bytecode::Executable const&) const; \
void visit_operands_impl(Function<void(Operand&)> visitor) \
{ \
visitor(m_dst); \
} \
\ \
Operand dst() const { return m_dst; } \ Operand dst() const { return m_dst; } \
StringTableIndex error_string() const { return m_error_string; } \ StringTableIndex error_string() const { return m_error_string; } \
@@ -263,6 +295,13 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_from_object);
for (size_t i = 0; i < m_excluded_names_count; i++)
visitor(m_excluded_names[i]);
}
size_t length_impl() const size_t length_impl() const
{ {
@@ -304,6 +343,12 @@ public:
void execute_impl(Bytecode::Interpreter&) const; void execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
for (size_t i = 0; i < m_element_count; i++)
visitor(m_elements[i]);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
@@ -340,6 +385,10 @@ public:
void execute_impl(Bytecode::Interpreter&) const; void execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
ReadonlySpan<Value> elements() const { return { m_elements, m_element_count }; } ReadonlySpan<Value> elements() const { return { m_elements, m_element_count }; }
@@ -377,6 +426,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_src);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand src() const { return m_src; } Operand src() const { return m_src; }
@@ -400,6 +454,12 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_specifier);
visitor(m_options);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand specifier() const { return m_specifier; } Operand specifier() const { return m_specifier; }
@@ -426,6 +486,12 @@ public:
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand iterator() const { return m_iterator; } Operand iterator() const { return m_iterator; }
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_iterator);
}
private: private:
Operand m_dst; Operand m_dst;
Operand m_iterator; Operand m_iterator;
@@ -446,6 +512,12 @@ public:
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand src() const { return m_src; } Operand src() const { return m_src; }
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_src);
}
private: private:
Operand m_dst; Operand m_dst;
Operand m_src; Operand m_src;
@@ -510,6 +582,11 @@ public:
Operand object() const { return m_object; } Operand object() const { return m_object; }
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_object);
}
private: private:
Operand m_object; Operand m_object;
}; };
@@ -527,6 +604,11 @@ public:
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
private: private:
Operand m_dst; Operand m_dst;
}; };
@@ -599,6 +681,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_src);
}
IdentifierTableIndex identifier() const { return m_identifier; } IdentifierTableIndex identifier() const { return m_identifier; }
Operand src() const { return m_src; } Operand src() const { return m_src; }
@@ -617,20 +703,25 @@ class SetLocal final : public Instruction {
public: public:
SetLocal(size_t index, Operand src) SetLocal(size_t index, Operand src)
: Instruction(Type::SetLocal) : Instruction(Type::SetLocal)
, m_index(index) , m_dst(Operand(Operand::Type::Local, index))
, m_src(src) , m_src(src)
{ {
} }
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_src);
}
u32 index() const { return m_index; } u32 index() const { return m_dst.index(); }
Operand dst() const { return Operand(Operand::Type::Local, m_index); } Operand dst() const { return m_dst; }
Operand src() const { return m_src; } Operand src() const { return m_src; }
private: private:
u32 m_index; Operand m_dst;
Operand m_src; Operand m_src;
}; };
@@ -645,6 +736,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_src);
}
size_t index() const { return m_index; } size_t index() const { return m_index; }
Operand src() const { return m_src; } Operand src() const { return m_src; }
@@ -665,6 +760,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
u32 index() const { return m_index; } u32 index() const { return m_index; }
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
@@ -686,6 +785,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_callee);
visitor(m_this_value);
}
IdentifierTableIndex identifier() const { return m_identifier; } IdentifierTableIndex identifier() const { return m_identifier; }
Operand callee() const { return m_callee; } Operand callee() const { return m_callee; }
@@ -713,6 +817,11 @@ public:
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
IdentifierTableIndex identifier() const { return m_identifier; } IdentifierTableIndex identifier() const { return m_identifier; }
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
private: private:
Operand m_dst; Operand m_dst;
IdentifierTableIndex m_identifier; IdentifierTableIndex m_identifier;
@@ -736,6 +845,11 @@ public:
IdentifierTableIndex identifier() const { return m_identifier; } IdentifierTableIndex identifier() const { return m_identifier; }
u32 cache_index() const { return m_cache_index; } u32 cache_index() const { return m_cache_index; }
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
private: private:
Operand m_dst; Operand m_dst;
IdentifierTableIndex m_identifier; IdentifierTableIndex m_identifier;
@@ -757,6 +871,11 @@ public:
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
IdentifierTableIndex identifier() const { return m_identifier; } IdentifierTableIndex identifier() const { return m_identifier; }
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
private: private:
Operand m_dst; Operand m_dst;
IdentifierTableIndex m_identifier; IdentifierTableIndex m_identifier;
@@ -776,6 +895,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_base);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand base() const { return m_base; } Operand base() const { return m_base; }
@@ -804,6 +928,12 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_base);
visitor(m_this_value);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand base() const { return m_base; } Operand base() const { return m_base; }
@@ -831,6 +961,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_base);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand base() const { return m_base; } Operand base() const { return m_base; }
@@ -854,6 +989,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_base);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand base() const { return m_base; } Operand base() const { return m_base; }
@@ -889,6 +1029,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_base);
visitor(m_src);
}
Operand base() const { return m_base; } Operand base() const { return m_base; }
IdentifierTableIndex property() const { return m_property; } IdentifierTableIndex property() const { return m_property; }
@@ -920,6 +1065,12 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_base);
visitor(m_this_value);
visitor(m_src);
}
Operand base() const { return m_base; } Operand base() const { return m_base; }
Operand this_value() const { return m_this_value; } Operand this_value() const { return m_this_value; }
@@ -950,6 +1101,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_base);
visitor(m_src);
}
Operand base() const { return m_base; } Operand base() const { return m_base; }
IdentifierTableIndex property() const { return m_property; } IdentifierTableIndex property() const { return m_property; }
@@ -974,6 +1130,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_base);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand base() const { return m_base; } Operand base() const { return m_base; }
@@ -998,6 +1159,12 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_base);
visitor(m_this_value);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand base() const { return m_base; } Operand base() const { return m_base; }
@@ -1024,6 +1191,12 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_base);
visitor(m_property);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand base() const { return m_base; } Operand base() const { return m_base; }
@@ -1051,6 +1224,13 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_base);
visitor(m_property);
visitor(m_this_value);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand base() const { return m_base; } Operand base() const { return m_base; }
@@ -1078,6 +1258,12 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_base);
visitor(m_property);
visitor(m_src);
}
Operand base() const { return m_base; } Operand base() const { return m_base; }
Operand property() const { return m_property; } Operand property() const { return m_property; }
@@ -1106,6 +1292,13 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_base);
visitor(m_property);
visitor(m_this_value);
visitor(m_src);
}
Operand base() const { return m_base; } Operand base() const { return m_base; }
Operand property() const { return m_property; } Operand property() const { return m_property; }
@@ -1133,6 +1326,12 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_base);
visitor(m_property);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand base() const { return m_base; } Operand base() const { return m_base; }
@@ -1162,6 +1361,13 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_base);
visitor(m_this_value);
visitor(m_property);
}
private: private:
Operand m_dst; Operand m_dst;
@@ -1212,6 +1418,10 @@ public:
visitor(m_true_target); visitor(m_true_target);
visitor(m_false_target); visitor(m_false_target);
} }
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_condition);
}
Operand condition() const { return m_condition; } Operand condition() const { return m_condition; }
auto& true_target() const { return m_true_target; } auto& true_target() const { return m_true_target; }
@@ -1240,6 +1450,10 @@ public:
{ {
visitor(m_target); visitor(m_target);
} }
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_condition);
}
Operand condition() const { return m_condition; } Operand condition() const { return m_condition; }
auto& target() const { return m_target; } auto& target() const { return m_target; }
@@ -1266,6 +1480,10 @@ public:
{ {
visitor(m_target); visitor(m_target);
} }
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_condition);
}
Operand condition() const { return m_condition; } Operand condition() const { return m_condition; }
auto& target() const { return m_target; } auto& target() const { return m_target; }
@@ -1305,6 +1523,11 @@ private:
{ \ { \
visitor(m_true_target); \ visitor(m_true_target); \
visitor(m_false_target); \ visitor(m_false_target); \
} \
void visit_operands_impl(Function<void(Operand&)> visitor) \
{ \
visitor(m_lhs); \
visitor(m_rhs); \
} \ } \
\ \
Operand lhs() const { return m_lhs; } \ Operand lhs() const { return m_lhs; } \
@@ -1340,6 +1563,10 @@ public:
visitor(m_true_target); visitor(m_true_target);
visitor(m_false_target); visitor(m_false_target);
} }
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_condition);
}
Operand condition() const { return m_condition; } Operand condition() const { return m_condition; }
auto& true_target() const { return m_true_target; } auto& true_target() const { return m_true_target; }
@@ -1370,6 +1597,10 @@ public:
visitor(m_true_target); visitor(m_true_target);
visitor(m_false_target); visitor(m_false_target);
} }
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_condition);
}
Operand condition() const { return m_condition; } Operand condition() const { return m_condition; }
auto& true_target() const { return m_true_target; } auto& true_target() const { return m_true_target; }
@@ -1422,6 +1653,14 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_callee);
visitor(m_this_value);
for (size_t i = 0; i < m_argument_count; i++)
visitor(m_arguments[i]);
}
private: private:
Operand m_dst; Operand m_dst;
@@ -1456,6 +1695,13 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_callee);
visitor(m_this_value);
visitor(m_arguments);
}
private: private:
Operand m_dst; Operand m_dst;
@@ -1478,6 +1724,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_arguments);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand arguments() const { return m_arguments; } Operand arguments() const { return m_arguments; }
@@ -1514,6 +1765,16 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
if (m_super_class.has_value())
visitor(m_super_class.value());
for (size_t i = 0; i < m_element_keys_count; i++) {
if (m_element_keys[i].has_value())
visitor(m_element_keys[i].value());
}
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Optional<Operand> const& super_class() const { return m_super_class; } Optional<Operand> const& super_class() const { return m_super_class; }
@@ -1542,6 +1803,12 @@ public:
void execute_impl(Bytecode::Interpreter&) const; void execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
if (m_home_object.has_value())
visitor(m_home_object.value());
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
FunctionNode const& function_node() const { return m_function_node; } FunctionNode const& function_node() const { return m_function_node; }
@@ -1584,6 +1851,11 @@ public:
void execute_impl(Bytecode::Interpreter&) const; void execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
if (m_value.has_value())
visitor(m_value.value());
}
Optional<Operand> const& value() const { return m_value; } Optional<Operand> const& value() const { return m_value; }
@@ -1601,6 +1873,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
@@ -1619,6 +1895,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_src);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand src() const { return m_src; } Operand src() const { return m_src; }
@@ -1638,6 +1919,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
@@ -1656,6 +1941,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_src);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand src() const { return m_src; } Operand src() const { return m_src; }
@@ -1677,6 +1967,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_src);
}
Operand src() const { return m_src; } Operand src() const { return m_src; }
@@ -1694,6 +1988,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_src);
}
Operand src() const { return m_src; } Operand src() const { return m_src; }
@@ -1711,6 +2009,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_src);
}
Operand src() const { return m_src; } Operand src() const { return m_src; }
@@ -1728,6 +2030,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_src);
}
Operand src() const { return m_src; } Operand src() const { return m_src; }
@@ -1863,6 +2169,10 @@ public:
if (m_continuation_label.has_value()) if (m_continuation_label.has_value())
visitor(m_continuation_label.value()); visitor(m_continuation_label.value());
} }
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_value);
}
auto& continuation() const { return m_continuation_label; } auto& continuation() const { return m_continuation_label; }
Operand value() const { return m_value; } Operand value() const { return m_value; }
@@ -1889,6 +2199,10 @@ public:
{ {
visitor(m_continuation_label); visitor(m_continuation_label);
} }
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_argument);
}
auto& continuation() const { return m_continuation_label; } auto& continuation() const { return m_continuation_label; }
Operand argument() const { return m_argument; } Operand argument() const { return m_argument; }
@@ -1910,6 +2224,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_iterable);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand iterable() const { return m_iterable; } Operand iterable() const { return m_iterable; }
@@ -1932,6 +2251,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_object);
visitor(m_iterator_record);
}
Operand object() const { return m_object; } Operand object() const { return m_object; }
Operand iterator_record() const { return m_iterator_record; } Operand iterator_record() const { return m_iterator_record; }
@@ -1952,6 +2276,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_next_method);
visitor(m_iterator_record);
}
Operand next_method() const { return m_next_method; } Operand next_method() const { return m_next_method; }
Operand iterator_record() const { return m_iterator_record; } Operand iterator_record() const { return m_iterator_record; }
@@ -1973,6 +2302,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_object);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand object() const { return m_object; } Operand object() const { return m_object; }
@@ -1995,6 +2329,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_object);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand object() const { return m_object; } Operand object() const { return m_object; }
@@ -2016,6 +2355,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_iterator_record);
}
Operand iterator_record() const { return m_iterator_record; } Operand iterator_record() const { return m_iterator_record; }
Completion::Type completion_type() const { return m_completion_type; } Completion::Type completion_type() const { return m_completion_type; }
@@ -2039,6 +2382,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_iterator_record);
}
Operand iterator_record() const { return m_iterator_record; } Operand iterator_record() const { return m_iterator_record; }
Completion::Type completion_type() const { return m_completion_type; } Completion::Type completion_type() const { return m_completion_type; }
@@ -2061,6 +2408,11 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
visitor(m_iterator_record);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
Operand iterator_record() const { return m_iterator_record; } Operand iterator_record() const { return m_iterator_record; }
@@ -2080,6 +2432,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
@@ -2097,6 +2453,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
@@ -2114,6 +2474,10 @@ public:
void execute_impl(Bytecode::Interpreter&) const; void execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
@@ -2131,6 +2495,10 @@ public:
void execute_impl(Bytecode::Interpreter&) const; void execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
@@ -2149,6 +2517,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_dst);
}
Operand dst() const { return m_dst; } Operand dst() const { return m_dst; }
IdentifierTableIndex identifier() const { return m_identifier; } IdentifierTableIndex identifier() const { return m_identifier; }
@@ -2170,6 +2542,10 @@ public:
ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const; ThrowCompletionOr<void> execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_value);
}
Operand value() const { return m_value; } Operand value() const { return m_value; }
@@ -2188,6 +2564,10 @@ public:
void execute_impl(Bytecode::Interpreter&) const; void execute_impl(Bytecode::Interpreter&) const;
ByteString to_byte_string_impl(Bytecode::Executable const&) const; ByteString to_byte_string_impl(Bytecode::Executable const&) const;
void visit_operands_impl(Function<void(Operand&)> visitor)
{
visitor(m_value);
}
private: private:
StringView m_text; StringView m_text;

View File

@@ -38,6 +38,8 @@ public:
[[nodiscard]] Register as_register() const; [[nodiscard]] Register as_register() const;
void offset_index_by(u32 offset) { m_index += offset; }
private: private:
Type m_type {}; Type m_type {};
u32 m_index { 0 }; u32 m_index { 0 };

View File

@@ -380,8 +380,6 @@ ThrowCompletionOr<Value> ECMAScriptFunctionObject::internal_call(Value this_argu
auto callee_context = ExecutionContext::create(heap()); auto callee_context = ExecutionContext::create(heap());
callee_context->locals.resize(m_local_variables_names.size());
// Non-standard // Non-standard
callee_context->arguments.ensure_capacity(max(arguments_list.size(), m_formal_parameters.size())); callee_context->arguments.ensure_capacity(max(arguments_list.size(), m_formal_parameters.size()));
callee_context->arguments.append(arguments_list.data(), arguments_list.size()); callee_context->arguments.append(arguments_list.data(), arguments_list.size());
@@ -457,8 +455,6 @@ ThrowCompletionOr<NonnullGCPtr<Object>> ECMAScriptFunctionObject::internal_const
auto callee_context = ExecutionContext::create(heap()); auto callee_context = ExecutionContext::create(heap());
callee_context->locals.resize(m_local_variables_names.size());
// Non-standard // Non-standard
callee_context->arguments.ensure_capacity(max(arguments_list.size(), m_formal_parameters.size())); callee_context->arguments.ensure_capacity(max(arguments_list.size(), m_formal_parameters.size()));
callee_context->arguments.append(arguments_list.data(), arguments_list.size()); callee_context->arguments.append(arguments_list.data(), arguments_list.size());
@@ -841,6 +837,8 @@ Completion ECMAScriptFunctionObject::ordinary_call_evaluate_body()
m_bytecode_executable = m_ecmascript_code->bytecode_executable(); m_bytecode_executable = m_ecmascript_code->bytecode_executable();
} }
vm.running_execution_context().registers_and_constants_and_locals.resize(m_local_variables_names.size() + m_bytecode_executable->number_of_registers + m_bytecode_executable->constants.size());
auto result_and_frame = vm.bytecode_interpreter().run_executable(*m_bytecode_executable, {}); auto result_and_frame = vm.bytecode_interpreter().run_executable(*m_bytecode_executable, {});
if (result_and_frame.value.is_error()) if (result_and_frame.value.is_error())

View File

@@ -43,8 +43,7 @@ NonnullOwnPtr<ExecutionContext> ExecutionContext::copy() const
copy->executable = executable; copy->executable = executable;
copy->arguments = arguments; copy->arguments = arguments;
copy->passed_argument_count = passed_argument_count; copy->passed_argument_count = passed_argument_count;
copy->locals = locals; copy->registers_and_constants_and_locals = registers_and_constants_and_locals;
copy->registers = registers;
copy->unwind_contexts = unwind_contexts; copy->unwind_contexts = unwind_contexts;
copy->saved_lexical_environments = saved_lexical_environments; copy->saved_lexical_environments = saved_lexical_environments;
copy->previously_scheduled_jumps = previously_scheduled_jumps; copy->previously_scheduled_jumps = previously_scheduled_jumps;
@@ -63,8 +62,7 @@ void ExecutionContext::visit_edges(Cell::Visitor& visitor)
visitor.visit(executable); visitor.visit(executable);
visitor.visit(function_name); visitor.visit(function_name);
visitor.visit(arguments); visitor.visit(arguments);
visitor.visit(locals); visitor.visit(registers_and_constants_and_locals);
visitor.visit(registers);
for (auto& context : unwind_contexts) { for (auto& context : unwind_contexts) {
visitor.visit(context.lexical_environment); visitor.visit(context.lexical_environment);
} }

View File

@@ -70,14 +70,13 @@ public:
Value& local(size_t index) Value& local(size_t index)
{ {
return locals[index]; return registers_and_constants_and_locals[index];
} }
u32 passed_argument_count { 0 }; u32 passed_argument_count { 0 };
Vector<Value> arguments; Vector<Value> arguments;
Vector<Value> locals; Vector<Value> registers_and_constants_and_locals;
Vector<Value> registers;
Vector<Bytecode::UnwindInfo> unwind_contexts; Vector<Bytecode::UnwindInfo> unwind_contexts;
Vector<Optional<size_t>> previously_scheduled_jumps; Vector<Optional<size_t>> previously_scheduled_jumps;
Vector<GCPtr<Environment>> saved_lexical_environments; Vector<GCPtr<Environment>> saved_lexical_environments;