|
1 # Pretty-printers for SpiderMonkey strings. |
|
2 |
|
3 import gdb |
|
4 import mozilla.prettyprinters |
|
5 from mozilla.prettyprinters import pretty_printer, ptr_pretty_printer |
|
6 |
|
7 # Forget any printers from previous loads of this module. |
|
8 mozilla.prettyprinters.clear_module_printers(__name__) |
|
9 |
|
10 # Cache information about the JSString type for this objfile. |
|
11 class JSStringTypeCache(object): |
|
12 def __init__(self, cache): |
|
13 dummy = gdb.Value(0).cast(cache.JSString_ptr_t) |
|
14 self.LENGTH_SHIFT = dummy['LENGTH_SHIFT'] |
|
15 self.FLAGS_MASK = dummy['FLAGS_MASK'] |
|
16 self.ROPE_FLAGS = dummy['ROPE_FLAGS'] |
|
17 self.ATOM_BIT = dummy['ATOM_BIT'] |
|
18 |
|
19 class Common(mozilla.prettyprinters.Pointer): |
|
20 def __init__(self, value, cache): |
|
21 super(Common, self).__init__(value, cache) |
|
22 if not cache.mod_JSString: |
|
23 cache.mod_JSString = JSStringTypeCache(cache) |
|
24 self.stc = cache.mod_JSString |
|
25 |
|
26 @ptr_pretty_printer("JSString") |
|
27 class JSStringPtr(Common): |
|
28 def display_hint(self): |
|
29 return "string" |
|
30 |
|
31 def jschars(self): |
|
32 d = self.value['d'] |
|
33 lengthAndFlags = d['lengthAndFlags'] |
|
34 length = lengthAndFlags >> self.stc.LENGTH_SHIFT |
|
35 is_rope = (lengthAndFlags & self.stc.FLAGS_MASK) == self.stc.ROPE_FLAGS |
|
36 if is_rope: |
|
37 for c in JSStringPtr(d['u1']['left'], self.cache).jschars(): |
|
38 yield c |
|
39 for c in JSStringPtr(d['s']['u2']['right'], self.cache).jschars(): |
|
40 yield c |
|
41 else: |
|
42 chars = d['u1']['chars'] |
|
43 for i in xrange(length): |
|
44 yield chars[i] |
|
45 |
|
46 def to_string(self): |
|
47 s = u'' |
|
48 for c in self.jschars(): |
|
49 s += unichr(c) |
|
50 return s |
|
51 |
|
52 @ptr_pretty_printer("JSAtom") |
|
53 class JSAtomPtr(Common): |
|
54 def to_string(self): |
|
55 return self.value.cast(self.cache.JSString_ptr_t) |