Skip to content

Commit ec03cf0

Browse files
Handle extended args.
1 parent 5b3c975 commit ec03cf0

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

Objects/codeobject.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)