Skip to content

Commit 4500eed

Browse files
[3.14] gh-156466: fix cleanup on error in codegen_function_body (GH-156511) (#156579)
Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>
1 parent 9c6905f commit 4500eed

1 file changed

Lines changed: 39 additions & 32 deletions

File tree

‎Python/codegen.c‎

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,44 @@ codegen_type_params(compiler *c, asdl_type_param_seq *type_params)
13201320
return SUCCESS;
13211321
}
13221322

1323+
static int
1324+
codegen_emit_function_body(compiler *c, asdl_stmt_seq *body)
1325+
{
1326+
PySTEntryObject *ste = SYMTABLE_ENTRY(c);
1327+
Py_ssize_t first_instr = 0;
1328+
if (ste->ste_has_docstring) {
1329+
PyObject *docstring = _PyAST_GetDocString(body);
1330+
assert(docstring);
1331+
first_instr = 1;
1332+
docstring = _PyCompile_CleanDoc(docstring);
1333+
if (docstring == NULL) {
1334+
return ERROR;
1335+
}
1336+
Py_ssize_t idx = _PyCompile_AddConst(c, docstring);
1337+
Py_DECREF(docstring);
1338+
RETURN_IF_ERROR(idx < 0 ? ERROR : SUCCESS);
1339+
}
1340+
1341+
NEW_JUMP_TARGET_LABEL(c, start);
1342+
USE_LABEL(c, start);
1343+
bool add_stopiteration_handler = ste->ste_coroutine || ste->ste_generator;
1344+
if (add_stopiteration_handler) {
1345+
/* codegen_wrap_in_stopiteration_handler will push a block, so we need to account for that */
1346+
RETURN_IF_ERROR(
1347+
_PyCompile_PushFBlock(c, NO_LOCATION, COMPILE_FBLOCK_STOP_ITERATION,
1348+
start, NO_LABEL, NULL));
1349+
}
1350+
1351+
for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(body); i++) {
1352+
VISIT(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
1353+
}
1354+
if (add_stopiteration_handler) {
1355+
RETURN_IF_ERROR(codegen_wrap_in_stopiteration_handler(c));
1356+
_PyCompile_PopFBlock(c, COMPILE_FBLOCK_STOP_ITERATION, start);
1357+
}
1358+
return SUCCESS;
1359+
}
1360+
13231361
static int
13241362
codegen_function_body(compiler *c, stmt_ty s, int is_async, Py_ssize_t funcflags,
13251363
int firstlineno)
@@ -1355,39 +1393,8 @@ codegen_function_body(compiler *c, stmt_ty s, int is_async, Py_ssize_t funcflags
13551393
RETURN_IF_ERROR(
13561394
codegen_enter_scope(c, name, scope_type, (void *)s, firstlineno, NULL, &umd));
13571395

1358-
PySTEntryObject *ste = SYMTABLE_ENTRY(c);
1359-
Py_ssize_t first_instr = 0;
1360-
if (ste->ste_has_docstring) {
1361-
PyObject *docstring = _PyAST_GetDocString(body);
1362-
assert(docstring);
1363-
first_instr = 1;
1364-
docstring = _PyCompile_CleanDoc(docstring);
1365-
if (docstring == NULL) {
1366-
_PyCompile_ExitScope(c);
1367-
return ERROR;
1368-
}
1369-
Py_ssize_t idx = _PyCompile_AddConst(c, docstring);
1370-
Py_DECREF(docstring);
1371-
RETURN_IF_ERROR_IN_SCOPE(c, idx < 0 ? ERROR : SUCCESS);
1372-
}
1396+
RETURN_IF_ERROR_IN_SCOPE(c, codegen_emit_function_body(c, body));
13731397

1374-
NEW_JUMP_TARGET_LABEL(c, start);
1375-
USE_LABEL(c, start);
1376-
bool add_stopiteration_handler = ste->ste_coroutine || ste->ste_generator;
1377-
if (add_stopiteration_handler) {
1378-
/* codegen_wrap_in_stopiteration_handler will push a block, so we need to account for that */
1379-
RETURN_IF_ERROR(
1380-
_PyCompile_PushFBlock(c, NO_LOCATION, COMPILE_FBLOCK_STOP_ITERATION,
1381-
start, NO_LABEL, NULL));
1382-
}
1383-
1384-
for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(body); i++) {
1385-
VISIT_IN_SCOPE(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
1386-
}
1387-
if (add_stopiteration_handler) {
1388-
RETURN_IF_ERROR_IN_SCOPE(c, codegen_wrap_in_stopiteration_handler(c));
1389-
_PyCompile_PopFBlock(c, COMPILE_FBLOCK_STOP_ITERATION, start);
1390-
}
13911398
PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
13921399
_PyCompile_ExitScope(c);
13931400
if (co == NULL) {

0 commit comments

Comments
 (0)