@@ -1690,7 +1690,27 @@ PyCode_GetFreevars(PyCodeObject *code)
16901690}
16911691
16921692
1693- #define GET_OPARG (co , i , initial ) (initial)
1693+ static _Py_CODEUNIT
1694+ advance_past_extended_arg (PyCodeObject * co , int * p_i , int * p_oparg )
1695+ {
1696+ int i = * p_i ;
1697+ _Py_CODEUNIT inst = _Py_GetBaseCodeUnit (co , i );
1698+ int opcode = inst .op .code ;
1699+ int oparg = 0 ;
1700+ while (opcode == EXTENDED_ARG ) {
1701+ oparg = (oparg << 8 ) | inst .op .arg ;
1702+ i ++ ;
1703+ inst = _Py_GetBaseCodeUnit (co , i );
1704+ opcode = inst .op .code ;
1705+ }
1706+ if (p_oparg != NULL ) {
1707+ * p_oparg = (oparg << 8 ) | inst .op .arg ;
1708+ }
1709+ * p_i = i ;
1710+ return inst ;
1711+ }
1712+
1713+
16941714// We may want to move these macros to pycore_opcode_utils.h
16951715// and use them in Python/bytecodes.c.
16961716#define LOAD_GLOBAL_NAME_INDEX (oparg ) ((oparg)>>1)
@@ -1731,9 +1751,9 @@ identify_unbound_names(PyThreadState *tstate, PyCodeObject *co,
17311751 struct co_unbound_counts unbound = {0 };
17321752 Py_ssize_t len = Py_SIZE (co );
17331753 for (int i = 0 ; i < len ; i += _PyInstruction_GetLength (co , i )) {
1734- _Py_CODEUNIT inst = _Py_GetBaseCodeUnit (co , i );
1754+ int oparg ;
1755+ _Py_CODEUNIT inst = advance_past_extended_arg (co , & i , & oparg );
17351756 if (inst .op .code == LOAD_ATTR ) {
1736- int oparg = GET_OPARG (co , i , inst .op .arg );
17371757 int index = LOAD_ATTR_NAME_INDEX (oparg );
17381758 PyObject * name = GETITEM (co -> co_names , index );
17391759 if (PySet_Contains (attrnames , name )) {
@@ -1749,7 +1769,6 @@ identify_unbound_names(PyThreadState *tstate, PyCodeObject *co,
17491769 }
17501770 }
17511771 else if (inst .op .code == LOAD_GLOBAL ) {
1752- int oparg = GET_OPARG (co , i , inst .op .arg );
17531772 int index = LOAD_ATTR_NAME_INDEX (oparg );
17541773 PyObject * name = GETITEM (co -> co_names , index );
17551774 if (PySet_Contains (globalnames , name )) {
@@ -1983,7 +2002,8 @@ code_returns_only_none(PyCodeObject *co)
19832002 if (IS_RETURN_OPCODE (inst .op .code )) {
19842003 assert (i != 0 );
19852004 // Ignore it if it returns None.
1986- _Py_CODEUNIT prev = _Py_GetBaseCodeUnit (co , i - 1 );
2005+ int prev_i = i - 1 ;
2006+ _Py_CODEUNIT prev = _Py_GetBaseCodeUnit (co , prev_i );
19872007 if (prev .op .code == LOAD_CONST ) {
19882008 // We don't worry about EXTENDED_ARG for now.
19892009 if (prev .op .arg == none_index ) {
0 commit comments