Bug 840723: Print js::Rooted<jsid> and related classes correctly in non-DEBUG builds. r=sfink

This commit is contained in:
Jim Blandy 2013-02-15 21:27:44 -08:00
parent bfdfc16b12
commit f0929a3045
5 changed files with 65 additions and 6 deletions

View File

@ -18,17 +18,38 @@ class Common(object):
# the template member holds the referent directly.
handle = False
def __init__(self, value, cache):
# Initialize a pretty-printer for |value|, using |cache|.
#
# If given, |content_printer| is a pretty-printer constructor to use for
# this handle/root/etc.'s referent. Usually, we can just omit this argument
# and let GDB choose a pretty-printer for the referent given its type, but
# when the referent is a typedef of an integral type (say, |jsid| in a
# non-|DEBUG| build), the GNU toolchain (at least) loses the typedef name,
# and all we know about the referent is its fundamental integer type ---
# |js::Rooted<jsid>|, for example, appears in GDB as |js::Rooted<long>| ---
# and we are left with no way to choose a meaningful pretty-printer based on
# the type of the referent alone. However, because we know that the only
# integer type for which |js::Rooted| is likely to be instantiated is
# |jsid|, we *can* register a pretty-printer constructor for the full
# instantiation |js::Rooted<long>|. That constructor creates a |js::Rooted|
# pretty-printer, and explicitly specifies the constructor for the referent,
# using this initializer's |content_printer| argument.
def __init__(self, value, cache, content_printer=None):
self.value = value
self.cache = cache
self.content_printer = content_printer
def to_string(self):
ptr = self.value[self.member]
if self.handle:
ptr = ptr.dereference()
# As of 2012-11, GDB suppresses printing pointers in replacement values;
# see http://sourceware.org/ml/gdb/2012-11/msg00055.html That means that
# simply returning the 'ptr' member won't work. Instead, just invoke
# GDB's formatter ourselves.
return str(ptr)
if self.content_printer:
return self.content_printer(ptr, self.cache).to_string()
else:
# As of 2012-11, GDB suppresses printing pointers in replacement
# values; see http://sourceware.org/ml/gdb/2012-11/msg00055.html
# That means that simply returning the 'ptr' member won't work.
# Instead, just invoke GDB's formatter ourselves.
return str(ptr)
@template_pretty_printer("js::Rooted")
class Rooted(Common):

View File

@ -2,6 +2,7 @@
import gdb
import mozilla.prettyprinters
import mozilla.Root
from mozilla.prettyprinters import pretty_printer
@ -52,3 +53,15 @@ class jsid(object):
else:
body = "<unrecognized>"
return '$jsid(%s)' % (body,)
# Hard-code the referent type pretty-printer for jsid roots and handles.
# See the comment for mozilla.Root.Common.__init__.
@pretty_printer('js::Rooted<long>')
def RootedJSID(value, cache):
return mozilla.Root.Rooted(value, cache, jsid)
@pretty_printer('JS::Handle<long>')
def HandleJSID(value, cache):
return mozilla.Root.Handle(value, cache, jsid)
@pretty_printer('JS::MutableHandle<long>')
def MutableHandleJSID(value, cache):
return mozilla.Root.MutableHandle(value, cache, jsid)

View File

@ -10,6 +10,9 @@ FRAGMENT(Root, null) {
void callee(JS::Handle<JSObject *> obj, JS::MutableHandle<JSObject *> mutableObj)
{
// Prevent the linker from unifying this function with others that are
// equivalent in machine code but not type.
fprintf(stderr, "Called " __FILE__ ":callee\n");
breakpoint();
}

View File

@ -17,3 +17,20 @@ FRAGMENT(jsid, simple) {
(void) void_id;
(void) object_id;
}
void
jsid_handles(JS::Handle<jsid> jsid_handle,
JS::MutableHandle<jsid> mutable_jsid_handle)
{
// Prevent the linker from unifying this function with others that are
// equivalent in machine code but not type.
fprintf(stderr, "Called " __FILE__ ":jsid_handles\n");
breakpoint();
}
FRAGMENT(jsid, handles) {
js::Rooted<JSString *> string(cx, JS_NewStringCopyZ(cx, "shovel"));
js::Rooted<JSString *> interned(cx, JS_InternJSString(cx, string));
js::Rooted<jsid> string_id(cx, INTERNED_STRING_TO_JSID(cx, interned));
jsid_handles(string_id, &string_id);
}

View File

@ -8,3 +8,8 @@ assert_pretty('string_id', '$jsid("moon")')
assert_pretty('int_id', '$jsid(1729)')
assert_pretty('void_id', 'JSID_VOID')
assert_pretty('object_id', '$jsid((JSObject *) [object global] delegate)')
run_fragment('jsid.handles')
assert_pretty('jsid_handle', '$jsid("shovel")')
assert_pretty('mutable_jsid_handle', '$jsid("shovel")')