diff options
Diffstat (limited to 'js/src/gdb/mozilla/Interpreter.py')
-rw-r--r-- | js/src/gdb/mozilla/Interpreter.py | 93 |
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_"]) |