# mozilla/prettyprinters.py --- infrastructure for SpiderMonkey's auto-loaded pretty-printers.

import gdb
import re

# Decorators for declaring pretty-printers.
#
# In each case, the decoratee should be a SpiderMonkey-style pretty-printer
# factory, taking both a gdb.Value instance and a TypeCache instance as
# arguments; see TypeCache, below.

# Check that |fn| hasn't been registered as a pretty-printer under some
# other name already. (The 'enabled' flags used by GDB's
# 'enable/disable/info pretty-printer' commands are simply stored as
# properties of the function objects themselves, so a single function
# object can't carry the 'enabled' flags for two different printers.)
def check_for_reused_pretty_printer(fn):
    if hasattr(fn, 'enabled'):
        raise RuntimeError, ("pretty-printer function %r registered more than once" % fn)

# a dictionary mapping gdb.Type tags to pretty-printer functions.
printers_by_tag = {}

# A decorator: add the decoratee as a pretty-printer lookup function for types
# named |type_name|.
def pretty_printer(type_name):
    def add(fn):
        check_for_reused_pretty_printer(fn)
        add_to_subprinter_list(fn, type_name)
        printers_by_tag[type_name] = fn
        return fn
    return add

# a dictionary mapping gdb.Type tags to pretty-printer functions for pointers to
# that type.
ptr_printers_by_tag = {}

# A decorator: add the decoratee as a pretty-printer lookup function for
# pointers to types named |type_name|.
def ptr_pretty_printer(type_name):
    def add(fn):
        check_for_reused_pretty_printer(fn)
        add_to_subprinter_list(fn, "ptr-to-" + type_name)
        ptr_printers_by_tag[type_name] = fn
        return fn
    return add

# a dictionary mapping gdb.Type tags to pretty-printer functions for
# references to that type.
ref_printers_by_tag = {}

# A decorator: add the decoratee as a pretty-printer lookup function for
# references to instances of types named |type_name|.
def ref_pretty_printer(type_name):
    def add(fn):
        check_for_reused_pretty_printer(fn)
        add_to_subprinter_list(fn, "ref-to-" + type_name)
        ref_printers_by_tag[type_name] = fn
        return fn
    return add

# a dictionary mapping the template name portion of gdb.Type tags to
# pretty-printer functions for instantiations of that template.
template_printers_by_tag = {}

# A decorator: add the decoratee as a pretty-printer lookup function for
# instantiations of templates named |template_name|.
def template_pretty_printer(template_name):
    def add(fn):
        check_for_reused_pretty_printer(fn)
        add_to_subprinter_list(fn, 'instantiations-of-' + template_name)
        template_printers_by_tag[template_name] = fn
        return fn
    return add

# A list of (REGEXP, PRINTER) pairs, such that if REGEXP (a RegexObject)
# matches the result of converting a gdb.Value's type to a string, then
# PRINTER is a pretty-printer lookup function that will probably like that
# value.
printers_by_regexp = []

# A decorator: add the decoratee as a pretty-printer factory for types
# that, when converted to a string, match |pattern|. Use |name| as the
# pretty-printer's name, when listing, enabling and disabling.
def pretty_printer_for_regexp(pattern, name):
    compiled = re.compile(pattern)
    def add(fn):
        check_for_reused_pretty_printer(fn)
        add_to_subprinter_list(fn, name)
        printers_by_regexp.append((compiled, fn))
        return fn
    return add

# Forget all pretty-printer lookup functions defined in the module name
# |module_name|, if any exist. Use this at the top of each pretty-printer
# module like this:
#
#   clear_module_printers(__name__)
def clear_module_printers(module_name):
    global printers_by_tag, ptr_printers_by_tag, ref_printers_by_tag
    global template_printers_by_tag, printers_by_regexp

    # Remove all pretty-printers defined in the module named |module_name|
    # from d.
    def clear_dictionary(d):
        # Walk the dictionary, building a list of keys whose entries we
        # should remove. (It's not safe to delete entries from a dictionary
        # while we're iterating over it.)
        to_delete = []
        for (k, v) in d.iteritems():
            if v.__module__ == module_name:
                to_delete.append(k)
                remove_from_subprinter_list(v)
        for k in to_delete:
            del d[k]

    clear_dictionary(printers_by_tag)
    clear_dictionary(ptr_printers_by_tag)
    clear_dictionary(ref_printers_by_tag)
    clear_dictionary(template_printers_by_tag)

    # Iterate over printers_by_regexp, deleting entries from the given module.
    new_list = []
    for p in printers_by_regexp:
        if p.__module__ == module_name:
            remove_from_subprinter_list(p)
        else:
            new_list.append(p)
    printers_by_regexp = new_list

