summaryrefslogtreecommitdiffstats
path: root/js/src/gdb/mozilla/JSString.py
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/gdb/mozilla/JSString.py')
-rw-r--r--js/src/gdb/mozilla/JSString.py105
1 files changed, 105 insertions, 0 deletions
diff --git a/js/src/gdb/mozilla/JSString.py b/js/src/gdb/mozilla/JSString.py
new file mode 100644
index 0000000000..3c758e0352
--- /dev/null
+++ b/js/src/gdb/mozilla/JSString.py
@@ -0,0 +1,105 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# Pretty-printers for SpiderMonkey strings.
+
+import gdb
+
+import mozilla.prettyprinters
+from mozilla.CellHeader import get_header_length_and_flags
+from mozilla.prettyprinters import ptr_pretty_printer
+
+try:
+ chr(10000) # UPPER RIGHT PENCIL
+except ValueError: # 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__)
+
+
+class JSStringTypeCache(object):
+ # Cache information about the JSString type for this objfile.
+ def __init__(self, cache):
+ dummy = gdb.Value(0).cast(cache.JSString_ptr_t)
+ self.ATOM_BIT = dummy["ATOM_BIT"]
+ self.LINEAR_BIT = dummy["LINEAR_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, flags = get_header_length_and_flags(self.value, self.cache)
+
+ corrupt = {
+ 0x2F2F2F2F: "JS_FRESH_NURSERY_PATTERN",
+ 0x2B2B2B2B: "JS_SWEPT_NURSERY_PATTERN",
+ 0xE5E5E5E5: "jemalloc freed memory",
+ }.get(flags & 0xFFFFFFFF)
+ if corrupt:
+ for ch in "<CORRUPT:%s>" % corrupt:
+ yield ch
+ return
+ is_rope = (flags & self.stc.LINEAR_BIT) == 0
+ 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, maxlen=200):
+ s = ""
+ invalid_chars_allowed = 2
+ for c in self.chars():
+ if len(s) >= maxlen:
+ s += "..."
+ break
+
+ try:
+ # Convert from gdb.Value to string.
+ s += chr(c)
+ except ValueError:
+ if invalid_chars_allowed == 0:
+ s += "<TOO_MANY_INVALID_CHARS>"
+ break
+ else:
+ invalid_chars_allowed -= 1
+ s += "\\x%04x" % (c & 0xFFFF)
+ return s
+
+
+@ptr_pretty_printer("JSAtom")
+class JSAtomPtr(Common):
+ def to_string(self):
+ return self.value.cast(self.cache.JSString_ptr_t)