[Tarantool-patches] [PATCH luajit] dbg: avoid hardcoded vmstate
Mikhail Elhimov
m.elhimov at vk.team
Fri Oct 16 01:53:25 MSK 2026
This patch is closed (it has been integrated into
https://lists.tarantool.org/pipermail/tarantool-patches/2026-October/030858.html)
On 14.10.2026 18:02, Mikhail Elhimov wrote:
> Follows-up f0897ba86494b250512be18e25bafccffadb27b1 ("dbg: avoid
> hardcoded enums (get them from target)").
>
> Also tests were adjusted to use stricter regex for vm state.
> ---
> Branch: https://github.com/tarantool/luajit/tree/elhimov/gh-13094-dbg-avoid-hardcoded-vmstate
> Related issues: https://github.com/tarantool/tarantool/issues/13094
>
> src/luajit_dbg.py | 88 +++++++++----------
> .../debug-extension-tests.py | 16 +++-
> 2 files changed, 58 insertions(+), 46 deletions(-)
>
> diff --git a/src/luajit_dbg.py b/src/luajit_dbg.py
> index 7c2d085f..e0b8f958 100644
> --- a/src/luajit_dbg.py
> +++ b/src/luajit_dbg.py
> @@ -198,7 +198,7 @@ class Debugger(object):
> # different in GDB and LLDB, so this method is needed to hide
> # the implementation details.
> @abc.abstractmethod
> - def create_enum_value(self, enum_name, enum_member_name):
> + def create_enum_value(self, enum_member_name, enum_name=None):
> '''Return debugger-specific value object that represents
> the given enum member.
> '''
> @@ -357,7 +357,7 @@ class _GDBDebugger(Debugger):
> def register_command(self, command, name):
> command(name)
>
> - def create_enum_value(self, enum_name, enum_member_name):
> + def create_enum_value(self, enum_member_name, enum_name):
> val = self.eval(enum_member_name)
> assert val.type.code == gdb.TYPE_CODE_ENUM
> return val
> @@ -752,27 +752,31 @@ class _LLDBDebugger(Debugger):
> )
> )
>
> - def create_enum_value(self, enum_name, enum_member_name):
> - # In LLDB an enum member has to be specified in the form:
> - # <enum_name>::<enum_member_name>
> - val = self.eval(enum_name + "::" + enum_member_name)
> - # Be aware that SBValue.IsValid() is necessary, but not
> - # sufficient as it only indicates that the object does
> - # contain the relevant data (including potential error),
> - # so it is necessary to check additionally that no error
> - # has occurred while evaluating the expression.
> - if val.sbvalue.IsValid() and val.sbvalue.error.Success():
> - assert self._lldb_tp_isenum(val.sbvalue.GetType())
> - return val
> -
> - # LLDB uses the enum name in the expression above but
> - # debugging information about the enum name might be
> - # optimized out if no variable of the given enum type is
> - # declared and its members are only used as the predefined
> - # constants (like in case of the enum IRFieldID).
> -
> - # In this case the above method doesn't work so trying to
> - # discover the enum type by the given enum member.
> + def create_enum_value(self, enum_member_name, enum_name):
> + if enum_name is not None:
> + # In LLDB an enum member has to be specified in the
> + # form: <enum_name>::<enum_member_name>
> + val = self.eval(enum_name + "::" + enum_member_name)
> + # Be aware that SBValue.IsValid() is necessary, but
> + # not sufficient as it only indicates that the object
> + # does contain the relevant data (including potential
> + # error), so it is necessary to check additionally
> + # that no error has occurred while evaluating the
> + # expression.
> + if val.sbvalue.IsValid() and val.sbvalue.error.Success():
> + assert self._lldb_tp_isenum(val.sbvalue.GetType())
> + return val
> +
> + # LLDB needs the enum name in the expression above but
> + # 1. Enum might be anonymous (like LJ_VMST__MAX)
> + # 2. Debugging information about the enum name might be
> + # optimized out if no variable of the given enum type
> + # is declared and its members are only used as the
> + # predefined constants (like in case of the enum
> + # IRFieldID)
> +
> + # In these cases the above method doesn't work so trying
> + # to discover the enum type by the given enum member.
>
> def find_enum_type_member(enum_type, enum_member_name):
> # SBTypeEnumMemberList supports members iteration and
> @@ -870,10 +874,10 @@ def strx64(val):
>
>
> class EnumBasedList(object):
> - def __init__(self, enum_name, max_enum_member, map_func=None,
> + def __init__(self, max_enum_member, enum_name, map_func=None,
> *map_func_extra_args):
> - self.__enum_name = enum_name
> self.__max_enum_member = max_enum_member
> + self.__enum_name = enum_name
> self.__map_func = map_func
> self.__map_func_extra_args = map_func_extra_args
> # Lazy initialization (see __get_items) as the required
> @@ -892,7 +896,7 @@ class EnumBasedList(object):
> def __get_items(self):
> if self.__items is None:
> max_enum_value = dbg.create_enum_value(
> - self.__enum_name, self.__max_enum_member
> + self.__max_enum_member, self.__enum_name
> )
> items = []
> for i in range(max_enum_value):
> @@ -985,7 +989,7 @@ def bc_d(ins):
> return int(ins) >> 16
>
>
> -BCMODE = EnumBasedList('BCMode', 'BCM_max', cut_prefix, 'BCM')
> +BCMODE = EnumBasedList('BCM_max', 'BCMode', cut_prefix, 'BCM')
>
>
> lj_bc_mode_ = None
> @@ -1011,7 +1015,7 @@ def bcmode_cd(op):
> return int((lj_bc_mode()[op] >> 7) & 15)
>
>
> -BYTECODES = EnumBasedList('BCOp', 'BC__MAX', cut_prefix, 'BC_')
> +BYTECODES = EnumBasedList('BC__MAX', 'BCOp', cut_prefix, 'BC_')
>
>
> def proto_bc(proto):
> @@ -1166,7 +1170,7 @@ def J(g):
>
>
> # Matched `MMDEF(_)`.
> -MM_NAMES = EnumBasedList('MMS', 'MM__MAX', cut_prefix, 'MM_')
> +MM_NAMES = EnumBasedList('MM__MAX', 'MMS', cut_prefix, 'MM_')
>
>
> # Get the name of the index in the predefined arrays.
> @@ -1219,18 +1223,12 @@ def ggfname_by_offset(offset):
> return ggfname
>
>
> +VM_STATES = EnumBasedList('LJ_VMST__MAX', None, cut_prefix, 'LJ_VMST_')
> +
> +
> def vm_state(g):
> - return {
> - i2notu32(0): 'INTERP',
> - i2notu32(1): 'LFUNC',
> - i2notu32(2): 'FFUNC',
> - i2notu32(3): 'CFUNC',
> - i2notu32(4): 'GC',
> - i2notu32(5): 'EXIT',
> - i2notu32(6): 'RECORD',
> - i2notu32(7): 'OPT',
> - i2notu32(8): 'ASM',
> - }.get(int(tou32(g['vmstate'])), 'TRACE')
> + index = i2notu32(g['vmstate'])
> + return VM_STATES[index] if index < len(VM_STATES) else 'TRACE'
>
>
> def gc_state(g):
> @@ -1427,7 +1425,7 @@ def cdataptr(cd):
> # JIT engine.
>
>
> -IRS = EnumBasedList('IROp', 'IR__MAX', cut_prefix, 'IR_')
> +IRS = EnumBasedList('IR__MAX', 'IROp', cut_prefix, 'IR_')
>
>
> # Mode bits: Commutative, {Normal/Ref, Alloc, Load, Store},
> @@ -1479,7 +1477,7 @@ def ir_mode(op):
> return mode
>
>
> -IRTYPES = EnumBasedList('IRType', 'IRT__MAX', lambda x: {
> +IRTYPES = EnumBasedList('IRT__MAX', 'IRType', lambda x: {
> 'IRT_CDATA': 'cdt',
> 'IRT_FLOAT': 'flt',
> 'IRT_LIGHTUD': 'lud',
> @@ -1488,11 +1486,11 @@ IRTYPES = EnumBasedList('IRType', 'IRT__MAX', lambda x: {
> }.get(x, cut_prefix(x, 'IRT_')[:3].ljust(3).lower()))
>
>
> -IRFIELDS = EnumBasedList('IRFieldID', 'IRFL__MAX', lambda x:
> +IRFIELDS = EnumBasedList('IRFL__MAX', 'IRFieldID', lambda x:
> cut_prefix(x, 'IRFL_').lower().replace('_', '.', 1))
>
>
> -IRFPMS = EnumBasedList('IRFPMathOp', 'IRFPM__MAX',
> +IRFPMS = EnumBasedList('IRFPM__MAX', 'IRFPMathOp',
> lambda x: cut_prefix(x, 'IRFPM_').lower())
>
>
> @@ -1522,7 +1520,7 @@ REGISTERS = {
> }
>
>
> -IR_CALLS = EnumBasedList('IRCallID', 'IRCALL__MAX', cut_prefix, 'IRCALL_')
> +IR_CALLS = EnumBasedList('IRCALL__MAX', 'IRCallID', cut_prefix, 'IRCALL_')
>
>
> def regname(reg_number):
> diff --git a/test/tarantool-debugger-tests/debug-extension-tests.py b/test/tarantool-debugger-tests/debug-extension-tests.py
> index 5e369f00..359163e9 100644
> --- a/test/tarantool-debugger-tests/debug-extension-tests.py
> +++ b/test/tarantool-debugger-tests/debug-extension-tests.py
> @@ -262,12 +262,26 @@ class TestLJArch(TestCaseBase):
> )
>
>
> +RX_VM_STATE = '({})'.format('|'.join([
> + 'INTERP',
> + 'LFUNC',
> + 'FFUNC',
> + 'CFUNC',
> + 'GC',
> + 'EXIT',
> + 'RECORD',
> + 'OPT',
> + 'ASM',
> + 'TRACE',
> +]))
> +
> +
> class TestLJState(TestCaseBase):
> extension_cmds = 'lj-state'
> location = 'lj_cf_print'
> lua_script = 'print(1)'
> pattern = (
> - r'VM state: [A-Z]+\n'
> + r'VM state: ' + RX_VM_STATE + '\n'
> r'GC state: [A-Z]+\n'
> r'JIT state: [A-Z]+\n'
> )
--
Best regards,
Mikhail Elhimov
More information about the Tarantool-patches
mailing list