Skip to content

Commit d2a63a9

Browse files
authored
gh-119786: remove part of devguide documentation which is duplicated in InternalDocs (#1334)
1 parent c3950af commit d2a63a9

File tree

1 file changed

+4
-27
lines changed

1 file changed

+4
-27
lines changed

Diff for: internals/interpreter.rst

+4-27
Original file line numberDiff line numberDiff line change
@@ -178,38 +178,15 @@ Then the interpreter function (``_PyEval_EvalFrameDefault()``) returns ``NULL``.
178178

179179
However, if an exception is raised in a ``try`` block, the interpreter must jump to the corresponding ``except`` or ``finally`` block.
180180
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
183+
<https://github.com/python/cpython/blob/main/InternalDocs/exception_handling.md>`_.
207184

208185
The locations table
209186
-------------------
210187

211188
Whenever an exception is raised, we add a traceback entry to the exception.
212-
The ``tb_lineno`` field of a traceback entry must be set to the line number of the instruction that raised it.
189+
The ``tb_lineno`` field of a traceback entry is (lazily) set to the line number of the instruction that raised it.
213190
This field is computed from the locations table, ``co_linetable`` (this name is an understatement), using :c:func:`PyCode_Addr2Line`.
214191
This table has an entry for every instruction rather than for every ``try`` block, so a compact format is very important.
215192

0 commit comments

Comments
 (0)