3 ms·
There are different ways to implement exceptions with different performance trade-offs. Mechanism used by CPython (and IIRC many C++ implementations) involves
by dfox 8y ago
There are different ways to implement exceptions with different performance trade-offs.
Mechanism used by CPython (and IIRC many C++ implementations) involves having per-thread flag "exception occurred" which is checked after every function return (this makes sense performance-wise when essentially every function contains "implicit try/finally" in form of bunch of Py_DECREF or destructors of locally scoped variables).
The same idea can be implemented by returning instances of special "ExceptionThrown" class and checking for that, which you in fact can do by doing "if argument is ExceptionThrown return argument" in prologue of every function, which is exactly the thing described in the article. (early versions of dfsch did exactly this)
Only when you know that in most cases you don't need to do significant cleanup on stack-unwind (ie. you have tracing GC that directly scans stack or you don't allocate that much) it starts to make sense to do stack unwinding by doing non-local jumps.
Typical implementation of that has some linked-list of currently active try/catch/finally sites that has to be maintained at runtime (typically as part of activation records on control stack). Extension of this idea is that such sites do not necessarilly have to unwind-stack before running the recovery code (i.e. Windows' SEH). And then that you can have two such lists, one for handling errors and other for cleanup during stack unwind (i.e. CL-style condition system)