◐ Shell
reader mode source ↗
Skip to content
Merged
Changes from 4 commits
File filter
Conversations
Jump to
Diff view
Apply and reload
Show whitespace
Diff view
Apply and reload
66 changes: 45 additions & 21 deletions Python/peephole.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,13 @@ fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t codelen,
PyTuple_SET_ITEM(newconst, i, constant);
}

/* Append folded constant onto consts */
if (PyList_Append(consts, newconst)) {
Py_DECREF(newconst);
Expand All @@ -160,7 +167,7 @@ fold_tuple_on_constants(_Py_CODEUNIT *codestr, Py_ssize_t codelen,
Py_DECREF(newconst);

return copy_op_arg(codestr, c_start, LOAD_CONST,
PyList_GET_SIZE(consts)-1, opcode_end);
}

static unsigned int *
Expand Down Expand Up @@ -221,7 +228,7 @@ PyObject *
PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
PyObject *lnotab_obj)
{
Py_ssize_t h, i, nexti, op_start, codelen, tgt;
unsigned int j, nops;
unsigned char opcode, nextop;
_Py_CODEUNIT *codestr = NULL;
Expand Down @@ -249,17 +256,22 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
the peephole optimizer doesn't modify line numbers. */

assert(PyBytes_Check(code));
codelen = PyBytes_GET_SIZE(code);
assert(codelen % sizeof(_Py_CODEUNIT) == 0);

/* Make a modifiable copy of the code string */
codestr = (_Py_CODEUNIT *)PyMem_Malloc(codelen);
if (codestr == NULL) {
PyErr_NoMemory();
goto exitError;
}
memcpy(codestr, PyBytes_AS_STRING(code), codelen);
codelen /= sizeof(_Py_CODEUNIT);

blocks = markblocks(codestr, codelen);
if (blocks == NULL)
Expand Down Expand Up @@ -357,7 +369,11 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
jump past it), and all conditional jumps pop their
argument when they're not taken (so change the
first jump to pop its argument when it's taken). */
h = set_arg(codestr, i, (tgt + 1) * sizeof(_Py_CODEUNIT));
j = opcode == JUMP_IF_TRUE_OR_POP ?
POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE;
}
Expand All @@ -383,17 +399,20 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
codestr[op_start] = PACKOPARG(RETURN_VALUE, 0);
fill_nops(codestr, op_start + 1, i + 1);
} else if (UNCONDITIONAL_JUMP(_Py_OPCODE(codestr[tgt]))) {
j = GETJUMPTGT(codestr, tgt);
if (opcode == JUMP_FORWARD) { /* JMP_ABS can go backwards */
opcode = JUMP_ABSOLUTE;
} else if (!ABSOLUTE_JUMP(opcode)) {
if ((Py_ssize_t)j < i + 1) {
break; /* No backward relative jumps */
}
j -= i + 1; /* Calc relative jump addr */
}
j *= sizeof(_Py_CODEUNIT);
copy_op_arg(codestr, op_start, opcode, j, i + 1);
}
break;

Expand Down @@ -427,11 +446,14 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,

/* Fixup lnotab */
for (i = 0, nops = 0; i < codelen; i++) {
assert(i - nops <= INT_MAX);
/* original code offset => new code offset */
blocks[i] = i - nops;
if (_Py_OPCODE(codestr[i]) == NOP)
nops++;
}
cum_orig_offset = 0;
last_offset = 0;
Expand Down Expand Up @@ -476,12 +498,14 @@ PyCode_Optimize(PyObject *code, PyObject* consts, PyObject *names,
j *= sizeof(_Py_CODEUNIT);
break;
}
nexti = i - op_start + 1;
if (instrsize(j) > nexti)
goto exitUnchanged;
/* If instrsize(j) < nexti, we'll emit EXTENDED_ARG 0 */
write_op_arg(codestr + h, opcode, j, nexti);
h += nexti;
}
assert(h + (Py_ssize_t)nops == codelen);

Expand Down
Toggle all file notes Toggle all file annotations