| # Pretty-printers for SpiderMonkey strings. |
| |
| import gdb |
| import mozilla.prettyprinters |
| from mozilla.prettyprinters import pretty_printer, ptr_pretty_printer |
| |
| try: |
| chr(10000) # UPPER RIGHT PENCIL |
| except ValueError as exc: # yuck, we are in Python 2.x, so chr() is 8-bit |
| chr = unichr # replace with teh unicodes |
| |
| # Forget any printers from previous loads of this module. |
| mozilla.prettyprinters.clear_module_printers(__name__) |
| |
| # Cache information about the JSString type for this objfile. |
| class JSStringTypeCache(object): |
| def __init__(self, cache): |
| dummy = gdb.Value(0).cast(cache.JSString_ptr_t) |
| self.ROPE_FLAGS = dummy['ROPE_FLAGS'] |
| self.ATOM_BIT = dummy['ATOM_BIT'] |
| self.INLINE_CHARS_BIT = dummy['INLINE_CHARS_BIT'] |
| self.TYPE_FLAGS_MASK = dummy['TYPE_FLAGS_MASK'] |
| self.LATIN1_CHARS_BIT = dummy['LATIN1_CHARS_BIT'] |
| |
| class Common(mozilla.prettyprinters.Pointer): |
| def __init__(self, value, cache): |
| super(Common, self).__init__(value, cache) |
| if not cache.mod_JSString: |
| cache.mod_JSString = JSStringTypeCache(cache) |
| self.stc = cache.mod_JSString |
| |
| @ptr_pretty_printer("JSString") |
| class JSStringPtr(Common): |
| def display_hint(self): |
| return "string" |
| |
| def chars(self): |
| d = self.value['d'] |
| length = d['u1']['length'] |
| flags = d['u1']['flags'] |
| is_rope = ((flags & self.stc.TYPE_FLAGS_MASK) == self.stc.ROPE_FLAGS) |
| if is_rope: |
| for c in JSStringPtr(d['s']['u2']['left'], self.cache).chars(): |
| yield c |
| for c in JSStringPtr(d['s']['u3']['right'], self.cache).chars(): |
| yield c |
| else: |
| is_inline = (flags & self.stc.INLINE_CHARS_BIT) != 0 |
| is_latin1 = (flags & self.stc.LATIN1_CHARS_BIT) != 0 |
| if is_inline: |
| if is_latin1: |
| chars = d['inlineStorageLatin1'] |
| else: |
| chars = d['inlineStorageTwoByte'] |
| else: |
| if is_latin1: |
| chars = d['s']['u2']['nonInlineCharsLatin1'] |
| else: |
| chars = d['s']['u2']['nonInlineCharsTwoByte'] |
| for i in range(int(length)): |
| yield chars[i] |
| |
| def to_string(self): |
| s = u'' |
| for c in self.chars(): |
| s += chr(c) |
| return s |
| |
| @ptr_pretty_printer("JSAtom") |
| class JSAtomPtr(Common): |
| def to_string(self): |
| return self.value.cast(self.cache.JSString_ptr_t) |