>> 14 PUSH_EXC_INFO
%3d 16 LOAD_GLOBAL 0 (Exception)
- 18 JUMP_IF_NOT_EXC_MATCH 26 (to 52)
- 20 POP_TOP
- 22 STORE_FAST 0 (e)
- 24 POP_TOP
-
-%3d 26 LOAD_FAST 0 (e)
- 28 LOAD_ATTR 1 (__traceback__)
- 30 STORE_FAST 1 (tb)
- 32 POP_EXCEPT
- 34 LOAD_CONST 0 (None)
- 36 STORE_FAST 0 (e)
- 38 DELETE_FAST 0 (e)
-
-%3d 40 LOAD_FAST 1 (tb)
- 42 RETURN_VALUE
- >> 44 LOAD_CONST 0 (None)
- 46 STORE_FAST 0 (e)
- 48 DELETE_FAST 0 (e)
- 50 RERAISE 1
-
-%3d >> 52 RERAISE 0
- >> 54 POP_EXCEPT_AND_RERAISE
+ 18 JUMP_IF_NOT_EXC_MATCH 24 (to 48)
+ 20 STORE_FAST 0 (e)
+
+%3d 22 LOAD_FAST 0 (e)
+ 24 LOAD_ATTR 1 (__traceback__)
+ 26 STORE_FAST 1 (tb)
+ 28 POP_EXCEPT
+ 30 LOAD_CONST 0 (None)
+ 32 STORE_FAST 0 (e)
+ 34 DELETE_FAST 0 (e)
+
+%3d 36 LOAD_FAST 1 (tb)
+ 38 RETURN_VALUE
+ >> 40 LOAD_CONST 0 (None)
+ 42 STORE_FAST 0 (e)
+ 44 DELETE_FAST 0 (e)
+ 46 RERAISE 1
+
+%3d >> 48 RERAISE 0
+ >> 50 POP_EXCEPT_AND_RERAISE
ExceptionTable:
2 to 8 -> 14 [0]
- 14 to 24 -> 54 [3] lasti
- 26 to 30 -> 44 [3] lasti
- 44 to 52 -> 54 [3] lasti
+ 14 to 20 -> 50 [1] lasti
+ 22 to 26 -> 40 [1] lasti
+ 40 to 48 -> 50 [1] lasti
""" % (TRACEBACK_CODE.co_firstlineno + 1,
TRACEBACK_CODE.co_firstlineno + 2,
TRACEBACK_CODE.co_firstlineno + 5,
>> 22 POP_EXCEPT_AND_RERAISE
ExceptionTable:
2 to 2 -> 12 [0]
- 12 to 20 -> 22 [3] lasti
+ 12 to 20 -> 22 [1] lasti
""" % (_tryfinally.__code__.co_firstlineno + 1,
_tryfinally.__code__.co_firstlineno + 2,
_tryfinally.__code__.co_firstlineno + 4,
22 RERAISE 0
>> 24 POP_EXCEPT_AND_RERAISE
ExceptionTable:
- 14 to 22 -> 24 [3] lasti
+ 14 to 22 -> 24 [1] lasti
""" % (_tryfinallyconst.__code__.co_firstlineno + 1,
_tryfinallyconst.__code__.co_firstlineno + 2,
_tryfinallyconst.__code__.co_firstlineno + 4,
Positional-only arguments: 0
Kw-only arguments: 0
Number of locals: 2
-Stack size: 10
+Stack size: 6
Flags: OPTIMIZED, NEWLOCALS, COROUTINE
Constants:
0: None
Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=108, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=110, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=112, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='JUMP_FORWARD', opcode=110, arg=14, argval=144, argrepr='to 144', offset=114, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='JUMP_FORWARD', opcode=110, arg=12, argval=140, argrepr='to 140', offset=114, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=116, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_GLOBAL', opcode=116, arg=2, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=118, starts_line=22, is_jump_target=False, positions=None),
- Instruction(opname='JUMP_IF_NOT_EXC_MATCH', opcode=121, arg=70, argval=140, argrepr='to 140', offset=120, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='JUMP_IF_NOT_EXC_MATCH', opcode=121, arg=68, argval=136, argrepr='to 136', offset=120, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=122, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=124, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=126, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=128, starts_line=23, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=130, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='CALL_NO_KW', opcode=169, arg=1, argval=1, argrepr='', offset=132, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=134, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=136, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='JUMP_FORWARD', opcode=110, arg=32, argval=204, argrepr='to 204', offset=138, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=140, starts_line=22, is_jump_target=True, positions=None),
- Instruction(opname='POP_EXCEPT_AND_RERAISE', opcode=37, arg=None, argval=None, argrepr='', offset=142, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=144, starts_line=25, is_jump_target=True, positions=None),
- Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=146, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=148, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=150, starts_line=26, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Never reach this', argrepr="'Never reach this'", offset=152, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='CALL_NO_KW', opcode=169, arg=1, argval=1, argrepr='', offset=154, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=156, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=158, starts_line=25, is_jump_target=False, positions=None),
- Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=160, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=162, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='CALL_NO_KW', opcode=169, arg=3, argval=3, argrepr='', offset=164, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=166, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='JUMP_FORWARD', opcode=110, arg=11, argval=192, argrepr='to 192', offset=168, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=170, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=172, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=90, argval=180, argrepr='to 180', offset=174, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='RERAISE', opcode=119, arg=4, argval=4, argrepr='', offset=176, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_EXCEPT_AND_RERAISE', opcode=37, arg=None, argval=None, argrepr='', offset=178, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=180, starts_line=None, is_jump_target=True, positions=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=124, starts_line=23, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=100, arg=8, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=126, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='CALL_NO_KW', opcode=169, arg=1, argval=1, argrepr='', offset=128, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=130, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=132, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='JUMP_FORWARD', opcode=110, arg=30, argval=196, argrepr='to 196', offset=134, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=136, starts_line=22, is_jump_target=True, positions=None),
+ Instruction(opname='POP_EXCEPT_AND_RERAISE', opcode=37, arg=None, argval=None, argrepr='', offset=138, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=140, starts_line=25, is_jump_target=True, positions=None),
+ Instruction(opname='BEFORE_WITH', opcode=53, arg=None, argval=None, argrepr='', offset=142, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='STORE_FAST', opcode=125, arg=1, argval='dodgy', argrepr='dodgy', offset=144, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=146, starts_line=26, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=100, arg=9, argval='Never reach this', argrepr="'Never reach this'", offset=148, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='CALL_NO_KW', opcode=169, arg=1, argval=1, argrepr='', offset=150, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=152, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=154, starts_line=25, is_jump_target=False, positions=None),
+ Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=156, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='DUP_TOP', opcode=4, arg=None, argval=None, argrepr='', offset=158, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='CALL_NO_KW', opcode=169, arg=3, argval=3, argrepr='', offset=160, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=162, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='JUMP_FORWARD', opcode=110, arg=9, argval=184, argrepr='to 184', offset=164, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=166, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='WITH_EXCEPT_START', opcode=49, arg=None, argval=None, argrepr='', offset=168, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='POP_JUMP_IF_TRUE', opcode=115, arg=88, argval=176, argrepr='to 176', offset=170, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='RERAISE', opcode=119, arg=2, argval=2, argrepr='', offset=172, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='POP_EXCEPT_AND_RERAISE', opcode=37, arg=None, argval=None, argrepr='', offset=174, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=176, starts_line=None, is_jump_target=True, positions=None),
+ Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=178, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=180, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=182, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=184, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_EXCEPT', opcode=89, arg=None, argval=None, argrepr='', offset=186, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=188, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=184, starts_line=28, is_jump_target=True, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=186, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='CALL_NO_KW', opcode=169, arg=1, argval=1, argrepr='', offset=188, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=190, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=192, starts_line=28, is_jump_target=True, positions=None),
- Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=194, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='CALL_NO_KW', opcode=169, arg=1, argval=1, argrepr='', offset=196, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=198, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=200, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=202, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=204, starts_line=23, is_jump_target=True, positions=None),
- Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=206, starts_line=28, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=208, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='CALL_NO_KW', opcode=169, arg=1, argval=1, argrepr='', offset=210, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=212, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=214, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=216, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=218, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=220, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=222, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='CALL_NO_KW', opcode=169, arg=1, argval=1, argrepr='', offset=224, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=226, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=228, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_EXCEPT_AND_RERAISE', opcode=37, arg=None, argval=None, argrepr='', offset=230, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=192, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=194, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=196, starts_line=23, is_jump_target=True, positions=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=198, starts_line=28, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=200, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='CALL_NO_KW', opcode=169, arg=1, argval=1, argrepr='', offset=202, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=204, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=100, arg=0, argval=None, argrepr='None', offset=206, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='RETURN_VALUE', opcode=83, arg=None, argval=None, argrepr='', offset=208, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=210, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=116, arg=1, argval='print', argrepr='print', offset=212, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=100, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=214, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='CALL_NO_KW', opcode=169, arg=1, argval=1, argrepr='', offset=216, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=218, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='RERAISE', opcode=119, arg=0, argval=0, argrepr='', offset=220, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='POP_EXCEPT_AND_RERAISE', opcode=37, arg=None, argval=None, argrepr='', offset=222, starts_line=None, is_jump_target=False, positions=None),
]
# One last piece of inspect fodder to check the default line number handling
static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause);
static PyObject *do_reraise_star(PyObject *excs, PyObject *orig);
static int exception_group_match(
- PyObject *exc_type, PyObject* exc_value, PyObject *match_type,
+ PyObject* exc_value, PyObject *match_type,
PyObject **match, PyObject **rest);
static int unpack_iterable(PyThreadState *, PyObject *, int, int, PyObject **);
-#ifdef Py_DEBUG
-static void
-_assert_exception_type_is_redundant(PyObject* type, PyObject* val)
-{
- if (type == NULL || type == Py_None) {
- assert(val == type);
- }
- else {
- assert(PyExceptionInstance_Check(val));
- assert(PyExceptionInstance_Class(val) == type);
- }
-}
-
-#define ASSERT_EXC_TYPE_IS_REDUNDANT(t, v) _assert_exception_type_is_redundant(t, v)
-#else
-#define ASSERT_EXC_TYPE_IS_REDUNDANT(t, v)
-#endif
-
PyObject *
PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals)
{
}
TARGET(POP_EXCEPT) {
- PyObject *type, *value, *traceback;
- _PyErr_StackItem *exc_info;
- exc_info = tstate->exc_info;
- type = exc_info->exc_type;
- value = exc_info->exc_value;
- traceback = exc_info->exc_traceback;
-
- exc_info->exc_type = POP();
+ _PyErr_StackItem *exc_info = tstate->exc_info;
+ PyObject *value = exc_info->exc_value;
exc_info->exc_value = POP();
- exc_info->exc_traceback = POP();
- ASSERT_EXC_TYPE_IS_REDUNDANT(exc_info->exc_type, exc_info->exc_value);
- Py_XDECREF(type);
Py_XDECREF(value);
- Py_XDECREF(traceback);
DISPATCH();
}
TARGET(POP_EXCEPT_AND_RERAISE) {
- PyObject *lasti = PEEK(4);
+ PyObject *lasti = PEEK(2);
if (PyLong_Check(lasti)) {
frame->f_lasti = PyLong_AsLong(lasti);
assert(!_PyErr_Occurred(tstate));
_PyErr_SetString(tstate, PyExc_SystemError, "lasti is not an int");
goto error;
}
- PyObject *type, *value, *traceback;
- _PyErr_StackItem *exc_info;
- type = POP();
- value = POP();
- traceback = POP();
- ASSERT_EXC_TYPE_IS_REDUNDANT(type, value);
+ PyObject *value = POP();
+ assert(value);
+ assert(PyExceptionInstance_Check(value));
+ PyObject *type = Py_NewRef(PyExceptionInstance_Class(value));
+ PyObject *traceback = PyException_GetTraceback(value);
Py_DECREF(POP()); /* lasti */
_PyErr_Restore(tstate, type, value, traceback);
- exc_info = tstate->exc_info;
- type = exc_info->exc_type;
+
+ _PyErr_StackItem *exc_info = tstate->exc_info;
value = exc_info->exc_value;
- traceback = exc_info->exc_traceback;
- exc_info->exc_type = POP();
exc_info->exc_value = POP();
- exc_info->exc_traceback = POP();
- ASSERT_EXC_TYPE_IS_REDUNDANT(exc_info->exc_type, exc_info->exc_value);
- Py_XDECREF(type);
Py_XDECREF(value);
- Py_XDECREF(traceback);
goto exception_unwind;
}
TARGET(RERAISE) {
if (oparg) {
- PyObject *lasti = PEEK(oparg+3);
+ PyObject *lasti = PEEK(oparg + 1);
if (PyLong_Check(lasti)) {
frame->f_lasti = PyLong_AsLong(lasti);
assert(!_PyErr_Occurred(tstate));
goto error;
}
}
- PyObject *exc = POP();
PyObject *val = POP();
- PyObject *tb = POP();
- ASSERT_EXC_TYPE_IS_REDUNDANT(exc, val);
- assert(PyExceptionClass_Check(exc));
+ assert(val && PyExceptionInstance_Check(val));
+ PyObject *exc = Py_NewRef(PyExceptionInstance_Class(val));
+ PyObject *tb = PyException_GetTraceback(val);
_PyErr_Restore(tstate, exc, val, tb);
goto exception_unwind;
}
PyObject *lasti_unused = Py_NewRef(_PyLong_GetZero());
PUSH(lasti_unused);
- if (!Py_IsNone(val)) {
- PyObject *tb = PyException_GetTraceback(val);
- PUSH(tb ? tb : Py_NewRef(Py_None));
- PUSH(val);
- PUSH(Py_NewRef(Py_TYPE(val)));
- }
- else {
- // nothing to reraise
- PUSH(Py_NewRef(Py_None));
- PUSH(val);
- PUSH(Py_NewRef(Py_None));
- }
+ PUSH(val);
DISPATCH();
}
TARGET(END_ASYNC_FOR) {
- PyObject *exc = POP();
PyObject *val = POP();
- PyObject *tb = POP();
- ASSERT_EXC_TYPE_IS_REDUNDANT(exc, val);
- assert(PyExceptionClass_Check(exc));
- if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) {
- Py_DECREF(exc);
+ assert(val && PyExceptionInstance_Check(val));
+ if (PyErr_GivenExceptionMatches(val, PyExc_StopAsyncIteration)) {
Py_DECREF(val);
- Py_DECREF(tb);
Py_DECREF(POP());
DISPATCH();
}
else {
+ PyObject *exc = Py_NewRef(PyExceptionInstance_Class(val));
+ PyObject *tb = PyException_GetTraceback(val);
_PyErr_Restore(tstate, exc, val, tb);
goto exception_unwind;
}
TARGET(JUMP_IF_NOT_EG_MATCH) {
PyObject *match_type = POP();
- PyObject *exc_type = TOP();
- PyObject *exc_value = SECOND();
if (check_except_star_type_valid(tstate, match_type) < 0) {
Py_DECREF(match_type);
goto error;
}
+ PyObject *exc_value = TOP();
PyObject *match = NULL, *rest = NULL;
- int res = exception_group_match(exc_type, exc_value,
- match_type, &match, &rest);
+ int res = exception_group_match(exc_value, match_type,
+ &match, &rest);
Py_DECREF(match_type);
if (res < 0) {
goto error;
else {
/* Total or partial match - update the stack from
- * [tb, val, exc]
+ * [val]
* to
- * [tb, rest, exc, tb, match, exc]
+ * [rest, match]
* (rest can be Py_None)
*/
+ PyObject *exc = TOP();
- PyObject *type = TOP();
- PyObject *val = SECOND();
- PyObject *tb = THIRD();
-
- if (!Py_IsNone(rest)) {
- /* tb remains the same */
- SET_TOP(Py_NewRef(Py_TYPE(rest)));
- SET_SECOND(Py_NewRef(rest));
- SET_THIRD(Py_NewRef(tb));
- }
- else {
- SET_TOP(Py_NewRef(Py_None));
- SET_SECOND(Py_NewRef(Py_None));
- SET_THIRD(Py_NewRef(Py_None));
- }
- /* Push match */
+ SET_TOP(rest);
+ PUSH(match);
- PUSH(Py_NewRef(tb));
- PUSH(Py_NewRef(match));
- PUSH(Py_NewRef(Py_TYPE(match)));
+ PyErr_SetExcInfo(NULL, Py_NewRef(match), NULL);
- // set exc_info to the current match
- PyErr_SetExcInfo(
- Py_NewRef(Py_TYPE(match)),
- Py_NewRef(match),
- Py_NewRef(tb));
-
- Py_DECREF(tb);
- Py_DECREF(val);
- Py_DECREF(type);
+ Py_DECREF(exc);
- Py_DECREF(match);
- Py_DECREF(rest);
}
DISPATCH();
TARGET(JUMP_IF_NOT_EXC_MATCH) {
PyObject *right = POP();
- ASSERT_EXC_TYPE_IS_REDUNDANT(TOP(), SECOND());
- PyObject *left = SECOND();
+ PyObject *left = TOP();
assert(PyExceptionInstance_Check(left));
if (check_except_type_valid(tstate, right) < 0) {
Py_DECREF(right);
}
TARGET(WITH_EXCEPT_START) {
- /* At the top of the stack are 8 values:
- - (TOP, SECOND, THIRD) = exc_info()
- - (FOURTH, FIFTH, SIXTH) = previous exception
- - SEVENTH: lasti of exception in exc_info()
- - EIGHTH: the context.__exit__ bound method
- We call EIGHTH(TOP, SECOND, THIRD).
- Then we push again the TOP exception and the __exit__
- return value.
+ /* At the top of the stack are 4 values:
+ - TOP = exc_info()
+ - SECOND = previous exception
+ - THIRD: lasti of exception in exc_info()
+ - FOURTH: the context.__exit__ bound method
+ We call FOURTH(type(TOP), TOP, GetTraceback(TOP)).
+ Then we push the __exit__ return value.
*/
PyObject *exit_func;
PyObject *exc, *val, *tb, *res;
- exc = TOP();
- val = SECOND();
- tb = THIRD();
- ASSERT_EXC_TYPE_IS_REDUNDANT(exc, val);
- assert(!Py_IsNone(exc));
- assert(!PyLong_Check(exc));
- assert(PyLong_Check(PEEK(7)));
- exit_func = PEEK(8);
+ val = TOP();
+ assert(val && PyExceptionInstance_Check(val));
+ exc = PyExceptionInstance_Class(val);
+ tb = PyException_GetTraceback(val);
+ Py_XDECREF(tb);
+ assert(PyLong_Check(PEEK(3)));
+ exit_func = PEEK(4);
PyObject *stack[4] = {NULL, exc, val, tb};
res = PyObject_Vectorcall(exit_func, stack + 1,
3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
}
TARGET(PUSH_EXC_INFO) {
- PyObject *type = TOP();
- PyObject *value = SECOND();
- PyObject *tb = THIRD();
- ASSERT_EXC_TYPE_IS_REDUNDANT(type, value);
+ PyObject *value = TOP();
+
_PyErr_StackItem *exc_info = tstate->exc_info;
- SET_THIRD(exc_info->exc_traceback);
if (exc_info->exc_value != NULL) {
- SET_SECOND(exc_info->exc_value);
- }
- else {
- Py_INCREF(Py_None);
- SET_SECOND(Py_None);
- }
- if (exc_info->exc_type != NULL) {
- SET_TOP(exc_info->exc_type);
+ SET_TOP(exc_info->exc_value);
}
else {
Py_INCREF(Py_None);
SET_TOP(Py_None);
}
- Py_INCREF(tb);
- PUSH(tb);
- exc_info->exc_traceback = tb;
Py_INCREF(value);
PUSH(value);
assert(PyExceptionInstance_Check(value));
exc_info->exc_value = value;
- Py_INCREF(type);
- PUSH(type);
- assert(PyExceptionClass_Check(type));
- exc_info->exc_type = type;
-
DISPATCH();
}
PyException_SetTraceback(val, tb);
else
PyException_SetTraceback(val, Py_None);
- if (tb == NULL) {
- tb = Py_None;
- Py_INCREF(Py_None);
- }
- PUSH(tb);
+ Py_XDECREF(tb);
+ Py_XDECREF(exc);
PUSH(val);
- PUSH(exc);
- ASSERT_EXC_TYPE_IS_REDUNDANT(exc, val);
JUMPTO(handler);
/* Resume normal execution */
frame->f_state = FRAME_EXECUTING;
*/
static int
-exception_group_match(PyObject *exc_type, PyObject* exc_value,
- PyObject *match_type, PyObject **match, PyObject **rest)
+exception_group_match(PyObject* exc_value, PyObject *match_type,
+ PyObject **match, PyObject **rest)
{
- if (Py_IsNone(exc_type)) {
- assert(Py_IsNone(exc_value));
+ if (Py_IsNone(exc_value)) {
*match = Py_NewRef(Py_None);
*rest = Py_NewRef(Py_None);
return 0;
}
- assert(PyExceptionClass_Check(exc_type));
assert(PyExceptionInstance_Check(exc_value));
- if (PyErr_GivenExceptionMatches(exc_type, match_type)) {
+ if (PyErr_GivenExceptionMatches(exc_value, match_type)) {
/* Full match of exc itself */
bool is_eg = _PyBaseExceptionGroup_Check(exc_value);
if (is_eg) {
case POP_BLOCK:
return 0;
case POP_EXCEPT:
- return -3;
+ return -1;
case POP_EXCEPT_AND_RERAISE:
- return -7;
+ return -3;
case STORE_NAME:
return -1;
case JUMP_IF_NOT_EXC_MATCH:
return -1;
case JUMP_IF_NOT_EG_MATCH:
- return jump > 0 ? -1 : 2;
+ return jump > 0 ? -1 : 0;
case IMPORT_NAME:
return -1;
case IMPORT_FROM:
/* Exception handling pseudo-instructions */
case SETUP_FINALLY:
/* 0 in the normal flow.
- * Restore the stack position and push 3 values before jumping to
+ * Restore the stack position and push 1 value before jumping to
* the handler if an exception be raised. */
- return jump ? 3 : 0;
+ return jump ? 1 : 0;
case SETUP_CLEANUP:
/* As SETUP_FINALLY, but pushes lasti as well */
- return jump ? 4 : 0;
+ return jump ? 2 : 0;
case SETUP_WITH:
/* 0 in the normal flow.
* Restore the stack position to the position before the result
- * of __(a)enter__ and push 4 values before jumping to the handler
+ * of __(a)enter__ and push 2 values before jumping to the handler
* if an exception be raised. */
- return jump ? -1 + 4 : 0;
+ return jump ? 1 : 0;
case PREP_RERAISE_STAR:
- return 2;
+ return 0;
case RERAISE:
- return -3;
+ return -1;
case PUSH_EXC_INFO:
- return 3;
+ return 1;
case WITH_EXCEPT_START:
return 1;
case GET_YIELD_FROM_ITER:
return 0;
case END_ASYNC_FOR:
- return -4;
+ return -2;
case FORMAT_VALUE:
/* If there's a fmt_spec on the stack, we go from 2->1,
else 1->1. */
case FINALLY_END:
if (preserve_tos) {
- ADDOP(c, ROT_FOUR);
+ ADDOP(c, ROT_TWO);
}
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
+ ADDOP(c, POP_TOP); /* exc_value */
if (preserve_tos) {
- ADDOP(c, ROT_FOUR);
+ ADDOP(c, ROT_TWO);
}
ADDOP(c, POP_BLOCK);
ADDOP(c, POP_EXCEPT);
ADDOP(c, POP_BLOCK);
}
if (preserve_tos) {
- ADDOP(c, ROT_FOUR);
+ ADDOP(c, ROT_TWO);
}
ADDOP(c, POP_BLOCK);
ADDOP(c, POP_EXCEPT);
[] POP_BLOCK
[] JUMP_FORWARD L0
- [tb, val, exc] L1: <evaluate E1> )
- [tb, val, exc, E1] JUMP_IF_NOT_EXC_MATCH L2 ) only if E1
- [tb, val, exc] POP
- [tb, val] <assign to V1> (or POP if no V1)
- [tb] POP
+ [exc] L1: <evaluate E1> )
+ [exc, E1] JUMP_IF_NOT_EXC_MATCH L2 ) only if E1
+ [exc] <assign to V1> (or POP if no V1)
[] <code for S1>
JUMP_FORWARD L0
- [tb, val, exc] L2: <evaluate E2>
+ [exc] L2: <evaluate E2>
.............................etc.......................
- [tb, val, exc] Ln+1: RERAISE # re-raise exception
+ [exc] Ln+1: RERAISE # re-raise exception
[] L0: <next statement>
ADDOP_JUMP(c, JUMP_IF_NOT_EXC_MATCH, except);
NEXT_BLOCK(c);
}
- ADDOP(c, POP_TOP);
if (handler->v.ExceptHandler.name) {
basicblock *cleanup_end, *cleanup_body;
}
compiler_nameop(c, handler->v.ExceptHandler.name, Store);
- ADDOP(c, POP_TOP);
/*
try:
if (!cleanup_body)
return 0;
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
+ ADDOP(c, POP_TOP); /* exc_value */
compiler_use_next_block(c, cleanup_body);
if (!compiler_push_fblock(c, HANDLER_CLEANUP, cleanup_body, NULL, NULL))
return 0;
at the right; 'tb' is trace-back info, 'val' the exception instance,
and 'typ' the exception's type.)
- Value stack Label Instruction Argument
- [] SETUP_FINALLY L1
- [] <code for S>
- [] POP_BLOCK
- [] JUMP_FORWARD L0
+ Value stack Label Instruction Argument
+ [] SETUP_FINALLY L1
+ [] <code for S>
+ [] POP_BLOCK
+ [] JUMP_FORWARD L0
- [tb, val, typ] L1: DUP_TOP_TWO ) save a copy of the
- [tb, val, typ, orig, typ] POP_TOP ) original raised exception
- [tb, val, typ, orig] ROT_FOUR )
- [orig, tb, val, typ] BUILD_LIST ) list for raised/reraised
- [orig, tb, val, typ, res] ROT_FOUR ) exceptions ("result")
+ [exc] L1: DUP_TOP ) save copy of the original exception
+ [orig, exc] BUILD_LIST ) list for raised/reraised excs ("result")
+ [orig, exc, res] ROT_TWO
- [orig, res, tb, val, typ] <evaluate E1> )
- [orig, res, tb, val, typ, E1] JUMP_IF_NOT_EXC_MATCH L2 ) only if E1
+ [orig, res, exc] <evaluate E1>
+ [orig, res, exc, E1] JUMP_IF_NOT_EG_MATCH L2
- [orig, res, tb, rest, typ, tb, match, typ] POP
- [orig, res, tb, rest, typ, tb, match] <assign to V1> (or POP if no V1)
- [orig, res, tb, rest, typ, tb] POP
+ [orig, res, rest, match] <assign to V1> (or POP if no V1)
- [orig, res, tb, rest, typ] SETUP_FINALLY R1
- [orig, res, tb, rest, typ] <code for S1>
- [orig, res, tb, rest, typ] JUMP_FORWARD L2
+ [orig, res, rest] SETUP_FINALLY R1
+ [orig, res, rest] <code for S1>
+ [orig, res, rest] JUMP_FORWARD L2
- [orig, res, tb, rest, typ, i, tb, v, t] R1: POP ) exception raised in except* body
- [orig, res, tb, rest, typ, i, tb, v] LIST_APPEND 6 ) add it to res
- [orig, res, tb, rest, typ, i, tb] POP
- [orig, res, tb, rest, typ, i] POP
+ [orig, res, rest, i, v] R1: LIST_APPEND 3 ) exc raised in except* body - add to res
+ [orig, res, rest, i] POP
- [orig, res, tb, rest, typ] L2: <evaluate E2>
+ [orig, res, rest] L2: <evaluate E2>
.............................etc.......................
- [orig, res, tb, rest, typ] Ln+1: POP ) add unhandled exception
- [orig, res, tb, rest] LIST_APPEND 2 ) to res (could be None)
- [orig, res, tb] POP
+ [orig, res, rest] Ln+1: LIST_APPEND 1 ) add unhandled exc to res (could be None)
- [orig, res] PREP_RERAISE_STAR
- [i, tb, val, typ] POP_JUMP_IF_TRUE RER
- [i, tb, val, typ] POP
- [i, tb, val] POP
- [i, tb] POP
- [i] POP
- [] JUMP_FORWARD L0
+ [orig, res] PREP_RERAISE_STAR
+ [i, exc] POP_JUMP_IF_TRUE RER
+ [i, exc] POP
+ [i] POP
+ [] JUMP_FORWARD L0
- [i, tb, val, typ] RER: POP_EXCEPT_AND_RERAISE
+ [i, exc] RER: POP_EXCEPT_AND_RERAISE
- [] L0: <next statement>
+ [] L0: <next statement>
*/
static int
compiler_try_star_except(struct compiler *c, stmt_ty s)
if (i == 0) {
/* Push the original EG into the stack */
/*
- [tb, val, exc] DUP_TOP_TWO
- [tb, val, exc, val, exc] POP_TOP
- [tb, val, exc, val] ROT_FOUR
- [val, tb, val, exc]
+ [exc] DUP_TOP
+ [orig, exc]
*/
- ADDOP(c, DUP_TOP_TWO);
- ADDOP(c, POP_TOP);
- ADDOP(c, ROT_FOUR);
+ ADDOP(c, DUP_TOP);
/* create empty list for exceptions raised/reraise in the except* blocks */
/*
- [val, tb, val, exc] BUILD_LIST
- [val, tb, val, exc, []] ROT_FOUR
- [val, [], tb, val, exc]
+ [orig, exc] BUILD_LIST
+ [orig, exc, []] ROT_TWO
+ [orig, [], exc]
*/
ADDOP_I(c, BUILD_LIST, 0);
- ADDOP(c, ROT_FOUR);
+ ADDOP(c, ROT_TWO);
}
if (handler->v.ExceptHandler.type) {
VISIT(c, expr, handler->v.ExceptHandler.type);
ADDOP_JUMP(c, JUMP_IF_NOT_EG_MATCH, except);
NEXT_BLOCK(c);
}
- ADDOP(c, POP_TOP); // exc_type
basicblock *cleanup_end = compiler_new_block(c);
if (cleanup_end == NULL) {
compiler_nameop(c, handler->v.ExceptHandler.name, Store);
}
else {
- ADDOP(c, POP_TOP); // val
+ ADDOP(c, POP_TOP); // exc
}
- ADDOP(c, POP_TOP); // tb
/*
try:
}
/* add exception raised to the res list */
- ADDOP(c, POP_TOP); // type
- ADDOP_I(c, LIST_APPEND, 6); // exc
- ADDOP(c, POP_TOP); // tb
+ ADDOP_I(c, LIST_APPEND, 3); // exc
ADDOP(c, POP_TOP); // lasti
ADDOP_JUMP(c, JUMP_ABSOLUTE, except);
if (i == n - 1) {
/* Add exc to the list (if not None it's the unhandled part of the EG) */
- ADDOP(c, POP_TOP);
- ADDOP_I(c, LIST_APPEND, 2);
- ADDOP(c, POP_TOP);
+ ADDOP_I(c, LIST_APPEND, 1);
ADDOP_JUMP(c, JUMP_FORWARD, reraise_star);
}
}
/* Nothing to reraise - pop it */
ADDOP(c, POP_TOP);
ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
ADDOP(c, POP_BLOCK);
ADDOP(c, POP_EXCEPT);
ADDOP_JUMP(c, JUMP_FORWARD, end);
return 0;
ADDOP_JUMP(c, POP_JUMP_IF_TRUE, exit);
NEXT_BLOCK(c);
- ADDOP_I(c, RERAISE, 4);
+ ADDOP_I(c, RERAISE, 2);
compiler_use_next_block(c, cleanup);
ADDOP(c, POP_EXCEPT_AND_RERAISE);
compiler_use_next_block(c, exit);
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
- ADDOP(c, POP_TOP);
+ ADDOP(c, POP_TOP); /* exc_value */
ADDOP(c, POP_BLOCK);
ADDOP(c, POP_EXCEPT);
ADDOP(c, POP_TOP);
E: WITH_EXCEPT_START (calls EXPR.__exit__)
POP_JUMP_IF_TRUE T:
RERAISE
- T: POP_TOP * 3 (remove exception from stack)
+ T: POP_TOP (remove exception from stack)
POP_EXCEPT
POP_TOP
EXIT:
int size = end-start;
assert(end > start);
int target = handler->b_offset;
- int depth = handler->b_preserve_lasti ? handler->b_startdepth-4 : handler->b_startdepth-3;
+ int depth = handler->b_startdepth - 1;
+ if (handler->b_preserve_lasti) {
+ depth -= 1;
+ }
assert(depth >= 0);
int depth_lasti = (depth<<1) | handler->b_preserve_lasti;
assemble_emit_exception_table_item(a, start, (1<<7));