Hi, Igor! Thanks for the patch! LGTM   -- Best regards, Maxim Kokryashkin     >  >>Fixed 149 occurrences of E302 ("expected 2 blank lines, found 1") error >>reported by pycodestyle[1]. >> >>[1]: https://www.flake8rules.com/rules/E302.html >> >>Signed-off-by: Igor Munkin < imun@tarantool.org > >>--- >> src/luajit-gdb.py | 73 ++++++++++++++++++++++++++++++++++++++++++++ >> src/luajit_lldb.py | 76 ++++++++++++++++++++++++++++++++++++++++++++++ >> 2 files changed, 149 insertions(+) >> >>diff --git a/src/luajit-gdb.py b/src/luajit-gdb.py >>index f87063f8..9c51be0b 100644 >>--- a/src/luajit-gdb.py >>+++ b/src/luajit-gdb.py >>@@ -18,6 +18,7 @@ if LEGACY: >>  >> gtype_cache = {} >>  >>+ >> def gtype(typestr): >>     global gtype_cache >>     if typestr in gtype_cache: >>@@ -31,13 +32,16 @@ def gtype(typestr): >>     gtype_cache[typestr] = gtype >>     return gtype >>  >>+ >> def cast(typestr, val): >>     return gdb.Value(val).cast(gtype(typestr)) >>  >>+ >> def lookup(symbol): >>     variable, _ = gdb.lookup_symbol(symbol) >>     return variable.value() if variable else None >>  >>+ >> def parse_arg(arg): >>     if not arg: >>         return None >>@@ -49,15 +53,19 @@ def parse_arg(arg): >>  >>     return ret >>  >>+ >> def tou64(val): >>     return cast('uint64_t', val) & 0xFFFFFFFFFFFFFFFF >>  >>+ >> def tou32(val): >>     return cast('uint32_t', val) & 0xFFFFFFFF >>  >>+ >> def i2notu32(val): >>     return ~int(val) & 0xFFFFFFFF >>  >>+ >> def strx64(val): >>     return re.sub('L?$', '', >>                   hex(int(cast('uint64_t', val) & 0xFFFFFFFFFFFFFFFF))) >>@@ -81,6 +89,7 @@ LJ_T = { >>     'NUMX': i2notu32(13), >> } >>  >>+ >> def typenames(value): >>     return { >>         LJ_T[k]: 'LJ_T' + k for k in LJ_T.keys() >>@@ -105,6 +114,7 @@ FRAME = { >>     'PCALLH': 0x7, >> } >>  >>+ >> def frametypes(ft): >>     return { >>         FRAME['LUA']: 'L', >>@@ -113,43 +123,55 @@ def frametypes(ft): >>         FRAME['VARG']: 'V', >>     }.get(ft, '?') >>  >>+ >> def bc_a(ins): >>     return (ins >> 8) & 0xff >>  >>+ >> def frame_ftsz(framelink): >>     return cast('ptrdiff_t', framelink['ftsz'] if LJ_FR2 \ >>                 else framelink['fr']['tp']['ftsz']) >>  >>+ >> def frame_pc(framelink): >>     return cast('BCIns *', frame_ftsz(framelink)) if LJ_FR2 \ >>         else mref('BCIns *', framelink['fr']['tp']['pcr']) >>  >>+ >> def frame_prevl(framelink): >>     return framelink - (1 + LJ_FR2 + bc_a(frame_pc(framelink)[-1])) >>  >>+ >> def frame_ispcall(framelink): >>     return (frame_ftsz(framelink) & FRAME['PCALL']) == FRAME['PCALL'] >>  >>+ >> def frame_sized(framelink): >>     return (frame_ftsz(framelink) & ~FRAME_TYPEP) >>  >>+ >> def frame_prevd(framelink): >>     return cast('TValue *', cast('char *', framelink) - frame_sized(framelink)) >>  >>+ >> def frame_type(framelink): >>     return frame_ftsz(framelink) & FRAME_TYPE >>  >>+ >> def frame_typep(framelink): >>     return frame_ftsz(framelink) & FRAME_TYPEP >>  >>+ >> def frame_islua(framelink): >>     return frametypes(int(frame_type(framelink))) == 'L' \ >>         and int(frame_ftsz(framelink)) > 0 >>  >>+ >> def frame_prev(framelink): >>     return frame_prevl(framelink) if frame_islua(framelink) \ >>         else frame_prevd(framelink) >>  >>+ >> def frame_sentinel(L): >>     return mref('TValue *', L['stack']) + LJ_FR2 >>  >>@@ -174,23 +196,29 @@ LIGHTUD_LO_MASK = (1 << LJ_LIGHTUD_BITS_LO) - 1 >>  >> # }}} >>  >>+ >> def itype(o): >>     return cast('uint32_t', o['it64'] >> 47) if LJ_GC64 else o['it'] >>  >>+ >> def mref(typename, obj): >>     return cast(typename, obj['ptr64'] if LJ_GC64 else obj['ptr32']) >>  >>+ >> def gcref(obj): >>     return cast('GCobj *', obj['gcptr64'] if LJ_GC64 >>                 else cast('uintptr_t', obj['gcptr32'])) >>  >>+ >> def gcval(obj): >>     return cast('GCobj *', obj['gcptr64'] & LJ_GCVMASK if LJ_GC64 >>                 else cast('uintptr_t', obj['gcptr32'])) >>  >>+ >> def gcnext(obj): >>     return gcref(obj)['gch']['nextgc'] >>  >>+ >> def L(L=None): >>     # lookup a symbol for the main coroutine considering the host app >>     # XXX Fragile: though the loop initialization looks like a crap but it >>@@ -205,9 +233,11 @@ def L(L=None): >>         if l: >>             return cast('lua_State *', l) >>  >>+ >> def G(L): >>     return mref('global_State *', L['glref']) >>  >>+ >> def J(g): >>     typeGG = gtype('GG_State') >>  >>@@ -215,6 +245,7 @@ def J(g): >>                 - int(typeGG['g'].bitpos / 8) >>                 + int(typeGG['J'].bitpos / 8)) >>  >>+ >> def vm_state(g): >>     return { >>         i2notu32(0): 'INTERP', >>@@ -228,6 +259,7 @@ def vm_state(g): >>         i2notu32(8): 'ASM', >>     }.get(int(tou32(g['vmstate'])), 'TRACE') >>  >>+ >> def gc_state(g): >>     return { >>         0: 'PAUSE', >>@@ -239,6 +271,7 @@ def gc_state(g): >>         6: 'LAST', >>     }.get(int(g['gc']['state']), 'INVALID') >>  >>+ >> def jit_state(g): >>     return { >>         0: 'IDLE', >>@@ -250,18 +283,22 @@ def jit_state(g): >>         0x15: 'ERR', >>     }.get(int(J(g)['state']), 'INVALID') >>  >>+ >> def tvisint(o): >>     return LJ_DUALNUM and itype(o) == LJ_TISNUM >>  >>+ >> def tvisnumber(o): >>     return itype(o) <= LJ_TISNUM >>  >>+ >> def tvislightud(o): >>     if LJ_64 and not LJ_GC64: >>         return (cast('int32_t', itype(o)) >> 15) == -2 >>     else: >>         return itype(o) == LJ_T['LIGHTUD'] >>  >>+ >> def strdata(obj): >>     # String is printed with pointer to it, thanks to gdb. Just strip it. >>     try: >>@@ -269,6 +306,7 @@ def strdata(obj): >>     except UnicodeEncodeError: >>         return "" >>  >>+ >> def itypemap(o): >>     if LJ_64 and not LJ_GC64: >>         return LJ_T['NUMX'] if tvisnumber(o) \ >>@@ -277,12 +315,14 @@ def itypemap(o): >>     else: >>         return LJ_T['NUMX'] if tvisnumber(o) else itype(o) >>  >>+ >> def funcproto(func): >>     assert(func['ffid'] == 0) >>  >>     return cast('GCproto *', >>                 mref('char *', func['pc']) - gdb.lookup_type('GCproto').sizeof) >>  >>+ >> def gclistlen(root, end=0x0): >>     count = 0 >>     while(gcref(root) != end): >>@@ -290,6 +330,7 @@ def gclistlen(root, end=0x0): >>         root = gcnext(root) >>     return count >>  >>+ >> def gcringlen(root): >>     if not gcref(root): >>         return 0 >>@@ -307,6 +348,7 @@ gclen = { >>     'mmudata': gcringlen, >> } >>  >>+ >> # The generator that implements frame iterator. >> # Every frame is represented as a tuple of framelink and frametop. >> def frames(L): >>@@ -320,6 +362,7 @@ def frames(L): >>             break >>         framelink = frame_prev(framelink) >>  >>+ >> def lightudV(tv): >>     if LJ_64: >>         u = int(tv['u64']) >>@@ -333,33 +376,42 @@ def lightudV(tv): >>  >> # Dumpers {{{ >>  >>+ >> def dump_lj_tnil(tv): >>     return 'nil' >>  >>+ >> def dump_lj_tfalse(tv): >>     return 'false' >>  >>+ >> def dump_lj_ttrue(tv): >>     return 'true' >>  >>+ >> def dump_lj_tlightud(tv): >>     return 'light userdata @ {}'.format(strx64(lightudV(tv))) >>  >>+ >> def dump_lj_tstr(tv): >>     return 'string {body} @ {address}'.format( >>         body=strdata(gcval(tv['gcr'])), >>         address=strx64(gcval(tv['gcr'])) >>     ) >>  >>+ >> def dump_lj_tupval(tv): >>     return 'upvalue @ {}'.format(strx64(gcval(tv['gcr']))) >>  >>+ >> def dump_lj_tthread(tv): >>     return 'thread @ {}'.format(strx64(gcval(tv['gcr']))) >>  >>+ >> def dump_lj_tproto(tv): >>     return 'proto @ {}'.format(strx64(gcval(tv['gcr']))) >>  >>+ >> def dump_lj_tfunc(tv): >>     func = cast('struct GCfuncC *', gcval(tv['gcr'])) >>     ffid = func['ffid'] >>@@ -377,6 +429,7 @@ def dump_lj_tfunc(tv): >>     else: >>         return 'fast function #{}'.format(int(ffid)) >>  >>+ >> def dump_lj_ttrace(tv): >>     trace = cast('struct GCtrace *', gcval(tv['gcr'])) >>     return 'trace {traceno} @ {addr}'.format( >>@@ -384,9 +437,11 @@ def dump_lj_ttrace(tv): >>         addr=strx64(trace) >>     ) >>  >>+ >> def dump_lj_tcdata(tv): >>     return 'cdata @ {}'.format(strx64(gcval(tv['gcr']))) >>  >>+ >> def dump_lj_ttab(tv): >>     table = cast('GCtab *', gcval(tv['gcr'])) >>     return 'table @ {gcr} (asize: {asize}, hmask: {hmask})'.format( >>@@ -395,15 +450,18 @@ def dump_lj_ttab(tv): >>         hmask=strx64(table['hmask']), >>     ) >>  >>+ >> def dump_lj_tudata(tv): >>     return 'userdata @ {}'.format(strx64(gcval(tv['gcr']))) >>  >>+ >> def dump_lj_tnumx(tv): >>     if tvisint(tv): >>         return 'integer {}'.format(cast('int32_t', tv['i'])) >>     else: >>         return 'number {}'.format(cast('double', tv['n'])) >>  >>+ >> def dump_lj_invalid(tv): >>     return 'not valid type @ {}'.format(strx64(gcval(tv['gcr']))) >>  >>@@ -426,13 +484,16 @@ dumpers = { >>     'LJ_TNUMX': dump_lj_tnumx, >> } >>  >>+ >> def dump_tvalue(tvalue): >>     return dumpers.get(typenames(itypemap(tvalue)), dump_lj_invalid)(tvalue) >>  >>+ >> def dump_framelink_slot_address(fr): >>     return '{}:{}'.format(fr - 1, fr) if LJ_FR2 \ >>         else '{}'.format(fr) + PADDING >>  >>+ >> def dump_framelink(L, fr): >>     if fr == frame_sentinel(L): >>         return '{addr} [S ] FRAME: dummy L'.format( >>@@ -448,6 +509,7 @@ def dump_framelink(L, fr): >>         f=dump_lj_tfunc(fr - LJ_FR2), >>     ) >>  >>+ >> def dump_stack_slot(L, slot, base=None, top=None): >>     base = base or L['base'] >>     top = top or L['top'] >>@@ -461,6 +523,7 @@ def dump_stack_slot(L, slot, base=None, top=None): >>         value=dump_tvalue(slot), >>     ) >>  >>+ >> def dump_stack(L, base=None, top=None): >>     base = base or L['base'] >>     top = top or L['top'] >>@@ -502,6 +565,7 @@ def dump_stack(L, base=None, top=None): >>  >>     return '\n'.join(dump) >>  >>+ >> def dump_gc(g): >>     gc = g['gc'] >>     stats = ['{key}: {value}'.format(key=f, value=gc[f]) for f in ( >>@@ -530,6 +594,7 @@ class LJBase(gdb.Command): >>         gdb.Command.__init__(self, name, gdb.COMMAND_DATA) >>         gdb.write('{} command initialized\n'.format(name)) >>  >>+ >> class LJDumpArch(LJBase): >>     ''' >> lj-arch >>@@ -549,6 +614,7 @@ pointers respectively. >>             ) >>         ) >>  >>+ >> class LJDumpTValue(LJBase): >>     ''' >> lj-tv >>@@ -582,6 +648,7 @@ error message occurs. >>         tv = cast('TValue *', parse_arg(arg)) >>         gdb.write('{}\n'.format(dump_tvalue(tv))) >>  >>+ >> class LJDumpString(LJBase): >>     ''' >> lj-str >>@@ -601,6 +668,7 @@ is replaced with the corresponding error when decoding fails. >>             len=string['len'], >>         )) >>  >>+ >> class LJDumpTable(LJBase): >>     ''' >> lj-tab >>@@ -646,6 +714,7 @@ The command receives a GCtab adress and dumps the table contents: >>                 n=mref('struct Node *', node['next']) >>             )) >>  >>+ >> class LJDumpStack(LJBase): >>     ''' >> lj-stack [] >>@@ -682,6 +751,7 @@ If L is ommited the main coroutine is used. >>     def invoke(self, arg, from_tty): >>         gdb.write('{}\n'.format(dump_stack(L(parse_arg(arg))))) >>  >>+ >> class LJState(LJBase): >>     ''' >> lj-state >>@@ -701,6 +771,7 @@ The command requires no args and dumps current VM and GC states >>             }.items()) >>         ))) >>  >>+ >> class LJGC(LJBase): >>     ''' >> lj-gc >>@@ -727,6 +798,7 @@ The command requires no args and dumps current GC stats: >>             stats=dump_gc(g) >>         )) >>  >>+ >> def init(commands): >>     global LJ_64, LJ_GC64, LJ_FR2, LJ_DUALNUM, LJ_TISNUM, PADDING >>  >>@@ -783,6 +855,7 @@ def init(commands): >>  >>     gdb.write('luajit-gdb.py is successfully loaded\n') >>  >>+ >> def load(event=None): >>     init({ >>         'lj-arch': LJDumpArch, >>diff --git a/src/luajit_lldb.py b/src/luajit_lldb.py >>index b62705c3..bd8353d5 100644 >>--- a/src/luajit_lldb.py >>+++ b/src/luajit_lldb.py >>@@ -21,6 +21,7 @@ LJ_TISNUM = None >> # Global >> target = None >>  >>+ >> class Ptr: >>     def __init__(self, value, normal_type): >>         self.value = value >>@@ -82,6 +83,7 @@ class Ptr: >>             return getattr(self.__deref, name) >>         return self.__deref >>  >>+ >> class MetaStruct(type): >>     def __init__(cls, name, bases, nmspc): >>         super(MetaStruct, cls).__init__(name, bases, nmspc) >>@@ -108,6 +110,7 @@ class MetaStruct(type): >>                         property(make_general(field[1], field[0])), >>                     ) >>  >>+ >> class Struct(metaclass=MetaStruct): >>     def __init__(self, value): >>         self.value = value >>@@ -274,6 +277,7 @@ class Command(object): >>         automatically transformed into proper errors. >>         """ >>  >>+ >> def cast(typename, value): >>     pointer_type = False >>     name = None >>@@ -321,31 +325,39 @@ def cast(typename, value): >>     else: >>         return casted >>  >>+ >> def lookup_global(name): >>     return target.FindFirstGlobalVariable(name) >>  >>+ >> def type_member(type_obj, name): >>     return next((x for x in type_obj.members if x.name == name), None) >>  >>+ >> def find_type(typename): >>     return target.FindFirstType(typename) >>  >>+ >> def offsetof(typename, membername): >>     type_obj = find_type(typename) >>     member = type_member(type_obj, membername) >>     assert member is not None >>     return member.GetOffsetInBytes() >>  >>+ >> def sizeof(typename): >>     type_obj = find_type(typename) >>     return type_obj.GetByteSize() >>  >>+ >> def vtou64(value): >>     return value.unsigned & 0xFFFFFFFFFFFFFFFF >>  >>+ >> def vtoi(value): >>     return value.signed >>  >>+ >> def dbg_eval(expr): >>     process = target.GetProcess() >>     thread = process.GetSelectedThread() >>@@ -354,17 +366,21 @@ def dbg_eval(expr): >>  >> # }}} Debugger specific >>  >>+ >> def gcval(obj): >>     return cast(GCobjPtr, cast('uintptr_t', obj.gcptr & LJ_GCVMASK) if LJ_GC64 >>                 else cast('uintptr_t', obj.gcptr)) >>  >>+ >> def gcref(obj): >>     return cast(GCobjPtr, obj.gcptr if LJ_GC64 >>                 else cast('uintptr_t', obj.gcptr)) >>  >>+ >> def gcnext(obj): >>     return gcref(obj).gch.nextgc >>  >>+ >> def gclistlen(root, end=0x0): >>     count = 0 >>     while(gcref(root) != end): >>@@ -372,6 +388,7 @@ def gclistlen(root, end=0x0): >>         root = gcnext(root) >>     return count >>  >>+ >> def gcringlen(root): >>     if not gcref(root): >>         return 0 >>@@ -389,6 +406,7 @@ gclen = { >>     'mmudata': gcringlen, >> } >>  >>+ >> def dump_gc(g): >>     gc = g.gc >>     stats = ['{key}: {value}'.format(key=f, value=getattr(gc, f)) for f in ( >>@@ -407,9 +425,11 @@ def dump_gc(g): >>     ) for stat, handler in gclen.items()] >>     return '\n'.join(map(lambda s: '\t' + s, stats)) >>  >>+ >> def mref(typename, obj): >>     return cast(typename, obj.ptr) >>  >>+ >> def J(g): >>     g_offset = offsetof('GG_State', 'g') >>     J_offset = offsetof('GG_State', 'J') >>@@ -418,9 +438,11 @@ def J(g): >>         vtou64(cast('char *', g)) - g_offset + J_offset, >>     ) >>  >>+ >> def G(L): >>     return mref(global_StatePtr, L.glref) >>  >>+ >> def L(L=None): >>     # lookup a symbol for the main coroutine considering the host app >>     # XXX Fragile: though the loop initialization looks like a crap but it >>@@ -435,12 +457,15 @@ def L(L=None): >>         if l: >>             return lua_State(l) >>  >>+ >> def tou32(val): >>     return val & 0xFFFFFFFF >>  >>+ >> def i2notu32(val): >>     return ~int(val) & 0xFFFFFFFF >>  >>+ >> def vm_state(g): >>     return { >>         i2notu32(0): 'INTERP', >>@@ -454,6 +479,7 @@ def vm_state(g): >>         i2notu32(8): 'ASM', >>     }.get(int(tou32(g.vmstate)), 'TRACE') >>  >>+ >> def gc_state(g): >>     return { >>         0: 'PAUSE', >>@@ -465,6 +491,7 @@ def gc_state(g): >>         6: 'LAST', >>     }.get(g.gc.state, 'INVALID') >>  >>+ >> def jit_state(g): >>     return { >>         0: 'IDLE', >>@@ -476,16 +503,19 @@ def jit_state(g): >>         0x15: 'ERR', >>     }.get(J(g).state, 'INVALID') >>  >>+ >> def strx64(val): >>     return re.sub('L?$', '', >>                   hex(int(val) & 0xFFFFFFFFFFFFFFFF)) >>  >>+ >> def funcproto(func): >>     assert(func.ffid == 0) >>     proto_size = sizeof('GCproto') >>     value = cast('uintptr_t', vtou64(mref('char *', func.pc)) - proto_size) >>     return cast(GCprotoPtr, value) >>  >>+ >> def strdata(obj): >>     try: >>         ptr = cast('char *', obj + 1) >>@@ -493,48 +523,61 @@ def strdata(obj): >>     except UnicodeEncodeError: >>         return "" >>  >>+ >> def itype(o): >>     return tou32(o.it64 >> 47) if LJ_GC64 else o.it >>  >>+ >> def tvisint(o): >>     return LJ_DUALNUM and itype(o) == LJ_TISNUM >>  >>+ >> def tvislightud(o): >>     if LJ_64 and not LJ_GC64: >>         return (vtoi(cast('int32_t', itype(o))) >> 15) == -2 >>     else: >>         return itype(o) == LJ_T['LIGHTUD'] >>  >>+ >> def tvisnumber(o): >>     return itype(o) <= LJ_TISNUM >>  >>+ >> def dump_lj_tnil(tv): >>     return 'nil' >>  >>+ >> def dump_lj_tfalse(tv): >>     return 'false' >>  >>+ >> def dump_lj_ttrue(tv): >>     return 'true' >>  >>+ >> def dump_lj_tlightud(tv): >>     return 'light userdata @ {}'.format(strx64(gcval(tv.gcr))) >>  >>+ >> def dump_lj_tstr(tv): >>     return 'string {body} @ {address}'.format( >>         body=strdata(cast(GCstrPtr, gcval(tv.gcr))), >>         address=strx64(gcval(tv.gcr)) >>     ) >>  >>+ >> def dump_lj_tupval(tv): >>     return 'upvalue @ {}'.format(strx64(gcval(tv.gcr))) >>  >>+ >> def dump_lj_tthread(tv): >>     return 'thread @ {}'.format(strx64(gcval(tv.gcr))) >>  >>+ >> def dump_lj_tproto(tv): >>     return 'proto @ {}'.format(strx64(gcval(tv.gcr))) >>  >>+ >> def dump_lj_tfunc(tv): >>     func = cast(GCfuncCPtr, gcval(tv.gcr)) >>     ffid = func.ffid >>@@ -552,6 +595,7 @@ def dump_lj_tfunc(tv): >>     else: >>         return 'fast function #{}'.format(ffid) >>  >>+ >> def dump_lj_ttrace(tv): >>     trace = cast(GCtracePtr, gcval(tv.gcr)) >>     return 'trace {traceno} @ {addr}'.format( >>@@ -559,9 +603,11 @@ def dump_lj_ttrace(tv): >>         addr=strx64(trace) >>     ) >>  >>+ >> def dump_lj_tcdata(tv): >>     return 'cdata @ {}'.format(strx64(gcval(tv.gcr))) >>  >>+ >> def dump_lj_ttab(tv): >>     table = cast(GCtabPtr, gcval(tv.gcr)) >>     return 'table @ {gcr} (asize: {asize}, hmask: {hmask})'.format( >>@@ -570,15 +616,18 @@ def dump_lj_ttab(tv): >>         hmask=strx64(table.hmask), >>     ) >>  >>+ >> def dump_lj_tudata(tv): >>     return 'userdata @ {}'.format(strx64(gcval(tv.gcr))) >>  >>+ >> def dump_lj_tnumx(tv): >>     if tvisint(tv): >>         return 'integer {}'.format(cast('int32_t', tv.i)) >>     else: >>         return 'number {}'.format(tv.n) >>  >>+ >> def dump_lj_invalid(tv): >>     return 'not valid type @ {}'.format(strx64(gcval(tv.gcr))) >>  >>@@ -616,6 +665,7 @@ LJ_T = { >>     'NUMX': i2notu32(13), >> } >>  >>+ >> def itypemap(o): >>     if LJ_64 and not LJ_GC64: >>         return LJ_T['NUMX'] if tvisnumber(o) \ >>@@ -623,11 +673,13 @@ def itypemap(o): >>     else: >>         return LJ_T['NUMX'] if tvisnumber(o) else itype(o) >>  >>+ >> def typenames(value): >>     return { >>         LJ_T[k]: 'LJ_T' + k for k in LJ_T.keys() >>     }.get(int(value), 'LJ_TINVALID') >>  >>+ >> def dump_tvalue(tvptr): >>     return dumpers.get(typenames(itypemap(tvptr)), dump_lj_invalid)(tvptr) >>  >>@@ -646,6 +698,7 @@ FRAME = { >>     'PCALLH': 0x7, >> } >>  >>+ >> def frametypes(ft): >>     return { >>         FRAME['LUA']: 'L', >>@@ -654,17 +707,21 @@ def frametypes(ft): >>         FRAME['VARG']: 'V', >>     }.get(ft, '?') >>  >>+ >> def bc_a(ins): >>     return (ins >> 8) & 0xff >>  >>+ >> def frame_ftsz(framelink): >>     return vtou64(cast('ptrdiff_t', framelink.ftsz if LJ_FR2 \ >>                        else framelink.fr.tp.ftsz)) >>  >>+ >> def frame_pc(framelink): >>     return cast(BCInsPtr, frame_ftsz(framelink)) if LJ_FR2 \ >>         else mref(BCInsPtr, framelink.fr.tp.pcr) >>  >>+ >> def frame_prevl(framelink): >>     # We are evaluating the `frame_pc(framelink)[-1])` with lldb's >>     # REPL, because the lldb API is faulty and it's not possible to cast >>@@ -673,32 +730,41 @@ def frame_prevl(framelink): >>     # a pointer to it. >>     return framelink - (1 + LJ_FR2 + bc_a(vtou64(dbg_eval('((BCIns *)' + str(frame_pc(framelink)) + ')[-1]')))) >>  >>+ >> def frame_ispcall(framelink): >>     return (frame_ftsz(framelink) & FRAME['PCALL']) == FRAME['PCALL'] >>  >>+ >> def frame_sized(framelink): >>     return (frame_ftsz(framelink) & ~FRAME_TYPEP) >>  >>+ >> def frame_prevd(framelink): >>     return framelink - int(frame_sized(framelink) / sizeof('TValue')) >>  >>+ >> def frame_type(framelink): >>     return frame_ftsz(framelink) & FRAME_TYPE >>  >>+ >> def frame_typep(framelink): >>     return frame_ftsz(framelink) & FRAME_TYPEP >>  >>+ >> def frame_islua(framelink): >>     return frametypes(frame_type(framelink)) == 'L' \ >>         and frame_ftsz(framelink) > 0 >>  >>+ >> def frame_prev(framelink): >>     return frame_prevl(framelink) if frame_islua(framelink) \ >>         else frame_prevd(framelink) >>  >>+ >> def frame_sentinel(L): >>     return mref(TValuePtr, L.stack) + LJ_FR2 >>  >>+ >> # The generator that implements frame iterator. >> # Every frame is represented as a tuple of framelink and frametop. >> def frames(L): >>@@ -712,6 +778,7 @@ def frames(L): >>             break >>         framelink = frame_prev(framelink) >>  >>+ >> def dump_framelink_slot_address(fr): >>     return '{start:{padding}}:{end:{padding}}'.format( >>         start=hex(int(fr - 1)), >>@@ -722,6 +789,7 @@ def dump_framelink_slot_address(fr): >>         padding=len(PADDING), >>     ) >>  >>+ >> def dump_framelink(L, fr): >>     if fr == frame_sentinel(L): >>         return '{addr} [S ] FRAME: dummy L'.format( >>@@ -737,6 +805,7 @@ def dump_framelink(L, fr): >>         f=dump_lj_tfunc(fr - LJ_FR2), >>     ) >>  >>+ >> def dump_stack_slot(L, slot, base=None, top=None): >>     base = base or L.base >>     top = top or L.top >>@@ -750,6 +819,7 @@ def dump_stack_slot(L, slot, base=None, top=None): >>         value=dump_tvalue(slot), >>     ) >>  >>+ >> def dump_stack(L, base=None, top=None): >>     base = base or L.base >>     top = top or L.top >>@@ -845,6 +915,7 @@ The command requires no args and dumps current VM and GC states >>             }.items()) >>         ))) >>  >>+ >> class LJDumpArch(Command): >>     ''' >> lj-arch >>@@ -863,6 +934,7 @@ pointers respectively. >>             ) >>         ) >>  >>+ >> class LJGC(Command): >>     ''' >> lj-gc >>@@ -888,6 +960,7 @@ The command requires no args and dumps current GC stats: >>             stats=dump_gc(g) >>         )) >>  >>+ >> class LJDumpString(Command): >>     ''' >> lj-str >>@@ -906,6 +979,7 @@ is replaced with the corresponding error when decoding fails. >>             len=string_ptr.len, >>         )) >>  >>+ >> class LJDumpTable(Command): >>     ''' >> lj-tab >>@@ -950,6 +1024,7 @@ The command receives a GCtab adress and dumps the table contents: >>                 n=strx64(mref(NodePtr, node.next)) >>             )) >>  >>+ >> class LJDumpStack(Command): >>     ''' >> lj-stack [] >>@@ -999,6 +1074,7 @@ def register_commands(debugger, commands): >>         ) >>         print('{cmd} command intialized'.format(cmd=cls.command)) >>  >>+ >> def configure(debugger): >>     global LJ_64, LJ_GC64, LJ_FR2, LJ_DUALNUM, PADDING, LJ_TISNUM, target >>     target = debugger.GetSelectedTarget() >>-- >>2.30.2 >