Skip to content

Commit b40e822

Browse files
committed
pythongh-119786: add links to code
1 parent e69d068 commit b40e822

File tree

1 file changed

+17
-33
lines changed

1 file changed

+17
-33
lines changed

InternalDocs/exception_handling.md

+17-33
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
Description of exception handling
23
---------------------------------
34

@@ -67,14 +68,18 @@ handler located at label `L1`.
6768
Handling Exceptions
6869
-------------------
6970

70-
At runtime, when an exception occurs, the interpreter looks up
71-
the offset of the current instruction in the exception table. If
72-
it finds a handler, control flow transfers to it. Otherwise, the
71+
At runtime, when an exception occurs, the interpreter calls
72+
``get_exception_handler()`` in
73+
[Python/ceval.c](https://github.com/python/cpython/blob/main/Python/ceval.c)
74+
to look up the offset of the current instruction in the exception
75+
table. If it finds a handler, control flow transfers to it. Otherwise, the
7376
exception bubbles up to the caller, and the caller's frame is
7477
checked for a handler covering the `CALL` instruction. This
7578
repeats until a handler is found or the topmost frame is reached.
7679
If no handler is found, the program terminates. During unwinding,
77-
the traceback is constructed as each frame is added to it.
80+
the traceback is constructed as each frame is added to it by
81+
``PyTraceBack_Here()``, which is in
82+
[Python/traceback.c](https://github.com/python/cpython/blob/main/Python/traceback.c).
7883

7984
Along with the location of an exception handler, each entry of the
8085
exception table also contains the stack depth of the `try` instruction
@@ -169,33 +174,12 @@ which is then encoded as:
169174

170175
for a total of five bytes.
171176

177+
The code to construct the exception table is in ``assemble_exception_table()``
178+
in [Python/assemble.c](https://github.com/python/cpython/blob/main/Python/assemble.c).
172179

173-
Script to parse the exception table
174-
-----------------------------------
175-
176-
```
177-
def parse_varint(iterator):
178-
b = next(iterator)
179-
val = b & 63
180-
while b&64:
181-
val <<= 6
182-
b = next(iterator)
183-
val |= b&63
184-
return val
185-
```
186-
```
187-
def parse_exception_table(code):
188-
iterator = iter(code.co_exceptiontable)
189-
try:
190-
while True:
191-
start = parse_varint(iterator)*2
192-
length = parse_varint(iterator)*2
193-
end = start + length - 2 # Present as inclusive, not exclusive
194-
target = parse_varint(iterator)*2
195-
dl = parse_varint(iterator)
196-
depth = dl >> 1
197-
lasti = bool(dl&1)
198-
yield start, end, target, depth, lasti
199-
except StopIteration:
200-
return
201-
```
180+
The interpreter's function to lookup the table by instruction offset is
181+
``get_exception_handler()`` in
182+
[Python/ceval.c](https://github.com/python/cpython/blob/main/Python/ceval.c).
183+
The Python function ``_parse_exception_table()`` in
184+
[Lib/dis.py](https://github.com/python/cpython/blob/main/Lib/dis.py)
185+
returns the exception table content as a list of namedtuple instances.

0 commit comments

Comments
 (0)