|
1 # Pretty-printers for SpiderMonkey JSObjects. |
|
2 |
|
3 import gdb |
|
4 import mozilla.JSString |
|
5 import mozilla.prettyprinters as prettyprinters |
|
6 from mozilla.prettyprinters import ptr_pretty_printer, ref_pretty_printer |
|
7 from mozilla.Root import deref |
|
8 |
|
9 prettyprinters.clear_module_printers(__name__) |
|
10 |
|
11 class JSObjectTypeCache(object): |
|
12 def __init__(self, value, cache): |
|
13 # In GDB 7.4.50, with some programs, this first dummy gdb.lookup_type |
|
14 # call is required to make the second lookup_type call succeed. A GDB |
|
15 # built from the public sources as of 2012-12-12 did not require the |
|
16 # dummy lookup. |
|
17 gdb.lookup_type('js::BaseShape') |
|
18 baseshape_flags = gdb.lookup_type('js::BaseShape::Flag') |
|
19 self.flag_DELEGATE = prettyprinters.enum_value(baseshape_flags, 'js::BaseShape::DELEGATE') |
|
20 self.func_ptr_type = gdb.lookup_type('JSFunction').pointer() |
|
21 |
|
22 # There should be no need to register this for JSFunction as well, since we |
|
23 # search for pretty-printers under the names of base classes, and |
|
24 # JSFunction has JSObject as a base class. |
|
25 |
|
26 @ptr_pretty_printer('JSObject') |
|
27 class JSObjectPtrOrRef(prettyprinters.Pointer): |
|
28 def __init__(self, value, cache): |
|
29 super(JSObjectPtrOrRef, self).__init__(value, cache) |
|
30 if not cache.mod_JSObject: |
|
31 cache.mod_JSObject = JSObjectTypeCache(value, cache) |
|
32 self.otc = cache.mod_JSObject |
|
33 |
|
34 def summary(self): |
|
35 shape = deref(self.value['shape_']) |
|
36 baseshape = deref(shape['base_']) |
|
37 otype = deref(self.value['type_']) |
|
38 class_name = otype['clasp_']['name'].string() |
|
39 flags = baseshape['flags'] |
|
40 is_delegate = bool(flags & self.otc.flag_DELEGATE) |
|
41 name = None |
|
42 if class_name == 'Function': |
|
43 function = self.value |
|
44 concrete_type = function.type.strip_typedefs() |
|
45 if concrete_type.code == gdb.TYPE_CODE_REF: |
|
46 function = function.address |
|
47 function = function.cast(self.otc.func_ptr_type) |
|
48 atom = deref(function['atom_']) |
|
49 name = str(atom) if atom else '<unnamed>' |
|
50 return '[object %s%s]%s' % (class_name, |
|
51 ' ' + name if name else '', |
|
52 ' delegate' if is_delegate else '') |
|
53 |
|
54 @ref_pretty_printer('JSObject') |
|
55 def JSObjectRef(value, cache): return JSObjectPtrOrRef(value, cache) |