Nuitka
The Python compiler
Loading...
Searching...
No Matches
CompiledGeneratorTypeUncompiledIntegration.c
1// Copyright 2025, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
10// This file is included from another C file, help IDEs to still parse it on
11// its own.
12#ifdef __IDE_ONLY__
13#include "nuitka/prelude.h"
14#endif
15
16// spell-checker: ignore f_valuestack,f_stacktop,PYGEN,_Py_CODEUNIT,OPARG
17// spell-checker: ignore localsplus,stacktop,f_funcobj,genexit
18// spell-checker: ignore deopt,subscr,isinstance,getitem,noargs,aiter,anext
19// spell-checker: ignore classderef,getattribute,precall,nondescriptor,pyfunc
20
21#if PYTHON_VERSION >= 0x300
22static PyObject *Nuitka_CallGeneratorThrowMethod(PyObject *throw_method,
23 struct Nuitka_ExceptionPreservationItem *exception_state);
24#endif
25
26#if PYTHON_VERSION >= 0x300
27static PyBaseExceptionObject *Nuitka_BaseExceptionSingleArg_new(PyThreadState *tstate, PyTypeObject *type,
28 PyObject *arg) {
29 PyBaseExceptionObject *result = (PyBaseExceptionObject *)type->tp_alloc(type, 0);
30
31 result->dict = NULL;
32 result->traceback = NULL;
33 result->cause = NULL;
34 result->context = NULL;
35 result->suppress_context = 0;
36
37 if (arg != NULL) {
38 result->args = MAKE_TUPLE1(tstate, arg);
39 } else {
40 result->args = const_tuple_empty;
41 Py_INCREF_IMMORTAL(result->args);
42 }
43
44 return result;
45}
46
47static PyObject *Nuitka_CreateStopIteration(PyThreadState *tstate, PyObject *value) {
48 if (value == Py_None) {
49 value = NULL;
50 }
51
52 PyStopIterationObject *result =
53 (PyStopIterationObject *)Nuitka_BaseExceptionSingleArg_new(tstate, (PyTypeObject *)PyExc_StopIteration, value);
54
55#if PYTHON_VERSION >= 0x3c0
56 if (value == NULL) {
57 // Immortal value.
58 result->value = Py_None;
59 } else {
60 result->value = value;
61 Py_INCREF(value);
62 }
63#else
64 result->value = value;
65 Py_XINCREF(value);
66#endif
67
68 return (PyObject *)result;
69}
70
71// This function takes no reference to value, and publishes a StopIteration
72// exception with it.
73static void Nuitka_SetStopIterationValue(PyThreadState *tstate, PyObject *value) {
74 CHECK_OBJECT(value);
75
76#if PYTHON_VERSION <= 0x352
77 PyObject *stop_value = CALL_FUNCTION_WITH_SINGLE_ARG(tstate, PyExc_StopIteration, value);
78
79 if (unlikely(stop_value == NULL)) {
80 return;
81 }
82
83 SET_CURRENT_EXCEPTION_TYPE0_VALUE1(tstate, PyExc_StopIteration, stop_value);
84#elif PYTHON_VERSION < 0x3c0
85 if (likely(!PyTuple_Check(value) && !PyExceptionInstance_Check(value))) {
86 SET_CURRENT_EXCEPTION_TYPE0_VALUE0(tstate, PyExc_StopIteration, value);
87 } else {
88 struct Nuitka_ExceptionPreservationItem exception_state = {Py_NewRef(PyExc_StopIteration),
89 Nuitka_CreateStopIteration(tstate, value)};
90
91 RESTORE_ERROR_OCCURRED_STATE(tstate, &exception_state);
92 }
93#else
94 struct Nuitka_ExceptionPreservationItem exception_state = {Nuitka_CreateStopIteration(tstate, value)};
95
96 RESTORE_ERROR_OCCURRED_STATE(tstate, &exception_state);
97#endif
98}
99#endif
100
101static void SET_CURRENT_EXCEPTION_STOP_ITERATION_EMPTY(PyThreadState *tstate) {
102#if PYTHON_VERSION < 0x3c0
103 SET_CURRENT_EXCEPTION_TYPE0(tstate, PyExc_StopIteration);
104#else
105 struct Nuitka_ExceptionPreservationItem exception_state = {Nuitka_CreateStopIteration(tstate, NULL)};
106
107 RESTORE_ERROR_OCCURRED_STATE(tstate, &exception_state);
108#endif
109}
110
111#if PYTHON_VERSION >= 0x360
112
113#if PYTHON_VERSION >= 0x3c0
114static PyObject *Nuitka_CreateStopAsyncIteration(PyThreadState *tstate) {
115 return (PyObject *)Nuitka_BaseExceptionSingleArg_new(tstate, (PyTypeObject *)PyExc_StopAsyncIteration, NULL);
116}
117#endif
118
119static void SET_CURRENT_EXCEPTION_STOP_ASYNC_ITERATION(PyThreadState *tstate) {
120#if PYTHON_VERSION < 0x3c0
121 SET_CURRENT_EXCEPTION_TYPE0(tstate, PyExc_StopAsyncIteration);
122#else
123 struct Nuitka_ExceptionPreservationItem exception_state = {Nuitka_CreateStopAsyncIteration(tstate)};
124
125 RESTORE_ERROR_OCCURRED_STATE(tstate, &exception_state);
126#endif
127}
128
129#endif
130
131#if PYTHON_VERSION >= 0x3c0
132static PyObject *Nuitka_CreateGeneratorExit(PyThreadState *tstate) {
133 return (PyObject *)Nuitka_BaseExceptionSingleArg_new(tstate, (PyTypeObject *)PyExc_GeneratorExit, NULL);
134}
135#endif
136
137#if PYTHON_VERSION >= 0x300
138static void SET_CURRENT_EXCEPTION_GENERATOR_EXIT(PyThreadState *tstate) {
139#if PYTHON_VERSION < 0x3c0
140 SET_CURRENT_EXCEPTION_TYPE0(tstate, PyExc_GeneratorExit);
141#else
142 struct Nuitka_ExceptionPreservationItem exception_state = {Nuitka_CreateGeneratorExit(tstate)};
143
144 RESTORE_ERROR_OCCURRED_STATE(tstate, &exception_state);
145#endif
146}
147#endif
148
149#if PYTHON_VERSION >= 0x300
150static bool Nuitka_PyGen_FetchStopIterationValue(PyThreadState *tstate, PyObject **pvalue) {
151#if PYTHON_VERSION < 0x3c0
152 if (!HAS_ERROR_OCCURRED(tstate)) {
153 *pvalue = Py_None;
154 Py_INCREF_IMMORTAL(Py_None);
155
156 return true;
157 } else if (EXCEPTION_MATCH_BOOL_SINGLE(tstate, tstate->curexc_type, PyExc_StopIteration)) {
158 PyObject *value = NULL;
159
160 PyObject *exception_type, *exception_value;
161 PyTracebackObject *exception_tb;
162
163 FETCH_ERROR_OCCURRED(tstate, &exception_type, &exception_value, &exception_tb);
164
165 if (exception_value) {
166 // TODO: API call here should be eliminated.
167 if (PyObject_TypeCheck(exception_value, (PyTypeObject *)exception_type)) {
168 value = ((PyStopIterationObject *)exception_value)->value;
169 Py_INCREF(value);
170 Py_DECREF(exception_value);
171 } else if (exception_type == PyExc_StopIteration && !PyTuple_Check(exception_value)) {
172 value = exception_value;
173 } else {
174 NORMALIZE_EXCEPTION(tstate, &exception_type, &exception_value, &exception_tb);
175
176 if (!PyObject_TypeCheck(exception_value, (PyTypeObject *)PyExc_StopIteration)) {
177 RESTORE_ERROR_OCCURRED(tstate, exception_type, exception_value, exception_tb);
178
179 return false;
180 }
181
182 value = ((PyStopIterationObject *)exception_value)->value;
183 Py_INCREF(value);
184
185 Py_DECREF(exception_value);
186 }
187 }
188
189 Py_XDECREF(exception_type);
190 Py_XDECREF(exception_tb);
191
192 if (value == NULL) {
193 value = Py_None;
194 Py_INCREF(value);
195 }
196
197 *pvalue = value;
198
199 return true;
200 } else {
201 return false;
202 }
203#else
204 if (!HAS_ERROR_OCCURRED(tstate)) {
205 *pvalue = Py_None;
206 Py_INCREF_IMMORTAL(Py_None);
207
208 return true;
209 } else if (EXCEPTION_MATCH_BOOL_SINGLE(tstate, tstate->current_exception, PyExc_StopIteration)) {
210 PyObject *value = NULL;
211
212 PyObject *exc = tstate->current_exception;
213 tstate->current_exception = NULL;
214
215 value = Py_NewRef(((PyStopIterationObject *)exc)->value);
216 Py_DECREF(exc);
217
218 if (value == NULL) {
219 value = Py_None;
220 }
221
222 *pvalue = value;
223
224 return true;
225
226 } else {
227 return false;
228 }
229#endif
230}
231#endif
232
233#if PYTHON_VERSION >= 0x370
234static inline void Nuitka_PyGen_exc_state_clear(_PyErr_StackItem *exc_state) {
235#if PYTHON_VERSION < 0x3b0
236 PyObject *t = exc_state->exc_type;
237#endif
238 PyObject *v = exc_state->exc_value;
239#if PYTHON_VERSION < 0x3b0
240 PyObject *tb = exc_state->exc_traceback;
241#endif
242
243#if PYTHON_VERSION < 0x3b0
244 exc_state->exc_type = NULL;
245#endif
246 exc_state->exc_value = NULL;
247#if PYTHON_VERSION < 0x3b0
248 exc_state->exc_traceback = NULL;
249#endif
250
251#if PYTHON_VERSION < 0x3b0
252 Py_XDECREF(t);
253#endif
254 Py_XDECREF(v);
255#if PYTHON_VERSION < 0x3b0
256 Py_XDECREF(tb);
257#endif
258}
259#endif
260
261#if PYTHON_VERSION >= 0x300
262
263#if PYTHON_VERSION < 0x3b0
264static inline bool Nuitka_PyFrameHasCompleted(PyFrameObject *const frame) {
265#if PYTHON_VERSION < 0x3a0
266 return frame->f_stacktop == NULL;
267#else
268 return frame->f_state > FRAME_EXECUTING;
269#endif
270}
271#endif
272
273// This is for CPython iterator objects, the respective code is not exported as
274// API, so we need to redo it. This is an re-implementation that closely follows
275// what it does. It's unrelated to compiled generators, and used from coroutines
276// and asyncgen to interact with them.
277static PyObject *Nuitka_PyGen_Send(PyThreadState *tstate, PyGenObject *gen, PyObject *arg) {
278#if PYTHON_VERSION >= 0x3a0
279 PyObject *result;
280
281 // TODO: Avoid API call for performance.
282 PySendResult res = PyIter_Send((PyObject *)gen, arg, &result);
283
284 switch (res) {
285 case PYGEN_RETURN:
286 if (result == NULL) {
287 SET_CURRENT_EXCEPTION_STOP_ITERATION_EMPTY(tstate);
288 } else {
289 if (result != Py_None) {
290 Nuitka_SetStopIterationValue(tstate, result);
291 }
292
293 Py_DECREF(result);
294 }
295
296 return NULL;
297 case PYGEN_NEXT:
298 return result;
299 case PYGEN_ERROR:
300 return NULL;
301 default:
302 NUITKA_CANNOT_GET_HERE("invalid PYGEN_ result");
303 }
304#else
305
306 PyFrameObject *f = gen->gi_frame;
307
308#if PYTHON_VERSION >= 0x3b0
309 if (gen->gi_frame_state == FRAME_EXECUTING) {
310#elif PYTHON_VERSION >= 0x3a0
311 if (f != NULL && _PyFrame_IsExecuting(f)) {
312#else
313 if (unlikely(gen->gi_running)) {
314#endif
315 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ValueError, "generator already executing");
316 return NULL;
317 }
318
319#if PYTHON_VERSION < 0x3b0
320 if (f == NULL || Nuitka_PyFrameHasCompleted(f)) {
321#else
322 if (gen->gi_frame_state >= FRAME_COMPLETED) {
323#endif
324 // Set exception if called from send()
325 if (arg != NULL) {
326 SET_CURRENT_EXCEPTION_STOP_ITERATION_EMPTY(tstate);
327 }
328
329 return NULL;
330 }
331
332#if PYTHON_VERSION < 0x3a0
333 if (f->f_lasti == -1) {
334 if (unlikely(arg && arg != Py_None)) {
335 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError,
336 "can't send non-None value to a just-started generator");
337
338 return NULL;
339 }
340 } else {
341 // Put arg on top of the value stack
342 PyObject *tmp = arg ? arg : Py_None;
343
344 Py_INCREF(tmp);
345 *(f->f_stacktop++) = tmp;
346 }
347#else
348 // CPython assertions, check them
349 assert(_PyFrame_IsRunnable(f));
350 assert(f->f_lasti >= 0 || ((unsigned char *)PyBytes_AS_STRING(f->f_code->co_code))[0] == 129);
351
352 PyObject *gen_result = arg ? arg : Py_None;
353 Py_INCREF(gen_result);
354 gen->gi_frame->f_valuestack[gen->gi_frame->f_stackdepth] = gen_result;
355 gen->gi_frame->f_stackdepth++;
356#endif
357
358 // Generators always return to their most recent caller, not necessarily
359 // their creator.
360 tstate = PyThreadState_GET();
361 Py_XINCREF(tstate->frame);
362
363 f->f_back = tstate->frame;
364
365#if PYTHON_VERSION < 0x3a0
366 gen->gi_running = 1;
367#endif
368#if PYTHON_VERSION >= 0x370
369 gen->gi_exc_state.previous_item = tstate->exc_info;
370 tstate->exc_info = &gen->gi_exc_state;
371#endif
372
373#if PYTHON_VERSION < 0x390
374 PyObject *result = PyEval_EvalFrameEx(f, 0);
375#else
376 PyObject *result = _PyEval_EvalFrame(tstate, f, 0);
377#endif
378
379#if PYTHON_VERSION >= 0x370
380 tstate->exc_info = gen->gi_exc_state.previous_item;
381 gen->gi_exc_state.previous_item = NULL;
382#endif
383#if PYTHON_VERSION < 0x3a0
384 gen->gi_running = 0;
385#endif
386
387 // Don't keep the reference to f_back any longer than necessary. It
388 // may keep a chain of frames alive or it could create a reference
389 // cycle.
390 Py_CLEAR(f->f_back);
391
392 // If the generator just returned (as opposed to yielding), signal that the
393 // generator is exhausted.
394#if PYTHON_VERSION < 0x3a0
395 if (result && f->f_stacktop == NULL) {
396 if (result == Py_None) {
397 SET_CURRENT_EXCEPTION_STOP_ITERATION_EMPTY(tstate);
398 } else {
399 PyObject *e = CALL_FUNCTION_WITH_SINGLE_ARG(tstate, (PyObject *)PyExc_StopIteration, result);
400
401 if (likely(e != NULL)) {
402 SET_CURRENT_EXCEPTION_TYPE0_VALUE1(tstate, PyExc_StopIteration, e);
403 }
404 }
405
406 Py_CLEAR(result);
407 }
408
409 if (result == NULL || f->f_stacktop == NULL) {
410#if PYTHON_VERSION < 0x370
411 // Generator is finished, remove exception from frame before releasing
412 // it.
413 PyObject *type = f->f_exc_type;
414 PyObject *value = f->f_exc_value;
415 PyObject *traceback = f->f_exc_traceback;
416 f->f_exc_type = NULL;
417 f->f_exc_value = NULL;
418 f->f_exc_traceback = NULL;
419 Py_XDECREF(type);
420 Py_XDECREF(value);
421 Py_XDECREF(traceback);
422#else
423 Nuitka_PyGen_exc_state_clear(&gen->gi_exc_state);
424#endif
425
426 // Now release frame.
427#if PYTHON_VERSION >= 0x300
428 gen->gi_frame->f_gen = NULL;
429#endif
430 gen->gi_frame = NULL;
431 Py_DECREF(f);
432 }
433#else
434 if (result) {
435 if (!_PyFrameHasCompleted(f)) {
436 return result;
437 }
438 assert(result == Py_None || !PyAsyncGen_CheckExact(gen));
439
440 if (result == Py_None && !PyAsyncGen_CheckExact(gen)) {
441 Py_DECREF_IMMORTAL(result);
442 result = NULL;
443 }
444 } else {
445 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
446 const char *msg = "generator raised StopIteration";
447 if (PyCoro_CheckExact(gen)) {
448 msg = "coroutine raised StopIteration";
449 } else if (PyAsyncGen_CheckExact(gen)) {
450 msg = "async generator raised StopIteration";
451 }
452 _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);
453 } else if (PyAsyncGen_CheckExact(gen) && PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) {
454 const char *msg = "async generator raised StopAsyncIteration";
455 _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);
456 }
457
458 result = NULL;
459 }
460
461 Nuitka_PyGen_exc_state_clear(&gen->gi_exc_state);
462
463 gen->gi_frame->f_gen = NULL;
464 gen->gi_frame = NULL;
465
466 Py_DECREF(f);
467
468#endif
469
470 return result;
471#endif
472}
473
474#endif
475
476// Not done for Python2, indicate usability for compiled generators, but it
477// seems that mostly coroutines need it anyway, so the benefit would be only for
478// performance and not by a lot.
479#if PYTHON_VERSION >= 0x300
480#define NUITKA_UNCOMPILED_THROW_INTEGRATION 1
481#endif
482
483#if NUITKA_UNCOMPILED_THROW_INTEGRATION
484
485static bool _Nuitka_Generator_check_throw(PyThreadState *tstate,
486 struct Nuitka_ExceptionPreservationItem *exception_state);
487
488#if PYTHON_VERSION < 0x3b0
489#include <opcode.h>
490// Clashes with our helper names.
491#undef CALL_FUNCTION
492#endif
493
494static PyObject *Nuitka_PyGen_gen_close(PyThreadState *tstate, PyGenObject *gen, PyObject *args);
495static int Nuitka_PyGen_gen_close_iter(PyThreadState *tstate, PyObject *yf);
496
497// Restarting with 3.11, because the structures and internal API have
498// changed so much, makes no sense to keep it in one code. For older
499// versions, the else branch is there.
500#if PYTHON_VERSION >= 0x3b0
501
502// Private opcode mapping, that we need too
503const uint8_t Nuitka_PyOpcode_Deopt[256] = {
504#if PYTHON_VERSION >= 0x3d0
505 [BEFORE_ASYNC_WITH] = BEFORE_ASYNC_WITH,
506 [BEFORE_WITH] = BEFORE_WITH,
507 [BINARY_OP] = BINARY_OP,
508 [BINARY_OP_ADD_FLOAT] = BINARY_OP,
509 [BINARY_OP_ADD_INT] = BINARY_OP,
510 [BINARY_OP_ADD_UNICODE] = BINARY_OP,
511 [BINARY_OP_INPLACE_ADD_UNICODE] = BINARY_OP,
512 [BINARY_OP_MULTIPLY_FLOAT] = BINARY_OP,
513 [BINARY_OP_MULTIPLY_INT] = BINARY_OP,
514 [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP,
515 [BINARY_OP_SUBTRACT_INT] = BINARY_OP,
516 [BINARY_SLICE] = BINARY_SLICE,
517 [BINARY_SUBSCR] = BINARY_SUBSCR,
518 [BINARY_SUBSCR_DICT] = BINARY_SUBSCR,
519 [BINARY_SUBSCR_GETITEM] = BINARY_SUBSCR,
520 [BINARY_SUBSCR_LIST_INT] = BINARY_SUBSCR,
521 [BINARY_SUBSCR_STR_INT] = BINARY_SUBSCR,
522 [BINARY_SUBSCR_TUPLE_INT] = BINARY_SUBSCR,
523 [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP,
524 [BUILD_LIST] = BUILD_LIST,
525 [BUILD_MAP] = BUILD_MAP,
526 [BUILD_SET] = BUILD_SET,
527 [BUILD_SLICE] = BUILD_SLICE,
528 [BUILD_STRING] = BUILD_STRING,
529 [BUILD_TUPLE] = BUILD_TUPLE,
530 [CACHE] = CACHE,
531 [CALL] = CALL,
532 [CALL_ALLOC_AND_ENTER_INIT] = CALL,
533 [CALL_BOUND_METHOD_EXACT_ARGS] = CALL,
534 [CALL_BOUND_METHOD_GENERAL] = CALL,
535 [CALL_BUILTIN_CLASS] = CALL,
536 [CALL_BUILTIN_FAST] = CALL,
537 [CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL,
538 [CALL_BUILTIN_O] = CALL,
539 [CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
540 [CALL_INTRINSIC_1] = CALL_INTRINSIC_1,
541 [CALL_INTRINSIC_2] = CALL_INTRINSIC_2,
542 [CALL_ISINSTANCE] = CALL,
543 [CALL_KW] = CALL_KW,
544 [CALL_LEN] = CALL,
545 [CALL_LIST_APPEND] = CALL,
546 [CALL_METHOD_DESCRIPTOR_FAST] = CALL,
547 [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL,
548 [CALL_METHOD_DESCRIPTOR_NOARGS] = CALL,
549 [CALL_METHOD_DESCRIPTOR_O] = CALL,
550 [CALL_NON_PY_GENERAL] = CALL,
551 [CALL_PY_EXACT_ARGS] = CALL,
552 [CALL_PY_GENERAL] = CALL,
553 [CALL_STR_1] = CALL,
554 [CALL_TUPLE_1] = CALL,
555 [CALL_TYPE_1] = CALL,
556 [CHECK_EG_MATCH] = CHECK_EG_MATCH,
557 [CHECK_EXC_MATCH] = CHECK_EXC_MATCH,
558 [CLEANUP_THROW] = CLEANUP_THROW,
559 [COMPARE_OP] = COMPARE_OP,
560 [COMPARE_OP_FLOAT] = COMPARE_OP,
561 [COMPARE_OP_INT] = COMPARE_OP,
562 [COMPARE_OP_STR] = COMPARE_OP,
563 [CONTAINS_OP] = CONTAINS_OP,
564 [CONTAINS_OP_DICT] = CONTAINS_OP,
565 [CONTAINS_OP_SET] = CONTAINS_OP,
566 [CONVERT_VALUE] = CONVERT_VALUE,
567 [COPY] = COPY,
568 [COPY_FREE_VARS] = COPY_FREE_VARS,
569 [DELETE_ATTR] = DELETE_ATTR,
570 [DELETE_DEREF] = DELETE_DEREF,
571 [DELETE_FAST] = DELETE_FAST,
572 [DELETE_GLOBAL] = DELETE_GLOBAL,
573 [DELETE_NAME] = DELETE_NAME,
574 [DELETE_SUBSCR] = DELETE_SUBSCR,
575 [DICT_MERGE] = DICT_MERGE,
576 [DICT_UPDATE] = DICT_UPDATE,
577 [END_ASYNC_FOR] = END_ASYNC_FOR,
578 [END_FOR] = END_FOR,
579 [END_SEND] = END_SEND,
580 [ENTER_EXECUTOR] = ENTER_EXECUTOR,
581 [EXIT_INIT_CHECK] = EXIT_INIT_CHECK,
582 [EXTENDED_ARG] = EXTENDED_ARG,
583 [FORMAT_SIMPLE] = FORMAT_SIMPLE,
584 [FORMAT_WITH_SPEC] = FORMAT_WITH_SPEC,
585 [FOR_ITER] = FOR_ITER,
586 [FOR_ITER_GEN] = FOR_ITER,
587 [FOR_ITER_LIST] = FOR_ITER,
588 [FOR_ITER_RANGE] = FOR_ITER,
589 [FOR_ITER_TUPLE] = FOR_ITER,
590 [GET_AITER] = GET_AITER,
591 [GET_ANEXT] = GET_ANEXT,
592 [GET_AWAITABLE] = GET_AWAITABLE,
593 [GET_ITER] = GET_ITER,
594 [GET_LEN] = GET_LEN,
595 [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER,
596 [IMPORT_FROM] = IMPORT_FROM,
597 [IMPORT_NAME] = IMPORT_NAME,
598 [INSTRUMENTED_CALL] = INSTRUMENTED_CALL,
599 [INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX,
600 [INSTRUMENTED_CALL_KW] = INSTRUMENTED_CALL_KW,
601 [INSTRUMENTED_END_FOR] = INSTRUMENTED_END_FOR,
602 [INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND,
603 [INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER,
604 [INSTRUMENTED_INSTRUCTION] = INSTRUMENTED_INSTRUCTION,
605 [INSTRUMENTED_JUMP_BACKWARD] = INSTRUMENTED_JUMP_BACKWARD,
606 [INSTRUMENTED_JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD,
607 [INSTRUMENTED_LINE] = INSTRUMENTED_LINE,
608 [INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
609 [INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE,
610 [INSTRUMENTED_POP_JUMP_IF_NONE] = INSTRUMENTED_POP_JUMP_IF_NONE,
611 [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE,
612 [INSTRUMENTED_POP_JUMP_IF_TRUE] = INSTRUMENTED_POP_JUMP_IF_TRUE,
613 [INSTRUMENTED_RESUME] = INSTRUMENTED_RESUME,
614 [INSTRUMENTED_RETURN_CONST] = INSTRUMENTED_RETURN_CONST,
615 [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE,
616 [INSTRUMENTED_YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE,
617 [INTERPRETER_EXIT] = INTERPRETER_EXIT,
618 [IS_OP] = IS_OP,
619 [JUMP_BACKWARD] = JUMP_BACKWARD,
620 [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT,
621 [JUMP_FORWARD] = JUMP_FORWARD,
622 [LIST_APPEND] = LIST_APPEND,
623 [LIST_EXTEND] = LIST_EXTEND,
624 [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR,
625 [LOAD_ATTR] = LOAD_ATTR,
626 [LOAD_ATTR_CLASS] = LOAD_ATTR,
627 [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = LOAD_ATTR,
628 [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR,
629 [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR,
630 [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR,
631 [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR,
632 [LOAD_ATTR_MODULE] = LOAD_ATTR,
633 [LOAD_ATTR_NONDESCRIPTOR_NO_DICT] = LOAD_ATTR,
634 [LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES] = LOAD_ATTR,
635 [LOAD_ATTR_PROPERTY] = LOAD_ATTR,
636 [LOAD_ATTR_SLOT] = LOAD_ATTR,
637 [LOAD_ATTR_WITH_HINT] = LOAD_ATTR,
638 [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS,
639 [LOAD_CONST] = LOAD_CONST,
640 [LOAD_DEREF] = LOAD_DEREF,
641 [LOAD_FAST] = LOAD_FAST,
642 [LOAD_FAST_AND_CLEAR] = LOAD_FAST_AND_CLEAR,
643 [LOAD_FAST_CHECK] = LOAD_FAST_CHECK,
644 [LOAD_FAST_LOAD_FAST] = LOAD_FAST_LOAD_FAST,
645 [LOAD_FROM_DICT_OR_DEREF] = LOAD_FROM_DICT_OR_DEREF,
646 [LOAD_FROM_DICT_OR_GLOBALS] = LOAD_FROM_DICT_OR_GLOBALS,
647 [LOAD_GLOBAL] = LOAD_GLOBAL,
648 [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL,
649 [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL,
650 [LOAD_LOCALS] = LOAD_LOCALS,
651 [LOAD_NAME] = LOAD_NAME,
652 [LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
653 [LOAD_SUPER_ATTR_ATTR] = LOAD_SUPER_ATTR,
654 [LOAD_SUPER_ATTR_METHOD] = LOAD_SUPER_ATTR,
655 [MAKE_CELL] = MAKE_CELL,
656 [MAKE_FUNCTION] = MAKE_FUNCTION,
657 [MAP_ADD] = MAP_ADD,
658 [MATCH_CLASS] = MATCH_CLASS,
659 [MATCH_KEYS] = MATCH_KEYS,
660 [MATCH_MAPPING] = MATCH_MAPPING,
661 [MATCH_SEQUENCE] = MATCH_SEQUENCE,
662 [NOP] = NOP,
663 [POP_EXCEPT] = POP_EXCEPT,
664 [POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE,
665 [POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE,
666 [POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE,
667 [POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE,
668 [POP_TOP] = POP_TOP,
669 [PUSH_EXC_INFO] = PUSH_EXC_INFO,
670 [PUSH_NULL] = PUSH_NULL,
671 [RAISE_VARARGS] = RAISE_VARARGS,
672 [RERAISE] = RERAISE,
673 [RESERVED] = RESERVED,
674 [RESUME] = RESUME,
675 [RESUME_CHECK] = RESUME,
676 [RETURN_CONST] = RETURN_CONST,
677 [RETURN_GENERATOR] = RETURN_GENERATOR,
678 [RETURN_VALUE] = RETURN_VALUE,
679 [SEND] = SEND,
680 [SEND_GEN] = SEND,
681 [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS,
682 [SET_ADD] = SET_ADD,
683 [SET_FUNCTION_ATTRIBUTE] = SET_FUNCTION_ATTRIBUTE,
684 [SET_UPDATE] = SET_UPDATE,
685 [STORE_ATTR] = STORE_ATTR,
686 [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR,
687 [STORE_ATTR_SLOT] = STORE_ATTR,
688 [STORE_ATTR_WITH_HINT] = STORE_ATTR,
689 [STORE_DEREF] = STORE_DEREF,
690 [STORE_FAST] = STORE_FAST,
691 [STORE_FAST_LOAD_FAST] = STORE_FAST_LOAD_FAST,
692 [STORE_FAST_STORE_FAST] = STORE_FAST_STORE_FAST,
693 [STORE_GLOBAL] = STORE_GLOBAL,
694 [STORE_NAME] = STORE_NAME,
695 [STORE_SLICE] = STORE_SLICE,
696 [STORE_SUBSCR] = STORE_SUBSCR,
697 [STORE_SUBSCR_DICT] = STORE_SUBSCR,
698 [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR,
699 [SWAP] = SWAP,
700 [TO_BOOL] = TO_BOOL,
701 [TO_BOOL_ALWAYS_TRUE] = TO_BOOL,
702 [TO_BOOL_BOOL] = TO_BOOL,
703 [TO_BOOL_INT] = TO_BOOL,
704 [TO_BOOL_LIST] = TO_BOOL,
705 [TO_BOOL_NONE] = TO_BOOL,
706 [TO_BOOL_STR] = TO_BOOL,
707 [UNARY_INVERT] = UNARY_INVERT,
708 [UNARY_NEGATIVE] = UNARY_NEGATIVE,
709 [UNARY_NOT] = UNARY_NOT,
710 [UNPACK_EX] = UNPACK_EX,
711 [UNPACK_SEQUENCE] = UNPACK_SEQUENCE,
712 [UNPACK_SEQUENCE_LIST] = UNPACK_SEQUENCE,
713 [UNPACK_SEQUENCE_TUPLE] = UNPACK_SEQUENCE,
714 [UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE,
715 [WITH_EXCEPT_START] = WITH_EXCEPT_START,
716 [YIELD_VALUE] = YIELD_VALUE,
717#elif PYTHON_VERSION >= 0x3c0
718 [BEFORE_ASYNC_WITH] = BEFORE_ASYNC_WITH,
719 [BEFORE_WITH] = BEFORE_WITH,
720 [BINARY_OP] = BINARY_OP,
721 [BINARY_OP_ADD_FLOAT] = BINARY_OP,
722 [BINARY_OP_ADD_INT] = BINARY_OP,
723 [BINARY_OP_ADD_UNICODE] = BINARY_OP,
724 [BINARY_OP_INPLACE_ADD_UNICODE] = BINARY_OP,
725 [BINARY_OP_MULTIPLY_FLOAT] = BINARY_OP,
726 [BINARY_OP_MULTIPLY_INT] = BINARY_OP,
727 [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP,
728 [BINARY_OP_SUBTRACT_INT] = BINARY_OP,
729 [BINARY_SLICE] = BINARY_SLICE,
730 [BINARY_SUBSCR] = BINARY_SUBSCR,
731 [BINARY_SUBSCR_DICT] = BINARY_SUBSCR,
732 [BINARY_SUBSCR_GETITEM] = BINARY_SUBSCR,
733 [BINARY_SUBSCR_LIST_INT] = BINARY_SUBSCR,
734 [BINARY_SUBSCR_TUPLE_INT] = BINARY_SUBSCR,
735 [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP,
736 [BUILD_LIST] = BUILD_LIST,
737 [BUILD_MAP] = BUILD_MAP,
738 [BUILD_SET] = BUILD_SET,
739 [BUILD_SLICE] = BUILD_SLICE,
740 [BUILD_STRING] = BUILD_STRING,
741 [BUILD_TUPLE] = BUILD_TUPLE,
742 [CACHE] = CACHE,
743 [CALL] = CALL,
744 [CALL_BOUND_METHOD_EXACT_ARGS] = CALL,
745 [CALL_BUILTIN_CLASS] = CALL,
746 [CALL_BUILTIN_FAST_WITH_KEYWORDS] = CALL,
747 [CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
748 [CALL_INTRINSIC_1] = CALL_INTRINSIC_1,
749 [CALL_INTRINSIC_2] = CALL_INTRINSIC_2,
750 [CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = CALL,
751 [CALL_NO_KW_BUILTIN_FAST] = CALL,
752 [CALL_NO_KW_BUILTIN_O] = CALL,
753 [CALL_NO_KW_ISINSTANCE] = CALL,
754 [CALL_NO_KW_LEN] = CALL,
755 [CALL_NO_KW_LIST_APPEND] = CALL,
756 [CALL_NO_KW_METHOD_DESCRIPTOR_FAST] = CALL,
757 [CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = CALL,
758 [CALL_NO_KW_METHOD_DESCRIPTOR_O] = CALL,
759 [CALL_NO_KW_STR_1] = CALL,
760 [CALL_NO_KW_TUPLE_1] = CALL,
761 [CALL_NO_KW_TYPE_1] = CALL,
762 [CALL_PY_EXACT_ARGS] = CALL,
763 [CALL_PY_WITH_DEFAULTS] = CALL,
764 [CHECK_EG_MATCH] = CHECK_EG_MATCH,
765 [CHECK_EXC_MATCH] = CHECK_EXC_MATCH,
766 [CLEANUP_THROW] = CLEANUP_THROW,
767 [COMPARE_OP] = COMPARE_OP,
768 [COMPARE_OP_FLOAT] = COMPARE_OP,
769 [COMPARE_OP_INT] = COMPARE_OP,
770 [COMPARE_OP_STR] = COMPARE_OP,
771 [CONTAINS_OP] = CONTAINS_OP,
772 [COPY] = COPY,
773 [COPY_FREE_VARS] = COPY_FREE_VARS,
774 [DELETE_ATTR] = DELETE_ATTR,
775 [DELETE_DEREF] = DELETE_DEREF,
776 [DELETE_FAST] = DELETE_FAST,
777 [DELETE_GLOBAL] = DELETE_GLOBAL,
778 [DELETE_NAME] = DELETE_NAME,
779 [DELETE_SUBSCR] = DELETE_SUBSCR,
780 [DICT_MERGE] = DICT_MERGE,
781 [DICT_UPDATE] = DICT_UPDATE,
782 [END_ASYNC_FOR] = END_ASYNC_FOR,
783 [END_FOR] = END_FOR,
784 [END_SEND] = END_SEND,
785 [EXTENDED_ARG] = EXTENDED_ARG,
786 [FORMAT_VALUE] = FORMAT_VALUE,
787 [FOR_ITER] = FOR_ITER,
788 [FOR_ITER_GEN] = FOR_ITER,
789 [FOR_ITER_LIST] = FOR_ITER,
790 [FOR_ITER_RANGE] = FOR_ITER,
791 [FOR_ITER_TUPLE] = FOR_ITER,
792 [GET_AITER] = GET_AITER,
793 [GET_ANEXT] = GET_ANEXT,
794 [GET_AWAITABLE] = GET_AWAITABLE,
795 [GET_ITER] = GET_ITER,
796 [GET_LEN] = GET_LEN,
797 [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER,
798 [IMPORT_FROM] = IMPORT_FROM,
799 [IMPORT_NAME] = IMPORT_NAME,
800 [INSTRUMENTED_CALL] = INSTRUMENTED_CALL,
801 [INSTRUMENTED_CALL_FUNCTION_EX] = INSTRUMENTED_CALL_FUNCTION_EX,
802 [INSTRUMENTED_END_FOR] = INSTRUMENTED_END_FOR,
803 [INSTRUMENTED_END_SEND] = INSTRUMENTED_END_SEND,
804 [INSTRUMENTED_FOR_ITER] = INSTRUMENTED_FOR_ITER,
805 [INSTRUMENTED_INSTRUCTION] = INSTRUMENTED_INSTRUCTION,
806 [INSTRUMENTED_JUMP_BACKWARD] = INSTRUMENTED_JUMP_BACKWARD,
807 [INSTRUMENTED_JUMP_FORWARD] = INSTRUMENTED_JUMP_FORWARD,
808 [INSTRUMENTED_LINE] = INSTRUMENTED_LINE,
809 [INSTRUMENTED_LOAD_SUPER_ATTR] = INSTRUMENTED_LOAD_SUPER_ATTR,
810 [INSTRUMENTED_POP_JUMP_IF_FALSE] = INSTRUMENTED_POP_JUMP_IF_FALSE,
811 [INSTRUMENTED_POP_JUMP_IF_NONE] = INSTRUMENTED_POP_JUMP_IF_NONE,
812 [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = INSTRUMENTED_POP_JUMP_IF_NOT_NONE,
813 [INSTRUMENTED_POP_JUMP_IF_TRUE] = INSTRUMENTED_POP_JUMP_IF_TRUE,
814 [INSTRUMENTED_RESUME] = INSTRUMENTED_RESUME,
815 [INSTRUMENTED_RETURN_CONST] = INSTRUMENTED_RETURN_CONST,
816 [INSTRUMENTED_RETURN_VALUE] = INSTRUMENTED_RETURN_VALUE,
817 [INSTRUMENTED_YIELD_VALUE] = INSTRUMENTED_YIELD_VALUE,
818 [INTERPRETER_EXIT] = INTERPRETER_EXIT,
819 [IS_OP] = IS_OP,
820 [JUMP_BACKWARD] = JUMP_BACKWARD,
821 [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT,
822 [JUMP_FORWARD] = JUMP_FORWARD,
823 [KW_NAMES] = KW_NAMES,
824 [LIST_APPEND] = LIST_APPEND,
825 [LIST_EXTEND] = LIST_EXTEND,
826 [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR,
827 [LOAD_ATTR] = LOAD_ATTR,
828 [LOAD_ATTR_CLASS] = LOAD_ATTR,
829 [LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN] = LOAD_ATTR,
830 [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR,
831 [LOAD_ATTR_METHOD_LAZY_DICT] = LOAD_ATTR,
832 [LOAD_ATTR_METHOD_NO_DICT] = LOAD_ATTR,
833 [LOAD_ATTR_METHOD_WITH_VALUES] = LOAD_ATTR,
834 [LOAD_ATTR_MODULE] = LOAD_ATTR,
835 [LOAD_ATTR_PROPERTY] = LOAD_ATTR,
836 [LOAD_ATTR_SLOT] = LOAD_ATTR,
837 [LOAD_ATTR_WITH_HINT] = LOAD_ATTR,
838 [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS,
839 [LOAD_CLOSURE] = LOAD_CLOSURE,
840 [LOAD_CONST] = LOAD_CONST,
841 [LOAD_CONST__LOAD_FAST] = LOAD_CONST,
842 [LOAD_DEREF] = LOAD_DEREF,
843 [LOAD_FAST] = LOAD_FAST,
844 [LOAD_FAST_AND_CLEAR] = LOAD_FAST_AND_CLEAR,
845 [LOAD_FAST_CHECK] = LOAD_FAST_CHECK,
846 [LOAD_FAST__LOAD_CONST] = LOAD_FAST,
847 [LOAD_FAST__LOAD_FAST] = LOAD_FAST,
848 [LOAD_FROM_DICT_OR_DEREF] = LOAD_FROM_DICT_OR_DEREF,
849 [LOAD_FROM_DICT_OR_GLOBALS] = LOAD_FROM_DICT_OR_GLOBALS,
850 [LOAD_GLOBAL] = LOAD_GLOBAL,
851 [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL,
852 [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL,
853 [LOAD_LOCALS] = LOAD_LOCALS,
854 [LOAD_NAME] = LOAD_NAME,
855 [LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
856 [LOAD_SUPER_ATTR_ATTR] = LOAD_SUPER_ATTR,
857 [LOAD_SUPER_ATTR_METHOD] = LOAD_SUPER_ATTR,
858 [MAKE_CELL] = MAKE_CELL,
859 [MAKE_FUNCTION] = MAKE_FUNCTION,
860 [MAP_ADD] = MAP_ADD,
861 [MATCH_CLASS] = MATCH_CLASS,
862 [MATCH_KEYS] = MATCH_KEYS,
863 [MATCH_MAPPING] = MATCH_MAPPING,
864 [MATCH_SEQUENCE] = MATCH_SEQUENCE,
865 [NOP] = NOP,
866 [POP_EXCEPT] = POP_EXCEPT,
867 [POP_JUMP_IF_FALSE] = POP_JUMP_IF_FALSE,
868 [POP_JUMP_IF_NONE] = POP_JUMP_IF_NONE,
869 [POP_JUMP_IF_NOT_NONE] = POP_JUMP_IF_NOT_NONE,
870 [POP_JUMP_IF_TRUE] = POP_JUMP_IF_TRUE,
871 [POP_TOP] = POP_TOP,
872 [PUSH_EXC_INFO] = PUSH_EXC_INFO,
873 [PUSH_NULL] = PUSH_NULL,
874 [RAISE_VARARGS] = RAISE_VARARGS,
875 [RERAISE] = RERAISE,
876 [RESERVED] = RESERVED,
877 [RESUME] = RESUME,
878 [RETURN_CONST] = RETURN_CONST,
879 [RETURN_GENERATOR] = RETURN_GENERATOR,
880 [RETURN_VALUE] = RETURN_VALUE,
881 [SEND] = SEND,
882 [SEND_GEN] = SEND,
883 [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS,
884 [SET_ADD] = SET_ADD,
885 [SET_UPDATE] = SET_UPDATE,
886 [STORE_ATTR] = STORE_ATTR,
887 [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR,
888 [STORE_ATTR_SLOT] = STORE_ATTR,
889 [STORE_ATTR_WITH_HINT] = STORE_ATTR,
890 [STORE_DEREF] = STORE_DEREF,
891 [STORE_FAST] = STORE_FAST,
892 [STORE_FAST__LOAD_FAST] = STORE_FAST,
893 [STORE_FAST__STORE_FAST] = STORE_FAST,
894 [STORE_GLOBAL] = STORE_GLOBAL,
895 [STORE_NAME] = STORE_NAME,
896 [STORE_SLICE] = STORE_SLICE,
897 [STORE_SUBSCR] = STORE_SUBSCR,
898 [STORE_SUBSCR_DICT] = STORE_SUBSCR,
899 [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR,
900 [SWAP] = SWAP,
901 [UNARY_INVERT] = UNARY_INVERT,
902 [UNARY_NEGATIVE] = UNARY_NEGATIVE,
903 [UNARY_NOT] = UNARY_NOT,
904 [UNPACK_EX] = UNPACK_EX,
905 [UNPACK_SEQUENCE] = UNPACK_SEQUENCE,
906 [UNPACK_SEQUENCE_LIST] = UNPACK_SEQUENCE,
907 [UNPACK_SEQUENCE_TUPLE] = UNPACK_SEQUENCE,
908 [UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE,
909 [WITH_EXCEPT_START] = WITH_EXCEPT_START,
910 [YIELD_VALUE] = YIELD_VALUE,
911#else
912 [ASYNC_GEN_WRAP] = ASYNC_GEN_WRAP,
913 [BEFORE_ASYNC_WITH] = BEFORE_ASYNC_WITH,
914 [BEFORE_WITH] = BEFORE_WITH,
915 [BINARY_OP] = BINARY_OP,
916 [BINARY_OP_ADAPTIVE] = BINARY_OP,
917 [BINARY_OP_ADD_FLOAT] = BINARY_OP,
918 [BINARY_OP_ADD_INT] = BINARY_OP,
919 [BINARY_OP_ADD_UNICODE] = BINARY_OP,
920 [BINARY_OP_INPLACE_ADD_UNICODE] = BINARY_OP,
921 [BINARY_OP_MULTIPLY_FLOAT] = BINARY_OP,
922 [BINARY_OP_MULTIPLY_INT] = BINARY_OP,
923 [BINARY_OP_SUBTRACT_FLOAT] = BINARY_OP,
924 [BINARY_OP_SUBTRACT_INT] = BINARY_OP,
925 [BINARY_SUBSCR] = BINARY_SUBSCR,
926 [BINARY_SUBSCR_ADAPTIVE] = BINARY_SUBSCR,
927 [BINARY_SUBSCR_DICT] = BINARY_SUBSCR,
928 [BINARY_SUBSCR_GETITEM] = BINARY_SUBSCR,
929 [BINARY_SUBSCR_LIST_INT] = BINARY_SUBSCR,
930 [BINARY_SUBSCR_TUPLE_INT] = BINARY_SUBSCR,
931 [BUILD_CONST_KEY_MAP] = BUILD_CONST_KEY_MAP,
932 [BUILD_LIST] = BUILD_LIST,
933 [BUILD_MAP] = BUILD_MAP,
934 [BUILD_SET] = BUILD_SET,
935 [BUILD_SLICE] = BUILD_SLICE,
936 [BUILD_STRING] = BUILD_STRING,
937 [BUILD_TUPLE] = BUILD_TUPLE,
938 [CACHE] = CACHE,
939 [CALL] = CALL,
940 [CALL_ADAPTIVE] = CALL,
941 [CALL_FUNCTION_EX] = CALL_FUNCTION_EX,
942 [CALL_PY_EXACT_ARGS] = CALL,
943 [CALL_PY_WITH_DEFAULTS] = CALL,
944 [CHECK_EG_MATCH] = CHECK_EG_MATCH,
945 [CHECK_EXC_MATCH] = CHECK_EXC_MATCH,
946 [COMPARE_OP] = COMPARE_OP,
947 [COMPARE_OP_ADAPTIVE] = COMPARE_OP,
948 [COMPARE_OP_FLOAT_JUMP] = COMPARE_OP,
949 [COMPARE_OP_INT_JUMP] = COMPARE_OP,
950 [COMPARE_OP_STR_JUMP] = COMPARE_OP,
951 [CONTAINS_OP] = CONTAINS_OP,
952 [COPY] = COPY,
953 [COPY_FREE_VARS] = COPY_FREE_VARS,
954 [DELETE_ATTR] = DELETE_ATTR,
955 [DELETE_DEREF] = DELETE_DEREF,
956 [DELETE_FAST] = DELETE_FAST,
957 [DELETE_GLOBAL] = DELETE_GLOBAL,
958 [DELETE_NAME] = DELETE_NAME,
959 [DELETE_SUBSCR] = DELETE_SUBSCR,
960 [DICT_MERGE] = DICT_MERGE,
961 [DICT_UPDATE] = DICT_UPDATE,
962 [END_ASYNC_FOR] = END_ASYNC_FOR,
963 [EXTENDED_ARG] = EXTENDED_ARG,
964 [EXTENDED_ARG_QUICK] = EXTENDED_ARG,
965 [FORMAT_VALUE] = FORMAT_VALUE,
966 [FOR_ITER] = FOR_ITER,
967 [GET_AITER] = GET_AITER,
968 [GET_ANEXT] = GET_ANEXT,
969 [GET_AWAITABLE] = GET_AWAITABLE,
970 [GET_ITER] = GET_ITER,
971 [GET_LEN] = GET_LEN,
972 [GET_YIELD_FROM_ITER] = GET_YIELD_FROM_ITER,
973 [IMPORT_FROM] = IMPORT_FROM,
974 [IMPORT_NAME] = IMPORT_NAME,
975 [IMPORT_STAR] = IMPORT_STAR,
976 [IS_OP] = IS_OP,
977 [JUMP_BACKWARD] = JUMP_BACKWARD,
978 [JUMP_BACKWARD_NO_INTERRUPT] = JUMP_BACKWARD_NO_INTERRUPT,
979 [JUMP_BACKWARD_QUICK] = JUMP_BACKWARD,
980 [JUMP_FORWARD] = JUMP_FORWARD,
981 [JUMP_IF_FALSE_OR_POP] = JUMP_IF_FALSE_OR_POP,
982 [JUMP_IF_TRUE_OR_POP] = JUMP_IF_TRUE_OR_POP,
983 [KW_NAMES] = KW_NAMES,
984 [LIST_APPEND] = LIST_APPEND,
985 [LIST_EXTEND] = LIST_EXTEND,
986 [LIST_TO_TUPLE] = LIST_TO_TUPLE,
987 [LOAD_ASSERTION_ERROR] = LOAD_ASSERTION_ERROR,
988 [LOAD_ATTR] = LOAD_ATTR,
989 [LOAD_ATTR_ADAPTIVE] = LOAD_ATTR,
990 [LOAD_ATTR_INSTANCE_VALUE] = LOAD_ATTR,
991 [LOAD_ATTR_MODULE] = LOAD_ATTR,
992 [LOAD_ATTR_SLOT] = LOAD_ATTR,
993 [LOAD_ATTR_WITH_HINT] = LOAD_ATTR,
994 [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS,
995 [LOAD_CLASSDEREF] = LOAD_CLASSDEREF,
996 [LOAD_CLOSURE] = LOAD_CLOSURE,
997 [LOAD_CONST] = LOAD_CONST,
998 [LOAD_CONST__LOAD_FAST] = LOAD_CONST,
999 [LOAD_DEREF] = LOAD_DEREF,
1000 [LOAD_FAST] = LOAD_FAST,
1001 [LOAD_FAST__LOAD_CONST] = LOAD_FAST,
1002 [LOAD_FAST__LOAD_FAST] = LOAD_FAST,
1003 [LOAD_GLOBAL] = LOAD_GLOBAL,
1004 [LOAD_GLOBAL_ADAPTIVE] = LOAD_GLOBAL,
1005 [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL,
1006 [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL,
1007 [LOAD_METHOD] = LOAD_METHOD,
1008 [LOAD_METHOD_ADAPTIVE] = LOAD_METHOD,
1009 [LOAD_METHOD_CLASS] = LOAD_METHOD,
1010 [LOAD_METHOD_MODULE] = LOAD_METHOD,
1011 [LOAD_METHOD_NO_DICT] = LOAD_METHOD,
1012 [LOAD_METHOD_WITH_DICT] = LOAD_METHOD,
1013 [LOAD_METHOD_WITH_VALUES] = LOAD_METHOD,
1014 [LOAD_NAME] = LOAD_NAME,
1015 [MAKE_CELL] = MAKE_CELL,
1016 [MAKE_FUNCTION] = MAKE_FUNCTION,
1017 [MAP_ADD] = MAP_ADD,
1018 [MATCH_CLASS] = MATCH_CLASS,
1019 [MATCH_KEYS] = MATCH_KEYS,
1020 [MATCH_MAPPING] = MATCH_MAPPING,
1021 [MATCH_SEQUENCE] = MATCH_SEQUENCE,
1022 [NOP] = NOP,
1023 [POP_EXCEPT] = POP_EXCEPT,
1024 [POP_JUMP_BACKWARD_IF_FALSE] = POP_JUMP_BACKWARD_IF_FALSE,
1025 [POP_JUMP_BACKWARD_IF_NONE] = POP_JUMP_BACKWARD_IF_NONE,
1026 [POP_JUMP_BACKWARD_IF_NOT_NONE] = POP_JUMP_BACKWARD_IF_NOT_NONE,
1027 [POP_JUMP_BACKWARD_IF_TRUE] = POP_JUMP_BACKWARD_IF_TRUE,
1028 [POP_JUMP_FORWARD_IF_FALSE] = POP_JUMP_FORWARD_IF_FALSE,
1029 [POP_JUMP_FORWARD_IF_NONE] = POP_JUMP_FORWARD_IF_NONE,
1030 [POP_JUMP_FORWARD_IF_NOT_NONE] = POP_JUMP_FORWARD_IF_NOT_NONE,
1031 [POP_JUMP_FORWARD_IF_TRUE] = POP_JUMP_FORWARD_IF_TRUE,
1032 [POP_TOP] = POP_TOP,
1033 [PRECALL] = PRECALL,
1034 [PRECALL_ADAPTIVE] = PRECALL,
1035 [PRECALL_BOUND_METHOD] = PRECALL,
1036 [PRECALL_BUILTIN_CLASS] = PRECALL,
1037 [PRECALL_BUILTIN_FAST_WITH_KEYWORDS] = PRECALL,
1038 [PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS] = PRECALL,
1039 [PRECALL_NO_KW_BUILTIN_FAST] = PRECALL,
1040 [PRECALL_NO_KW_BUILTIN_O] = PRECALL,
1041 [PRECALL_NO_KW_ISINSTANCE] = PRECALL,
1042 [PRECALL_NO_KW_LEN] = PRECALL,
1043 [PRECALL_NO_KW_LIST_APPEND] = PRECALL,
1044 [PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST] = PRECALL,
1045 [PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS] = PRECALL,
1046 [PRECALL_NO_KW_METHOD_DESCRIPTOR_O] = PRECALL,
1047 [PRECALL_NO_KW_STR_1] = PRECALL,
1048 [PRECALL_NO_KW_TUPLE_1] = PRECALL,
1049 [PRECALL_NO_KW_TYPE_1] = PRECALL,
1050 [PRECALL_PYFUNC] = PRECALL,
1051 [PREP_RERAISE_STAR] = PREP_RERAISE_STAR,
1052 [PRINT_EXPR] = PRINT_EXPR,
1053 [PUSH_EXC_INFO] = PUSH_EXC_INFO,
1054 [PUSH_NULL] = PUSH_NULL,
1055 [RAISE_VARARGS] = RAISE_VARARGS,
1056 [RERAISE] = RERAISE,
1057 [RESUME] = RESUME,
1058 [RESUME_QUICK] = RESUME,
1059 [RETURN_GENERATOR] = RETURN_GENERATOR,
1060 [RETURN_VALUE] = RETURN_VALUE,
1061 [SEND] = SEND,
1062 [SETUP_ANNOTATIONS] = SETUP_ANNOTATIONS,
1063 [SET_ADD] = SET_ADD,
1064 [SET_UPDATE] = SET_UPDATE,
1065 [STORE_ATTR] = STORE_ATTR,
1066 [STORE_ATTR_ADAPTIVE] = STORE_ATTR,
1067 [STORE_ATTR_INSTANCE_VALUE] = STORE_ATTR,
1068 [STORE_ATTR_SLOT] = STORE_ATTR,
1069 [STORE_ATTR_WITH_HINT] = STORE_ATTR,
1070 [STORE_DEREF] = STORE_DEREF,
1071 [STORE_FAST] = STORE_FAST,
1072 [STORE_FAST__LOAD_FAST] = STORE_FAST,
1073 [STORE_FAST__STORE_FAST] = STORE_FAST,
1074 [STORE_GLOBAL] = STORE_GLOBAL,
1075 [STORE_NAME] = STORE_NAME,
1076 [STORE_SUBSCR] = STORE_SUBSCR,
1077 [STORE_SUBSCR_ADAPTIVE] = STORE_SUBSCR,
1078 [STORE_SUBSCR_DICT] = STORE_SUBSCR,
1079 [STORE_SUBSCR_LIST_INT] = STORE_SUBSCR,
1080 [SWAP] = SWAP,
1081 [UNARY_INVERT] = UNARY_INVERT,
1082 [UNARY_NEGATIVE] = UNARY_NEGATIVE,
1083 [UNARY_NOT] = UNARY_NOT,
1084 [UNARY_POSITIVE] = UNARY_POSITIVE,
1085 [UNPACK_EX] = UNPACK_EX,
1086 [UNPACK_SEQUENCE] = UNPACK_SEQUENCE,
1087 [UNPACK_SEQUENCE_ADAPTIVE] = UNPACK_SEQUENCE,
1088 [UNPACK_SEQUENCE_LIST] = UNPACK_SEQUENCE,
1089 [UNPACK_SEQUENCE_TUPLE] = UNPACK_SEQUENCE,
1090 [UNPACK_SEQUENCE_TWO_TUPLE] = UNPACK_SEQUENCE,
1091 [WITH_EXCEPT_START] = WITH_EXCEPT_START,
1092 [YIELD_VALUE] = YIELD_VALUE,
1093#endif
1094};
1095
1096#if PYTHON_VERSION >= 0x3d0
1097static inline bool _Nuitka_is_resume(_Py_CODEUNIT *instr) {
1098 uint8_t code = FT_ATOMIC_LOAD_UINT8_RELAXED(instr->op.code);
1099 return (code == RESUME || code == RESUME_CHECK || code == INSTRUMENTED_RESUME);
1100}
1101#endif
1102
1103PyObject *Nuitka_PyGen_yf(PyGenObject *gen) {
1104#if PYTHON_VERSION >= 0x3d0
1105 if (gen->gi_frame_state == FRAME_SUSPENDED_YIELD_FROM) {
1106 _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
1107 assert(_Nuitka_is_resume(frame->instr_ptr));
1108 assert((frame->instr_ptr->op.arg & RESUME_OPARG_LOCATION_MASK) >= RESUME_AFTER_YIELD_FROM);
1109 return Py_NewRef(_PyFrame_StackPeek(frame));
1110 }
1111 return NULL;
1112#else
1113 PyObject *yf = NULL;
1114
1115 if (gen->gi_frame_state < FRAME_CLEARED) {
1116 _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
1117
1118 if (gen->gi_frame_state == FRAME_CREATED) {
1119 return NULL;
1120 }
1121
1122 _Py_CODEUNIT next = frame->prev_instr[1];
1123
1124 if (Nuitka_PyOpcode_Deopt[_Py_OPCODE(next)] != RESUME || _Py_OPARG(next) < 2) {
1125 return NULL;
1126 }
1127
1128 yf = _PyFrame_StackPeek(frame);
1129
1130 Py_INCREF(yf);
1131 }
1132
1133 return yf;
1134#endif
1135}
1136
1137#if PYTHON_VERSION < 0x3c0
1138// Because it is not exported, we need to duplicate this.
1139static PyFrameObject *_Nuitka_PyFrame_New_NoTrack(PyCodeObject *code) {
1140 int slots = code->co_nlocalsplus + code->co_stacksize;
1141
1142 PyFrameObject *f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type, slots);
1143
1144 if (f == NULL) {
1145 return NULL;
1146 }
1147
1148 f->f_back = NULL;
1149 f->f_trace = NULL;
1150 f->f_trace_lines = 1;
1151 f->f_trace_opcodes = 0;
1152 f->f_fast_as_locals = 0;
1153 f->f_lineno = 0;
1154
1155 return f;
1156}
1157
1158// Also not exported.
1159static PyFrameObject *_Nuitka_PyFrame_MakeAndSetFrameObject(PyThreadState *tstate, _PyInterpreterFrame *frame) {
1160 assert(frame->frame_obj == NULL);
1161
1162 struct Nuitka_ExceptionPreservationItem saved_exception_state;
1163 FETCH_ERROR_OCCURRED_STATE(tstate, &saved_exception_state);
1164
1165 PyFrameObject *f = _Nuitka_PyFrame_New_NoTrack(frame->f_code);
1166
1167 // Out of memory should be rare.
1168 assert(f != NULL);
1169
1170 RESTORE_ERROR_OCCURRED_STATE(tstate, &saved_exception_state);
1171
1172 // Apparently there are situations where there is a race with what code creates the
1173 // frame, and this time it's not us.
1174 if (frame->frame_obj) {
1175 f->f_frame = (_PyInterpreterFrame *)f->_f_frame_data;
1176 f->f_frame->owner = FRAME_CLEARED;
1177 f->f_frame->frame_obj = f;
1178 Py_DECREF(f);
1179
1180 return frame->frame_obj;
1181 }
1182
1183 assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT);
1184 assert(frame->owner != FRAME_CLEARED);
1185
1186 f->f_frame = frame;
1187 frame->frame_obj = f;
1188
1189 return f;
1190}
1191
1192// The header variant uses un-exported code, replicate it with using our own variation.
1193static inline PyFrameObject *_Nuitka_PyFrame_GetFrameObject(PyThreadState *tstate, _PyInterpreterFrame *frame) {
1194 assert(!_PyFrame_IsIncomplete(frame));
1195
1196 PyFrameObject *res = frame->frame_obj;
1197
1198 if (res != NULL) {
1199 return res;
1200 }
1201
1202 return _Nuitka_PyFrame_MakeAndSetFrameObject(tstate, frame);
1203}
1204
1205// Also not exported, taking over a frame object.
1206static void _Nuitka_take_ownership(PyThreadState *tstate, PyFrameObject *f, _PyInterpreterFrame *frame) {
1207 assert(frame->owner != FRAME_OWNED_BY_FRAME_OBJECT);
1208 assert(frame->owner != FRAME_CLEARED);
1209
1210 Py_ssize_t size = ((char *)&frame->localsplus[frame->stacktop]) - (char *)frame;
1211 memcpy((_PyInterpreterFrame *)f->_f_frame_data, frame, size);
1212
1213 frame = (_PyInterpreterFrame *)f->_f_frame_data;
1214 f->f_frame = frame;
1215 frame->owner = FRAME_OWNED_BY_FRAME_OBJECT;
1216
1217 assert(f->f_back == NULL);
1218
1219 _PyInterpreterFrame *prev = frame->previous;
1220 while (prev && _PyFrame_IsIncomplete(prev)) {
1221 prev = prev->previous;
1222 }
1223
1224 // Link the back frame, which may have to be created.
1225 if (prev) {
1226 // Link PyFrameObject "f_back" and remove link through "_PyInterpreterFrame".previous
1227 // TODO: Nuitka doesn't do that for compiled frames ever, is that really needed?
1228 PyFrameObject *back = _Nuitka_PyFrame_GetFrameObject(tstate, prev);
1229
1230 if (unlikely(back == NULL)) {
1231 DROP_ERROR_OCCURRED(tstate);
1232 } else {
1233 f->f_back = (PyFrameObject *)Py_NewRef(back);
1234 }
1235
1236 frame->previous = NULL;
1237 }
1238
1239 if (!_PyObject_GC_IS_TRACKED((PyObject *)f)) {
1240 Nuitka_GC_Track((PyObject *)f);
1241 }
1242}
1243
1244// Cleanup up the frame is also not exported.
1245static void _Nuitka_PyFrame_Clear(PyThreadState *tstate, _PyInterpreterFrame *frame) {
1246 assert(frame->owner != FRAME_OWNED_BY_GENERATOR || _PyFrame_GetGenerator(frame)->gi_frame_state == FRAME_CLEARED);
1247
1248 if (frame->frame_obj) {
1249 PyFrameObject *f = frame->frame_obj;
1250 frame->frame_obj = NULL;
1251
1252 if (Py_REFCNT(f) > 1) {
1253 _Nuitka_take_ownership(tstate, f, frame);
1254 Py_DECREF(f);
1255
1256 return;
1257 }
1258
1259 Py_DECREF(f);
1260 }
1261
1262 assert(frame->stacktop >= 0);
1263 for (int i = 0; i < frame->stacktop; i++) {
1264 Py_XDECREF(frame->localsplus[i]);
1265 }
1266
1267 Py_XDECREF(frame->frame_obj);
1268 Py_XDECREF(frame->f_locals);
1269#if PYTHON_VERSION < 0x3c0
1270 Py_DECREF(frame->f_func);
1271#else
1272 Py_DECREF(frame->f_funcobj);
1273#endif
1274
1275#if PYTHON_VERSION < 0x3d0
1276 Py_XDECREF(frame->f_code);
1277#else
1278 Py_XDECREF(frame->f_executable);
1279#endif
1280}
1281#endif
1282
1283// Needs to be similar to "gen_send_ex2" implementation in CPython. This is the low
1284// end of an uncompiled generator receiving a value.
1285static PySendResult Nuitka_PyGen_gen_send_ex2(PyThreadState *tstate, PyGenObject *gen, PyObject *arg,
1286 PyObject **result_ptr, int exc, int closing) {
1287 _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
1288 PyObject *result;
1289
1290 *result_ptr = NULL;
1291
1292 if (gen->gi_frame_state == FRAME_CREATED && arg != NULL && arg != Py_None) {
1293 const char *msg = "can't send non-None value to a just-started generator";
1294 if (PyCoro_CheckExact(gen)) {
1295 msg = "can't send non-None value to a just-started coroutine";
1296 } else if (PyAsyncGen_CheckExact(gen)) {
1297 msg = "can't send non-None value to a just-started async generator";
1298 }
1299
1300 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError, msg);
1301 return PYGEN_ERROR;
1302 }
1303
1304 if (gen->gi_frame_state == FRAME_EXECUTING) {
1305 const char *msg = "generator already executing";
1306
1307 if (PyCoro_CheckExact(gen)) {
1308 msg = "coroutine already executing";
1309 } else if (PyAsyncGen_CheckExact(gen)) {
1310 msg = "async generator already executing";
1311 }
1312
1313 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ValueError, msg);
1314 return PYGEN_ERROR;
1315 }
1316
1317 if (gen->gi_frame_state >= FRAME_COMPLETED) {
1318 if (PyCoro_CheckExact(gen) && !closing) {
1319 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_RuntimeError, "cannot reuse already awaited coroutine");
1320 } else if (arg && !exc) {
1321 *result_ptr = Py_None;
1322 Py_INCREF_IMMORTAL(*result_ptr);
1323 return PYGEN_RETURN;
1324 }
1325 return PYGEN_ERROR;
1326 }
1327
1328 assert(gen->gi_frame_state < FRAME_EXECUTING);
1329
1330 // Put arg on the frame's stack
1331 result = arg ? arg : Py_None;
1332 Py_INCREF(result);
1333 _PyFrame_StackPush(frame, result);
1334
1335#if PYTHON_VERSION < 0x3c0
1336 frame->previous = CURRENT_TSTATE_INTERPRETER_FRAME(tstate);
1337#endif
1338
1339 _PyErr_StackItem *prev_exc_info = tstate->exc_info;
1340 gen->gi_exc_state.previous_item = prev_exc_info;
1341
1342 tstate->exc_info = &gen->gi_exc_state;
1343
1344 if (exc) {
1345 assert(_PyErr_Occurred(tstate));
1346#if PYTHON_VERSION >= 0x3d0
1347 {
1348 _PyErr_StackItem *exc_info = tstate->exc_info;
1349
1350 if (exc_info->exc_value != NULL && exc_info->exc_value != Py_None) {
1351 PyObject *current_exception = tstate->current_exception;
1352
1353 PyErr_SetObject((PyObject *)Py_TYPE(current_exception), current_exception);
1354 Py_DECREF(current_exception);
1355 }
1356 }
1357#else
1358 _PyErr_ChainStackItem(NULL);
1359#endif
1360 }
1361
1362 gen->gi_frame_state = FRAME_EXECUTING;
1363 result = _PyEval_EvalFrame(tstate, frame, exc);
1364#if PYTHON_VERSION < 0x3c0
1365 if (gen->gi_frame_state == FRAME_EXECUTING) {
1366 gen->gi_frame_state = FRAME_COMPLETED;
1367 }
1368 tstate->exc_info = gen->gi_exc_state.previous_item;
1369 gen->gi_exc_state.previous_item = NULL;
1370
1371 assert(CURRENT_TSTATE_INTERPRETER_FRAME(tstate) == frame->previous);
1372 frame->previous = NULL;
1373#else
1374 assert(tstate->exc_info == prev_exc_info);
1375 assert(gen->gi_exc_state.previous_item == NULL);
1376 assert(gen->gi_frame_state != FRAME_EXECUTING);
1377 assert(frame->previous == NULL);
1378#endif
1379 if (result != NULL) {
1380 if (gen->gi_frame_state == FRAME_SUSPENDED) {
1381 *result_ptr = result;
1382 return PYGEN_NEXT;
1383 }
1384
1385 assert(result == Py_None || !PyAsyncGen_CheckExact(gen));
1386
1387 if (result == Py_None && !PyAsyncGen_CheckExact(gen) && !arg) {
1388 // TODO: Have Py_CLEAR_IMMORTAL maybe
1389
1390 Py_CLEAR(result);
1391 }
1392 } else {
1393#if PYTHON_VERSION < 0x3c0
1394 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
1395 const char *msg = "generator raised StopIteration";
1396 if (PyCoro_CheckExact(gen)) {
1397 msg = "coroutine raised StopIteration";
1398 } else if (PyAsyncGen_CheckExact(gen)) {
1399 msg = "async generator raised StopIteration";
1400 }
1401 _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);
1402 } else if (PyAsyncGen_CheckExact(gen) && PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) {
1403 const char *msg = "async generator raised StopAsyncIteration";
1404 _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);
1405 }
1406#else
1407 assert(!PyErr_ExceptionMatches(PyExc_StopIteration));
1408 assert(!PyAsyncGen_CheckExact(gen) || !PyErr_ExceptionMatches(PyExc_StopAsyncIteration));
1409
1410#endif
1411 }
1412
1413 _PyErr_ClearExcState(&gen->gi_exc_state);
1414
1415 gen->gi_frame_state = FRAME_CLEARED;
1416
1417#if PYTHON_VERSION < 0x3c0
1418 _Nuitka_PyFrame_Clear(tstate, frame);
1419#endif
1420
1421 *result_ptr = result;
1422 return result ? PYGEN_RETURN : PYGEN_ERROR;
1423}
1424
1425static PyObject *Nuitka_PyGen_gen_send_ex(PyThreadState *tstate, PyGenObject *gen, PyObject *arg, int exc,
1426 int closing) {
1427 PyObject *result;
1428
1429 if (Nuitka_PyGen_gen_send_ex2(tstate, gen, arg, &result, exc, closing) == PYGEN_RETURN) {
1430 if (PyAsyncGen_CheckExact(gen)) {
1431 assert(result == Py_None);
1432 SET_CURRENT_EXCEPTION_STOP_ASYNC_ITERATION(tstate);
1433 } else if (result == Py_None) {
1434 SET_CURRENT_EXCEPTION_STOP_ITERATION_EMPTY(tstate);
1435 } else {
1436 Nuitka_SetStopIterationValue(tstate, result);
1437 }
1438
1439 Py_DECREF(result);
1440 return NULL;
1441 }
1442
1443 return result;
1444}
1445
1446// This function is called when throwing to an uncompiled generator. Coroutines and generators
1447// do this in their yielding from.
1448// Note:
1449// Exception arguments are passed for ownership and must be released before returning. The
1450// value of exception_type will not be NULL, but the actual exception will not necessarily
1451// be normalized.
1452static PyObject *Nuitka_UncompiledGenerator_throw(PyThreadState *tstate, PyGenObject *gen, int close_on_genexit,
1453 struct Nuitka_ExceptionPreservationItem *exception_state) {
1454#if _DEBUG_GENERATOR
1455 PRINT_STRING("Nuitka_UncompiledGenerator_throw: Enter ");
1456 PRINT_ITEM((PyObject *)gen);
1457 PRINT_EXCEPTION_STATE(exception_state);
1458 PRINT_NEW_LINE();
1459#endif
1460
1461 PyObject *yf = Nuitka_PyGen_yf(gen);
1462
1463 if (yf != NULL) {
1464 _PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
1465
1466 if (close_on_genexit && EXCEPTION_STATE_MATCH_BOOL_SINGLE(tstate, exception_state, PyExc_GeneratorExit)) {
1467 PyFrameState state = (PyFrameState)gen->gi_frame_state;
1468 gen->gi_frame_state = FRAME_EXECUTING;
1469
1470 int err = Nuitka_PyGen_gen_close_iter(tstate, yf);
1471
1472 gen->gi_frame_state = state;
1473
1474 Py_DECREF(yf);
1475
1476 if (err < 0) {
1477 // Releasing exception, we are done with it, raising instead the error just
1478 // occurred.
1479 RELEASE_ERROR_OCCURRED_STATE(exception_state);
1480
1481 return Nuitka_PyGen_gen_send_ex(tstate, gen, Py_None, 1, 0);
1482 }
1483
1484 // Handing exception ownership to this code.
1485 goto throw_here;
1486 }
1487
1488 PyObject *ret;
1489
1490 if (PyGen_CheckExact(yf) || PyCoro_CheckExact(yf)) {
1491 _PyInterpreterFrame *prev = CURRENT_TSTATE_INTERPRETER_FRAME(tstate);
1492 frame->previous = prev;
1493 CURRENT_TSTATE_INTERPRETER_FRAME(tstate) = frame;
1494 PyFrameState state = (PyFrameState)gen->gi_frame_state;
1495 gen->gi_frame_state = FRAME_EXECUTING;
1496
1497 // Handing exception ownership to "Nuitka_UncompiledGenerator_throw".
1498 ret = Nuitka_UncompiledGenerator_throw(tstate, (PyGenObject *)yf, close_on_genexit, exception_state);
1499 gen->gi_frame_state = state;
1500 CURRENT_TSTATE_INTERPRETER_FRAME(tstate) = prev;
1501 frame->previous = NULL;
1502 } else {
1503#if 0
1504 // TODO: Add slow mode traces.
1505 PRINT_ITEM(yf);
1506 PRINT_NEW_LINE();
1507#endif
1508
1509 PyObject *meth = LOOKUP_ATTRIBUTE(tstate, yf, const_str_plain_throw);
1510
1511 if (unlikely(meth == NULL)) {
1512 Py_DECREF(yf);
1513
1514 goto failed_throw;
1515 }
1516
1517 if (meth == NULL) {
1518 Py_DECREF(yf);
1519 goto throw_here;
1520 }
1521
1522 PyFrameState state = (PyFrameState)gen->gi_frame_state;
1523 gen->gi_frame_state = FRAME_EXECUTING;
1524
1525 ret = Nuitka_CallGeneratorThrowMethod(meth, exception_state);
1526
1527 gen->gi_frame_state = state;
1528
1529 // Releasing exception, we are done with it.
1530 RELEASE_ERROR_OCCURRED_STATE(exception_state);
1531
1532 Py_DECREF(meth);
1533 }
1534 Py_DECREF(yf);
1535
1536 if (ret == NULL) {
1537#if PYTHON_VERSION < 0x3c0
1538 PyObject *val;
1539 assert(gen->gi_frame_state < FRAME_CLEARED);
1540 ret = _PyFrame_StackPop((_PyInterpreterFrame *)gen->gi_iframe);
1541 assert(ret == yf);
1542 Py_DECREF(ret);
1543 assert(_PyInterpreterFrame_LASTI(frame) >= 0);
1544 assert(_Py_OPCODE(frame->prev_instr[-1]) == SEND);
1545 int jump = _Py_OPARG(frame->prev_instr[-1]);
1546 frame->prev_instr += jump - 1;
1547 if (Nuitka_PyGen_FetchStopIterationValue(tstate, &val)) {
1548 ret = Nuitka_PyGen_gen_send_ex(tstate, gen, val, 0, 0);
1549 Py_DECREF(val);
1550 } else
1551#endif
1552 {
1553 ret = Nuitka_PyGen_gen_send_ex(tstate, gen, Py_None, 1, 0);
1554 }
1555 }
1556
1557 return ret;
1558 }
1559
1560throw_here:
1561 tstate = _PyThreadState_GET();
1562
1563 if (unlikely(_Nuitka_Generator_check_throw(tstate, exception_state) == false)) {
1564 // Exception was released by _Nuitka_Generator_check_throw already.
1565 return NULL;
1566 }
1567
1568 RESTORE_ERROR_OCCURRED_STATE(tstate, exception_state);
1569
1570 return Nuitka_PyGen_gen_send_ex(tstate, gen, Py_None, 1, 1);
1571
1572failed_throw:
1573 RELEASE_ERROR_OCCURRED_STATE(exception_state);
1574
1575 return NULL;
1576}
1577
1578#else
1579
1580// For Python3.10 or earlier:
1581
1582static PyObject *Nuitka_PyGen_yf(PyGenObject *gen) {
1583 PyFrameObject *f = gen->gi_frame;
1584
1585#if PYTHON_VERSION < 0x3a0
1586 if (f && f->f_stacktop) {
1587#else
1588 if (f) {
1589#endif
1590 PyObject *bytecode = f->f_code->co_code;
1591 unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode);
1592
1593 if (f->f_lasti < 0) {
1594 return NULL;
1595 }
1596
1597#if PYTHON_VERSION < 0x360
1598 if (code[f->f_lasti + 1] != YIELD_FROM)
1599#elif PYTHON_VERSION < 0x3a0
1600 if (code[f->f_lasti + sizeof(_Py_CODEUNIT)] != YIELD_FROM)
1601#else
1602 if (code[(f->f_lasti + 1) * sizeof(_Py_CODEUNIT)] != YIELD_FROM)
1603#endif
1604 {
1605 return NULL;
1606 }
1607
1608#if PYTHON_VERSION < 0x3a0
1609 PyObject *yf = f->f_stacktop[-1];
1610#else
1611 assert(f->f_stackdepth > 0);
1612 PyObject *yf = f->f_valuestack[f->f_stackdepth - 1];
1613#endif
1614 Py_INCREF(yf);
1615 return yf;
1616 } else {
1617 return NULL;
1618 }
1619}
1620
1621static PyObject *Nuitka_PyGen_gen_send_ex(PyThreadState *tstate, PyGenObject *gen, PyObject *arg, int exc,
1622 int closing) {
1623 PyFrameObject *f = gen->gi_frame;
1624 PyObject *result;
1625
1626#if PYTHON_VERSION >= 0x3a0
1627 if (f != NULL && unlikely(_PyFrame_IsExecuting(f))) {
1628#else
1629 if (unlikely(gen->gi_running)) {
1630#endif
1631 char const *msg = "generator already executing";
1632
1633#if PYTHON_VERSION >= 0x350
1634 if (PyCoro_CheckExact(gen)) {
1635 msg = "coroutine already executing";
1636 }
1637#if PYTHON_VERSION >= 0x360
1638 else if (PyAsyncGen_CheckExact(gen)) {
1639 msg = "async generator already executing";
1640 }
1641#endif
1642#endif
1643 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ValueError, msg);
1644
1645 return NULL;
1646 }
1647
1648 if (f == NULL || Nuitka_PyFrameHasCompleted(f)) {
1649#if PYTHON_VERSION >= 0x350
1650 if (PyCoro_CheckExact(gen) && !closing) {
1651 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_RuntimeError, "cannot reuse already awaited coroutine");
1652 } else
1653#endif
1654 if (arg && !exc) {
1655#if PYTHON_VERSION >= 0x360
1656 if (PyAsyncGen_CheckExact(gen)) {
1657 SET_CURRENT_EXCEPTION_STOP_ASYNC_ITERATION(tstate);
1658 } else
1659#endif
1660 {
1661 SET_CURRENT_EXCEPTION_STOP_ITERATION_EMPTY(tstate);
1662 }
1663 }
1664 return NULL;
1665 }
1666
1667#if PYTHON_VERSION < 0x3a0
1668 if (f->f_lasti == -1) {
1669 if (unlikely(arg != NULL && arg != Py_None)) {
1670 char const *msg = "can't send non-None value to a just-started generator";
1671
1672#if PYTHON_VERSION >= 0x350
1673 if (PyCoro_CheckExact(gen)) {
1674 msg = "can't send non-None value to a just-started coroutine";
1675 }
1676#if PYTHON_VERSION >= 0x360
1677 else if (PyAsyncGen_CheckExact(gen)) {
1678 msg = "can't send non-None value to a just-started async generator";
1679 }
1680#endif
1681#endif
1682
1683 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_TypeError, msg);
1684 return NULL;
1685 }
1686 } else {
1687 // Put arg on the frame's stack
1688 result = arg ? arg : Py_None;
1689 Py_INCREF(result);
1690 *(f->f_stacktop++) = result;
1691 }
1692#else
1693 // CPython assertions, check them
1694 assert(_PyFrame_IsRunnable(f));
1695 assert(f->f_lasti >= 0 || ((unsigned char *)PyBytes_AS_STRING(f->f_code->co_code))[0] == GEN_START);
1696
1697 result = arg ? arg : Py_None;
1698 Py_INCREF(result);
1699 gen->gi_frame->f_valuestack[gen->gi_frame->f_stackdepth] = result;
1700 gen->gi_frame->f_stackdepth++;
1701#endif
1702
1703 Py_XINCREF(tstate->frame);
1704 f->f_back = tstate->frame;
1705
1706#if PYTHON_VERSION < 0x3a0
1707 gen->gi_running = 1;
1708#endif
1709#if PYTHON_VERSION >= 0x370
1710 gen->gi_exc_state.previous_item = tstate->exc_info;
1711 tstate->exc_info = &gen->gi_exc_state;
1712#endif
1713#if PYTHON_VERSION < 0x390
1714 result = PyEval_EvalFrameEx(f, exc);
1715#else
1716 result = _PyEval_EvalFrame(tstate, f, exc);
1717#endif
1718#if PYTHON_VERSION >= 0x370
1719 tstate->exc_info = gen->gi_exc_state.previous_item;
1720 gen->gi_exc_state.previous_item = NULL;
1721#endif
1722#if PYTHON_VERSION < 0x3a0
1723 gen->gi_running = 0;
1724#endif
1725
1726 Py_CLEAR(f->f_back);
1727
1728#if PYTHON_VERSION < 0x3a0
1729 if (result && f->f_stacktop == NULL) {
1730 if (result == Py_None) {
1731#if PYTHON_VERSION >= 0x360
1732 if (PyAsyncGen_CheckExact(gen)) {
1733 SET_CURRENT_EXCEPTION_STOP_ASYNC_ITERATION(tstate);
1734 } else
1735#endif
1736 {
1737 SET_CURRENT_EXCEPTION_STOP_ITERATION_EMPTY(tstate);
1738 }
1739 } else {
1740 Nuitka_SetStopIterationValue(tstate, result);
1741 }
1742
1743 // TODO: Add Py_CLEAR_IMMORTAL maybe
1744 Py_CLEAR(result);
1745 }
1746#if PYTHON_VERSION >= 0x350
1747 else if (result == NULL && PyErr_ExceptionMatches(PyExc_StopIteration)) {
1748#if PYTHON_VERSION < 0x370
1749 const int check_stop_iter_error_flags = CO_FUTURE_GENERATOR_STOP | CO_COROUTINE |
1750#if PYTHON_VERSION >= 0x360
1751 CO_ASYNC_GENERATOR |
1752#endif
1753 CO_ITERABLE_COROUTINE;
1754
1755 if (unlikely(gen->gi_code != NULL && ((PyCodeObject *)gen->gi_code)->co_flags & check_stop_iter_error_flags))
1756#endif
1757 {
1758 char const *msg = "generator raised StopIteration";
1759
1760 if (PyCoro_CheckExact(gen)) {
1761 msg = "coroutine raised StopIteration";
1762 }
1763#if PYTHON_VERSION >= 0x360
1764 else if (PyAsyncGen_CheckExact(gen)) {
1765 msg = "async generator raised StopIteration";
1766 }
1767#endif
1768
1769#if PYTHON_VERSION >= 0x360
1770 _PyErr_FormatFromCause(
1771#else
1772 PyErr_Format(
1773#endif
1774 PyExc_RuntimeError, "%s", msg);
1775 }
1776 }
1777#endif
1778#if PYTHON_VERSION >= 0x360
1779 else if (result == NULL && PyAsyncGen_CheckExact(gen) && PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) {
1780 char const *msg = "async generator raised StopAsyncIteration";
1781 _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);
1782 }
1783#endif
1784
1785 if (!result || f->f_stacktop == NULL) {
1786#if PYTHON_VERSION < 0x370
1787 PyObject *t, *v, *tb;
1788 t = f->f_exc_type;
1789 v = f->f_exc_value;
1790 tb = f->f_exc_traceback;
1791 f->f_exc_type = NULL;
1792 f->f_exc_value = NULL;
1793 f->f_exc_traceback = NULL;
1794 Py_XDECREF(t);
1795 Py_XDECREF(v);
1796 Py_XDECREF(tb);
1797#else
1798 Nuitka_PyGen_exc_state_clear(&gen->gi_exc_state);
1799#endif
1800 gen->gi_frame->f_gen = NULL;
1801 gen->gi_frame = NULL;
1802 Py_DECREF(f);
1803 }
1804#else
1805 if (result) {
1806 if (!_PyFrameHasCompleted(f)) {
1807 return result;
1808 }
1809 assert(result == Py_None || !PyAsyncGen_CheckExact(gen));
1810 if (result == Py_None && !PyAsyncGen_CheckExact(gen) && !arg) {
1811 // TODO: Add Py_CLEAR_IMMORTAL maybe
1812 Py_CLEAR(result);
1813 }
1814 } else {
1815 if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
1816 const char *msg = "generator raised StopIteration";
1817 if (PyCoro_CheckExact(gen)) {
1818 msg = "coroutine raised StopIteration";
1819 } else if (PyAsyncGen_CheckExact(gen)) {
1820 msg = "async generator raised StopIteration";
1821 }
1822 _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);
1823 } else if (PyAsyncGen_CheckExact(gen) && PyErr_ExceptionMatches(PyExc_StopAsyncIteration)) {
1824 const char *msg = "async generator raised StopAsyncIteration";
1825
1826 // TODO: Have our own variant of this.
1827 _PyErr_FormatFromCause(PyExc_RuntimeError, "%s", msg);
1828 }
1829 }
1830
1831 Nuitka_PyGen_exc_state_clear(&gen->gi_exc_state);
1832
1833 gen->gi_frame->f_gen = NULL;
1834 gen->gi_frame = NULL;
1835
1836 Py_DECREF(f);
1837#endif
1838 return result;
1839}
1840
1841// This function is called when throwing to an uncompiled generator. Coroutines and generators
1842// do this in their yielding from.
1843// Note:
1844// Exception arguments are passed for ownership and must be released before returning. The
1845// value of exception_type will not be NULL, but the actual exception will not necessarily
1846// be normalized.
1847static PyObject *Nuitka_UncompiledGenerator_throw(PyThreadState *tstate, PyGenObject *gen, int close_on_genexit,
1848 struct Nuitka_ExceptionPreservationItem *exception_state) {
1849#if _DEBUG_GENERATOR
1850 PRINT_STRING("Nuitka_UncompiledGenerator_throw: Enter ");
1851 PRINT_ITEM((PyObject *)gen);
1852 PRINT_EXCEPTION_STATE(exception_state);
1853 PRINT_NEW_LINE();
1854#endif
1855
1856 PyObject *yf = Nuitka_PyGen_yf(gen);
1857
1858 assert(HAS_EXCEPTION_STATE(exception_state));
1859
1860 if (yf != NULL) {
1861 if (close_on_genexit &&
1862 EXCEPTION_MATCH_BOOL_SINGLE(tstate, exception_state->exception_type, PyExc_GeneratorExit)) {
1863#if PYTHON_VERSION < 0x3a0
1864 gen->gi_running = 1;
1865#else
1866 PyFrameState state = gen->gi_frame->f_state;
1867 gen->gi_frame->f_state = FRAME_EXECUTING;
1868#endif
1869
1870 int err = Nuitka_PyGen_gen_close_iter(tstate, yf);
1871#if PYTHON_VERSION < 0x3a0
1872 gen->gi_running = 0;
1873#else
1874 gen->gi_frame->f_state = state;
1875#endif
1876 Py_DECREF(yf);
1877
1878 if (err < 0) {
1879 // Releasing exception, we are done with it, raising instead the error just
1880 // occurred.
1881 RELEASE_ERROR_OCCURRED_STATE(exception_state);
1882
1883 return Nuitka_PyGen_gen_send_ex(tstate, gen, Py_None, 1, 0);
1884 }
1885
1886 // Handing exception ownership to this code.
1887 goto throw_here;
1888 }
1889
1890 PyObject *ret;
1891
1892 if (PyGen_CheckExact(yf)
1893#if PYTHON_VERSION >= 0x350
1894 || PyCoro_CheckExact(yf)
1895#endif
1896 ) {
1897#if PYTHON_VERSION < 0x3a0
1898 gen->gi_running = 1;
1899#else
1900 PyFrameState state = gen->gi_frame->f_state;
1901 gen->gi_frame->f_state = FRAME_EXECUTING;
1902#endif
1903
1904 // Handing exception ownership to "Nuitka_UncompiledGenerator_throw".
1905 ret = Nuitka_UncompiledGenerator_throw(tstate, (PyGenObject *)yf, close_on_genexit, exception_state);
1906
1907#if PYTHON_VERSION < 0x3a0
1908 gen->gi_running = 0;
1909#else
1910 gen->gi_frame->f_state = state;
1911#endif
1912 } else {
1913#if 0
1914 // TODO: Add slow mode traces.
1915 PRINT_ITEM(yf);
1916 PRINT_NEW_LINE();
1917#endif
1918
1919 // TODO: Use faster code here too.
1920 PyObject *meth = PyObject_GetAttr(yf, const_str_plain_throw);
1921
1922 if (meth == NULL) {
1923 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
1924 Py_DECREF(yf);
1925
1926 // Releasing exception, we are done with it.
1927 RELEASE_ERROR_OCCURRED_STATE(exception_state);
1928
1929 return NULL;
1930 }
1931
1932 CLEAR_ERROR_OCCURRED(tstate);
1933 Py_DECREF(yf);
1934
1935 // Handing exception ownership to this code.
1936 goto throw_here;
1937 }
1938
1939#if PYTHON_VERSION < 0x3a0
1940 gen->gi_running = 1;
1941#else
1942 PyFrameState state = gen->gi_frame->f_state;
1943 gen->gi_frame->f_state = FRAME_EXECUTING;
1944#endif
1945 // TODO: Faster call code should be used.
1946 ret = Nuitka_CallGeneratorThrowMethod(meth, exception_state);
1947
1948#if PYTHON_VERSION < 0x3a0
1949 gen->gi_running = 0;
1950#else
1951 gen->gi_frame->f_state = state;
1952#endif
1953
1954 // Releasing exception, we are done with it.
1955 RELEASE_ERROR_OCCURRED_STATE(exception_state);
1956
1957 Py_DECREF(meth);
1958 }
1959
1960 Py_DECREF(yf);
1961
1962 if (ret == NULL) {
1963#if PYTHON_VERSION < 0x3a0
1964 ret = *(--gen->gi_frame->f_stacktop);
1965#else
1966 assert(gen->gi_frame->f_stackdepth > 0);
1967 gen->gi_frame->f_stackdepth--;
1968 ret = gen->gi_frame->f_valuestack[gen->gi_frame->f_stackdepth];
1969#endif
1970 Py_DECREF(ret);
1971
1972#if PYTHON_VERSION >= 0x360
1973 gen->gi_frame->f_lasti += sizeof(_Py_CODEUNIT);
1974#else
1975 gen->gi_frame->f_lasti += 1;
1976#endif
1977
1978 if (Nuitka_PyGen_FetchStopIterationValue(tstate, &exception_state->exception_value)) {
1979 ret = Nuitka_PyGen_gen_send_ex(tstate, gen, exception_state->exception_value, 0, 0);
1980
1981 Py_DECREF(exception_state->exception_value);
1982 } else {
1983 ret = Nuitka_PyGen_gen_send_ex(tstate, gen, Py_None, 1, 0);
1984 }
1985 }
1986 return ret;
1987 }
1988
1989throw_here:
1990 // We continue to have exception ownership here.
1991 if (unlikely(_Nuitka_Generator_check_throw(tstate, exception_state) == false)) {
1992 // Exception was released by _Nuitka_Generator_check_throw already.
1993 return NULL;
1994 }
1995
1996 // Transfer exception ownership to published exception.
1997 RESTORE_ERROR_OCCURRED_STATE(tstate, exception_state);
1998
1999 return Nuitka_PyGen_gen_send_ex(tstate, gen, Py_None, 1, 1);
2000}
2001
2002#endif
2003
2004static int Nuitka_PyGen_gen_close_iter(PyThreadState *tstate, PyObject *yf) {
2005 PyObject *retval = NULL;
2006
2007 if (PyGen_CheckExact(yf)
2008#if PYTHON_VERSION >= 0x350
2009 || PyCoro_CheckExact(yf)
2010#endif
2011 ) {
2012 assert(false);
2013 retval = Nuitka_PyGen_gen_close(tstate, (PyGenObject *)yf, NULL);
2014
2015 if (retval == NULL) {
2016 return -1;
2017 }
2018 } else {
2019 PyObject *meth = PyObject_GetAttr(yf, const_str_plain_close);
2020
2021 if (meth == NULL) {
2022 if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
2023 PyErr_WriteUnraisable(yf);
2024 }
2025
2026 CLEAR_ERROR_OCCURRED(tstate);
2027 } else {
2028 retval = CALL_FUNCTION_NO_ARGS(tstate, meth);
2029
2030 Py_DECREF(meth);
2031
2032 if (retval == NULL) {
2033 return -1;
2034 }
2035 }
2036 }
2037
2038 Py_XDECREF(retval);
2039 return 0;
2040}
2041
2042static PyObject *Nuitka_PyGen_gen_close(PyThreadState *tstate, PyGenObject *gen, PyObject *args) {
2043 PyObject *yf = Nuitka_PyGen_yf(gen);
2044 int err = 0;
2045
2046 if (yf != NULL) {
2047#if PYTHON_VERSION >= 0x3b0
2048 PyFrameState state = (PyFrameState)gen->gi_frame_state;
2049 gen->gi_frame_state = FRAME_EXECUTING;
2050#elif PYTHON_VERSION >= 0x3a0
2051 PyFrameState state = gen->gi_frame->f_state;
2052 gen->gi_frame->f_state = FRAME_EXECUTING;
2053#else
2054 gen->gi_running = 1;
2055#endif
2056 err = Nuitka_PyGen_gen_close_iter(tstate, yf);
2057
2058#if PYTHON_VERSION >= 0x3b0
2059 gen->gi_frame_state = state;
2060#elif PYTHON_VERSION >= 0x3a0
2061 gen->gi_frame->f_state = state;
2062#else
2063 gen->gi_running = 0;
2064#endif
2065 Py_DECREF(yf);
2066 }
2067
2068 if (err == 0) {
2069 SET_CURRENT_EXCEPTION_GENERATOR_EXIT(tstate);
2070 }
2071
2072 PyObject *retval = Nuitka_PyGen_gen_send_ex(tstate, gen, Py_None, 1, 1);
2073
2074 if (retval != NULL) {
2075 char const *msg = "generator ignored GeneratorExit";
2076
2077#if PYTHON_VERSION >= 0x350
2078 if (PyCoro_CheckExact(gen)) {
2079 msg = "coroutine ignored GeneratorExit";
2080 }
2081#if PYTHON_VERSION >= 0x360
2082 else if (PyAsyncGen_CheckExact(gen)) {
2083 msg = "async generator ignored GeneratorExit";
2084 }
2085#endif
2086#endif
2087 Py_DECREF(retval);
2088
2089 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_RuntimeError, msg);
2090 return NULL;
2091 }
2092
2093 if (PyErr_ExceptionMatches(PyExc_StopIteration) || PyErr_ExceptionMatches(PyExc_GeneratorExit)) {
2094 CLEAR_ERROR_OCCURRED(tstate);
2095
2096 Py_INCREF_IMMORTAL(Py_None);
2097 return Py_None;
2098 }
2099 return NULL;
2100}
2101
2102#endif
2103
2104// Part of "Nuitka", an optimizing Python compiler that is compatible and
2105// integrates with CPython, but also works on its own.
2106//
2107// Licensed under the Apache License, Version 2.0 (the "License");
2108// you may not use this file except in compliance with the License.
2109// You may obtain a copy of the License at
2110//
2111// http://www.apache.org/licenses/LICENSE-2.0
2112//
2113// Unless required by applicable law or agreed to in writing, software
2114// distributed under the License is distributed on an "AS IS" BASIS,
2115// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2116// See the License for the specific language governing permissions and
2117// limitations under the License.
Definition exceptions.h:712