mirror of
https://github.com/python/cpython.git
synced 2025-07-19 17:25:54 +00:00
gh-87092: Make jump target label equal to the offset of the target in the instructions sequence (#102093)
This commit is contained in:
parent
6b2d7c0ddb
commit
9f799ab020
4 changed files with 116 additions and 113 deletions
117
Python/compile.c
117
Python/compile.c
|
@ -9704,56 +9704,77 @@ instructions_to_cfg(PyObject *instructions, cfg_builder *g)
|
|||
{
|
||||
assert(PyList_Check(instructions));
|
||||
|
||||
Py_ssize_t instr_size = PyList_GET_SIZE(instructions);
|
||||
for (Py_ssize_t i = 0; i < instr_size; i++) {
|
||||
Py_ssize_t num_insts = PyList_GET_SIZE(instructions);
|
||||
bool *is_target = PyMem_Calloc(num_insts, sizeof(bool));
|
||||
if (is_target == NULL) {
|
||||
return ERROR;
|
||||
}
|
||||
for (Py_ssize_t i = 0; i < num_insts; i++) {
|
||||
PyObject *item = PyList_GET_ITEM(instructions, i);
|
||||
if (PyLong_Check(item)) {
|
||||
int lbl_id = PyLong_AsLong(item);
|
||||
if (PyErr_Occurred()) {
|
||||
return ERROR;
|
||||
}
|
||||
if (lbl_id <= 0 || lbl_id > instr_size) {
|
||||
/* expect label in a reasonable range */
|
||||
PyErr_SetString(PyExc_ValueError, "label out of range");
|
||||
return ERROR;
|
||||
}
|
||||
jump_target_label lbl = {lbl_id};
|
||||
RETURN_IF_ERROR(cfg_builder_use_label(g, lbl));
|
||||
if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 6) {
|
||||
PyErr_SetString(PyExc_ValueError, "expected a 6-tuple");
|
||||
goto error;
|
||||
}
|
||||
else {
|
||||
if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 6) {
|
||||
PyErr_SetString(PyExc_ValueError, "expected a 6-tuple");
|
||||
return ERROR;
|
||||
}
|
||||
int opcode = PyLong_AsLong(PyTuple_GET_ITEM(item, 0));
|
||||
if (PyErr_Occurred()) {
|
||||
return ERROR;
|
||||
}
|
||||
int opcode = PyLong_AsLong(PyTuple_GET_ITEM(item, 0));
|
||||
if (PyErr_Occurred()) {
|
||||
goto error;
|
||||
}
|
||||
if (HAS_TARGET(opcode)) {
|
||||
int oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1));
|
||||
if (PyErr_Occurred()) {
|
||||
return ERROR;
|
||||
goto error;
|
||||
}
|
||||
location loc;
|
||||
loc.lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 2));
|
||||
if (PyErr_Occurred()) {
|
||||
return ERROR;
|
||||
if (oparg < 0 || oparg >= num_insts) {
|
||||
PyErr_SetString(PyExc_ValueError, "label out of range");
|
||||
goto error;
|
||||
}
|
||||
loc.end_lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 3));
|
||||
if (PyErr_Occurred()) {
|
||||
return ERROR;
|
||||
}
|
||||
loc.col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 4));
|
||||
if (PyErr_Occurred()) {
|
||||
return ERROR;
|
||||
}
|
||||
loc.end_col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 5));
|
||||
if (PyErr_Occurred()) {
|
||||
return ERROR;
|
||||
}
|
||||
RETURN_IF_ERROR(cfg_builder_addop(g, opcode, oparg, loc));
|
||||
is_target[oparg] = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_insts; i++) {
|
||||
if (is_target[i]) {
|
||||
jump_target_label lbl = {i};
|
||||
RETURN_IF_ERROR(cfg_builder_use_label(g, lbl));
|
||||
}
|
||||
PyObject *item = PyList_GET_ITEM(instructions, i);
|
||||
if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 6) {
|
||||
PyErr_SetString(PyExc_ValueError, "expected a 6-tuple");
|
||||
goto error;
|
||||
}
|
||||
int opcode = PyLong_AsLong(PyTuple_GET_ITEM(item, 0));
|
||||
if (PyErr_Occurred()) {
|
||||
goto error;
|
||||
}
|
||||
int oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1));
|
||||
if (PyErr_Occurred()) {
|
||||
goto error;
|
||||
}
|
||||
location loc;
|
||||
loc.lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 2));
|
||||
if (PyErr_Occurred()) {
|
||||
goto error;
|
||||
}
|
||||
loc.end_lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 3));
|
||||
if (PyErr_Occurred()) {
|
||||
goto error;
|
||||
}
|
||||
loc.col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 4));
|
||||
if (PyErr_Occurred()) {
|
||||
goto error;
|
||||
}
|
||||
loc.end_col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 5));
|
||||
if (PyErr_Occurred()) {
|
||||
goto error;
|
||||
}
|
||||
RETURN_IF_ERROR(cfg_builder_addop(g, opcode, oparg, loc));
|
||||
}
|
||||
|
||||
PyMem_Free(is_target);
|
||||
return SUCCESS;
|
||||
error:
|
||||
PyMem_Free(is_target);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
|
@ -9763,20 +9784,12 @@ cfg_to_instructions(cfg_builder *g)
|
|||
if (instructions == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
int lbl = 1;
|
||||
int lbl = 0;
|
||||
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
|
||||
b->b_label = lbl++;
|
||||
b->b_label = lbl;
|
||||
lbl += b->b_iused;
|
||||
}
|
||||
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
|
||||
PyObject *lbl = PyLong_FromLong(b->b_label);
|
||||
if (lbl == NULL) {
|
||||
goto error;
|
||||
}
|
||||
if (PyList_Append(instructions, lbl) != 0) {
|
||||
Py_DECREF(lbl);
|
||||
goto error;
|
||||
}
|
||||
Py_DECREF(lbl);
|
||||
for (int i = 0; i < b->b_iused; i++) {
|
||||
struct instr *instr = &b->b_instr[i];
|
||||
location loc = instr->i_loc;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue