diff --git a/Python/compile.c b/Python/compile.c index dd8596defb8efe..da31f1c45c363e 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -8730,6 +8730,41 @@ remove_redundant_jumps(cfg_builder *g) { 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 * assemble(struct compiler *c, int addNone) { @@ -8751,20 +8786,6 @@ assemble(struct compiler *c, int addNone) 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; for (basicblock *b = CFG_BUILDER(c)->g_block_list; b != NULL; b = b->b_list) { 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 **/ /* Map labels to targets and mark exception handlers */ if (translate_jump_labels_to_targets(g->g_entryblock)) { @@ -8839,6 +8847,12 @@ assemble(struct compiler *c, int addNone) } /** Assembly **/ + + int nlocalsplus = prepare_localsplus(c, code_flags); + if (nlocalsplus < 0) { + goto error; + } + int maxdepth = stackdepth(g->g_entryblock, code_flags); if (maxdepth < 0) { goto error; @@ -8904,9 +8918,6 @@ assemble(struct compiler *c, int addNone) error: Py_XDECREF(consts); assemble_free(&a); - if (cellfixedoffsets != NULL) { - PyMem_Free(cellfixedoffsets); - } return co; }