brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · cc8778b Raw
168 lines · python
1"""2This is the llvm::Optional data formatter from llvm/utils/lldbDataFormatters.py3with the implementation replaced by bytecode.4"""5 6from __future__ import annotations7from formatter_bytecode import *8import lldb9 10 11def __lldb_init_module(debugger, internal_dict):12    debugger.HandleCommand(13        "type synthetic add -w llvm "14        f"-l {__name__}.MyOptionalSynthProvider "15        '-x "^MyOptional<.+>$"'16    )17    debugger.HandleCommand(18        "type summary add -w llvm "19        f"-e -F {__name__}.MyOptionalSummaryProvider "20        '-x "^MyOptional<.+>$"'21    )22 23 24def stringify(bytecode: bytearray) -> str:25    s = ""26    in_hex = False27    for b in bytecode:28        if (b < 32 or b > 127 or chr(b) in ['"', "`", "'"]) or (29            in_hex30            and chr(b).lower()31            in [32                "a",33                "b",34                "c",35                "d",36                "e",37                "f",38                "0",39                "1",40                "2",41                "3",42                "4",43                "5",44                "6",45                "7",46                "8",47                "9",48            ]49        ):50            s += r"\x" + hex(b)[2:]51            in_hex = True52        else:53            s += chr(b)54            in_hex = False55    return s56 57 58def evaluate(assembler: str, data: list):59    bytecode = compile(assembler)60    trace = True61    if trace:62        print(63            "Compiled to {0} bytes of bytecode:\n{1}".format(64                len(bytecode), stringify(bytecode)65            )66        )67    result = interpret(bytecode, [], data, False)  # trace)68    if trace:69        print("--> {0}".format(result))70    return result71 72 73# def GetOptionalValue(valobj):74#    storage = valobj.GetChildMemberWithName("Storage")75#    if not storage:76#        storage = valobj77#78#    failure = 279#    hasVal = storage.GetChildMemberWithName("hasVal").GetValueAsUnsigned(failure)80#    if hasVal == failure:81#        return "<could not read MyOptional>"82#83#    if hasVal == 0:84#        return None85#86#    underlying_type = storage.GetType().GetTemplateArgumentType(0)87#    storage = storage.GetChildMemberWithName("value")88#    return storage.Cast(underlying_type)89 90 91def MyOptionalSummaryProvider(valobj, internal_dict):92    #    val = GetOptionalValue(valobj)93    #    if val is None:94    #        return "None"95    #    if val.summary:96    #        return val.summary97    #    return val.GetValue()98    summary = ""99    summary += ' dup "Storage" @get_child_with_name call'  # valobj storage100    summary += " dup is_null ~ { swap } if drop"  # storage101    summary += ' dup "hasVal" @get_child_with_name call'  # storage obj(hasVal)102    summary += ' dup is_null { drop "<could not read MyOptional>" } {'103    summary += "   @get_value_as_unsigned call"  # storage int(hasVal)104    summary += '   0u = { "None" } {'105    summary += "     dup @get_type call"106    summary += "     0u @get_template_argument_type call"  # storage type107    summary += "     swap"  # type storage108    summary += '     "value" @get_child_with_name call'  # type value109    summary += "     swap @cast call"  # type(value)110    summary += '     dup is_null { "None" } {'111    summary += (112        "       dup @summary call dup @strlen call { @get_value call } { drop } ifelse"113    )114    summary += "     } ifelse"115    summary += "   } ifelse"116    summary += " } ifelse"117    return evaluate(summary, [valobj])118 119 120class MyOptionalSynthProvider:121    """Provides deref support to llvm::Optional<T>"""122 123    def __init__(self, valobj, internal_dict):124        self.valobj = valobj125 126    def num_children(self):127        # return self.valobj.num_children128        num_children = " @get_num_children call"129        return evaluate(num_children, [self.valobj])130 131    def get_child_index(self, name):132        # if name == "$$dereference$$":133        #    return self.valobj.num_children134        # return self.valobj.GetIndexOfChildWithName(name)135        get_child_index = ' dup "$$dereference$$" ='136        get_child_index += " { drop @get_num_children call } {"  # obj name137        get_child_index += "   @get_child_index call"  # index138        get_child_index += " } ifelse"139        return evaluate(get_child_index, [self.valobj, name])140 141    def get_child_at_index(self, index):142        # if index < self.valobj.num_children:143        #    return self.valobj.GetChildAtIndex(index)144        # return GetOptionalValue(self.valobj) or lldb.SBValue()145        get_child_at_index = " over over swap"  # obj index index obj146        get_child_at_index += " @get_num_children call"  # obj index index n147        get_child_at_index += " < { @get_child_at_index call } {"  # obj index148 149        get_opt_val = ' dup "Storage" @get_child_with_name call'  # valobj storage150        get_opt_val += " dup { swap } if drop"  # storage151        get_opt_val += ' dup "hasVal" @get_child_with_name call'  # storage152        get_opt_val += " @get_value_as_unsigned call"  # storage int(hasVal)153        get_opt_val += ' dup 2 = { drop "<could not read MyOptional>" } {'154        get_opt_val += '   0 = { "None" } {'155        get_opt_val += (156            "     dup @get_type call 0 @get_template_argument_type call"  # storage type157        )158        get_opt_val += "     swap"  # type storage159        get_opt_val += '     "value" @get_child_with_name call'  # type value160        get_opt_val += "     swap @cast call"  # type(value)161        get_opt_val += "   } ifelse"162        get_opt_val += " } ifelse"163 164        get_child_at_index += get_opt_val165        get_child_at_index += " } ifelse"166 167        return evaluate(get_child_at_index, [self.valobj, index])168