summaryrefslogtreecommitdiffstats
path: root/Python/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/compile.c')
-rw-r--r--Python/compile.c115
1 files changed, 64 insertions, 51 deletions
diff --git a/Python/compile.c b/Python/compile.c
index 3f620be..2f1130e 100644
--- a/Python/compile.c
+++ b/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 (!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;
+ }
+ if (HAS_TARGET(opcode)) {
+ int oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1));
if (PyErr_Occurred()) {
- return ERROR;
+ goto error;
}
- if (lbl_id <= 0 || lbl_id > instr_size) {
- /* expect label in a reasonable range */
+ if (oparg < 0 || oparg >= num_insts) {
PyErr_SetString(PyExc_ValueError, "label out of range");
- return ERROR;
+ goto error;
}
- jump_target_label lbl = {lbl_id};
+ 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));
}
- 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 oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1));
- if (PyErr_Occurred()) {
- return ERROR;
- }
- location loc;
- loc.lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 2));
- if (PyErr_Occurred()) {
- return 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));
+ 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;