github-actions[bot] wrote: <!--LLVM CODE FORMAT COMMENT: {darker}-->
:warning: Python code formatter, darker found issues in your code. :warning: <details> <summary> You can test this locally with the following command: </summary> ``````````bash darker --check --diff -r 2e0506f83bfde6db93454bdf28e4a71c160d4f5b...642525847da7d874a127f94f155fd738e3d78196 lldb/examples/formatter-bytecode/compiler.py lldb/examples/formatter-bytecode/test/formatter.py `````````` </details> <details> <summary> View the diff from darker here. </summary> ``````````diff --- compiler.py 2024-10-22 23:29:50.000000 +0000 +++ compiler.py 2024-10-22 23:43:37.694386 +0000 @@ -13,171 +13,183 @@ type_Object = 4 type_Type = 5 # Opcodes opcode = dict() + + def define_opcode(n, mnemonic, name): - globals()['op_'+name] = n + globals()["op_" + name] = n if mnemonic: opcode[mnemonic] = n opcode[n] = mnemonic -define_opcode(1, 'dup', 'dup') -define_opcode(2, 'drop', 'drop') -define_opcode(3, 'pick', 'pick') -define_opcode(4, 'over', 'over') -define_opcode(5, 'swap', 'swap') -define_opcode(6, 'rot', 'rot') - -define_opcode(0x10, '{', 'begin') -define_opcode(0x11, 'if', 'if') -define_opcode(0x12, 'ifelse', 'ifelse') - -define_opcode(0x20, None, 'lit_uint') -define_opcode(0x21, None, 'lit_int') -define_opcode(0x22, None, 'lit_string') -define_opcode(0x23, None, 'lit_selector') - -define_opcode(0x30, '+', 'plus') -define_opcode(0x31, '-', 'minus') -define_opcode(0x32, '*', 'mul') -define_opcode(0x33, '/', 'div') -define_opcode(0x34, '%', 'mod') -define_opcode(0x35, '<<', 'shl') -define_opcode(0x36, '>>', 'shr') -define_opcode(0x37, 'shra', 'shra') - -define_opcode(0x40, '&', 'and') -define_opcode(0x41, '|', 'or') -define_opcode(0x42, '^', 'xor') -define_opcode(0x43, '~', 'not') - -define_opcode(0x50, '=', 'eq') -define_opcode(0x51, '!=', 'neq') -define_opcode(0x52, '<', 'lt') -define_opcode(0x53, '>', 'gt') -define_opcode(0x54, '=<', 'le') -define_opcode(0x55, '>=', 'ge') - -define_opcode(0x60, 'call', 'call') + +define_opcode(1, "dup", "dup") +define_opcode(2, "drop", "drop") +define_opcode(3, "pick", "pick") +define_opcode(4, "over", "over") +define_opcode(5, "swap", "swap") +define_opcode(6, "rot", "rot") + +define_opcode(0x10, "{", "begin") +define_opcode(0x11, "if", "if") +define_opcode(0x12, "ifelse", "ifelse") + +define_opcode(0x20, None, "lit_uint") +define_opcode(0x21, None, "lit_int") +define_opcode(0x22, None, "lit_string") +define_opcode(0x23, None, "lit_selector") + +define_opcode(0x30, "+", "plus") +define_opcode(0x31, "-", "minus") +define_opcode(0x32, "*", "mul") +define_opcode(0x33, "/", "div") +define_opcode(0x34, "%", "mod") +define_opcode(0x35, "<<", "shl") +define_opcode(0x36, ">>", "shr") +define_opcode(0x37, "shra", "shra") + +define_opcode(0x40, "&", "and") +define_opcode(0x41, "|", "or") +define_opcode(0x42, "^", "xor") +define_opcode(0x43, "~", "not") + +define_opcode(0x50, "=", "eq") +define_opcode(0x51, "!=", "neq") +define_opcode(0x52, "<", "lt") +define_opcode(0x53, ">", "gt") +define_opcode(0x54, "=<", "le") +define_opcode(0x55, ">=", "ge") + +define_opcode(0x60, "call", "call") # Function signatures sig_summary = 0 sig_init = 1 sig_get_num_children = 2 sig_get_child_index = 3 sig_get_child_at_index = 4 # Selectors selector = dict() + + def define_selector(n, name): - globals()['sel_'+name] = n - selector['@'+name] = n - selector[n] = '@'+name - -define_selector(0, 'summary') -define_selector(1, 'type_summary') - -define_selector(0x10, 'get_num_children') -define_selector(0x11, 'get_child_at_index') -define_selector(0x12, 'get_child_with_name') -define_selector(0x13, 'get_child_index') -define_selector(0x15, 'get_type') -define_selector(0x16, 'get_template_argument_type') -define_selector(0x20, 'get_value') -define_selector(0x21, 'get_value_as_unsigned') -define_selector(0x22, 'get_value_as_signed') -define_selector(0x23, 'get_value_as_address') -define_selector(0x24, 'cast') - -define_selector(0x40, 'read_memory_byte') -define_selector(0x41, 'read_memory_uint32') -define_selector(0x42, 'read_memory_int32') -define_selector(0x43, 'read_memory_unsigned') -define_selector(0x44, 'read_memory_signed') -define_selector(0x45, 'read_memory_address') -define_selector(0x46, 'read_memory') - -define_selector(0x50, 'fmt') -define_selector(0x51, 'sprintf') -define_selector(0x52, 'strlen') + globals()["sel_" + name] = n + selector["@" + name] = n + selector[n] = "@" + name + + +define_selector(0, "summary") +define_selector(1, "type_summary") + +define_selector(0x10, "get_num_children") +define_selector(0x11, "get_child_at_index") +define_selector(0x12, "get_child_with_name") +define_selector(0x13, "get_child_index") +define_selector(0x15, "get_type") +define_selector(0x16, "get_template_argument_type") +define_selector(0x20, "get_value") +define_selector(0x21, "get_value_as_unsigned") +define_selector(0x22, "get_value_as_signed") +define_selector(0x23, "get_value_as_address") +define_selector(0x24, "cast") + +define_selector(0x40, "read_memory_byte") +define_selector(0x41, "read_memory_uint32") +define_selector(0x42, "read_memory_int32") +define_selector(0x43, "read_memory_unsigned") +define_selector(0x44, "read_memory_signed") +define_selector(0x45, "read_memory_address") +define_selector(0x46, "read_memory") + +define_selector(0x50, "fmt") +define_selector(0x51, "sprintf") +define_selector(0x52, "strlen") ################################################################################ # Compiler. ################################################################################ + def compile(assembler: str) -> bytearray: """Compile assembler into bytecode""" # This is a stack of all in-flight/unterminated blocks. bytecode = [bytearray()] def emit(byte): bytecode[-1].append(byte) - tokens = list(assembler.split(' ')) + tokens = list(assembler.split(" ")) tokens.reverse() while tokens: tok = tokens.pop() - if tok == '': pass - elif tok == '{': bytecode.append(bytearray()) - elif tok == '}': + if tok == "": + pass + elif tok == "{": + bytecode.append(bytearray()) + elif tok == "}": block = bytecode.pop() emit(op_begin) - emit(len(block)) # FIXME: uleb + emit(len(block)) # FIXME: uleb bytecode[-1].extend(block) elif tok[0].isdigit(): - if tok[-1] == 'u': + if tok[-1] == "u": emit(op_lit_uint) - emit(int(tok[:-1])) # FIXME + emit(int(tok[:-1])) # FIXME else: emit(op_lit_int) - emit(int(tok)) # FIXME - elif tok[0] == '@': + emit(int(tok)) # FIXME + elif tok[0] == "@": emit(op_lit_selector) emit(selector[tok]) elif tok[0] == '"': s = bytearray() done = False chrs = tok[1:] while not done: quoted = False for c in chrs: if quoted: - s.append(ord(c)) #FIXME + s.append(ord(c)) # FIXME quoted = False - elif c == '\\': + elif c == "\\": quoted = True elif c == '"': - done = True; - break; # FIXME assert this is last in token + done = True + break + # FIXME assert this is last in token else: s.append(ord(c)) if not done: - s.append(ord(' ')) + s.append(ord(" ")) chrs = tokens.pop() emit(op_lit_string) emit(len(s)) bytecode[-1].extend(s) else: emit(opcode[tok]) - assert(len(bytecode) == 1) # unterminated { + assert len(bytecode) == 1 # unterminated { return bytecode[0] ################################################################################ # Disassembler. ################################################################################ + def disassemble(bytecode: bytearray) -> (str, int): """Disassemble bytecode into (assembler, token starts)""" asm = "" all_bytes = list(bytecode) all_bytes.reverse() blocks = [] tokens = [0] + def next_byte(): """Fetch the next byte in the bytecode and keep track of all in-flight blocks""" for i in range(len(blocks)): blocks[i] -= 1 @@ -185,17 +197,17 @@ return all_bytes.pop() while all_bytes: b = next_byte() if b == op_begin: - asm += '{' + asm += "{" length = next_byte() blocks.append(length) elif b == op_lit_uint: b = next_byte() - asm += str(b) # FIXME uleb - asm += 'u' + asm += str(b) # FIXME uleb + asm += "u" elif b == op_lit_int: b = next_byte() asm += str(b) elif b == op_lit_selector: b = next_byte() @@ -209,28 +221,30 @@ asm += '"' + repr(s)[2:] else: asm += opcode[b] while blocks and blocks[-1] == 0: - asm += ' }' + asm += " }" blocks.pop() if all_bytes: - asm += ' ' + asm += " " if blocks: asm += "ERROR" return asm, tokens ################################################################################ # Interpreter. ################################################################################ + def count_fmt_params(fmt: str) -> int: """Count the number of parameters in a format string""" from string import Formatter + f = Formatter() n = 0 for _, name, _, _ in f.parse(fmt): if name > n: n = name @@ -244,25 +258,30 @@ def trace(): """print a trace of the execution for debugging purposes""" def fmt(d): - if isinstance(d, int): return str(d) - if isinstance(d, str): return d + if isinstance(d, int): + return str(d) + if isinstance(d, str): + return d return repr(type(d)) pc, end = frame[-1] asm, tokens = disassemble(bytecode) - print('=== frame = {1}, data = {2}, opcode = {0}' - .format(opcode[b], frame, [fmt(d) for d in data])) + print( + "=== frame = {1}, data = {2}, opcode = {0}".format( + opcode[b], frame, [fmt(d) for d in data] + ) + ) print(asm) - print(' '*(tokens[pc]) + '^') + print(" " * (tokens[pc]) + "^") def next_byte(): """Fetch the next byte and update the PC""" pc, end = frame[-1] - assert(pc < len(bytecode)) + assert pc < len(bytecode) b = bytecode[pc] frame[-1] = pc + 1, end # At the end of a block? while pc >= end: frame.pop() @@ -280,14 +299,18 @@ if b == None: break if tracing: trace() # Data stack manipulation. - if b == op_dup: data.append(data[-1]) - elif b == op_drop: data.pop() - elif b == op_pick: data.append(data[data.pop()]) - elif b == op_over: data.append(data[-2]) + if b == op_dup: + data.append(data[-1]) + elif b == op_drop: + data.pop() + elif b == op_pick: + data.append(data[data.pop()]) + elif b == op_over: + data.append(data[-2]) elif b == op_swap: x = data.pop() y = data.pop() data.append(x) data.append(y) @@ -301,11 +324,11 @@ # Control stack manipulation. elif b == op_begin: length = next_byte() pc, end = frame[-1] - control.append((pc, pc+length)) + control.append((pc, pc + length)) frame[-1] = pc + length, end elif b == op_if: if data.pop(): frame.append(control.pop()) elif b == op_ifelse: @@ -333,28 +356,51 @@ s += chr(next_byte()) length -= 1 data.append(s) # Arithmetic, logic, etc. - elif b == op_plus: data.append(data.pop() + data.pop()) - elif b == op_minus: data.append(- data.pop() + data.pop()) - elif b == op_mul: data.append(data.pop() * data.pop()) - elif b == op_div: y = data.pop(); data.append(data.pop() / y) - elif b == op_mod: y = data.pop(); data.append(data.pop() % y) - elif b == op_shl: y = data.pop(); data.append(data.pop() << y) - elif b == op_shr: y = data.pop(); data.append(data.pop() >> y) - elif b == op_shra: y = data.pop(); data.append(data.pop() >> y) # FIXME - elif b == op_and: data.append(data.pop() & data.pop()) - elif b == op_or: data.append(data.pop() | data.pop()) - elif b == op_xor: data.append(data.pop() ^ data.pop()) - elif b == op_not: data.append(not data.pop()) - elif b == op_eq: data.append(data.pop() == data.pop()) - elif b == op_neq: data.append(data.pop() != data.pop()) - elif b == op_lt: data.append(data.pop() > data.pop()) - elif b == op_gt: data.append(data.pop() < data.pop()) - elif b == op_le: data.append(data.pop() >= data.pop()) - elif b == op_ge: data.append(data.pop() <= data.pop()) + elif b == op_plus: + data.append(data.pop() + data.pop()) + elif b == op_minus: + data.append(-data.pop() + data.pop()) + elif b == op_mul: + data.append(data.pop() * data.pop()) + elif b == op_div: + y = data.pop() + data.append(data.pop() / y) + elif b == op_mod: + y = data.pop() + data.append(data.pop() % y) + elif b == op_shl: + y = data.pop() + data.append(data.pop() << y) + elif b == op_shr: + y = data.pop() + data.append(data.pop() >> y) + elif b == op_shra: + y = data.pop() + data.append(data.pop() >> y) # FIXME + elif b == op_and: + data.append(data.pop() & data.pop()) + elif b == op_or: + data.append(data.pop() | data.pop()) + elif b == op_xor: + data.append(data.pop() ^ data.pop()) + elif b == op_not: + data.append(not data.pop()) + elif b == op_eq: + data.append(data.pop() == data.pop()) + elif b == op_neq: + data.append(data.pop() != data.pop()) + elif b == op_lt: + data.append(data.pop() > data.pop()) + elif b == op_gt: + data.append(data.pop() < data.pop()) + elif b == op_le: + data.append(data.pop() >= data.pop()) + elif b == op_ge: + data.append(data.pop() <= data.pop()) # Function calls. elif b == op_call: sel = data.pop() if sel == sel_summary: @@ -400,38 +446,41 @@ for i in range(n): args.append(data.pop()) data.append(fmt.format(*args)) else: print("not implemented: " + selector[sel]) - assert(False) + assert False pass return data[-1] ################################################################################ # Tests. ################################################################################ import unittest + class TestCompiler(unittest.TestCase): - def test(self): - self.assertEqual(compile("1u dup").hex(), '200101') - self.assertEqual(compile("\"1u dup\"").hex(), '2206317520647570') - self.assertEqual(compile("16 < { dup } if").hex(), '21105210010111') - self.assertEqual(compile("{ { \" } \" } }").hex(), '100710052203207d20') + self.assertEqual(compile("1u dup").hex(), "200101") + self.assertEqual(compile('"1u dup"').hex(), "2206317520647570") + self.assertEqual(compile("16 < { dup } if").hex(), "21105210010111") + self.assertEqual(compile('{ { " } " } }').hex(), "100710052203207d20") def roundtrip(asm): self.assertEqual(disassemble(compile(asm))[0], asm) roundtrip("1u dup") - roundtrip("1u dup \"1u dup\"") + roundtrip('1u dup "1u dup"') roundtrip("16 < { dup } if") - roundtrip("{ { \" } \" } }") + roundtrip('{ { " } " } }') self.assertEqual(interpret(compile("1 1 +"), [], []), 2) self.assertEqual(interpret(compile("2 1 1 + *"), [], []), 4) - self.assertEqual(interpret(compile('2 1 > { "yes" } { "no" } ifelse'), [], []), "yes") - -if __name__ == '__main__': + self.assertEqual( + interpret(compile('2 1 > { "yes" } { "no" } ifelse'), [], []), "yes" + ) + + +if __name__ == "__main__": unittest.main() --- test/formatter.py 2024-10-22 23:29:50.000000 +0000 +++ test/formatter.py 2024-10-22 23:43:37.737784 +0000 @@ -3,10 +3,11 @@ with the implementation replaced by bytecode. """ from __future__ import annotations from compiler import * import lldb + def __lldb_init_module(debugger, internal_dict): debugger.HandleCommand( "type synthetic add -w llvm " f"-l {__name__}.MyOptionalSynthProvider " @@ -16,22 +17,27 @@ "type summary add -w llvm " f"-e -F {__name__}.MyOptionalSummaryProvider " '-x "^MyOptional<.+>$"' ) -def evaluate(assembler : str, data : list): + +def evaluate(assembler: str, data: list): bytecode = compile(assembler) trace = True if trace: - print("Compiled to {0} bytes of bytecode:\n0x{1}" - .format(len(bytecode), bytecode.hex())) - result = interpret(bytecode, [], data, False) #trace) + print( + "Compiled to {0} bytes of bytecode:\n0x{1}".format( + len(bytecode), bytecode.hex() + ) + ) + result = interpret(bytecode, [], data, False) # trace) if trace: print("--> {0}".format(result)) return result -#def GetOptionalValue(valobj): + +# def GetOptionalValue(valobj): # storage = valobj.GetChildMemberWithName("Storage") # if not storage: # storage = valobj # # failure = 2 @@ -46,75 +52,80 @@ # storage = storage.GetChildMemberWithName("value") # return storage.Cast(underlying_type) def MyOptionalSummaryProvider(valobj, internal_dict): -# val = GetOptionalValue(valobj) -# if val is None: -# return "None" -# if val.summary: -# return val.summary -# return val.GetValue() + # val = GetOptionalValue(valobj) + # if val is None: + # return "None" + # if val.summary: + # return val.summary + # return val.GetValue() summary = "" - summary += ' dup "Storage" @get_child_with_name call' # valobj storage - summary += ' dup { swap } if drop' # storage - summary += ' dup "hasVal" @get_child_with_name call' # storage - summary += ' @get_value_as_unsigned call' # storage int(hasVal) + summary += ' dup "Storage" @get_child_with_name call' # valobj storage + summary += " dup { swap } if drop" # storage + summary += ' dup "hasVal" @get_child_with_name call' # storage + summary += " @get_value_as_unsigned call" # storage int(hasVal) summary += ' dup 2 = { drop "<could not read MyOptional>" } {' summary += ' 0 = { "None" } {' - summary += ' dup @get_type call 0 @get_template_argument_type call' # storage type - summary += ' swap' # type storage - summary += ' "value" @get_child_with_name call' # type value - summary += ' swap @cast call' # type(value) + summary += ( + " dup @get_type call 0 @get_template_argument_type call" # storage type + ) + summary += " swap" # type storage + summary += ' "value" @get_child_with_name call' # type value + summary += " swap @cast call" # type(value) summary += ' dup 0 = { "None" } {' - summary += ' dup @summary call { @summary call } { @get_value call } ifelse' - summary += ' } ifelse' - summary += ' } ifelse' - summary += ' } ifelse' + summary += " dup @summary call { @summary call } { @get_value call } ifelse" + summary += " } ifelse" + summary += " } ifelse" + summary += " } ifelse" return evaluate(summary, [valobj]) + class MyOptionalSynthProvider: """Provides deref support to llvm::Optional<T>""" def __init__(self, valobj, internal_dict): self.valobj = valobj def num_children(self): - #return self.valobj.num_children - num_children = ' @get_num_children call' + # return self.valobj.num_children + num_children = " @get_num_children call" return evaluate(num_children, [self.valobj]) def get_child_index(self, name): - #if name == "$$dereference$$": + # if name == "$$dereference$$": # return self.valobj.num_children - #return self.valobj.GetIndexOfChildWithName(name) + # return self.valobj.GetIndexOfChildWithName(name) get_child_index = ' dup "$$dereference$$" =' - get_child_index += ' { drop @get_num_children call } {' # obj name - get_child_index += ' @get_child_index call' # index - get_child_index += ' } ifelse' + get_child_index += " { drop @get_num_children call } {" # obj name + get_child_index += " @get_child_index call" # index + get_child_index += " } ifelse" return evaluate(get_child_index, [self.valobj, name]) def get_child_at_index(self, index): - #if index < self.valobj.num_children: + # if index < self.valobj.num_children: # return self.valobj.GetChildAtIndex(index) - #return GetOptionalValue(self.valobj) or lldb.SBValue() - get_child_at_index = ' over over swap' # obj index index obj - get_child_at_index += ' @get_num_children call' # obj index index n - get_child_at_index += ' < { @get_child_at_index call } {' # obj index + # return GetOptionalValue(self.valobj) or lldb.SBValue() + get_child_at_index = " over over swap" # obj index index obj + get_child_at_index += " @get_num_children call" # obj index index n + get_child_at_index += " < { @get_child_at_index call } {" # obj index - get_opt_val = ' dup "Storage" @get_child_with_name call' # valobj storage - get_opt_val += ' dup { swap } if drop' # storage - get_opt_val += ' dup "hasVal" @get_child_with_name call' # storage - get_opt_val += ' @get_value_as_unsigned call' # storage int(hasVal) + get_opt_val = ' dup "Storage" @get_child_with_name call' # valobj storage + get_opt_val += " dup { swap } if drop" # storage + get_opt_val += ' dup "hasVal" @get_child_with_name call' # storage + get_opt_val += " @get_value_as_unsigned call" # storage int(hasVal) get_opt_val += ' dup 2 = { drop "<could not read MyOptional>" } {' get_opt_val += ' 0 = { "None" } {' - get_opt_val += ' dup @get_type call 0 @get_template_argument_type call' # storage type - get_opt_val += ' swap' # type storage - get_opt_val += ' "value" @get_child_with_name call' # type value - get_opt_val += ' swap @cast call' # type(value) - get_opt_val += ' } ifelse' - get_opt_val += ' } ifelse' + get_opt_val += ( + " dup @get_type call 0 @get_template_argument_type call" # storage type + ) + get_opt_val += " swap" # type storage + get_opt_val += ' "value" @get_child_with_name call' # type value + get_opt_val += " swap @cast call" # type(value) + get_opt_val += " } ifelse" + get_opt_val += " } ifelse" get_child_at_index += get_opt_val - get_child_at_index += ' } ifelse' + get_child_at_index += " } ifelse" return evaluate(get_child_at_index, [self.valobj, index]) `````````` </details> https://github.com/llvm/llvm-project/pull/113398 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits