summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHendiadyoin1 <leon.a@serenityos.org>2022-10-30 11:58:46 +0100
committerAndreas Kling <kling@serenityos.org>2022-11-01 11:21:18 +0100
commita1f1d9e4a7309fe3ea2c3aa6e31fd4fe0a704121 (patch)
tree30ac52c68fdc2a206453910d8f7c6da5b1e07074
parent937fcfc75c417b37030e47b97050c2a705a174d0 (diff)
downloadserenity-a1f1d9e4a7309fe3ea2c3aa6e31fd4fe0a704121.zip
LibJS: Expose some information about the bytecode interpreters state
This is quite helpful, when reporting internal errors.
-rw-r--r--Userland/Libraries/LibJS/Bytecode/Interpreter.cpp12
-rw-r--r--Userland/Libraries/LibJS/Bytecode/Interpreter.h4
2 files changed, 11 insertions, 5 deletions
diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp
index 492fa85874..e7b60f9618 100644
--- a/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp
+++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp
@@ -61,7 +61,7 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
pushed_execution_context = true;
}
- auto block = entry_point ?: &executable.basic_blocks.first();
+ m_current_block = entry_point ?: &executable.basic_blocks.first();
if (in_frame)
m_register_windows.append(in_frame);
else
@@ -70,7 +70,9 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
registers().resize(executable.number_of_registers);
for (;;) {
- Bytecode::InstructionStreamIterator pc(block->instruction_stream());
+ Bytecode::InstructionStreamIterator pc(m_current_block->instruction_stream());
+ TemporaryChange temp_change { m_pc, &pc };
+
bool will_jump = false;
bool will_return = false;
while (!pc.at_end()) {
@@ -85,7 +87,7 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
if (unwind_context.executable != m_current_executable)
break;
if (unwind_context.handler) {
- block = unwind_context.handler;
+ m_current_block = unwind_context.handler;
unwind_context.handler = nullptr;
// If there's no finalizer, there's nowhere for the handler block to unwind to, so the unwind context is no longer needed.
@@ -98,7 +100,7 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
break;
}
if (unwind_context.finalizer) {
- block = unwind_context.finalizer;
+ m_current_block = unwind_context.finalizer;
m_unwind_contexts.take_last();
will_jump = true;
break;
@@ -108,7 +110,7 @@ Interpreter::ValueAndFrame Interpreter::run_and_return_frame(Executable const& e
VERIFY_NOT_REACHED();
}
if (m_pending_jump.has_value()) {
- block = m_pending_jump.release_value();
+ m_current_block = m_pending_jump.release_value();
will_jump = true;
break;
}
diff --git a/Userland/Libraries/LibJS/Bytecode/Interpreter.h b/Userland/Libraries/LibJS/Bytecode/Interpreter.h
index 82883ced7f..c6451eaf69 100644
--- a/Userland/Libraries/LibJS/Bytecode/Interpreter.h
+++ b/Userland/Libraries/LibJS/Bytecode/Interpreter.h
@@ -64,6 +64,8 @@ public:
ThrowCompletionOr<void> continue_pending_unwind(Label const& resume_label);
Executable const& current_executable() { return *m_current_executable; }
+ BasicBlock const& current_block() const { return *m_current_block; }
+ size_t pc() const { return m_pc ? m_pc->offset() : 0; }
enum class OptimizationLevel {
None,
@@ -99,6 +101,8 @@ private:
Vector<UnwindInfo> m_unwind_contexts;
Handle<Value> m_saved_exception;
OwnPtr<JS::Interpreter> m_ast_interpreter;
+ BasicBlock const* m_current_block { nullptr };
+ InstructionStreamIterator* m_pc { nullptr };
};
extern bool g_dump_bytecode;