Skip to main content

Python/ceval.c (part 4)

Source:

cpython 3.14 @ ab2d84fe1023/Python/ceval.c

This annotation covers exception handling, with statement, and structural pattern matching opcodes. See python_ceval_detail (part 3) for iteration and container opcodes.

Map

LinesSymbolRole
1-200PUSH_EXC_INFO, POP_EXCEPTPush/pop the exception info block
201-400RAISE_VARARGS, RERAISEraise and reraise
401-600CLEANUP_THROW, YIELD_VALUEGenerator send/throw/close
601-800BEFORE_WITH, WITH_EXCEPT_STARTwith statement management
801-1000COPY_FREE_VARS, MAKE_CELLClosure cell setup
1001-1200MATCH_CLASS, MATCH_MAPPING, MATCH_SEQUENCE, MATCH_KEYSStructural pattern matching
1201-1400COPY, SWAPStack manipulation
1401-5500Specialized opcodes_BINARY_OP_ADD_INT, _LOAD_ATTR_MODULE, etc.

Reading

RAISE_VARARGS

// CPython: Python/ceval.c:2940 RAISE_VARARGS
inst(RAISE_VARARGS, (args[oparg] -- )) {
PyObject *cause = NULL, *exc = NULL;
switch (oparg) {
case 2:
cause = args[1];
/* fall through */
case 1:
exc = args[0];
/* fall through */
case 0:
if (do_raise(tstate, exc, cause)) {
...
}
}
...
}

oparg=0: bare raise (reraise current exception). oparg=1: raise exc. oparg=2: raise exc from cause.

PUSH_EXC_INFO and POP_EXCEPT

PUSH_EXC_INFO saves the current exception onto the exception stack and sets the new exception as current. POP_EXCEPT restores the previous exception from the stack.

// CPython: Python/ceval.c:2885 PUSH_EXC_INFO
inst(PUSH_EXC_INFO, (new_exc -- prev_exc, new_exc)) {
_PyErr_StackItem *exc_info = tstate->exc_info;
prev_exc = exc_info->exc_value;
exc_info->exc_value = Py_NewRef(new_exc);
}

BEFORE_WITH and WITH_EXCEPT_START

BEFORE_WITH calls __enter__ on the context manager and pushes the result. WITH_EXCEPT_START calls __exit__ with the exception info when the with body raises.

// CPython: Python/ceval.c:3380 BEFORE_WITH
inst(BEFORE_WITH, (mgr -- exit, res)) {
PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__enter__));
...
exit = _PyObject_LookupSpecial(mgr, &_Py_ID(__exit__));
...
res = _PyObject_CallNoArgs(enter);
}

MATCH_CLASS

Pattern matching in Python 3.10+. MATCH_CLASS checks if TOS is an instance of the pattern class and extracts keyword attributes.

// CPython: Python/ceval.c:3580 MATCH_CLASS
inst(MATCH_CLASS, (subject, type, names -- attrs)) {
assert(PyTuple_CheckExact(names));
attrs = _PyMatchCase_IsInstance(tstate, subject, type, names, oparg);
...
}

gopy notes

Exception handling opcodes are in vm/eval_unwind.go. RAISE_VARARGS routes through errors.Raise. The exception stack (exc_info) maps to a field in vm.Frame. BEFORE_WITH / WITH_EXCEPT_START are in vm/eval_stmt.go. Match opcodes are partially implemented.