summaryrefslogtreecommitdiffstats
path: root/js/src/gdb/mozilla/Interpreter.py
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/gdb/mozilla/Interpreter.py')
-rw-r--r--js/src/gdb/mozilla/Interpreter.py93
1 files changed, 93 insertions, 0 deletions
diff --git a/js/src/gdb/mozilla/Interpreter.py b/js/src/gdb/mozilla/Interpreter.py
new file mode 100644
index 0000000000..febf92b86d
--- /dev/null
+++ b/js/src/gdb/mozilla/Interpreter.py
@@ -0,0 +1,93 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# Pretty-printers for InterpreterRegs.
+
+import gdb
+import mozilla.prettyprinters as prettyprinters
+
+prettyprinters.clear_module_printers(__name__)
+
+from mozilla.prettyprinters import pretty_printer
+
+
+class InterpreterTypeCache(object):
+ # Cache information about the Interpreter types for this objfile.
+ def __init__(self):
+ self.tValue = gdb.lookup_type("JS::Value")
+ self.tJSOp = gdb.lookup_type("JSOp")
+ try:
+ self.tScriptFrameIterData = gdb.lookup_type("js::ScriptFrameIter::Data")
+ except gdb.error:
+ # Work around problem with gcc optimized debuginfo where it doesn't
+ # seem to be able to see that ScriptFrameIter inherits the
+ # FrameIter::Data type.
+ self.tScriptFrameIterData = gdb.lookup_type("js::FrameIter::Data")
+ self.tInterpreterFrame = gdb.lookup_type("js::InterpreterFrame")
+ self.tBaselineFrame = gdb.lookup_type("js::jit::BaselineFrame")
+ self.tRematerializedFrame = gdb.lookup_type("js::jit::RematerializedFrame")
+ self.tDebugFrame = gdb.lookup_type("js::wasm::DebugFrame")
+
+
+@pretty_printer("js::InterpreterRegs")
+class InterpreterRegs(object):
+ def __init__(self, value, cache):
+ self.value = value
+ self.cache = cache
+ if not cache.mod_Interpreter:
+ cache.mod_Interpreter = InterpreterTypeCache()
+ self.itc = cache.mod_Interpreter
+
+ # There's basically no way to co-operate with 'set print pretty' (how would
+ # you get the current level of indentation?), so we don't even bother
+ # trying. No 'children', just 'to_string'.
+ def to_string(self):
+ fp_ = "fp_ = {}".format(self.value["fp_"])
+ slots = (self.value["fp_"] + 1).cast(self.itc.tValue.pointer())
+ sp = "sp = fp_.slots() + {}".format(self.value["sp"] - slots)
+ pc = "pc = {}".format(self.value["pc"])
+ return "{{ {}, {}, {} }}".format(fp_, sp, pc)
+
+
+@pretty_printer("js::AbstractFramePtr")
+class AbstractFramePtr(object):
+ Tag_ScriptFrameIterData = 0x0
+ Tag_InterpreterFrame = 0x1
+ Tag_BaselineFrame = 0x2
+ Tag_RematerializedFrame = 0x3
+ Tag_WasmDebugFrame = 0x4
+ TagMask = 0x7
+
+ def __init__(self, value, cache):
+ self.value = value
+ self.cache = cache
+ if not cache.mod_Interpreter:
+ cache.mod_Interpreter = InterpreterTypeCache()
+ self.itc = cache.mod_Interpreter
+
+ def to_string(self):
+ ptr = self.value["ptr_"]
+ tag = ptr & AbstractFramePtr.TagMask
+ ptr = ptr & ~AbstractFramePtr.TagMask
+ if tag == AbstractFramePtr.Tag_ScriptFrameIterData:
+ label = "js::ScriptFrameIter::Data"
+ ptr = ptr.cast(self.itc.tScriptFrameIterData.pointer())
+ if tag == AbstractFramePtr.Tag_InterpreterFrame:
+ label = "js::InterpreterFrame"
+ ptr = ptr.cast(self.itc.tInterpreterFrame.pointer())
+ if tag == AbstractFramePtr.Tag_BaselineFrame:
+ label = "js::jit::BaselineFrame"
+ ptr = ptr.cast(self.itc.tBaselineFrame.pointer())
+ if tag == AbstractFramePtr.Tag_RematerializedFrame:
+ label = "js::jit::RematerializedFrame"
+ ptr = ptr.cast(self.itc.tRematerializedFrame.pointer())
+ if tag == AbstractFramePtr.Tag_WasmDebugFrame:
+ label = "js::wasm::DebugFrame"
+ ptr = ptr.cast(self.itc.tDebugFrame.pointer())
+ return "AbstractFramePtr (({} *) {})".format(label, ptr)
+
+ # Provide the ptr_ field as a child, so it prints after the pretty string
+ # provided above.
+ def children(self):
+ yield ("ptr_", self.value["ptr_"])