Title: [239651] trunk/Tools
Revision
239651
Author
[email protected]
Date
2019-01-04 21:03:29 -0800 (Fri, 04 Jan 2019)

Log Message

[lldb-webkit]: Add support for pretty-printing raw bitmask types
https://bugs.webkit.org/show_bug.cgi?id=193024

Reviewed by Jer Noble.

Add support infrastructure to pretty-print a raw bitmask type. Included is a pretty-printer
for the bitmask type WebEventFlags as an example.

Exposed a new function lldb_webkit.addSummaryAndSyntheticFormattersForRawBitmaskType()
that can be used to register summary and synthetic child formatters for a bitmask type.
For example, consider the following enum and bitmask typedefs:

typedef enum {
    A = 1 << 0,
    B = 1 << 1,
    C = 1 << 2,
} SpecialFlagValues;
typedef unsigned SpecialFlags;

To teach lldb-webkit how to pretty print SpecialFlags types, add the following code inside
__lldb_init_module():

    addSummaryAndSyntheticFormattersForRawBitmaskType(debugger, "SpecialFlags", {
            1 << 0: "A",
            1 << 1: "B",
            1 << 2: "C",
    })

* lldb/lldb_webkit.py:
(addSummaryAndSyntheticFormattersForRawBitmaskType):
(addSummaryAndSyntheticFormattersForRawBitmaskType.GeneratedRawBitmaskProvider):
(addSummaryAndSyntheticFormattersForRawBitmaskType.raw_bitmask_summary_provider):
(addSummaryAndSyntheticFormattersForRawBitmaskType.lldb_webkit):
A convenience function to dynamically creaste a synthetic formatter class and summary
string function for the specified bitmask type and enumerator value to name map. This
function register the dynamically created class and function with LLDB.

(__lldb_init_module):
(FlagEnumerationProvider):
(FlagEnumerationProvider._enumerator_value_to_name_map):
(FlagEnumerationProvider._bitmask):
(FlagEnumerationProvider._update):
(FlagEnumerationProvider.has_children):
(FlagEnumerationProvider.num_children):
(FlagEnumerationProvider.get_child_index):
(FlagEnumerationProvider.get_child_at_index):
(FlagEnumerationProvider.update):
Extract out provider logic from WTFOptionSetProvider into a base class that can be shared.

(WTFOptionSetProvider):
(WTFOptionSetProvider._enumerator_value_to_name_map):
(WTFOptionSetProvider._bitmask):
(WTFOptionSetProvider._update):
Write in terms of the base class.

(RawBitmaskProviderBase):
(RawBitmaskProviderBase._enumerator_value_to_name_map):
(RawBitmaskProviderBase._bitmask):
Added. Base synthetic formatter class for a raw bitmask type. Derived classes are expected to
override the class variable ENUMERATOR_VALUE_TO_NAME_MAP with a dictionary of the form:
{
    1 << 0: "A",
    1 << 1: "B",
    1 << 2: "C",
}
It is not necessary to instantiate such a derived class directory. Instead use the convenience
function addSummaryAndSyntheticFormattersForRawBitmaskType.

(WTFOptionSetProvider.has_children): Deleted.
(WTFOptionSetProvider.num_children): Deleted.
(WTFOptionSetProvider.get_child_index): Deleted.
(WTFOptionSetProvider.get_child_at_index): Deleted.
(WTFOptionSetProvider.update): Deleted.

Modified Paths

Diff

Modified: trunk/Tools/ChangeLog (239650 => 239651)


