You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: internals/interpreter.rst
+4-27
Original file line number
Diff line number
Diff line change
@@ -178,38 +178,15 @@ Then the interpreter function (``_PyEval_EvalFrameDefault()``) returns ``NULL``.
178
178
179
179
However, if an exception is raised in a ``try`` block, the interpreter must jump to the corresponding ``except`` or ``finally`` block.
180
180
In 3.10 and before, there was a separate "block stack" which was used to keep track of nesting ``try`` blocks.
181
-
In 3.11, this mechanism has been replaced by a statically generated table, ``code->co_exceptiontable``.
182
-
The advantage of this approach is that entering and leaving a ``try`` block normally does not execute any code, making execution faster.
183
-
But of course, this table needs to be generated by the compiler, and decoded (by ``get_exception_handler``) when an exception happens.
184
-
185
-
Exception table format
186
-
----------------------
187
-
188
-
The table is conceptually a list of records, each containing four variable-length integer fields (in a unique format, see below):
189
-
190
-
- start: start of ``try`` block, in code units from the start of the bytecode
191
-
- length: size of the ``try`` block, in code units
192
-
- target: start of the first instruction of the ``except`` or ``finally`` block, in code units from the start of the bytecode
193
-
- depth_and_lasti: the low bit gives the "lasti" flag, the remaining bits give the stack depth
194
-
195
-
The stack depth is used to clean up evaluation stack entries above this depth.
196
-
The "lasti" flag indicates whether, after stack cleanup, the instruction offset of the raising instruction should be pushed (as a ``PyLongObject *``).
197
-
For more information on the design, see :cpy-file:`Objects/exception_handling_notes.txt`.
198
-
199
-
Each varint is encoded as one or more bytes.
200
-
The high bit (bit 7) is reserved for random access -- it is set for the first varint of a record.
201
-
The second bit (bit 6) indicates whether this is the last byte or not -- it is set for all but the last bytes of a varint.
202
-
The low 6 bits (bits 0-5) are used for the integer value, in big-endian order.
203
-
204
-
To find the table entry (if any) for a given instruction offset, we can use bisection without decoding the whole table.
205
-
We bisect the raw bytes, at each probe finding the start of the record by scanning back for a byte with the high bit set, and then decode the first varint.
206
-
See ``get_exception_handler()`` in :cpy-file:`Python/ceval.c` for the exact code (like all bisection algorithms, the code is a bit subtle).
181
+
In 3.11, this mechanism has been replaced by a statically generated table, ``code->co_exceptiontable``,
182
+
which is described in detail in the `internals documentation
0 commit comments