gh-87092: move all localsplus preparation into separate function called from assembler stage (GH-99869)

This commit is contained in:
Irit Katriel 2022-11-30 12:37:30 +00:00 committed by GitHub
parent 417206a05c
commit ac12e3941f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -8730,6 +8730,41 @@ remove_redundant_jumps(cfg_builder *g) {
return 0; return 0;
} }
static int
prepare_localsplus(struct compiler* c, int code_flags)
{
assert(PyDict_GET_SIZE(c->u->u_varnames) < INT_MAX);
assert(PyDict_GET_SIZE(c->u->u_cellvars) < INT_MAX);
assert(PyDict_GET_SIZE(c->u->u_freevars) < INT_MAX);
int nlocals = (int)PyDict_GET_SIZE(c->u->u_varnames);
int ncellvars = (int)PyDict_GET_SIZE(c->u->u_cellvars);
int nfreevars = (int)PyDict_GET_SIZE(c->u->u_freevars);
assert(INT_MAX - nlocals - ncellvars > 0);
assert(INT_MAX - nlocals - ncellvars - nfreevars > 0);
int nlocalsplus = nlocals + ncellvars + nfreevars;
int* cellfixedoffsets = build_cellfixedoffsets(c);
if (cellfixedoffsets == NULL) {
return -1;
}
cfg_builder* g = CFG_BUILDER(c);
// This must be called before fix_cell_offsets().
if (insert_prefix_instructions(c, g->g_entryblock, cellfixedoffsets, nfreevars, code_flags)) {
PyMem_Free(cellfixedoffsets);
return -1;
}
int numdropped = fix_cell_offsets(c, g->g_entryblock, cellfixedoffsets);
PyMem_Free(cellfixedoffsets); // At this point we're done with it.
cellfixedoffsets = NULL;
if (numdropped < 0) {
return -1;
}
nlocalsplus -= numdropped;
return nlocalsplus;
}
static PyCodeObject * static PyCodeObject *
assemble(struct compiler *c, int addNone) assemble(struct compiler *c, int addNone)
{ {
@ -8751,20 +8786,6 @@ assemble(struct compiler *c, int addNone)
ADDOP(c, NO_LOCATION, RETURN_VALUE); ADDOP(c, NO_LOCATION, RETURN_VALUE);
} }
assert(PyDict_GET_SIZE(c->u->u_varnames) < INT_MAX);
assert(PyDict_GET_SIZE(c->u->u_cellvars) < INT_MAX);
assert(PyDict_GET_SIZE(c->u->u_freevars) < INT_MAX);
int nlocals = (int)PyDict_GET_SIZE(c->u->u_varnames);
int ncellvars = (int)PyDict_GET_SIZE(c->u->u_cellvars);
int nfreevars = (int)PyDict_GET_SIZE(c->u->u_freevars);
assert(INT_MAX - nlocals - ncellvars > 0);
assert(INT_MAX - nlocals - ncellvars - nfreevars > 0);
int nlocalsplus = nlocals + ncellvars + nfreevars;
int *cellfixedoffsets = build_cellfixedoffsets(c);
if (cellfixedoffsets == NULL) {
goto error;
}
int nblocks = 0; int nblocks = 0;
for (basicblock *b = CFG_BUILDER(c)->g_block_list; b != NULL; b = b->b_list) { for (basicblock *b = CFG_BUILDER(c)->g_block_list; b != NULL; b = b->b_list) {
nblocks++; nblocks++;
@ -8787,19 +8808,6 @@ assemble(struct compiler *c, int addNone)
} }
} }
// This must be called before fix_cell_offsets().
if (insert_prefix_instructions(c, g->g_entryblock, cellfixedoffsets, nfreevars, code_flags)) {
goto error;
}
int numdropped = fix_cell_offsets(c, g->g_entryblock, cellfixedoffsets);
PyMem_Free(cellfixedoffsets); // At this point we're done with it.
cellfixedoffsets = NULL;
if (numdropped < 0) {
goto error;
}
nlocalsplus -= numdropped;
/** Preprocessing **/ /** Preprocessing **/
/* Map labels to targets and mark exception handlers */ /* Map labels to targets and mark exception handlers */
if (translate_jump_labels_to_targets(g->g_entryblock)) { if (translate_jump_labels_to_targets(g->g_entryblock)) {
@ -8839,6 +8847,12 @@ assemble(struct compiler *c, int addNone)
} }
/** Assembly **/ /** Assembly **/
int nlocalsplus = prepare_localsplus(c, code_flags);
if (nlocalsplus < 0) {
goto error;
}
int maxdepth = stackdepth(g->g_entryblock, code_flags); int maxdepth = stackdepth(g->g_entryblock, code_flags);
if (maxdepth < 0) { if (maxdepth < 0) {
goto error; goto error;
@ -8904,9 +8918,6 @@ assemble(struct compiler *c, int addNone)
error: error:
Py_XDECREF(consts); Py_XDECREF(consts);
assemble_free(&a); assemble_free(&a);
if (cellfixedoffsets != NULL) {
PyMem_Free(cellfixedoffsets);
}
return co; return co;
} }