--- trunk/Tools/ChangeLog	2019-01-05 02:30:03 UTC (rev 239650)
+++ trunk/Tools/ChangeLog	2019-01-05 05:03:29 UTC (rev 239651)
@@ -1,3 +1,79 @@
+2019-01-04  Daniel Bates  <[email protected]>
+
+        [lldb-webkit]: Add support for pretty-printing raw bitmask types
+        https://bugs.webkit.org/show_bug.cgi?id=193024
+
+        Reviewed by Jer Noble.
+
+        Add support infrastructure to pretty-print a raw bitmask type. Included is a pretty-printer
+        for the bitmask type WebEventFlags as an example.
+
+        Exposed a new function lldb_webkit.addSummaryAndSyntheticFormattersForRawBitmaskType()
+        that can be used to register summary and synthetic child formatters for a bitmask type.
+        For example, consider the following enum and bitmask typedefs:
+
+        typedef enum {
+            A = 1 << 0,
+            B = 1 << 1,
+            C = 1 << 2,
+        } SpecialFlagValues;
+        typedef unsigned SpecialFlags;
+
+        To teach lldb-webkit how to pretty print SpecialFlags types, add the following code inside
+        __lldb_init_module():
+
+            addSummaryAndSyntheticFormattersForRawBitmaskType(debugger, "SpecialFlags", {
+                    1 << 0: "A",
+                    1 << 1: "B",
+                    1 << 2: "C",
+            })
+
+        * lldb/lldb_webkit.py:
+        (addSummaryAndSyntheticFormattersForRawBitmaskType):
+        (addSummaryAndSyntheticFormattersForRawBitmaskType.GeneratedRawBitmaskProvider):
+        (addSummaryAndSyntheticFormattersForRawBitmaskType.raw_bitmask_summary_provider):
+        (addSummaryAndSyntheticFormattersForRawBitmaskType.lldb_webkit):
+        A convenience function to dynamically creaste a synthetic formatter class and summary
+        string function for the specified bitmask type and enumerator value to name map. This
+        function register the dynamically created class and function with LLDB.
+
+        (__lldb_init_module):
+        (FlagEnumerationProvider):
+        (FlagEnumerationProvider._enumerator_value_to_name_map):
+        (FlagEnumerationProvider._bitmask):
+        (FlagEnumerationProvider._update):
+        (FlagEnumerationProvider.has_children):
+        (FlagEnumerationProvider.num_children):
+        (FlagEnumerationProvider.get_child_index):
+        (FlagEnumerationProvider.get_child_at_index):
+        (FlagEnumerationProvider.update):
+        Extract out provider logic from WTFOptionSetProvider into a base class that can be shared.
+
+        (WTFOptionSetProvider):
+        (WTFOptionSetProvider._enumerator_value_to_name_map):
+        (WTFOptionSetProvider._bitmask):
+        (WTFOptionSetProvider._update):
+        Write in terms of the base class.
+
+        (RawBitmaskProviderBase):
+        (RawBitmaskProviderBase._enumerator_value_to_name_map):
+        (RawBitmaskProviderBase._bitmask):
+        Added. Base synthetic formatter class for a raw bitmask type. Derived classes are expected to
+        override the class variable ENUMERATOR_VALUE_TO_NAME_MAP with a dictionary of the form:
+        {
+            1 << 0: "A",
+            1 << 1: "B",
+            1 << 2: "C",
+        }
+        It is not necessary to instantiate such a derived class directory. Instead use the convenience
+        function addSummaryAndSyntheticFormattersForRawBitmaskType.
+
+        (WTFOptionSetProvider.has_children): Deleted.
+        (WTFOptionSetProvider.num_children): Deleted.
+        (WTFOptionSetProvider.get_child_index): Deleted.
+        (WTFOptionSetProvider.get_child_at_index): Deleted.
+        (WTFOptionSetProvider.update): Deleted.
+
 2019-01-04  Aakash Jain  <[email protected]>
 
         [ews-build] Add build step to validate the patch before processing it

Modified: trunk/Tools/lldb/lldb_webkit.py (239650 => 239651)


--- trunk/Tools/lldb/lldb_webkit.py	2019-01-05 02:30:03 UTC (rev 239650)
+++ trunk/Tools/lldb/lldb_webkit.py	2019-01-05 05:03:29 UTC (rev 239651)
@@ -33,6 +33,26 @@
 import string
 import struct
 
+
+def addSummaryAndSyntheticFormattersForRawBitmaskType(debugger, type_name, enumerator_value_to_name_map):
+    class GeneratedRawBitmaskProvider(RawBitmaskProviderBase):
+        ENUMERATOR_VALUE_TO_NAME_MAP = enumerator_value_to_name_map.copy()
+
+    def raw_bitmask_summary_provider(valobj, dict):
+        provider = GeneratedRawBitmaskProvider(valobj, dict)
+        return "{ size = %d }" % provider.size
+
+    # Add the provider class and summary function to the global scope so that LLDB
+    # can find them.
+    synthetic_provider_class_name = type_name + 'Provider'
+    summary_provider_function_name = type_name + '_SummaryProvider'
+    globals()[synthetic_provider_class_name] = GeneratedRawBitmaskProvider
+    globals()[summary_provider_function_name] = raw_bitmask_summary_provider
+
+    debugger.HandleCommand('type summary add --expand -F lldb_webkit.%s "%s"' % (summary_provider_function_name, type_name))
+    debugger.HandleCommand('type synthetic add %s --python-class lldb_webkit.%s' % (type_name, synthetic_provider_class_name))
+
+
 def __lldb_init_module(debugger, dict):
     debugger.HandleCommand('command script add -f lldb_webkit.btjs btjs')
     debugger.HandleCommand('type summary add --expand -F lldb_webkit.WTFString_SummaryProvider WTF::String')
