GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Extract common bytecode retrieval logic from `_PyFrame_GetBytecode` and `_PyFrame_SafeGetLasti` · Issue #142929 · python/cpython

Extract common bytecode retrieval logic from _PyFrame_GetBytecode and _PyFrame_SafeGetLasti #142929

New issue
Copy link
New issue
Copy link
Open
Open
Extract common bytecode retrieval logic from _PyFrame_GetBytecode and _PyFrame_SafeGetLasti#142929
Copy link
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-refactorCode refactoring (with no changes in behavior)Code refactoring (with no changes in behavior)

Description

@nybblista
nybblista
opened on Dec 18, 2025
Issue body actions

Both _PyFrame_GetBytecode and _PyFrame_SafeGetLasti inline functions currently duplicate the same logic for retrieving the bytecode, differing only in whether they call _PyFrame_GetCode or _PyFrame_SafeGetCode.

static inline _Py_CODEUNIT *
_PyFrame_GetBytecode(_PyInterpreterFrame *f)
{
#ifdef Py_GIL_DISABLED
    PyCodeObject *co = _PyFrame_GetCode(f);
    _PyCodeArray *tlbc = _PyCode_GetTLBCArray(co);
    assert(f->tlbc_index >= 0 && f->tlbc_index < tlbc->size);
    return (_Py_CODEUNIT *)tlbc->entries[f->tlbc_index];
#else
    return _PyCode_CODE(_PyFrame_GetCode(f));
#endif
}

static inline int
_PyFrame_SafeGetLasti(struct _PyInterpreterFrame *f)
{
    // Code based on _PyFrame_GetBytecode() but replace _PyFrame_GetCode()
    // with _PyFrame_SafeGetCode().
    PyCodeObject *co = _PyFrame_SafeGetCode(f);
    if (co == NULL) {
        return -1;
    }

    _Py_CODEUNIT *bytecode;
#ifdef Py_GIL_DISABLED
    _PyCodeArray *tlbc = _PyCode_GetTLBCArray(co);
    assert(f->tlbc_index >= 0 && f->tlbc_index < tlbc->size);
    bytecode = (_Py_CODEUNIT *)tlbc->entries[f->tlbc_index];
#else
    bytecode = _PyCode_CODE(co);
#endif

    return (int)(f->instr_ptr - bytecode) * sizeof(_Py_CODEUNIT);
}

However, I think we should extract the bytecode retrieving logic into another helper, let's say, _PyFrame_GetBytecodeFromCodeObject, as:

static inline _Py_CODEUNIT *
_PyFrame_GetBytecodeFromCodeObject(_PyInterpreterFrame *f, PyCodeObject *co)
{
#ifdef Py_GIL_DISABLED
     _PyCodeArray *tlbc = _PyCode_GetTLBCArray(co);
    assert(f->tlbc_index >= 0 && f->tlbc_index < tlbc->size);
    return (_Py_CODEUNIT *)tlbc->entries[f->tlbc_index];
#else
    return _PyCode_CODE(co);
#endif
}

So we can use that helper as:

static inline _Py_CODEUNIT *
_PyFrame_GetBytecode(_PyInterpreterFrame *f)
{
    PyCodeObject *co = _PyFrame_GetCode(f);
    return _PyFrame_GetBytecodeFromCodeObject(f, co);
}

static inline int
_PyFrame_SafeGetLasti(_PyInterpreterFrame *f)
{
    PyCodeObject *co = _PyFrame_SafGetCode(f);
    if(co == NULL){
        return -1;
    }

    _Py_CODEUNIT *bytecode = _PyFrame_GetBytecodeFromCodeObject(f, co);
    return (int)(f->insert_ptr - bytecode) * sizeof(_Py_CODEUNIT);
}

However, we can use different types of helpers such as inline helper with a function pointer or a macro wrapper. My point here is not about the implementation of the helper itself, but about extracting the bytecode retrieving logic into another helper regardless of the helper name and the method used to implement that helper.

Activity

  1. sergey-miryanov
    added
    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
    type-refactorCode refactoring (with no changes in behavior)Code refactoring (with no changes in behavior)
    on Dec 18, 2025
  2. kmalvin241-blip commented on Dec 18, 2025

    @kmalvin241-blip
    kmalvin241-blip
    on Dec 18, 2025 · Hidden as spam
    show commentMore actions
  3. kmalvin241-blip commented on Dec 18, 2025

    @kmalvin241-blip
    kmalvin241-blip
    on Dec 18, 2025 · Hidden as spam
    show commentMore actions
  4. colesbury commented on Dec 18, 2025

    @colesbury
    colesbury
    on Dec 18, 2025
    Contributor
    More actions

    I'm not sure it's worth extracting common code here. A little bit of duplicate code is not such a big deal and we will want to treat these functions differently when it comes to things like sanitizers. _PyFrame_SafeGetLasti is used in unsafe ways -- we call it when programs are already crashing -- while _PyFrame_GetBytecode is used normally. So we'll probably want to avoid TSan or ASan instrumentation of _PyFrame_SafeGetLasti but keep it in _PyFrame_GetBytecode. Extracting common code will make this harder.

    Reacted by Maxim Martynov and Nybblista
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)type-refactorCode refactoring (with no changes in behavior)Code refactoring (with no changes in behavior)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.