Jelajahi Sumber

LibJS: Expose some information about the bytecode interpreters state

This is quite helpful, when reporting internal errors.
Hendiadyoin1 2 tahun lalu
induk
melakukan
a1f1d9e4a7

+ 7 - 5
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;
             }

+ 4 - 0
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;