@@ -71,7 +91,19 @@
     debugger.HandleCommand('type synthetic add -x "^WTF::HashTable<.+>$" --python-class lldb_webkit.WTFHashTableProvider')
     debugger.HandleCommand('type synthetic add -x "^WTF::OptionSet<.+>$" --python-class lldb_webkit.WTFOptionSetProvider')
 
+    addSummaryAndSyntheticFormattersForRawBitmaskType(debugger, "WebEventFlags", {
+        0x00010000: "WebEventFlagMaskLeftCommandKey",
+        0x00020000: "WebEventFlagMaskLeftShiftKey",
+        0x00040000: "WebEventFlagMaskLeftCapsLockKey",
+        0x00080000: "WebEventFlagMaskLeftOptionKey",
+        0x00100000: "WebEventFlagMaskLeftControlKey",
+        0x00800000: "WebEventFlagMaskRightControlKey",
+        0x00200000: "WebEventFlagMaskRightShiftKey",
+        0x00400000: "WebEventFlagMaskRightOptionKey",
+        0x01000000: "WebEventFlagMaskRightCommandKey",
+    })
 
+
 def WTFString_SummaryProvider(valobj, dict):
     provider = WTFStringProvider(valobj, dict)
     return "{ length = %d, contents = '%s' }" % (provider.get_length(), provider.to_string())
@@ -697,11 +729,24 @@
         return WebCoreFrameProvider(frame_ptr, dict())
 
 
-class WTFOptionSetProvider:
+class FlagEnumerationProvider(object):
     def __init__(self, valobj, internal_dict):
         self.valobj = valobj
         self.update()
 
+    # Subclasses must override this to return a dictionary that maps emumerator values to names.
+    def _enumerator_value_to_name_map(self):
+        pass
+
+    # Subclasses must override this to return the bitmask.
+    def _bitmask(self):
+        pass
+
+    # Subclasses can override this to perform any computations when LLDB needs to refresh
+    # this provider.
+    def _update(self):
+        pass
+
     def has_children(self):
         return bool(self._elements)
 
@@ -723,21 +768,17 @@
         return None
 
     def update(self):
-        self.storage = self.valobj.GetChildMemberWithName('m_storage')  # May be an invalid value.
+        self._update()
+
         self._elements = []
         self.size = 0
 
-        template_argument_sbType = self.valobj.GetType().GetTemplateArgumentType(0)
-        enumerator_value_to_name_map = {}
-        for sbTypeEnumMember in template_argument_sbType.get_enum_members_array():
-            enumerator_value = sbTypeEnumMember.GetValueAsUnsigned()
-            if enumerator_value not in enumerator_value_to_name_map:
-                enumerator_value_to_name_map[enumerator_value] = sbTypeEnumMember.GetName()
+        enumerator_value_to_name_map = self._enumerator_value_to_name_map()
         if not enumerator_value_to_name_map:
             return
 
         bitmask_with_all_options_set = sum(enumerator_value_to_name_map)
-        bitmask = self.storage.GetValueAsUnsigned(0)
+        bitmask = self._bitmask()
         if bitmask > bitmask_with_all_options_set:
             return  # Since this is an invalid value, return so the raw hex form is written out.
 
@@ -752,6 +793,33 @@
         self.size = len(elements)
 
 
+class WTFOptionSetProvider(FlagEnumerationProvider):
+    def _enumerator_value_to_name_map(self):
+        template_argument_sbType = self.valobj.GetType().GetTemplateArgumentType(0)
+        enumerator_value_to_name_map = {}
+        for sbTypeEnumMember in template_argument_sbType.get_enum_members_array():
+            enumerator_value = sbTypeEnumMember.GetValueAsUnsigned()
+            if enumerator_value not in enumerator_value_to_name_map:
+                enumerator_value_to_name_map[enumerator_value] = sbTypeEnumMember.GetName()
+        return enumerator_value_to_name_map
+
+    def _bitmask(self):
+        return self.storage.GetValueAsUnsigned(0)
+
+    def _update(self):
+        self.storage = self.valobj.GetChildMemberWithName('m_storage')  # May be an invalid value.
+
+
+class RawBitmaskProviderBase(FlagEnumerationProvider):
+    ENUMERATOR_VALUE_TO_NAME_MAP = {}
+
+    def _enumerator_value_to_name_map(self):
+        return self.ENUMERATOR_VALUE_TO_NAME_MAP
+
+    def _bitmask(self):
+        return self.valobj.GetValueAsUnsigned(0)
+
+
 class WTFVectorProvider:
     def __init__(self, valobj, internal_dict):
         self.valobj = valobj
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to