Skip to content

Commit e2d4d04

Browse files
[3.15] gh-156466: fix cleanup on error in codegen_function_body (GH-156511) (GH-156578)
(cherry picked from commit d94c4ad) Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>
1 parent 6d34079 commit e2d4d04

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
@@ -1370,6 +1370,44 @@ codegen_type_params(compiler *c, asdl_type_param_seq *type_params)
13701370
return SUCCESS;
13711371
}
13721372

1373+
static int
1374+
codegen_emit_function_body(compiler *c, asdl_stmt_seq *body)
1375+
{
1376+
PySTEntryObject *ste = SYMTABLE_ENTRY(c);
1377+
Py_ssize_t first_instr = 0;
1378+
if (ste->ste_has_docstring) {
1379+
PyObject *docstring = _PyAST_GetDocString(body);
1380+
assert(docstring);
1381+
first_instr = 1;
1382+
docstring = _PyCompile_CleanDoc(docstring);
1383+
if (docstring == NULL) {
1384+
return ERROR;
1385+
}
1386+
Py_ssize_t idx = _PyCompile_AddConst(c, docstring);
1387+
Py_DECREF(docstring);
1388+
RETURN_IF_ERROR(idx < 0 ? ERROR : SUCCESS);
1389+
}
1390+
1391+
NEW_JUMP_TARGET_LABEL(c, start);
1392+
USE_LABEL(c, start);
1393+
bool add_stopiteration_handler = ste->ste_coroutine || ste->ste_generator;
1394+
if (add_stopiteration_handler) {
1395+
/* codegen_wrap_in_stopiteration_handler will push a block, so we need to account for that */
1396+
RETURN_IF_ERROR(
1397+
_PyCompile_PushFBlock(c, NO_LOCATION, COMPILE_FBLOCK_STOP_ITERATION,
1398+
start, NO_LABEL, NULL));
1399+
}
1400+
1401+
for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(body); i++) {
1402+
VISIT(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
1403+
}
1404+
if (add_stopiteration_handler) {
1405+
RETURN_IF_ERROR(codegen_wrap_in_stopiteration_handler(c));
1406+
_PyCompile_PopFBlock(c, COMPILE_FBLOCK_STOP_ITERATION, start);
1407+
}
1408+
return SUCCESS;
1409+
}
1410+
13731411
static int
13741412
codegen_function_body(compiler *c, stmt_ty s, int is_async, Py_ssize_t funcflags,
13751413
int firstlineno)
@@ -1405,39 +1443,8 @@ codegen_function_body(compiler *c, stmt_ty s, int is_async, Py_ssize_t funcflags
14051443
RETURN_IF_ERROR(
14061444
codegen_enter_scope(c, name, scope_type, (void *)s, firstlineno, NULL, &umd));
14071445

1408-
PySTEntryObject *ste = SYMTABLE_ENTRY(c);
1409-
Py_ssize_t first_instr = 0;
1410-
if (ste->ste_has_docstring) {
1411-
PyObject *docstring = _PyAST_GetDocString(body);
1412-
assert(docstring);
1413-
first_instr = 1;
1414-
docstring = _PyCompile_CleanDoc(docstring);
1415-
if (docstring == NULL) {
1416-
_PyCompile_ExitScope(c);
1417-
return ERROR;
1418-
}
1419-
Py_ssize_t idx = _PyCompile_AddConst(c, docstring);
1420-
Py_DECREF(docstring);
1421-
RETURN_IF_ERROR_IN_SCOPE(c, idx < 0 ? ERROR : SUCCESS);
1422-
}
1446+
RETURN_IF_ERROR_IN_SCOPE(c, codegen_emit_function_body(c, body));
14231447

1424-
NEW_JUMP_TARGET_LABEL(c, start);
1425-
USE_LABEL(c, start);
1426-
bool add_stopiteration_handler = ste->ste_coroutine || ste->ste_generator;
1427-
if (add_stopiteration_handler) {
1428-
/* codegen_wrap_in_stopiteration_handler will push a block, so we need to account for that */
1429-
RETURN_IF_ERROR(
1430-
_PyCompile_PushFBlock(c, NO_LOCATION, COMPILE_FBLOCK_STOP_ITERATION,
1431-
start, NO_LABEL, NULL));
1432-
}
1433-
1434-
for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(body); i++) {
1435-
VISIT_IN_SCOPE(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
1436-
}
1437-
if (add_stopiteration_handler) {
1438-
RETURN_IF_ERROR_IN_SCOPE(c, codegen_wrap_in_stopiteration_handler(c));
1439-
_PyCompile_PopFBlock(c, COMPILE_FBLOCK_STOP_ITERATION, start);
1440-
}
14411448
PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
14421449
_PyCompile_ExitScope(c);
14431450
if (co == NULL) {

0 commit comments

Comments
 (0)