Interpreter.py (3568B)
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 7 import gdb 8 9 from mozilla import prettyprinters 10 11 prettyprinters.clear_module_printers(__name__) 12 13 from mozilla.prettyprinters import pretty_printer 14 15 16 class InterpreterTypeCache: 17 # Cache information about the Interpreter types for this objfile. 18 def __init__(self): 19 self.tValue = gdb.lookup_type("JS::Value") 20 self.tJSOp = gdb.lookup_type("JSOp") 21 try: 22 self.tScriptFrameIterData = gdb.lookup_type("js::ScriptFrameIter::Data") 23 except gdb.error: 24 # Work around problem with gcc optimized debuginfo where it doesn't 25 # seem to be able to see that ScriptFrameIter inherits the 26 # FrameIter::Data type. 27 self.tScriptFrameIterData = gdb.lookup_type("js::FrameIter::Data") 28 self.tInterpreterFrame = gdb.lookup_type("js::InterpreterFrame") 29 self.tBaselineFrame = gdb.lookup_type("js::jit::BaselineFrame") 30 self.tRematerializedFrame = gdb.lookup_type("js::jit::RematerializedFrame") 31 self.tDebugFrame = gdb.lookup_type("js::wasm::DebugFrame") 32 33 34 @pretty_printer("js::InterpreterRegs") 35 class InterpreterRegs: 36 def __init__(self, value, cache): 37 self.value = value 38 self.cache = cache 39 if not cache.mod_Interpreter: 40 cache.mod_Interpreter = InterpreterTypeCache() 41 self.itc = cache.mod_Interpreter 42 43 # There's basically no way to co-operate with 'set print pretty' (how would 44 # you get the current level of indentation?), so we don't even bother 45 # trying. No 'children', just 'to_string'. 46 def to_string(self): 47 fp_ = "fp_ = {}".format(self.value["fp_"]) 48 slots = (self.value["fp_"] + 1).cast(self.itc.tValue.pointer()) 49 sp = "sp = fp_.slots() + {}".format(self.value["sp"] - slots) 50 pc = "pc = {}".format(self.value["pc"]) 51 return f"{{ {fp_}, {sp}, {pc} }}" 52 53 54 @pretty_printer("js::AbstractFramePtr") 55 class AbstractFramePtr: 56 Tag_InterpreterFrame = 0x0 57 Tag_BaselineFrame = 0x1 58 Tag_RematerializedFrame = 0x2 59 Tag_WasmDebugFrame = 0x3 60 TagMask = 0x3 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_InterpreterFrame: 74 label = "js::InterpreterFrame" 75 ptr = ptr.cast(self.itc.tInterpreterFrame.pointer()) 76 if tag == AbstractFramePtr.Tag_BaselineFrame: 77 label = "js::jit::BaselineFrame" 78 ptr = ptr.cast(self.itc.tBaselineFrame.pointer()) 79 if tag == AbstractFramePtr.Tag_RematerializedFrame: 80 label = "js::jit::RematerializedFrame" 81 ptr = ptr.cast(self.itc.tRematerializedFrame.pointer()) 82 if tag == AbstractFramePtr.Tag_WasmDebugFrame: 83 label = "js::wasm::DebugFrame" 84 ptr = ptr.cast(self.itc.tDebugFrame.pointer()) 85 return f"AbstractFramePtr (({label} *) {ptr})" 86 87 # Provide the ptr_ field as a child, so it prints after the pretty string 88 # provided above. 89 def children(self): 90 yield ("ptr_", self.value["ptr_"])