# Our subprinters array. The 'subprinters' attributes of all lookup
# functions returned by lookup_for_objfile point to this array instance,
# which we mutate as subprinters are added and removed.
subprinters = []

# Set up the 'name' and 'enabled' attributes on |subprinter|, and add it to our
# list of all SpiderMonkey subprinters.
def add_to_subprinter_list(subprinter, name):
    subprinter.name = name
    subprinter.enabled = True
    subprinters.append(subprinter)

# Remove |subprinter| from our list of all SpiderMonkey subprinters.
def remove_from_subprinter_list(subprinter):
    subprinters.remove(subprinter)

# An exception class meaning, "This objfile has no SpiderMonkey in it."
class NotSpiderMonkeyObjfileError(TypeError):
    pass

# TypeCache: a cache for frequently used information about an objfile.
#
# When a new SpiderMonkey objfile is loaded, we construct an instance of
# this class for it. Then, whenever we construct a pretty-printer for some
# gdb.Value, we also pass, as a second argument, the TypeCache for the
# objfile to which that value's type belongs.
#
# if objfile doesn't seem to have SpiderMonkey code in it, the constructor
# raises NotSpiderMonkeyObjfileError.
#
# Pretty-printer modules may add attributes to this to hold their own
# cached values. Such attributes should be named mod_NAME, where the module
# is named mozilla.NAME; for example, mozilla.JSString should store its
# metadata in the TypeCache's mod_JSString attribute.
class TypeCache(object):
    def __init__(self, objfile):
        self.objfile = objfile

        # Unfortunately, the Python interface doesn't allow us to specify
        # the objfile in whose scope lookups should occur. But simply
        # knowing that we need to lookup the types afresh is probably
        # enough.
        self.void_t = gdb.lookup_type('void')
        self.void_ptr_t = self.void_t.pointer()
        try:
            self.JSString_ptr_t = gdb.lookup_type('JSString').pointer()
            self.JSObject_ptr_t = gdb.lookup_type('JSObject').pointer()
        except gdb.error:
            raise NotSpiderMonkeyObjfileError

        self.mod_JSString = None
        self.mod_JSObject = None
        self.mod_jsval = None

# Yield a series of all the types that |t| implements, by following typedefs
# and iterating over base classes. Specifically:
# - |t| itself is the first value yielded.
# - If we yield a typedef, we later yield its definition.
# - If we yield a type with base classes, we later yield those base classes.
# - If we yield a type with some base classes that are typedefs,
#   we yield all the type's base classes before following the typedefs.
#   (Actually, this never happens, because G++ doesn't preserve the typedefs in
#   the DWARF.)
#
# This is a hokey attempt to order the implemented types by meaningfulness when
# pretty-printed. Perhaps it is entirely misguided, and we should actually
# collect all applicable pretty-printers, and then use some ordering on the
# pretty-printers themselves.
#
# We may yield a type more than once (say, if it appears more than once in the
# class hierarchy).
def implemented_types(t):

    # Yield all types that follow |t|.
    def followers(t):
        if t.code == gdb.TYPE_CODE_TYPEDEF:
            yield t.target()
            for t2 in followers(t.target()): yield t2
        elif t.code == gdb.TYPE_CODE_STRUCT:
            base_classes = []
            for f in t.fields():
                if f.is_base_class:
                    yield f.type
                    base_classes.append(f.type)
            for b in base_classes:
                for t2 in followers(b): yield t2

    yield t
    for t2 in followers(t): yield t2

template_regexp = re.compile("([\w_:]+)<")

