michael@0: # Pretty-printers for SpiderMonkey JSObjects. michael@0: michael@0: import gdb michael@0: import mozilla.JSString michael@0: import mozilla.prettyprinters as prettyprinters michael@0: from mozilla.prettyprinters import ptr_pretty_printer, ref_pretty_printer michael@0: from mozilla.Root import deref michael@0: michael@0: prettyprinters.clear_module_printers(__name__) michael@0: michael@0: class JSObjectTypeCache(object): michael@0: def __init__(self, value, cache): michael@0: # In GDB 7.4.50, with some programs, this first dummy gdb.lookup_type michael@0: # call is required to make the second lookup_type call succeed. A GDB michael@0: # built from the public sources as of 2012-12-12 did not require the michael@0: # dummy lookup. michael@0: gdb.lookup_type('js::BaseShape') michael@0: baseshape_flags = gdb.lookup_type('js::BaseShape::Flag') michael@0: self.flag_DELEGATE = prettyprinters.enum_value(baseshape_flags, 'js::BaseShape::DELEGATE') michael@0: self.func_ptr_type = gdb.lookup_type('JSFunction').pointer() michael@0: michael@0: # There should be no need to register this for JSFunction as well, since we michael@0: # search for pretty-printers under the names of base classes, and michael@0: # JSFunction has JSObject as a base class. michael@0: michael@0: @ptr_pretty_printer('JSObject') michael@0: class JSObjectPtrOrRef(prettyprinters.Pointer): michael@0: def __init__(self, value, cache): michael@0: super(JSObjectPtrOrRef, self).__init__(value, cache) michael@0: if not cache.mod_JSObject: michael@0: cache.mod_JSObject = JSObjectTypeCache(value, cache) michael@0: self.otc = cache.mod_JSObject michael@0: michael@0: def summary(self): michael@0: shape = deref(self.value['shape_']) michael@0: baseshape = deref(shape['base_']) michael@0: otype = deref(self.value['type_']) michael@0: class_name = otype['clasp_']['name'].string() michael@0: flags = baseshape['flags'] michael@0: is_delegate = bool(flags & self.otc.flag_DELEGATE) michael@0: name = None michael@0: if class_name == 'Function': michael@0: function = self.value michael@0: concrete_type = function.type.strip_typedefs() michael@0: if concrete_type.code == gdb.TYPE_CODE_REF: michael@0: function = function.address michael@0: function = function.cast(self.otc.func_ptr_type) michael@0: atom = deref(function['atom_']) michael@0: name = str(atom) if atom else '' michael@0: return '[object %s%s]%s' % (class_name, michael@0: ' ' + name if name else '', michael@0: ' delegate' if is_delegate else '') michael@0: michael@0: @ref_pretty_printer('JSObject') michael@0: def JSObjectRef(value, cache): return JSObjectPtrOrRef(value, cache)