michael@0: # Pretty-printers for JSID values. michael@0: michael@0: import gdb michael@0: import mozilla.prettyprinters michael@0: import mozilla.Root michael@0: michael@0: from mozilla.prettyprinters import pretty_printer michael@0: michael@0: # Forget any printers from previous loads of this module. michael@0: mozilla.prettyprinters.clear_module_printers(__name__) michael@0: michael@0: @pretty_printer('jsid') michael@0: class jsid(object): michael@0: # Since people don't always build with macro debugging info, I can't michael@0: # think of any way to avoid copying these values here, short of using michael@0: # inferior calls for every operation (which, I hear, is broken from michael@0: # pretty-printers in some recent GDBs). michael@0: TYPE_STRING = 0x0 michael@0: TYPE_INT = 0x1 michael@0: TYPE_VOID = 0x2 michael@0: TYPE_OBJECT = 0x4 michael@0: TYPE_MASK = 0x7 michael@0: michael@0: def __init__(self, value, cache): michael@0: self.value = value michael@0: self.cache = cache michael@0: self.concrete_type = self.value.type.strip_typedefs() michael@0: michael@0: # SpiderMonkey has two alternative definitions of jsid: a typedef for michael@0: # ptrdiff_t, and a struct with == and != operators defined on it. michael@0: # Extract the bits from either one. michael@0: def as_bits(self): michael@0: if self.concrete_type.code == gdb.TYPE_CODE_STRUCT: michael@0: return self.value['asBits'] michael@0: elif self.concrete_type.code == gdb.TYPE_CODE_INT: michael@0: return self.value michael@0: else: michael@0: raise RuntimeError, ("definition of SpiderMonkey 'jsid' type" michael@0: "neither struct nor integral type") michael@0: michael@0: def to_string(self): michael@0: bits = self.as_bits() michael@0: tag = bits & jsid.TYPE_MASK michael@0: if tag == jsid.TYPE_STRING: michael@0: body = bits.cast(self.cache.JSString_ptr_t) michael@0: elif tag & jsid.TYPE_INT: michael@0: body = bits >> 1 michael@0: elif tag == jsid.TYPE_VOID: michael@0: return "JSID_VOID" michael@0: elif tag == jsid.TYPE_OBJECT: michael@0: body = ((bits & ~jsid.TYPE_MASK) michael@0: .cast(self.cache.JSObject_ptr_t)) michael@0: else: michael@0: body = "" michael@0: return '$jsid(%s)' % (body,) michael@0: michael@0: # Hard-code the referent type pretty-printer for jsid roots and handles. michael@0: # See the comment for mozilla.Root.Common.__init__. michael@0: @pretty_printer('JS::Rooted') michael@0: def RootedJSID(value, cache): michael@0: return mozilla.Root.Rooted(value, cache, jsid) michael@0: @pretty_printer('JS::Handle') michael@0: def HandleJSID(value, cache): michael@0: return mozilla.Root.Handle(value, cache, jsid) michael@0: @pretty_printer('JS::MutableHandle') michael@0: def MutableHandleJSID(value, cache): michael@0: return mozilla.Root.MutableHandle(value, cache, jsid)