# Construct and return a pretty-printer lookup function for objfile, or
# return None if the objfile doesn't contain SpiderMonkey code
# (specifically, definitions for SpiderMonkey types).
def lookup_for_objfile(objfile):
    # Create a type cache for this objfile.
    try:
        cache = TypeCache(objfile)
    except NotSpiderMonkeyObjfileError:
        if gdb.parameter("verbose"):
            gdb.write("objfile '%s' has no SpiderMonkey code; not registering pretty-printers\n"
                      % (objfile.filename,))
        return None

    # Return a pretty-printer for |value|, if we have one. This is the lookup
    # function object we place in each gdb.Objfile's pretty-printers list, so it
    # carries |name|, |enabled|, and |subprinters| attributes.
    def lookup(value):
        # If |table| has a pretty-printer for |tag|, apply it to |value|.
        def check_table(table, tag):
            if tag in table:
                f = table[tag]
                if f.enabled:
                    return f(value, cache)
            return None

        def check_table_by_type_name(table, t):
            if t.code == gdb.TYPE_CODE_TYPEDEF:
                return check_table(table, str(t))
            elif t.code == gdb.TYPE_CODE_STRUCT and t.tag:
                return check_table(table, t.tag)
            else:
                return None

        for t in implemented_types(value.type):
            if t.code == gdb.TYPE_CODE_PTR:
                for t2 in implemented_types(t.target()):
                    p = check_table_by_type_name(ptr_printers_by_tag, t2)
                    if p: return p
            elif t.code == gdb.TYPE_CODE_REF:
                for t2 in implemented_types(t.target()):
                    p = check_table_by_type_name(ref_printers_by_tag, t2)
                    if p: return p
            else:
                p = check_table_by_type_name(printers_by_tag, t)
                if p: return p
                if t.code == gdb.TYPE_CODE_STRUCT and t.tag:
                    m = template_regexp.match(t.tag)
                    if m:
                        p = check_table(template_printers_by_tag, m.group(1))
                        if p: return p

        # Failing that, look for a printer in printers_by_regexp. We have
        # to scan the whole list, so regexp printers should be used
        # sparingly.
        s = str(value.type)
        for (r, f) in printers_by_regexp:
            if f.enabled:
                m = r.match(s)
                if m:
                    p = f(value, cache)
                    if p: return p

        # No luck.
        return None

    # Give |lookup| the attributes expected of a pretty-printer with
    # subprinters, for enabling and disabling.
    lookup.name = "SpiderMonkey"
    lookup.enabled = True
    lookup.subprinters = subprinters

    return lookup

# A base class for pretty-printers for pointer values that handles null
# pointers, by declining to construct a pretty-printer for them at all.
# Derived classes may simply assume that self.value is non-null.
#
# To help share code, this class can also be used with reference types.
#
# This class provides the following methods, which subclasses are free to
# override:
#
# __init__(self, value, cache): Save value and cache as properties by those names
#     on the instance.
#
# to_string(self): format the type's name and address, as GDB would, and then
#     call a 'summary' method (which the subclass must define) to produce a
#     description of the referent.
#
#     Note that pretty-printers returning a 'string' display hint must not use
#     this default 'to_string' method, as GDB will take everything it returns,
#     including the type name and address, as string contents.
class Pointer(object):
    def __new__(cls, value, cache):
        # Don't try to provide pretty-printers for NULL pointers.
        if value.type.strip_typedefs().code == gdb.TYPE_CODE_PTR and value == 0:
            return None
        return super(Pointer, cls).__new__(cls)

    def __init__(self, value, cache):
        self.value = value
        self.cache = cache

    def to_string(self):
        # See comment above.
        assert not hasattr(self, 'display_hint') or self.display_hint() != 'string'
        concrete_type = self.value.type.strip_typedefs()
        if concrete_type.code == gdb.TYPE_CODE_PTR:
            address = self.value.cast(self.cache.void_ptr_t)
        elif concrete_type.code == gdb.TYPE_CODE_REF:
            address = '@' + str(self.value.address.cast(self.cache.void_ptr_t))
        else:
            assert not "mozilla.prettyprinters.Pointer applied to bad value type"
        try:
            summary = self.summary()
        except gdb.MemoryError as r:
            summary = str(r)
        v = '(%s) %s %s' % (self.value.type, address, summary)
        return v

    def summary(self):
        raise NotImplementedError

field_enum_value = None

# Given |t|, a gdb.Type instance representing an enum type, return the
# numeric value of the enum value named |name|.
#
# Pre-2012-4-18 versions of GDB store the value of an enum member on the
# gdb.Field's 'bitpos' attribute; later versions store it on the 'enumval'
# attribute. This function retrieves the value from either.
def enum_value(t, name):
    global field_enum_value
    f = t[name]
    # Monkey-patching is a-okay in polyfills! Just because.
    if not field_enum_value:
        if hasattr(f, 'enumval'):
            field_enum_value = lambda f: f.enumval
        else:
            field_enum_value = lambda f: f.bitpos
    return field_enum_value(f)
