1# This Source Code Form is subject to the terms of the Mozilla Public 2# License, v. 2.0. If a copy of the MPL was not distributed with this file, 3# You can obtain one at http://mozilla.org/MPL/2.0/. 4 5# Pretty-printers for InterpreterRegs. 6 7import gdb 8import mozilla.prettyprinters as prettyprinters 9 10prettyprinters.clear_module_printers(__name__) 11 12from mozilla.prettyprinters import pretty_printer 13 14 15class InterpreterTypeCache(object): 16 # Cache information about the Interpreter types for this objfile. 17 def __init__(self): 18 self.tValue = gdb.lookup_type("JS::Value") 19 self.tJSOp = gdb.lookup_type("JSOp") 20 try: 21 self.tScriptFrameIterData = gdb.lookup_type("js::ScriptFrameIter::Data") 22 except gdb.error: 23 # Work around problem with gcc optimized debuginfo where it doesn't 24 # seem to be able to see that ScriptFrameIter inherits the 25 # FrameIter::Data type. 26 self.tScriptFrameIterData = gdb.lookup_type("js::FrameIter::Data") 27 self.tInterpreterFrame = gdb.lookup_type("js::InterpreterFrame") 28 self.tBaselineFrame = gdb.lookup_type("js::jit::BaselineFrame") 29 self.tRematerializedFrame = gdb.lookup_type("js::jit::RematerializedFrame") 30 self.tDebugFrame = gdb.lookup_type("js::wasm::DebugFrame") 31 32 33@pretty_printer("js::InterpreterRegs") 34class InterpreterRegs(object): 35 def __init__(self, value, cache): 36 self.value = value 37 self.cache = cache 38 if not cache.mod_Interpreter: 39 cache.mod_Interpreter = InterpreterTypeCache() 40 self.itc = cache.mod_Interpreter 41 42 # There's basically no way to co-operate with 'set print pretty' (how would 43 # you get the current level of indentation?), so we don't even bother 44 # trying. No 'children', just 'to_string'. 45 def to_string(self): 46 fp_ = "fp_ = {}".format(self.value["fp_"]) 47 slots = (self.value["fp_"] + 1).cast(self.itc.tValue.pointer()) 48 sp = "sp = fp_.slots() + {}".format(self.value["sp"] - slots) 49 pc = "pc = {}".format(self.value["pc"]) 50 return "{{ {}, {}, {} }}".format(fp_, sp, pc) 51 52 53@pretty_printer("js::AbstractFramePtr") 54class AbstractFramePtr(object): 55 Tag_ScriptFrameIterData = 0x0 56 Tag_InterpreterFrame = 0x1 57 Tag_BaselineFrame = 0x2 58 Tag_RematerializedFrame = 0x3 59 Tag_WasmDebugFrame = 0x4 60 TagMask = 0x7 61 62 def __init__(self, value, cache): 63 self.value = value 64 self.cache = cache 65 if not cache.mod_Interpreter: 66 cache.mod_Interpreter = InterpreterTypeCache() 67 self.itc = cache.mod_Interpreter 68 69 def to_string(self): 70 ptr = self.value["ptr_"] 71 tag = ptr & AbstractFramePtr.TagMask 72 ptr = ptr & ~AbstractFramePtr.TagMask 73 if tag == AbstractFramePtr.Tag_ScriptFrameIterData: 74 label = "js::ScriptFrameIter::Data" 75 ptr = ptr.cast(self.itc.tScriptFrameIterData.pointer()) 76 if tag == AbstractFramePtr.Tag_InterpreterFrame: 77 label = "js::InterpreterFrame" 78 ptr = ptr.cast(self.itc.tInterpreterFrame.pointer()) 79 if tag == AbstractFramePtr.Tag_BaselineFrame: 80 label = "js::jit::BaselineFrame" 81 ptr = ptr.cast(self.itc.tBaselineFrame.pointer()) 82 if tag == AbstractFramePtr.Tag_RematerializedFrame: 83 label = "js::jit::RematerializedFrame" 84 ptr = ptr.cast(self.itc.tRematerializedFrame.pointer()) 85 if tag == AbstractFramePtr.Tag_WasmDebugFrame: 86 label = "js::wasm::DebugFrame" 87 ptr = ptr.cast(self.itc.tDebugFrame.pointer()) 88 return "AbstractFramePtr (({} *) {})".format(label, ptr) 89 90 # Provide the ptr_ field as a child, so it prints after the pretty string 91 # provided above. 92 def children(self): 93 yield ("ptr_", self.value["ptr_"]) 94