/src/cpython/Python/ceval.h
Line | Count | Source |
1 | | #define _PY_INTERPRETER |
2 | | |
3 | | #include "Python.h" |
4 | | #include "pycore_abstract.h" // _PyIndex_Check() |
5 | | #include "pycore_audit.h" // _PySys_Audit() |
6 | | #include "pycore_backoff.h" |
7 | | #include "pycore_call.h" // _PyObject_CallNoArgs() |
8 | | #include "pycore_cell.h" // PyCell_GetRef() |
9 | | #include "pycore_ceval.h" // SPECIAL___ENTER__ |
10 | | #include "pycore_code.h" |
11 | | #include "pycore_dict.h" |
12 | | #include "pycore_emscripten_signal.h" // _Py_CHECK_EMSCRIPTEN_SIGNALS |
13 | | #include "pycore_floatobject.h" // _PyFloat_ExactDealloc() |
14 | | #include "pycore_frame.h" |
15 | | #include "pycore_function.h" |
16 | | #include "pycore_genobject.h" // _PyCoro_GetAwaitableIter() |
17 | | #include "pycore_import.h" // _PyImport_IsDefaultImportFunc() |
18 | | #include "pycore_instruments.h" |
19 | | #include "pycore_interpframe.h" // _PyFrame_SetStackPointer() |
20 | | #include "pycore_interpolation.h" // _PyInterpolation_Build() |
21 | | #include "pycore_intrinsics.h" |
22 | | #include "pycore_jit.h" |
23 | | #include "pycore_lazyimportobject.h" |
24 | | #include "pycore_list.h" // _PyList_GetItemRef() |
25 | | #include "pycore_long.h" // _PyLong_GetZero() |
26 | | #include "pycore_moduleobject.h" // PyModuleObject |
27 | | #include "pycore_object.h" // _PyObject_GC_TRACK() |
28 | | #include "pycore_opcode_metadata.h" // EXTRA_CASES |
29 | | #include "pycore_opcode_utils.h" // MAKE_FUNCTION_* |
30 | | #include "pycore_optimizer.h" // _PyUOpExecutor_Type |
31 | | #include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_* |
32 | | #include "pycore_pyerrors.h" // _PyErr_GetRaisedException() |
33 | | #include "pycore_pystate.h" // _PyInterpreterState_GET() |
34 | | #include "pycore_range.h" // _PyRangeIterObject |
35 | | #include "pycore_setobject.h" // _PySet_Update() |
36 | | #include "pycore_sliceobject.h" // _PyBuildSlice_ConsumeRefs |
37 | | #include "pycore_sysmodule.h" // _PySys_GetOptionalAttrString() |
38 | | #include "pycore_template.h" // _PyTemplate_Build() |
39 | | #include "pycore_traceback.h" // _PyTraceBack_FromFrame |
40 | | #include "pycore_tuple.h" // _PyTuple_ITEMS() |
41 | | #include "pycore_uop_ids.h" // Uops |
42 | | |
43 | | #include "dictobject.h" |
44 | | #include "frameobject.h" // _PyInterpreterFrame_GetLine |
45 | | #include "opcode.h" |
46 | | #include "pydtrace.h" |
47 | | #include "setobject.h" |
48 | | #include "pycore_stackref.h" |
49 | | |
50 | | #include <stdbool.h> // bool |
51 | | |
52 | | #if !defined(Py_BUILD_CORE) |
53 | | # error "ceval.c must be build with Py_BUILD_CORE define for best performance" |
54 | | #endif |
55 | | |
56 | | #if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) |
57 | | // GH-89279: The MSVC compiler does not inline these static inline functions |
58 | | // in PGO build in _PyEval_EvalFrameDefault(), because this function is over |
59 | | // the limit of PGO, and that limit cannot be configured. |
60 | | // Define them as macros to make sure that they are always inlined by the |
61 | | // preprocessor. |
62 | | |
63 | | #undef Py_IS_TYPE |
64 | | #define Py_IS_TYPE(ob, type) \ |
65 | 10.7G | (_PyObject_CAST(ob)->ob_type == (type)) |
66 | | |
67 | | #undef Py_XDECREF |
68 | | #define Py_XDECREF(arg) \ |
69 | 693M | do { \ |
70 | 693M | PyObject *xop = _PyObject_CAST(arg); \ |
71 | 693M | if (xop != NULL) { \ |
72 | 305M | Py_DECREF(xop); \ |
73 | 305M | } \ |
74 | 693M | } while (0) |
75 | | |
76 | | #ifndef Py_GIL_DISABLED |
77 | | |
78 | | #undef Py_DECREF |
79 | | #define Py_DECREF(arg) \ |
80 | 453M | do { \ |
81 | 453M | PyObject *op = _PyObject_CAST(arg); \ |
82 | 453M | if (_Py_IsImmortal(op)) { \ |
83 | 173M | _Py_DECREF_IMMORTAL_STAT_INC(); \ |
84 | 173M | break; \ |
85 | 173M | } \ |
86 | 453M | _Py_DECREF_STAT_INC(); \ |
87 | 280M | if (--op->ob_refcnt == 0) { \ |
88 | 110M | _PyReftracerTrack(op, PyRefTracer_DESTROY); \ |
89 | 110M | destructor dealloc = Py_TYPE(op)->tp_dealloc; \ |
90 | 110M | (*dealloc)(op); \ |
91 | 110M | } \ |
92 | 280M | } while (0) |
93 | | |
94 | | #undef _Py_DECREF_SPECIALIZED |
95 | | #define _Py_DECREF_SPECIALIZED(arg, dealloc) \ |
96 | 8.38M | do { \ |
97 | 8.38M | PyObject *op = _PyObject_CAST(arg); \ |
98 | 8.38M | if (_Py_IsImmortal(op)) { \ |
99 | 7.61M | _Py_DECREF_IMMORTAL_STAT_INC(); \ |
100 | 7.61M | break; \ |
101 | 7.61M | } \ |
102 | 8.38M | _Py_DECREF_STAT_INC(); \ |
103 | 771k | if (--op->ob_refcnt == 0) { \ |
104 | 257k | _PyReftracerTrack(op, PyRefTracer_DESTROY); \ |
105 | 257k | destructor d = (destructor)(dealloc); \ |
106 | 257k | d(op); \ |
107 | 257k | } \ |
108 | 771k | } while (0) |
109 | | |
110 | | #else // Py_GIL_DISABLED |
111 | | |
112 | | #undef Py_DECREF |
113 | | #define Py_DECREF(arg) \ |
114 | | do { \ |
115 | | PyObject *op = _PyObject_CAST(arg); \ |
116 | | uint32_t local = _Py_atomic_load_uint32_relaxed(&op->ob_ref_local); \ |
117 | | if (local == _Py_IMMORTAL_REFCNT_LOCAL) { \ |
118 | | _Py_DECREF_IMMORTAL_STAT_INC(); \ |
119 | | break; \ |
120 | | } \ |
121 | | _Py_DECREF_STAT_INC(); \ |
122 | | if (_Py_IsOwnedByCurrentThread(op)) { \ |
123 | | local--; \ |
124 | | _Py_atomic_store_uint32_relaxed(&op->ob_ref_local, local); \ |
125 | | if (local == 0) { \ |
126 | | _Py_MergeZeroLocalRefcount(op); \ |
127 | | } \ |
128 | | } \ |
129 | | else { \ |
130 | | _Py_DecRefShared(op); \ |
131 | | } \ |
132 | | } while (0) |
133 | | |
134 | | #undef _Py_DECREF_SPECIALIZED |
135 | | #define _Py_DECREF_SPECIALIZED(arg, dealloc) Py_DECREF(arg) |
136 | | |
137 | | #endif |
138 | | #endif |
139 | | |
140 | | static void |
141 | | check_invalid_reentrancy(void) |
142 | 261M | { |
143 | | #if defined(Py_DEBUG) && defined(Py_GIL_DISABLED) |
144 | | // In the free-threaded build, the interpreter must not be re-entered if |
145 | | // the world-is-stopped. If so, that's a bug somewhere (quite likely in |
146 | | // the painfully complex typeobject code). |
147 | | PyInterpreterState *interp = _PyInterpreterState_GET(); |
148 | | assert(!interp->stoptheworld.world_stopped); |
149 | | #endif |
150 | 261M | } |
151 | | |
152 | | |
153 | | #ifdef Py_DEBUG |
154 | | static void |
155 | | dump_item(_PyStackRef item) |
156 | | { |
157 | | if (PyStackRef_IsNull(item)) { |
158 | | printf("<NULL>"); |
159 | | return; |
160 | | } |
161 | | if (PyStackRef_IsMalformed(item)) { |
162 | | printf("<INVALID>"); |
163 | | return; |
164 | | } |
165 | | if (PyStackRef_IsTaggedInt(item)) { |
166 | | printf("%" PRId64, (int64_t)PyStackRef_UntagInt(item)); |
167 | | return; |
168 | | } |
169 | | PyObject *obj = PyStackRef_AsPyObjectBorrow(item); |
170 | | if (obj == NULL) { |
171 | | printf("<nil>"); |
172 | | return; |
173 | | } |
174 | | // Don't call __repr__(), it might recurse into the interpreter. |
175 | | printf("<%s at %p>", Py_TYPE(obj)->tp_name, (void *)obj); |
176 | | } |
177 | | |
178 | | static void |
179 | | dump_stack(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer) |
180 | | { |
181 | | _PyFrame_SetStackPointer(frame, stack_pointer); |
182 | | _PyStackRef *locals_base = _PyFrame_GetLocalsArray(frame); |
183 | | _PyStackRef *stack_base = _PyFrame_Stackbase(frame); |
184 | | PyObject *exc = PyErr_GetRaisedException(); |
185 | | printf(" locals=["); |
186 | | for (_PyStackRef *ptr = locals_base; ptr < stack_base; ptr++) { |
187 | | if (ptr != locals_base) { |
188 | | printf(", "); |
189 | | } |
190 | | dump_item(*ptr); |
191 | | } |
192 | | printf("]\n"); |
193 | | if (stack_pointer < stack_base) { |
194 | | printf(" stack=%d\n", (int)(stack_pointer-stack_base)); |
195 | | } |
196 | | else { |
197 | | printf(" stack=["); |
198 | | for (_PyStackRef *ptr = stack_base; ptr < stack_pointer; ptr++) { |
199 | | if (ptr != stack_base) { |
200 | | printf(", "); |
201 | | } |
202 | | dump_item(*ptr); |
203 | | } |
204 | | printf("]\n"); |
205 | | } |
206 | | fflush(stdout); |
207 | | PyErr_SetRaisedException(exc); |
208 | | _PyFrame_GetStackPointer(frame); |
209 | | } |
210 | | |
211 | | #if defined(_Py_TIER2) && !defined(_Py_JIT) && defined(Py_DEBUG) |
212 | | static void |
213 | | dump_cache_item(_PyStackRef cache, int position, int depth) |
214 | | { |
215 | | if (position < depth) { |
216 | | dump_item(cache); |
217 | | } |
218 | | else { |
219 | | printf("---"); |
220 | | } |
221 | | } |
222 | | #endif |
223 | | |
224 | | static void |
225 | | lltrace_instruction(_PyInterpreterFrame *frame, |
226 | | _PyStackRef *stack_pointer, |
227 | | _Py_CODEUNIT *next_instr, |
228 | | int opcode, |
229 | | int oparg) |
230 | | { |
231 | | int offset = 0; |
232 | | if (frame->owner < FRAME_OWNED_BY_INTERPRETER) { |
233 | | dump_stack(frame, stack_pointer); |
234 | | offset = (int)(next_instr - _PyFrame_GetBytecode(frame)); |
235 | | } |
236 | | const char *opname = _PyOpcode_OpName[opcode]; |
237 | | assert(opname != NULL); |
238 | | if (OPCODE_HAS_ARG((int)_PyOpcode_Deopt[opcode])) { |
239 | | printf("%d: %s %d\n", offset * 2, opname, oparg); |
240 | | } |
241 | | else { |
242 | | printf("%d: %s\n", offset * 2, opname); |
243 | | } |
244 | | fflush(stdout); |
245 | | } |
246 | | |
247 | | static void |
248 | | lltrace_resume_frame(_PyInterpreterFrame *frame) |
249 | | { |
250 | | PyObject *fobj = PyStackRef_AsPyObjectBorrow(frame->f_funcobj); |
251 | | if (!PyStackRef_CodeCheck(frame->f_executable) || |
252 | | fobj == NULL || |
253 | | !PyFunction_Check(fobj) |
254 | | ) { |
255 | | printf("\nResuming frame.\n"); |
256 | | return; |
257 | | } |
258 | | PyFunctionObject *f = (PyFunctionObject *)fobj; |
259 | | PyObject *exc = PyErr_GetRaisedException(); |
260 | | PyObject *name = Py_XNewRef(FT_ATOMIC_LOAD_PTR_ACQUIRE(f->func_qualname)); |
261 | | if (name == NULL) { |
262 | | name = Py_XNewRef(FT_ATOMIC_LOAD_PTR_ACQUIRE(f->func_name)); |
263 | | } |
264 | | printf("\nResuming frame"); |
265 | | if (name) { |
266 | | printf(" for "); |
267 | | if (PyObject_Print(name, stdout, 0) < 0) { |
268 | | PyErr_Clear(); |
269 | | } |
270 | | Py_DECREF(name); |
271 | | } |
272 | | PyObject *module = Py_XNewRef(FT_ATOMIC_LOAD_PTR_ACQUIRE(f->func_module)); |
273 | | if (module) { |
274 | | printf(" in module "); |
275 | | if (PyObject_Print(module, stdout, 0) < 0) { |
276 | | PyErr_Clear(); |
277 | | } |
278 | | Py_DECREF(module); |
279 | | } |
280 | | printf("\n"); |
281 | | fflush(stdout); |
282 | | PyErr_SetRaisedException(exc); |
283 | | } |
284 | | |
285 | | static int |
286 | | maybe_lltrace_resume_frame(_PyInterpreterFrame *frame, PyObject *globals) |
287 | | { |
288 | | if (globals == NULL) { |
289 | | return 0; |
290 | | } |
291 | | if (frame->owner >= FRAME_OWNED_BY_INTERPRETER) { |
292 | | return 0; |
293 | | } |
294 | | int r = PyDict_Contains(globals, &_Py_ID(__lltrace__)); |
295 | | if (r < 0) { |
296 | | PyErr_Clear(); |
297 | | return 0; |
298 | | } |
299 | | int lltrace = r * 5; // Levels 1-4 only trace uops |
300 | | if (!lltrace) { |
301 | | // Can also be controlled by environment variable |
302 | | char *python_lltrace = Py_GETENV("PYTHON_LLTRACE"); |
303 | | if (python_lltrace != NULL && *python_lltrace >= '0') { |
304 | | lltrace = *python_lltrace - '0'; // TODO: Parse an int and all that |
305 | | } |
306 | | } |
307 | | if (lltrace >= 5) { |
308 | | lltrace_resume_frame(frame); |
309 | | } |
310 | | return lltrace; |
311 | | } |
312 | | |
313 | | #endif |
314 | | |
315 | | static void monitor_reraise(PyThreadState *tstate, |
316 | | _PyInterpreterFrame *frame, |
317 | | _Py_CODEUNIT *instr); |
318 | | static int monitor_stop_iteration(PyThreadState *tstate, |
319 | | _PyInterpreterFrame *frame, |
320 | | _Py_CODEUNIT *instr, |
321 | | PyObject *value); |
322 | | static void monitor_unwind(PyThreadState *tstate, |
323 | | _PyInterpreterFrame *frame, |
324 | | _Py_CODEUNIT *instr); |
325 | | static int monitor_handled(PyThreadState *tstate, |
326 | | _PyInterpreterFrame *frame, |
327 | | _Py_CODEUNIT *instr, PyObject *exc); |
328 | | static void monitor_throw(PyThreadState *tstate, |
329 | | _PyInterpreterFrame *frame, |
330 | | _Py_CODEUNIT *instr); |
331 | | |
332 | | static int get_exception_handler(PyCodeObject *, int, int*, int*, int*); |
333 | | |
334 | | #ifdef HAVE_ERRNO_H |
335 | | #include <errno.h> |
336 | | #endif |
337 | | |
338 | | typedef struct { |
339 | | _PyInterpreterFrame frame; |
340 | | _PyStackRef stack[1]; |
341 | | } _PyEntryFrame; |
342 | | |
343 | | static int |
344 | | do_monitor_exc(PyThreadState *tstate, _PyInterpreterFrame *frame, |
345 | | _Py_CODEUNIT *instr, int event) |
346 | 0 | { |
347 | 0 | assert(event < _PY_MONITORING_UNGROUPED_EVENTS); |
348 | 0 | if (_PyFrame_GetCode(frame)->co_flags & CO_NO_MONITORING_EVENTS) { |
349 | 0 | return 0; |
350 | 0 | } |
351 | 0 | PyObject *exc = PyErr_GetRaisedException(); |
352 | 0 | assert(exc != NULL); |
353 | 0 | int err = _Py_call_instrumentation_arg(tstate, event, frame, instr, exc); |
354 | 0 | if (err == 0) { |
355 | 0 | PyErr_SetRaisedException(exc); |
356 | 0 | } |
357 | 0 | else { |
358 | 0 | assert(PyErr_Occurred()); |
359 | 0 | Py_DECREF(exc); |
360 | 0 | } |
361 | 0 | return err; |
362 | 0 | } |
363 | | |
364 | | static inline bool |
365 | | no_tools_for_global_event(PyThreadState *tstate, int event) |
366 | 153M | { |
367 | 153M | return tstate->interp->monitors.tools[event] == 0; |
368 | 153M | } |
369 | | |
370 | | static inline bool |
371 | | no_tools_for_local_event(PyThreadState *tstate, _PyInterpreterFrame *frame, int event) |
372 | 153M | { |
373 | 153M | assert(event < _PY_MONITORING_UNGROUPED_EVENTS); |
374 | 153M | _PyCoMonitoringData *data = _PyFrame_GetCode(frame)->_co_monitoring; |
375 | 153M | if (data) { |
376 | 0 | return data->active_monitors.tools[event] == 0; |
377 | 0 | } |
378 | 153M | else { |
379 | 153M | return no_tools_for_global_event(tstate, event); |
380 | 153M | } |
381 | 153M | } |
382 | | |
383 | | static int |
384 | | monitor_handled(PyThreadState *tstate, |
385 | | _PyInterpreterFrame *frame, |
386 | | _Py_CODEUNIT *instr, PyObject *exc) |
387 | 29.0M | { |
388 | 29.0M | if (no_tools_for_local_event(tstate, frame, PY_MONITORING_EVENT_EXCEPTION_HANDLED)) { |
389 | 29.0M | return 0; |
390 | 29.0M | } |
391 | 0 | return _Py_call_instrumentation_arg(tstate, PY_MONITORING_EVENT_EXCEPTION_HANDLED, frame, instr, exc); |
392 | 29.0M | } |
393 | | |
394 | | static void |
395 | | monitor_throw(PyThreadState *tstate, |
396 | | _PyInterpreterFrame *frame, |
397 | | _Py_CODEUNIT *instr) |
398 | 36.6k | { |
399 | 36.6k | if (no_tools_for_local_event(tstate, frame, PY_MONITORING_EVENT_PY_THROW)) { |
400 | 36.6k | return; |
401 | 36.6k | } |
402 | 0 | do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_PY_THROW); |
403 | 0 | } |
404 | | |
405 | | static void |
406 | | monitor_reraise(PyThreadState *tstate, _PyInterpreterFrame *frame, |
407 | | _Py_CODEUNIT *instr) |
408 | 4.93M | { |
409 | 4.93M | if (no_tools_for_local_event(tstate, frame, PY_MONITORING_EVENT_RERAISE)) { |
410 | 4.93M | return; |
411 | 4.93M | } |
412 | 0 | do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_RERAISE); |
413 | 0 | } |
414 | | |
415 | | static int |
416 | | monitor_stop_iteration(PyThreadState *tstate, _PyInterpreterFrame *frame, |
417 | | _Py_CODEUNIT *instr, PyObject *value) |
418 | 0 | { |
419 | 0 | if (no_tools_for_local_event(tstate, frame, PY_MONITORING_EVENT_STOP_ITERATION)) { |
420 | 0 | return 0; |
421 | 0 | } |
422 | 0 | assert(!PyErr_Occurred()); |
423 | 0 | PyErr_SetObject(PyExc_StopIteration, value); |
424 | 0 | int res = do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_STOP_ITERATION); |
425 | 0 | if (res < 0) { |
426 | 0 | return res; |
427 | 0 | } |
428 | 0 | PyErr_SetRaisedException(NULL); |
429 | 0 | return 0; |
430 | 0 | } |
431 | | |
432 | | static void |
433 | | monitor_unwind(PyThreadState *tstate, |
434 | | _PyInterpreterFrame *frame, |
435 | | _Py_CODEUNIT *instr) |
436 | 40.3M | { |
437 | 40.3M | if (no_tools_for_local_event(tstate, frame, PY_MONITORING_EVENT_PY_UNWIND)) { |
438 | 40.3M | return; |
439 | 40.3M | } |
440 | 0 | do_monitor_exc(tstate, frame, instr, PY_MONITORING_EVENT_PY_UNWIND); |
441 | 0 | } |
442 | | |
443 | | static inline unsigned char * |
444 | 20.2M | scan_back_to_entry_start(unsigned char *p) { |
445 | 51.9M | for (; (p[0]&128) == 0; p--); |
446 | 20.2M | return p; |
447 | 20.2M | } |
448 | | |
449 | | static inline unsigned char * |
450 | 35.7M | skip_to_next_entry(unsigned char *p, unsigned char *end) { |
451 | 140M | while (p < end && ((p[0] & 128) == 0)) { |
452 | 104M | p++; |
453 | 104M | } |
454 | 35.7M | return p; |
455 | 35.7M | } |
456 | | |
457 | | |
458 | 89.6M | #define MAX_LINEAR_SEARCH 40 |
459 | | |
460 | | static Py_NO_INLINE int |
461 | | get_exception_handler(PyCodeObject *code, int index, int *level, int *handler, int *lasti) |
462 | 69.4M | { |
463 | 69.4M | unsigned char *start = (unsigned char *)PyBytes_AS_STRING(code->co_exceptiontable); |
464 | 69.4M | unsigned char *end = start + PyBytes_GET_SIZE(code->co_exceptiontable); |
465 | | /* Invariants: |
466 | | * start_table == end_table OR |
467 | | * start_table points to a legal entry and end_table points |
468 | | * beyond the table or to a legal entry that is after index. |
469 | | */ |
470 | 69.4M | if (end - start > MAX_LINEAR_SEARCH) { |
471 | 9.37M | int offset; |
472 | 9.37M | parse_varint(start, &offset); |
473 | 9.37M | if (offset > index) { |
474 | 231k | return 0; |
475 | 231k | } |
476 | 20.2M | do { |
477 | 20.2M | unsigned char * mid = start + ((end-start)>>1); |
478 | 20.2M | mid = scan_back_to_entry_start(mid); |
479 | 20.2M | parse_varint(mid, &offset); |
480 | 20.2M | if (offset > index) { |
481 | 18.1M | end = mid; |
482 | 18.1M | } |
483 | 2.07M | else { |
484 | 2.07M | start = mid; |
485 | 2.07M | } |
486 | | |
487 | 20.2M | } while (end - start > MAX_LINEAR_SEARCH); |
488 | 9.14M | } |
489 | 69.2M | unsigned char *scan = start; |
490 | 104M | while (scan < end) { |
491 | 70.2M | int start_offset, size; |
492 | 70.2M | scan = parse_varint(scan, &start_offset); |
493 | 70.2M | if (start_offset > index) { |
494 | 5.41M | break; |
495 | 5.41M | } |
496 | 64.7M | scan = parse_varint(scan, &size); |
497 | 64.7M | if (start_offset + size > index) { |
498 | 29.0M | scan = parse_varint(scan, handler); |
499 | 29.0M | int depth_and_lasti; |
500 | 29.0M | parse_varint(scan, &depth_and_lasti); |
501 | 29.0M | *level = depth_and_lasti >> 1; |
502 | 29.0M | *lasti = depth_and_lasti & 1; |
503 | 29.0M | return 1; |
504 | 29.0M | } |
505 | 35.7M | scan = skip_to_next_entry(scan, end); |
506 | 35.7M | } |
507 | 40.1M | return 0; |
508 | 69.2M | } |
509 | | |
510 | | |
511 | | #ifdef Py_DEBUG |
512 | | #define ASSERT_WITHIN_STACK_BOUNDS(F, L) _Py_assert_within_stack_bounds(frame, stack_pointer, (F), (L)) |
513 | | #else |
514 | 45.9G | #define ASSERT_WITHIN_STACK_BOUNDS(F, L) (void)0 |
515 | | #endif |
516 | | |
517 | | /* Logic for the raise statement (too complicated for inlining). |
518 | | This *consumes* a reference count to each of its arguments. */ |
519 | | static int |
520 | | do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause) |
521 | 19.7M | { |
522 | 19.7M | PyObject *type = NULL, *value = NULL; |
523 | | |
524 | 19.7M | if (exc == NULL) { |
525 | | /* Reraise */ |
526 | 13.3k | _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate); |
527 | 13.3k | exc = exc_info->exc_value; |
528 | 13.3k | if (Py_IsNone(exc) || exc == NULL) { |
529 | 0 | _PyErr_SetString(tstate, PyExc_RuntimeError, |
530 | 0 | "No active exception to reraise"); |
531 | 0 | return 0; |
532 | 0 | } |
533 | 13.3k | Py_INCREF(exc); |
534 | 13.3k | assert(PyExceptionInstance_Check(exc)); |
535 | 13.3k | _PyErr_SetRaisedException(tstate, exc); |
536 | 13.3k | return 1; |
537 | 13.3k | } |
538 | | |
539 | | /* We support the following forms of raise: |
540 | | raise |
541 | | raise <instance> |
542 | | raise <type> */ |
543 | | |
544 | 19.7M | if (PyExceptionClass_Check(exc)) { |
545 | 14.1M | type = exc; |
546 | 14.1M | value = _PyObject_CallNoArgs(exc); |
547 | 14.1M | if (value == NULL) |
548 | 0 | goto raise_error; |
549 | 14.1M | if (!PyExceptionInstance_Check(value)) { |
550 | 0 | _PyErr_Format(tstate, PyExc_TypeError, |
551 | 0 | "calling %R should have returned an instance of " |
552 | 0 | "BaseException, not %R", |
553 | 0 | type, Py_TYPE(value)); |
554 | 0 | goto raise_error; |
555 | 0 | } |
556 | 14.1M | } |
557 | 5.58M | else if (PyExceptionInstance_Check(exc)) { |
558 | 5.58M | value = exc; |
559 | 5.58M | type = PyExceptionInstance_Class(exc); |
560 | 5.58M | Py_INCREF(type); |
561 | 5.58M | } |
562 | 0 | else { |
563 | | /* Not something you can raise. You get an exception |
564 | | anyway, just not what you specified :-) */ |
565 | 0 | Py_DECREF(exc); |
566 | 0 | _PyErr_SetString(tstate, PyExc_TypeError, |
567 | 0 | "exceptions must derive from BaseException"); |
568 | 0 | goto raise_error; |
569 | 0 | } |
570 | | |
571 | 19.7M | assert(type != NULL); |
572 | 19.7M | assert(value != NULL); |
573 | | |
574 | 19.7M | if (cause) { |
575 | 8.90k | PyObject *fixed_cause; |
576 | 8.90k | if (PyExceptionClass_Check(cause)) { |
577 | 0 | fixed_cause = _PyObject_CallNoArgs(cause); |
578 | 0 | if (fixed_cause == NULL) |
579 | 0 | goto raise_error; |
580 | 0 | if (!PyExceptionInstance_Check(fixed_cause)) { |
581 | 0 | _PyErr_Format(tstate, PyExc_TypeError, |
582 | 0 | "calling %R should have returned an instance of " |
583 | 0 | "BaseException, not %R", |
584 | 0 | cause, Py_TYPE(fixed_cause)); |
585 | 0 | Py_DECREF(fixed_cause); |
586 | 0 | goto raise_error; |
587 | 0 | } |
588 | 0 | Py_DECREF(cause); |
589 | 0 | } |
590 | 8.90k | else if (PyExceptionInstance_Check(cause)) { |
591 | 2.93k | fixed_cause = cause; |
592 | 2.93k | } |
593 | 5.97k | else if (Py_IsNone(cause)) { |
594 | 5.97k | Py_DECREF(cause); |
595 | 5.97k | fixed_cause = NULL; |
596 | 5.97k | } |
597 | 0 | else { |
598 | 0 | _PyErr_SetString(tstate, PyExc_TypeError, |
599 | 0 | "exception causes must derive from " |
600 | 0 | "BaseException"); |
601 | 0 | goto raise_error; |
602 | 0 | } |
603 | 8.90k | PyException_SetCause(value, fixed_cause); |
604 | 8.90k | } |
605 | | |
606 | 19.7M | _PyErr_SetObject(tstate, type, value); |
607 | | /* _PyErr_SetObject incref's its arguments */ |
608 | 19.7M | Py_DECREF(value); |
609 | 19.7M | Py_DECREF(type); |
610 | 19.7M | return 0; |
611 | | |
612 | 0 | raise_error: |
613 | 0 | Py_XDECREF(value); |
614 | 0 | Py_XDECREF(type); |
615 | | Py_XDECREF(cause); |
616 | 0 | return 0; |
617 | 19.7M | } |
618 | | |
619 | | /* Disable unused label warnings. They are handy for debugging, even |
620 | | if computed gotos aren't used. */ |
621 | | |
622 | | /* TBD - what about other compilers? */ |
623 | | #if defined(__GNUC__) || defined(__clang__) |
624 | | # pragma GCC diagnostic push |
625 | | # pragma GCC diagnostic ignored "-Wunused-label" |
626 | | #elif defined(_MSC_VER) /* MS_WINDOWS */ |
627 | | # pragma warning(push) |
628 | | # pragma warning(disable:4102) |
629 | | #endif |