Skip to content

Commit 7194723

Browse files
committed
Fix crash when WITH_EXCEPT_START errors out
This was popping the common items off the stack.
1 parent 20062f4 commit 7194723

File tree

3 files changed

+17
-9
lines changed

3 files changed

+17
-9
lines changed

Python/bytecodes.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ do { \
8282
static PyObject *value, *value1, *value2, *left, *right, *res, *sum, *prod, *sub;
8383
static PyObject *container, *start, *stop, *v, *lhs, *rhs;
8484
static PyObject *list, *tuple, *dict;
85+
static PyObject *exit_func, *lasti, *val;
8586

8687
static PyObject *
8788
dummy_func(
@@ -2726,10 +2727,10 @@ dummy_func(
27262727

27272728
inst(WITH_EXCEPT_START, (exit_func, lasti, unused, val -- exit_func, lasti, unused, val, res)) {
27282729
/* At the top of the stack are 4 values:
2729-
- TOP = exc_info()
2730-
- SECOND = previous exception
2731-
- THIRD: lasti of exception in exc_info()
2732-
- FOURTH: the context.__exit__ bound method
2730+
- val: TOP = exc_info()
2731+
- unused: SECOND = previous exception
2732+
- lasti: THIRD = lasti of exception in exc_info()
2733+
- exit_func: FOURTH = the context.__exit__ bound method
27332734
We call FOURTH(type(TOP), TOP, GetTraceback(TOP)).
27342735
Then we push the __exit__ return value.
27352736
*/

Python/generated_cases.c.h

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tools/cases_generator/generate_cases.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,13 @@ def write_body(self, f: typing.TextIO, ndent: str, dedent: int) -> None:
161161
# The code block is responsible for DECREF()ing them.
162162
# NOTE: If the label doesn't exist, just add it to ceval.c.
163163
ninputs = len(self.input_effects)
164+
# Don't pop common input/output effects at the bottom!
165+
# These aren't DECREF'ed so they can stay.
166+
for ieff, oeff in zip(self.input_effects, self.output_effects):
167+
if ieff.name == oeff.name:
168+
ninputs -= 1
169+
else:
170+
break
164171
if ninputs:
165172
f.write(f"{space}if ({cond}) goto pop_{ninputs}_{label};\n")
166173
else:

0 commit comments

Comments
 (0)