Skip to content

Commit

Permalink
stop pushing the exception type onto the stack
Browse files Browse the repository at this point in the history
  • Loading branch information
cfbolz committed Sep 27, 2024
1 parent 397cadd commit ac1a884
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 15 deletions.
10 changes: 8 additions & 2 deletions pypy/interpreter/astcompiler/assemble.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ def __init__(self):
self.exits_function = False
self.auto_inserted_return = False

def __repr__(self):
return "<Block %s>" % (self.instructions, )

def emit_instr(self, instr):
self.instructions.append(instr)
op = instr.opcode
Expand Down Expand Up @@ -326,6 +329,9 @@ def __init__(self, space, name, first_lineno, scope, compile_info):
self.add_none_to_final_return = True
self.match_context = None

def __repr__(self):
return "<PythonCodeMaker %s in %s:%s>" % (self.name, self.compile_info.filename, self.first_lineno)

def _check_consistency(self, blocks):
current_off = 0
for block in blocks:
Expand Down Expand Up @@ -1092,7 +1098,7 @@ def _list_from_dict(d, offset=0):
ops.GET_AITER: 0,
ops.GET_ANEXT: 1,
ops.GET_YIELD_FROM_ITER: 0,
ops.END_ASYNC_FOR: -4,
ops.END_ASYNC_FOR: -3,

ops.LOAD_CONST: 1,

Expand Down Expand Up @@ -1236,7 +1242,7 @@ def _opcode_stack_effect_jump(op):
elif op == ops.SETUP_FINALLY:
return 1
elif op == ops.SETUP_EXCEPT:
return 3
return 2
elif op == ops.SETUP_WITH:
return 1
elif op == ops.SETUP_ASYNC_WITH:
Expand Down
8 changes: 3 additions & 5 deletions pypy/interpreter/astcompiler/codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -887,6 +887,8 @@ def _visit_try_except(self, tr):
self.use_next_block(exc)
self.push_frame_block(F_EXCEPTION_HANDLER, None)
handler = None
if self.name == "_spec_from_module":
import pdb;pdb.set_trace()
for i, handler in enumerate(tr.handlers):
assert isinstance(handler, ast.ExceptHandler)
self.update_position(handler)
Expand All @@ -899,7 +901,6 @@ def _visit_try_except(self, tr):
if i != len(tr.handlers) - 1:
self.error(
"bare 'except:' must be the last except block", handler)
self.emit_op(ops.POP_TOP)
if handler.name:
## generate the equivalent of:
##
Expand Down Expand Up @@ -957,7 +958,6 @@ def _visit_try_except(self, tr):
self.pop_frame_block(F_EXCEPTION_HANDLER, None)
# pypy difference: get rid of exception
self.emit_op(ops.POP_TOP)
self.emit_op(ops.POP_TOP)
self.emit_op(ops.RERAISE) # reraise uses the SApplicationException
self.use_next_block(otherwise)
self._visit_body(tr.orelse)
Expand Down Expand Up @@ -1092,7 +1092,6 @@ def _visit_try_except_star(self, tr):
next_except_with_nop = self.new_block() # L2 in comment above
assert handler.type is not None
if i == 0:
self.emit_op(ops.POP_TOP) # XXX pypy difference: exception type is on stack
self.emit_op(ops.DUP_TOP)
self.emit_op(ops.BUILD_LIST)
self.emit_op(ops.ROT_TWO)
Expand Down Expand Up @@ -1138,7 +1137,6 @@ def _visit_try_except_star(self, tr):
self.name_op(handler.name, ast.Store, handler)
self.name_op(handler.name, ast.Del, handler)

self.emit_op(ops.POP_TOP) # get rid of type
self.emit_op_arg(ops.LIST_APPEND, 3)
self.emit_op(ops.POP_TOP)
self.emit_jump(ops.JUMP_FORWARD, next_except)
Expand Down Expand Up @@ -1167,7 +1165,7 @@ def _visit_try_except_star(self, tr):
if handler is not None:
self.update_position(handler)
self.pop_frame_block(F_EXCEPTION_GROUP_HANDLER, None)
# pypy difference: get rid of exception # XXX is this correct for groups?
# pypy difference: get rid of exception
self.emit_op(ops.ROT_TWO)
self.emit_op(ops.POP_TOP)
self.emit_op(ops.RERAISE)
Expand Down
4 changes: 2 additions & 2 deletions pypy/interpreter/astcompiler/test/test_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,7 @@ def test_stackeffect_bug3(self):
finally: pass
"""
code = compile_with_astcompiler(source, 'exec', self.space)
assert code.co_stacksize == 1
assert code.co_stacksize == 2 # maybe should be 1

def test_stackeffect_bug4(self):
source = """if 1:
Expand Down Expand Up @@ -1014,7 +1014,7 @@ def test_stackeffect_try_except_precision(self):
print(6)
"""
code = compile_with_astcompiler(source, 'exec', self.space)
assert code.co_stacksize == 5 # used to be 6
assert code.co_stacksize == 4 # used to be 6, then 5

def test_lambda(self):
yield self.st, "y = lambda x: x", "y(4)", 4
Expand Down
10 changes: 4 additions & 6 deletions pypy/interpreter/pyopcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -969,7 +969,7 @@ def cmp_exc_match(self, w_1, w_2):
raise oefmt(space.w_TypeError, CANNOT_CATCH_MSG)
elif not space.exception_is_valid_class_w(w_2):
raise oefmt(space.w_TypeError, CANNOT_CATCH_MSG)
return space.exception_match(w_1, w_2)
return space.exception_match(space.type(w_1), w_2)

def COMPARE_OP(self, testnum, next_instr):
w_2 = self.popvalue()
Expand Down Expand Up @@ -1599,14 +1599,13 @@ def END_ASYNC_FOR(self, oparg, next_instr):
assert isinstance(block, SysExcInfoRestorer)
block.cleanupstack(self) # restores ec.sys_exc_operror

w_typ = self.popvalue()
if self.space.exception_match(w_typ, self.space.w_StopAsyncIteration):
self.popvalue() # w_exc
w_exc = self.popvalue()
if self.space.exception_match(self.space.type(w_exc), self.space.w_StopAsyncIteration):
self.popvalue() # unroller
self.popvalue() # aiter
return next_instr
else:
unroller = self.peekvalue(1)
unroller = self.peekvalue(0)
if not isinstance(unroller, SApplicationException):
raise oefmt(self.space.w_RuntimeError,
"END_ASYNC_FOR found no exception")
Expand Down Expand Up @@ -1900,7 +1899,6 @@ def handle(self, frame, unroller):
w_value = operationerr.normalize_exception(frame.space)
frame.pushvalue(unroller)
frame.pushvalue(w_value)
frame.pushvalue(operationerr.w_type)
# set the current value of sys_exc_info to operationerr,
# saving the old value in a custom type of FrameBlock
frame.save_and_change_sys_exc_info(operationerr)
Expand Down

0 comments on commit ac1a884

Please sign in to comment.