xref: /llvm-project/lldb/test/Shell/ScriptInterpreter/Python/Inputs/FormatterBytecode/formatter.py (revision fffe8c668461e73055182f229765cb7de908e295)
1*fffe8c66SAdrian Prantl"""
2*fffe8c66SAdrian PrantlThis is the llvm::Optional data formatter from llvm/utils/lldbDataFormatters.py
3*fffe8c66SAdrian Prantlwith the implementation replaced by bytecode.
4*fffe8c66SAdrian Prantl"""
5*fffe8c66SAdrian Prantl
6*fffe8c66SAdrian Prantlfrom __future__ import annotations
7*fffe8c66SAdrian Prantlfrom formatter_bytecode import *
8*fffe8c66SAdrian Prantlimport lldb
9*fffe8c66SAdrian Prantl
10*fffe8c66SAdrian Prantl
11*fffe8c66SAdrian Prantldef __lldb_init_module(debugger, internal_dict):
12*fffe8c66SAdrian Prantl    debugger.HandleCommand(
13*fffe8c66SAdrian Prantl        "type synthetic add -w llvm "
14*fffe8c66SAdrian Prantl        f"-l {__name__}.MyOptionalSynthProvider "
15*fffe8c66SAdrian Prantl        '-x "^MyOptional<.+>$"'
16*fffe8c66SAdrian Prantl    )
17*fffe8c66SAdrian Prantl    debugger.HandleCommand(
18*fffe8c66SAdrian Prantl        "type summary add -w llvm "
19*fffe8c66SAdrian Prantl        f"-e -F {__name__}.MyOptionalSummaryProvider "
20*fffe8c66SAdrian Prantl        '-x "^MyOptional<.+>$"'
21*fffe8c66SAdrian Prantl    )
22*fffe8c66SAdrian Prantl
23*fffe8c66SAdrian Prantl
24*fffe8c66SAdrian Prantldef stringify(bytecode: bytearray) -> str:
25*fffe8c66SAdrian Prantl    s = ""
26*fffe8c66SAdrian Prantl    in_hex = False
27*fffe8c66SAdrian Prantl    for b in bytecode:
28*fffe8c66SAdrian Prantl        if (b < 32 or b > 127 or chr(b) in ['"', "`", "'"]) or (
29*fffe8c66SAdrian Prantl            in_hex
30*fffe8c66SAdrian Prantl            and chr(b).lower()
31*fffe8c66SAdrian Prantl            in [
32*fffe8c66SAdrian Prantl                "a",
33*fffe8c66SAdrian Prantl                "b",
34*fffe8c66SAdrian Prantl                "c",
35*fffe8c66SAdrian Prantl                "d",
36*fffe8c66SAdrian Prantl                "e",
37*fffe8c66SAdrian Prantl                "f",
38*fffe8c66SAdrian Prantl                "0",
39*fffe8c66SAdrian Prantl                "1",
40*fffe8c66SAdrian Prantl                "2",
41*fffe8c66SAdrian Prantl                "3",
42*fffe8c66SAdrian Prantl                "4",
43*fffe8c66SAdrian Prantl                "5",
44*fffe8c66SAdrian Prantl                "6",
45*fffe8c66SAdrian Prantl                "7",
46*fffe8c66SAdrian Prantl                "8",
47*fffe8c66SAdrian Prantl                "9",
48*fffe8c66SAdrian Prantl            ]
49*fffe8c66SAdrian Prantl        ):
50*fffe8c66SAdrian Prantl            s += r"\x" + hex(b)[2:]
51*fffe8c66SAdrian Prantl            in_hex = True
52*fffe8c66SAdrian Prantl        else:
53*fffe8c66SAdrian Prantl            s += chr(b)
54*fffe8c66SAdrian Prantl            in_hex = False
55*fffe8c66SAdrian Prantl    return s
56*fffe8c66SAdrian Prantl
57*fffe8c66SAdrian Prantl
58*fffe8c66SAdrian Prantldef evaluate(assembler: str, data: list):
59*fffe8c66SAdrian Prantl    bytecode = compile(assembler)
60*fffe8c66SAdrian Prantl    trace = True
61*fffe8c66SAdrian Prantl    if trace:
62*fffe8c66SAdrian Prantl        print(
63*fffe8c66SAdrian Prantl            "Compiled to {0} bytes of bytecode:\n{1}".format(
64*fffe8c66SAdrian Prantl                len(bytecode), stringify(bytecode)
65*fffe8c66SAdrian Prantl            )
66*fffe8c66SAdrian Prantl        )
67*fffe8c66SAdrian Prantl    result = interpret(bytecode, [], data, False)  # trace)
68*fffe8c66SAdrian Prantl    if trace:
69*fffe8c66SAdrian Prantl        print("--> {0}".format(result))
70*fffe8c66SAdrian Prantl    return result
71*fffe8c66SAdrian Prantl
72*fffe8c66SAdrian Prantl
73*fffe8c66SAdrian Prantl# def GetOptionalValue(valobj):
74*fffe8c66SAdrian Prantl#    storage = valobj.GetChildMemberWithName("Storage")
75*fffe8c66SAdrian Prantl#    if not storage:
76*fffe8c66SAdrian Prantl#        storage = valobj
77*fffe8c66SAdrian Prantl#
78*fffe8c66SAdrian Prantl#    failure = 2
79*fffe8c66SAdrian Prantl#    hasVal = storage.GetChildMemberWithName("hasVal").GetValueAsUnsigned(failure)
80*fffe8c66SAdrian Prantl#    if hasVal == failure:
81*fffe8c66SAdrian Prantl#        return "<could not read MyOptional>"
82*fffe8c66SAdrian Prantl#
83*fffe8c66SAdrian Prantl#    if hasVal == 0:
84*fffe8c66SAdrian Prantl#        return None
85*fffe8c66SAdrian Prantl#
86*fffe8c66SAdrian Prantl#    underlying_type = storage.GetType().GetTemplateArgumentType(0)
87*fffe8c66SAdrian Prantl#    storage = storage.GetChildMemberWithName("value")
88*fffe8c66SAdrian Prantl#    return storage.Cast(underlying_type)
89*fffe8c66SAdrian Prantl
90*fffe8c66SAdrian Prantl
91*fffe8c66SAdrian Prantldef MyOptionalSummaryProvider(valobj, internal_dict):
92*fffe8c66SAdrian Prantl    #    val = GetOptionalValue(valobj)
93*fffe8c66SAdrian Prantl    #    if val is None:
94*fffe8c66SAdrian Prantl    #        return "None"
95*fffe8c66SAdrian Prantl    #    if val.summary:
96*fffe8c66SAdrian Prantl    #        return val.summary
97*fffe8c66SAdrian Prantl    #    return val.GetValue()
98*fffe8c66SAdrian Prantl    summary = ""
99*fffe8c66SAdrian Prantl    summary += ' dup "Storage" @get_child_with_name call'  # valobj storage
100*fffe8c66SAdrian Prantl    summary += " dup is_null ~ { swap } if drop"  # storage
101*fffe8c66SAdrian Prantl    summary += ' dup "hasVal" @get_child_with_name call'  # storage obj(hasVal)
102*fffe8c66SAdrian Prantl    summary += ' dup is_null { drop "<could not read MyOptional>" } {'
103*fffe8c66SAdrian Prantl    summary += "   @get_value_as_unsigned call"  # storage int(hasVal)
104*fffe8c66SAdrian Prantl    summary += '   0u = { "None" } {'
105*fffe8c66SAdrian Prantl    summary += "     dup @get_type call"
106*fffe8c66SAdrian Prantl    summary += "     0u @get_template_argument_type call"  # storage type
107*fffe8c66SAdrian Prantl    summary += "     swap"  # type storage
108*fffe8c66SAdrian Prantl    summary += '     "value" @get_child_with_name call'  # type value
109*fffe8c66SAdrian Prantl    summary += "     swap @cast call"  # type(value)
110*fffe8c66SAdrian Prantl    summary += '     dup is_null { "None" } {'
111*fffe8c66SAdrian Prantl    summary += (
112*fffe8c66SAdrian Prantl        "       dup @summary call dup @strlen call { @get_value call } { drop } ifelse"
113*fffe8c66SAdrian Prantl    )
114*fffe8c66SAdrian Prantl    summary += "     } ifelse"
115*fffe8c66SAdrian Prantl    summary += "   } ifelse"
116*fffe8c66SAdrian Prantl    summary += " } ifelse"
117*fffe8c66SAdrian Prantl    return evaluate(summary, [valobj])
118*fffe8c66SAdrian Prantl
119*fffe8c66SAdrian Prantl
120*fffe8c66SAdrian Prantlclass MyOptionalSynthProvider:
121*fffe8c66SAdrian Prantl    """Provides deref support to llvm::Optional<T>"""
122*fffe8c66SAdrian Prantl
123*fffe8c66SAdrian Prantl    def __init__(self, valobj, internal_dict):
124*fffe8c66SAdrian Prantl        self.valobj = valobj
125*fffe8c66SAdrian Prantl
126*fffe8c66SAdrian Prantl    def num_children(self):
127*fffe8c66SAdrian Prantl        # return self.valobj.num_children
128*fffe8c66SAdrian Prantl        num_children = " @get_num_children call"
129*fffe8c66SAdrian Prantl        return evaluate(num_children, [self.valobj])
130*fffe8c66SAdrian Prantl
131*fffe8c66SAdrian Prantl    def get_child_index(self, name):
132*fffe8c66SAdrian Prantl        # if name == "$$dereference$$":
133*fffe8c66SAdrian Prantl        #    return self.valobj.num_children
134*fffe8c66SAdrian Prantl        # return self.valobj.GetIndexOfChildWithName(name)
135*fffe8c66SAdrian Prantl        get_child_index = ' dup "$$dereference$$" ='
136*fffe8c66SAdrian Prantl        get_child_index += " { drop @get_num_children call } {"  # obj name
137*fffe8c66SAdrian Prantl        get_child_index += "   @get_child_index call"  # index
138*fffe8c66SAdrian Prantl        get_child_index += " } ifelse"
139*fffe8c66SAdrian Prantl        return evaluate(get_child_index, [self.valobj, name])
140*fffe8c66SAdrian Prantl
141*fffe8c66SAdrian Prantl    def get_child_at_index(self, index):
142*fffe8c66SAdrian Prantl        # if index < self.valobj.num_children:
143*fffe8c66SAdrian Prantl        #    return self.valobj.GetChildAtIndex(index)
144*fffe8c66SAdrian Prantl        # return GetOptionalValue(self.valobj) or lldb.SBValue()
145*fffe8c66SAdrian Prantl        get_child_at_index = " over over swap"  # obj index index obj
146*fffe8c66SAdrian Prantl        get_child_at_index += " @get_num_children call"  # obj index index n
147*fffe8c66SAdrian Prantl        get_child_at_index += " < { @get_child_at_index call } {"  # obj index
148*fffe8c66SAdrian Prantl
149*fffe8c66SAdrian Prantl        get_opt_val = ' dup "Storage" @get_child_with_name call'  # valobj storage
150*fffe8c66SAdrian Prantl        get_opt_val += " dup { swap } if drop"  # storage
151*fffe8c66SAdrian Prantl        get_opt_val += ' dup "hasVal" @get_child_with_name call'  # storage
152*fffe8c66SAdrian Prantl        get_opt_val += " @get_value_as_unsigned call"  # storage int(hasVal)
153*fffe8c66SAdrian Prantl        get_opt_val += ' dup 2 = { drop "<could not read MyOptional>" } {'
154*fffe8c66SAdrian Prantl        get_opt_val += '   0 = { "None" } {'
155*fffe8c66SAdrian Prantl        get_opt_val += (
156*fffe8c66SAdrian Prantl            "     dup @get_type call 0 @get_template_argument_type call"  # storage type
157*fffe8c66SAdrian Prantl        )
158*fffe8c66SAdrian Prantl        get_opt_val += "     swap"  # type storage
159*fffe8c66SAdrian Prantl        get_opt_val += '     "value" @get_child_with_name call'  # type value
160*fffe8c66SAdrian Prantl        get_opt_val += "     swap @cast call"  # type(value)
161*fffe8c66SAdrian Prantl        get_opt_val += "   } ifelse"
162*fffe8c66SAdrian Prantl        get_opt_val += " } ifelse"
163*fffe8c66SAdrian Prantl
164*fffe8c66SAdrian Prantl        get_child_at_index += get_opt_val
165*fffe8c66SAdrian Prantl        get_child_at_index += " } ifelse"
166*fffe8c66SAdrian Prantl
167*fffe8c66SAdrian Prantl        return evaluate(get_child_at_index, [self.valobj, index])
168