From ba18f2d0ac67c3944a1c6c82cb437d2bd162ce2c Mon Sep 17 00:00:00 2001 From: Matt Page Date: Thu, 20 Apr 2023 16:58:58 -0700 Subject: [PATCH 1/7] Add support for reconstructing async call stacks When profiling an async Python application it's useful to see both the stack for the currently executing task as well as the chain of coroutines that are transitively awaiting the task. Consider the following example, where T represents a task, C represents a coroutine, and A '->' B indicates A is awaiting B. T0 +---> T1 | | | C0 | C2 | | | v | v C1 | C3 | | +-----| The async stack from C3 would be C3, C2, C1, C0. In contrast, the synchronous call stack while C3 is executing is only C3, C2. It's possible to reconstruct this view in most cases using what is currently available in CPython, however it's difficult to do so efficiently, and would be very challenging to do so, let alone efficiently, in an out of process profiler that leverages eBPF. This introduces a new field onto coroutines and async generators that makes it easy to efficiently reconstruct the async call stack. The field stores an owned reference, set by the interpreter, to the coroutine or async generator that is awaiting the field's owner. To reconstruct the chain of coroutines/async generators one only needs to walk the new field backwards. Intermediate awaitables (e.g. `Task`, `_GatheringFuture`) complicate maintaining a complete chain of awaiters. A special method, `__set_awaiter__` is introduced to simplify the process. Types can provide an implementation of this method to forward the awaiter on child objects. --- Doc/c-api/typeobj.rst | 284 +++---- Include/cpython/genobject.h | 10 + Include/cpython/object.h | 2 + .../pycore_global_objects_fini_generated.h | 1 + Include/internal/pycore_global_strings.h | 1 + .../internal/pycore_runtime_init_generated.h | 1 + .../internal/pycore_unicodeobject_generated.h | 3 + Include/typeslots.h | 4 + Lib/asyncio/tasks.py | 63 ++ Lib/test/test_asyncgen.py | 34 + Lib/test/test_asyncio/test_tasks.py | 87 +++ Lib/test/test_coroutines.py | 67 ++ Lib/test/test_sys.py | 4 +- Misc/ACKS | 1 + ...3-04-28-08-59-23.gh-issue-91048.IghN67.rst | 17 + Modules/_asynciomodule.c | 17 +- Objects/genobject.c | 57 ++ Objects/iterobject.c | 1 + Objects/typeobject.c | 37 + Objects/typeslots.inc | 1 + Python/bytecodes.c | 13 + Python/generated_cases.c.h | 703 +++++++++--------- Tools/build/generate_global_objects.py | 1 + 23 files changed, 929 insertions(+), 480 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-04-28-08-59-23.gh-issue-91048.IghN67.rst diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index e963b90628aa49..442b1d5c4b333e 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -197,138 +197,140 @@ sub-slots .. table:: :widths: 26,17,12 - +---------------------------------------------------------+-----------------------------------+---------------+ - | Slot | :ref:`Type ` | special | - | | | methods | - +=========================================================+===================================+===============+ - | :c:member:`~PyAsyncMethods.am_await` | :c:type:`unaryfunc` | __await__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyAsyncMethods.am_aiter` | :c:type:`unaryfunc` | __aiter__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyAsyncMethods.am_anext` | :c:type:`unaryfunc` | __anext__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyAsyncMethods.am_send` | :c:type:`sendfunc` | | - +---------------------------------------------------------+-----------------------------------+---------------+ - | | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_add` | :c:type:`binaryfunc` | __add__ | - | | | __radd__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_inplace_add` | :c:type:`binaryfunc` | __iadd__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_subtract` | :c:type:`binaryfunc` | __sub__ | - | | | __rsub__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_inplace_subtract` | :c:type:`binaryfunc` | __isub__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_multiply` | :c:type:`binaryfunc` | __mul__ | - | | | __rmul__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_inplace_multiply` | :c:type:`binaryfunc` | __imul__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_remainder` | :c:type:`binaryfunc` | __mod__ | - | | | __rmod__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_inplace_remainder` | :c:type:`binaryfunc` | __imod__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_divmod` | :c:type:`binaryfunc` | __divmod__ | - | | | __rdivmod__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_power` | :c:type:`ternaryfunc` | __pow__ | - | | | __rpow__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_inplace_power` | :c:type:`ternaryfunc` | __ipow__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_negative` | :c:type:`unaryfunc` | __neg__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_positive` | :c:type:`unaryfunc` | __pos__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_absolute` | :c:type:`unaryfunc` | __abs__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_bool` | :c:type:`inquiry` | __bool__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_invert` | :c:type:`unaryfunc` | __invert__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_lshift` | :c:type:`binaryfunc` | __lshift__ | - | | | __rlshift__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_inplace_lshift` | :c:type:`binaryfunc` | __ilshift__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_rshift` | :c:type:`binaryfunc` | __rshift__ | - | | | __rrshift__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_inplace_rshift` | :c:type:`binaryfunc` | __irshift__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_and` | :c:type:`binaryfunc` | __and__ | - | | | __rand__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_inplace_and` | :c:type:`binaryfunc` | __iand__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_xor` | :c:type:`binaryfunc` | __xor__ | - | | | __rxor__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_inplace_xor` | :c:type:`binaryfunc` | __ixor__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_or` | :c:type:`binaryfunc` | __or__ | - | | | __ror__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_inplace_or` | :c:type:`binaryfunc` | __ior__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_int` | :c:type:`unaryfunc` | __int__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_reserved` | void * | | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_float` | :c:type:`unaryfunc` | __float__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_floor_divide` | :c:type:`binaryfunc` | __floordiv__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_inplace_floor_divide` | :c:type:`binaryfunc` | __ifloordiv__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_true_divide` | :c:type:`binaryfunc` | __truediv__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_inplace_true_divide` | :c:type:`binaryfunc` | __itruediv__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_index` | :c:type:`unaryfunc` | __index__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_matrix_multiply` | :c:type:`binaryfunc` | __matmul__ | - | | | __rmatmul__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyNumberMethods.nb_inplace_matrix_multiply` | :c:type:`binaryfunc` | __imatmul__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyMappingMethods.mp_length` | :c:type:`lenfunc` | __len__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyMappingMethods.mp_subscript` | :c:type:`binaryfunc` | __getitem__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyMappingMethods.mp_ass_subscript` | :c:type:`objobjargproc` | __setitem__, | - | | | __delitem__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PySequenceMethods.sq_length` | :c:type:`lenfunc` | __len__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PySequenceMethods.sq_concat` | :c:type:`binaryfunc` | __add__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PySequenceMethods.sq_repeat` | :c:type:`ssizeargfunc` | __mul__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PySequenceMethods.sq_item` | :c:type:`ssizeargfunc` | __getitem__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PySequenceMethods.sq_ass_item` | :c:type:`ssizeobjargproc` | __setitem__ | - | | | __delitem__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PySequenceMethods.sq_contains` | :c:type:`objobjproc` | __contains__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PySequenceMethods.sq_inplace_concat` | :c:type:`binaryfunc` | __iadd__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PySequenceMethods.sq_inplace_repeat` | :c:type:`ssizeargfunc` | __imul__ | - +---------------------------------------------------------+-----------------------------------+---------------+ - | | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyBufferProcs.bf_getbuffer` | :c:func:`getbufferproc` | | - +---------------------------------------------------------+-----------------------------------+---------------+ - | :c:member:`~PyBufferProcs.bf_releasebuffer` | :c:func:`releasebufferproc` | | - +---------------------------------------------------------+-----------------------------------+---------------+ + +---------------------------------------------------------+-----------------------------------+-----------------+ + | Slot | :ref:`Type ` | special | + | | | methods | + +=========================================================+===================================+=================+ + | :c:member:`~PyAsyncMethods.am_await` | :c:type:`unaryfunc` | __await__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyAsyncMethods.am_aiter` | :c:type:`unaryfunc` | __aiter__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyAsyncMethods.am_anext` | :c:type:`unaryfunc` | __anext__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyAsyncMethods.am_send` | :c:type:`sendfunc` | | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyAsyncMethods.am_set_awaiter` | :c:type:`setawaiterfunc` | __set_awaiter__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_add` | :c:type:`binaryfunc` | __add__ | + | | | __radd__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_inplace_add` | :c:type:`binaryfunc` | __iadd__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_subtract` | :c:type:`binaryfunc` | __sub__ | + | | | __rsub__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_inplace_subtract` | :c:type:`binaryfunc` | __isub__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_multiply` | :c:type:`binaryfunc` | __mul__ | + | | | __rmul__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_inplace_multiply` | :c:type:`binaryfunc` | __imul__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_remainder` | :c:type:`binaryfunc` | __mod__ | + | | | __rmod__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_inplace_remainder` | :c:type:`binaryfunc` | __imod__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_divmod` | :c:type:`binaryfunc` | __divmod__ | + | | | __rdivmod__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_power` | :c:type:`ternaryfunc` | __pow__ | + | | | __rpow__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_inplace_power` | :c:type:`ternaryfunc` | __ipow__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_negative` | :c:type:`unaryfunc` | __neg__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_positive` | :c:type:`unaryfunc` | __pos__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_absolute` | :c:type:`unaryfunc` | __abs__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_bool` | :c:type:`inquiry` | __bool__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_invert` | :c:type:`unaryfunc` | __invert__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_lshift` | :c:type:`binaryfunc` | __lshift__ | + | | | __rlshift__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_inplace_lshift` | :c:type:`binaryfunc` | __ilshift__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_rshift` | :c:type:`binaryfunc` | __rshift__ | + | | | __rrshift__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_inplace_rshift` | :c:type:`binaryfunc` | __irshift__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_and` | :c:type:`binaryfunc` | __and__ | + | | | __rand__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_inplace_and` | :c:type:`binaryfunc` | __iand__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_xor` | :c:type:`binaryfunc` | __xor__ | + | | | __rxor__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_inplace_xor` | :c:type:`binaryfunc` | __ixor__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_or` | :c:type:`binaryfunc` | __or__ | + | | | __ror__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_inplace_or` | :c:type:`binaryfunc` | __ior__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_int` | :c:type:`unaryfunc` | __int__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_reserved` | void * | | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_float` | :c:type:`unaryfunc` | __float__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_floor_divide` | :c:type:`binaryfunc` | __floordiv__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_inplace_floor_divide` | :c:type:`binaryfunc` | __ifloordiv__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_true_divide` | :c:type:`binaryfunc` | __truediv__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_inplace_true_divide` | :c:type:`binaryfunc` | __itruediv__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_index` | :c:type:`unaryfunc` | __index__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_matrix_multiply` | :c:type:`binaryfunc` | __matmul__ | + | | | __rmatmul__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyNumberMethods.nb_inplace_matrix_multiply` | :c:type:`binaryfunc` | __imatmul__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyMappingMethods.mp_length` | :c:type:`lenfunc` | __len__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyMappingMethods.mp_subscript` | :c:type:`binaryfunc` | __getitem__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyMappingMethods.mp_ass_subscript` | :c:type:`objobjargproc` | __setitem__, | + | | | __delitem__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PySequenceMethods.sq_length` | :c:type:`lenfunc` | __len__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PySequenceMethods.sq_concat` | :c:type:`binaryfunc` | __add__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PySequenceMethods.sq_repeat` | :c:type:`ssizeargfunc` | __mul__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PySequenceMethods.sq_item` | :c:type:`ssizeargfunc` | __getitem__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PySequenceMethods.sq_ass_item` | :c:type:`ssizeobjargproc` | __setitem__ | + | | | __delitem__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PySequenceMethods.sq_contains` | :c:type:`objobjproc` | __contains__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PySequenceMethods.sq_inplace_concat` | :c:type:`binaryfunc` | __iadd__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PySequenceMethods.sq_inplace_repeat` | :c:type:`ssizeargfunc` | __imul__ | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyBufferProcs.bf_getbuffer` | :c:func:`getbufferproc` | | + +---------------------------------------------------------+-----------------------------------+-----------------+ + | :c:member:`~PyBufferProcs.bf_releasebuffer` | :c:func:`releasebufferproc` | | + +---------------------------------------------------------+-----------------------------------+-----------------+ .. _slot-typedefs-table: @@ -2496,6 +2498,7 @@ Async Object Structures unaryfunc am_aiter; unaryfunc am_anext; sendfunc am_send; + setawaiterfunc am_set_awaiter; } PyAsyncMethods; .. c:member:: unaryfunc PyAsyncMethods.am_await @@ -2541,6 +2544,20 @@ Async Object Structures .. versionadded:: 3.10 +.. c:member:: setawaiterfunc PyAsyncMethods.am_set_awaiter + + The signature of this function is:: + + int am_set_awaiter(PyObject *self, PyObject *awaiter); + + This is used to maintain the chain of awaiters on coroutines and async + generators. Classes that await children should forward the awaiter to + the children. + + This slot may be set to ``NULL``. + + .. versionadded:: 3.12 + .. _slot-typedefs: @@ -2650,6 +2667,9 @@ Slot Type typedefs .. c:type:: int (*objobjargproc)(PyObject *, PyObject *, PyObject *) +.. c:type:: int (*setawaiterfunc)(PyObject *, PyObject *) + + See :c:member:`~PyAsyncMethods.am_set_awaiter`. .. _typedef-examples: diff --git a/Include/cpython/genobject.h b/Include/cpython/genobject.h index 18b8ce913e6e31..eda1fea6298f58 100644 --- a/Include/cpython/genobject.h +++ b/Include/cpython/genobject.h @@ -7,6 +7,15 @@ extern "C" { #endif +static inline int _PyAwaitable_SetAwaiter(PyObject *receiver, PyObject *awaiter) { + PyTypeObject *ty = Py_TYPE(receiver); + PyAsyncMethods *am = (PyAsyncMethods *) ty->tp_as_async; + if ((am != NULL) && (am->am_set_awaiter != NULL)) { + return am->am_set_awaiter(receiver, awaiter); + } + return 0; +} + /* --- Generators --------------------------------------------------------- */ /* _PyGenObject_HEAD defines the initial segment of generator @@ -24,6 +33,7 @@ extern "C" { char prefix##_hooks_inited; \ char prefix##_closed; \ char prefix##_running_async; \ + PyObject *prefix##_awaiter; \ /* The frame */ \ int8_t prefix##_frame_state; \ PyObject *prefix##_iframe[1]; \ diff --git a/Include/cpython/object.h b/Include/cpython/object.h index ce4d13cd9c28fe..338f738e03e453 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -124,12 +124,14 @@ typedef struct { } PyMappingMethods; typedef PySendResult (*sendfunc)(PyObject *iter, PyObject *value, PyObject **result); +typedef int (*setawaiterfunc)(PyObject *iter, PyObject *awaiter); typedef struct { unaryfunc am_await; unaryfunc am_aiter; unaryfunc am_anext; sendfunc am_send; + setawaiterfunc am_set_awaiter; } PyAsyncMethods; typedef struct { diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h index 4fa15d74b3ad64..43a041a6ed6950 100644 --- a/Include/internal/pycore_global_objects_fini_generated.h +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -708,6 +708,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rtruediv__)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__rxor__)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__set__)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__set_awaiter__)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__set_name__)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__setattr__)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__setitem__)); diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index e19d8ff1b50468..9c0dfc8d00352f 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -196,6 +196,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(__rtruediv__) STRUCT_FOR_ID(__rxor__) STRUCT_FOR_ID(__set__) + STRUCT_FOR_ID(__set_awaiter__) STRUCT_FOR_ID(__set_name__) STRUCT_FOR_ID(__setattr__) STRUCT_FOR_ID(__setitem__) diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h index 42c4874d9466bf..f2895eb7d1987c 100644 --- a/Include/internal/pycore_runtime_init_generated.h +++ b/Include/internal/pycore_runtime_init_generated.h @@ -702,6 +702,7 @@ extern "C" { INIT_ID(__rtruediv__), \ INIT_ID(__rxor__), \ INIT_ID(__set__), \ + INIT_ID(__set_awaiter__), \ INIT_ID(__set_name__), \ INIT_ID(__setattr__), \ INIT_ID(__setitem__), \ diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h index 6d9cd24d9f3a13..256fc0ec022bc3 100644 --- a/Include/internal/pycore_unicodeobject_generated.h +++ b/Include/internal/pycore_unicodeobject_generated.h @@ -441,6 +441,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { string = &_Py_ID(__set__); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); + string = &_Py_ID(__set_awaiter__); + assert(_PyUnicode_CheckConsistency(string, 1)); + _PyUnicode_InternInPlace(interp, &string); string = &_Py_ID(__set_name__); assert(_PyUnicode_CheckConsistency(string, 1)); _PyUnicode_InternInPlace(interp, &string); diff --git a/Include/typeslots.h b/Include/typeslots.h index 506b05580de146..01994d282239b8 100644 --- a/Include/typeslots.h +++ b/Include/typeslots.h @@ -86,3 +86,7 @@ /* New in 3.10 */ #define Py_am_send 81 #endif +#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030C0000 +/* New in 3.12 */ +#define Py_am_set_awaiter 82 +#endif diff --git a/Lib/asyncio/tasks.py b/Lib/asyncio/tasks.py index c90d32c97add78..97bc60a836234c 100644 --- a/Lib/asyncio/tasks.py +++ b/Lib/asyncio/tasks.py @@ -7,6 +7,7 @@ 'gather', 'shield', 'ensure_future', 'run_coroutine_threadsafe', 'current_task', 'all_tasks', '_register_task', '_unregister_task', '_enter_task', '_leave_task', + 'get_async_stack' ) import concurrent.futures @@ -14,6 +15,7 @@ import functools import inspect import itertools +import sys import types import warnings import weakref @@ -684,6 +686,11 @@ def cancel(self, msg=None): self._cancel_requested = True return ret + def __set_awaiter__(self, awaiter): + for child in self._children: + if hasattr(child, "__set_awaiter__"): + child.__set_awaiter__(awaiter) + def gather(*coros_or_futures, return_exceptions=False): """Return a future aggregating results from the given coroutines/futures. @@ -897,6 +904,62 @@ def callback(): return future +def get_async_stack(): + """Return the async call stack for the currently executing task as a list of + frames, with the most recent frame last. + + The async call stack consists of the call stack for the currently executing + task, if any, plus the call stack formed by the transitive set of coroutines/async + generators awaiting the current task. + + Consider the following example, where T represents a task, C represents + a coroutine, and A '->' B indicates A is awaiting B. + + T0 +---> T1 + | | | + C0 | C2 + | | | + v | v + C1 | C3 + | | + +-----| + + The await stack from C3 would be C3, C2, C1, C0. In contrast, the + synchronous call stack while C3 is executing is only C3, C2. + """ + if not hasattr(sys, "_getframe"): + return [] + + task = current_task() + coro = task.get_coro() + coro_frame = coro.cr_frame + + # Get the active portion of the stack + stack = [] + frame = sys._getframe().f_back + while frame is not None: + stack.append(frame) + if frame is coro_frame: + break + frame = frame.f_back + assert frame is coro_frame + + # Get the suspended portion of the stack + awaiter = coro.cr_awaiter + while awaiter is not None: + if hasattr(awaiter, "cr_frame"): + stack.append(awaiter.cr_frame) + awaiter = awaiter.cr_awaiter + elif hasattr(awaiter, "ag_frame"): + stack.append(awaiter.ag_frame) + awaiter = awaiter.ag_awaiter + else: + raise ValueError(f"Unexpected awaiter {awaiter}") + + stack.reverse() + return stack + + # WeakSet containing all alive tasks. _all_tasks = weakref.WeakSet() diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py index 09e4010b0e53d6..9fb210ec12836e 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -1693,5 +1693,39 @@ async def run(): self.loop.run_until_complete(run()) +class AsyncGeneratorAwaiterTest(unittest.TestCase): + def setUp(self): + self.loop = asyncio.new_event_loop() + asyncio.set_event_loop(None) + + def tearDown(self): + self.loop.close() + self.loop = None + asyncio.set_event_loop_policy(None) + + def test_basic_await(self): + async def async_gen(): + self.assertIs(agen_obj.ag_awaiter, awaiter_obj) + yield 10 + + async def awaiter(agen): + async for x in agen: + pass + + agen_obj = async_gen() + awaiter_obj = awaiter(agen_obj) + self.assertIsNone(agen_obj.ag_awaiter) + self.loop.run_until_complete(awaiter_obj) + + def test_set_invalid_awaiter(self): + async def async_gen(): + yield "hi" + + agen_obj = async_gen() + msg = "awaiter must be None, a coroutine, or an async generator" + with self.assertRaisesRegex(TypeError, msg): + agen_obj.__set_awaiter__("testing 123") + + if __name__ == "__main__": unittest.main() diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index 31622c91470bcb..ab60657049c34a 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -2477,6 +2477,25 @@ def test_get_context(self): finally: loop.close() + def test_get_awaiter(self): + ctask = getattr(tasks, '_CTask', None) + if ctask is None or not issubclass(self.Task, ctask): + self.skipTest("Only subclasses of _CTask set cr_awaiter on wrapped coroutines") + + async def coro(): + self.assertIs(coro_obj.cr_awaiter, awaiter_obj) + return "ok" + + async def awaiter(coro): + task = self.loop.create_task(coro) + return await task + + coro_obj = coro() + awaiter_obj = awaiter(coro_obj) + self.assertIsNone(coro_obj.cr_awaiter) + self.assertEqual(self.loop.run_until_complete(awaiter_obj), "ok") + self.assertIsNone(coro_obj.cr_awaiter) + def add_subclass_tests(cls): BaseTask = cls.Task @@ -3225,6 +3244,23 @@ async def coro(s): # NameError should not happen: self.one_loop.call_exception_handler.assert_not_called() + def test_propagate_awaiter(self): + async def coro(idx): + self.assertIs(coro_objs[idx].cr_awaiter, awaiter_obj) + return "ok" + + async def awaiter(coros): + tasks = [self.one_loop.create_task(c) for c in coros] + return await asyncio.gather(*tasks) + + coro_objs = [coro(0), coro(1)] + awaiter_obj = awaiter(coro_objs) + self.assertIsNone(coro_objs[0].cr_awaiter) + self.assertIsNone(coro_objs[1].cr_awaiter) + self.assertEqual(self.one_loop.run_until_complete(awaiter_obj), ["ok", "ok"]) + self.assertIsNone(coro_objs[0].cr_awaiter) + self.assertIsNone(coro_objs[1].cr_awaiter) + class RunCoroutineThreadsafeTests(test_utils.TestCase): """Test case for asyncio.run_coroutine_threadsafe.""" @@ -3368,5 +3404,56 @@ def tearDown(self): super().tearDown() +class GetAsyncStackTests(test_utils.TestCase): + def setUp(self): + self.loop = asyncio.new_event_loop() + asyncio.set_event_loop(None) + + def tearDown(self): + self.loop.close() + self.loop = None + asyncio.set_event_loop_policy(None) + + def check_stack(self, frames, expected_funcs): + given = [f.f_code for f in frames] + expected = [f.__code__ for f in expected_funcs] + self.assertEqual(given, expected) + + def test_single_task(self): + async def coro(): + await coro2() + + async def coro2(): + stack = asyncio.get_async_stack() + self.check_stack(stack, [coro, coro2]) + + self.loop.run_until_complete(coro()) + + def test_cross_tasks(self): + async def coro(): + t = asyncio.ensure_future(coro2()) + await t + + async def coro2(): + t = asyncio.ensure_future(coro3()) + await t + + async def coro3(): + stack = asyncio.get_async_stack() + self.check_stack(stack, [coro, coro2, coro3]) + + self.loop.run_until_complete(coro()) + + def test_cross_gather(self): + async def coro(): + await asyncio.gather(coro2(), coro2()) + + async def coro2(): + stack = asyncio.get_async_stack() + self.check_stack(stack, [coro, coro2]) + + self.loop.run_until_complete(coro()) + + if __name__ == '__main__': unittest.main() diff --git a/Lib/test/test_coroutines.py b/Lib/test/test_coroutines.py index 47145782c0f04f..670147d09eed84 100644 --- a/Lib/test/test_coroutines.py +++ b/Lib/test/test_coroutines.py @@ -2465,5 +2465,72 @@ async def foo(): self.assertEqual(foo().send(None), 1) +class CoroutineAwaiterTest(unittest.TestCase): + def test_basic_await(self): + async def coro(): + self.assertIs(coro_obj.cr_awaiter, awaiter_obj) + return "success" + + async def awaiter(): + return await coro_obj + + coro_obj = coro() + awaiter_obj = awaiter() + self.assertIsNone(coro_obj.cr_awaiter) + self.assertEqual(run_async(awaiter_obj), ([], "success")) + + class FakeFuture: + def __await__(self): + return iter(["future"]) + + def test_coro_outlives_awaiter(self): + async def coro(): + await self.FakeFuture() + + async def awaiter(cr): + await cr + + coro_obj = coro() + self.assertIsNone(coro_obj.cr_awaiter) + awaiter_obj = awaiter(coro_obj) + self.assertIsNone(coro_obj.cr_awaiter) + + v1 = awaiter_obj.send(None) + self.assertEqual(v1, "future") + self.assertIs(coro_obj.cr_awaiter, awaiter_obj) + + awaiter_id = id(awaiter_obj) + del awaiter_obj + self.assertEqual(id(coro_obj.cr_awaiter), awaiter_id) + + def test_async_gen_awaiter(self): + async def coro(): + self.assertIs(coro_obj.cr_awaiter, agen) + await self.FakeFuture() + + async def async_gen(cr): + await cr + yield "hi" + + coro_obj = coro() + self.assertIsNone(coro_obj.cr_awaiter) + agen = async_gen(coro_obj) + self.assertIsNone(coro_obj.cr_awaiter) + + v1 = agen.asend(None).send(None) + self.assertEqual(v1, "future") + + def test_set_invalid_awaiter(self): + async def coro(): + return True + + coro_obj = coro() + msg = "awaiter must be None, a coroutine, or an async generator" + with self.assertRaisesRegex(TypeError, msg): + coro_obj.__set_awaiter__("testing 123") + run_async(coro_obj) + + + if __name__=="__main__": unittest.main() diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 611cd27ecf1240..fc7215f21e9844 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1463,7 +1463,7 @@ def bar(cls): check(bar, size('PP')) # generator def get_gen(): yield 1 - check(get_gen(), size('PP4P4c7P2ic??2P')) + check(get_gen(), size('PP4P3cPc7P2ic??2P')) # iterator check(iter('abc'), size('lP')) # callable-iterator @@ -1551,7 +1551,7 @@ def delx(self): del self.__x check(int, s) # class s = vsize(fmt + # PyTypeObject - '4P' # PyAsyncMethods + '5P' # PyAsyncMethods '36P' # PyNumberMethods '3P' # PyMappingMethods '10P' # PySequenceMethods diff --git a/Misc/ACKS b/Misc/ACKS index 65be5cfc3c7945..a304533b9638cc 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -1346,6 +1346,7 @@ Noah Oxer Joonas Paalasmaa Yaroslav Pankovych Martin Packman +Matt Page Elisha Paine Shriphani Palakodety Julien Palard diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-04-28-08-59-23.gh-issue-91048.IghN67.rst b/Misc/NEWS.d/next/Core and Builtins/2023-04-28-08-59-23.gh-issue-91048.IghN67.rst new file mode 100644 index 00000000000000..28d594375aa19a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-04-28-08-59-23.gh-issue-91048.IghN67.rst @@ -0,0 +1,17 @@ +When profiling an async Python application it's useful to see both the stack +for the currently executing task as well as the chain of coroutines that are +transitively awaiting the task. Consider the following example, where T +represents a task, C represents a coroutine, and A '->' B indicates A is +awaiting B. + +T0 +---> T1 | | | C0 | C2 | | +| v | v C1 | C3 | | +-----| + +The async stack from C3 would be C3, C2, C1, C0. In contrast, the +synchronous call stack while C3 is executing is only C3, C2. It's possible +to reconstruct this view in most cases using what is currently available in +CPython, however it's difficult to do so efficiently, and would be very +challenging to do so, let alone efficiently, in an out of process profiler +that leverages eBPF. This adds a new field `{cr,ag}_awaiter` to coroutines +and async generators, respectively, that allows one to efficiently +reconstruct the chain of suspended coroutines. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 2476dca6f58ebf..2a9002b111d907 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1634,6 +1634,14 @@ FutureIter_am_send(futureiterobject *it, return PYGEN_ERROR; } +static int +FutureIter_set_awaiter(futureiterobject *it, PyObject *awaiter) { + if (it->future != NULL) { + _PyAwaitable_SetAwaiter((PyObject *)it->future, awaiter); + } + return 0; +} + static PyObject * FutureIter_iternext(futureiterobject *it) { @@ -1775,6 +1783,7 @@ static PyType_Slot FutureIter_slots[] = { // async methods {Py_am_send, (sendfunc)FutureIter_am_send}, + {Py_am_set_awaiter, (setawaiterfunc) FutureIter_set_awaiter}, {0, NULL}, }; @@ -2542,6 +2551,12 @@ TaskObj_finalize(TaskObj *task) static void TaskObj_dealloc(PyObject *); /* Needs Task_CheckExact */ +static int +TaskObj_set_awaiter(TaskObj *task, PyObject *awaiter) +{ + return _PyAwaitable_SetAwaiter(task->task_coro, awaiter); +} + static PyMethodDef TaskType_methods[] = { _ASYNCIO_FUTURE_RESULT_METHODDEF _ASYNCIO_FUTURE_EXCEPTION_METHODDEF @@ -2597,6 +2612,7 @@ static PyType_Slot Task_slots[] = { // async slots {Py_am_await, (unaryfunc)future_new_iter}, + {Py_am_set_awaiter, (setawaiterfunc) TaskObj_set_awaiter}, {0, NULL}, }; @@ -3326,7 +3342,6 @@ _asyncio_current_task_impl(PyObject *module, PyObject *loop) return ret; } - /*********************** Module **************************/ diff --git a/Objects/genobject.c b/Objects/genobject.c index 6316fa9865fe65..bf840c319386fb 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -60,6 +60,7 @@ gen_traverse(PyGenObject *gen, visitproc visit, void *arg) return err; } } + Py_VISIT(gen->gi_awaiter); /* No need to visit cr_origin, because it's just tuples/str/int, so can't participate in a reference cycle. */ return exc_state_traverse(&gen->gi_exc_state, visit, arg); @@ -75,6 +76,16 @@ _PyGen_Finalize(PyObject *self) return; } + if (PyCoro_CheckExact(self)) { + /* If we're suspended in an `await`, remove us as the awaiter of the + * target awaitable. */ + PyObject *yf = _PyGen_yf(gen); + if (yf) { + _PyAwaitable_SetAwaiter(yf, NULL); + Py_DECREF(yf); + } + } + if (PyAsyncGen_CheckExact(self)) { PyAsyncGenObject *agen = (PyAsyncGenObject*)self; PyObject *finalizer = agen->ag_origin_or_finalizer; @@ -156,6 +167,7 @@ gen_dealloc(PyGenObject *gen) Py_CLEAR(gen->gi_name); Py_CLEAR(gen->gi_qualname); _PyErr_ClearExcState(&gen->gi_exc_state); + Py_CLEAR(gen->gi_awaiter); PyObject_GC_Del(gen); } @@ -251,6 +263,10 @@ gen_send_ex2(PyGenObject *gen, PyObject *arg, PyObject **presult, !PyErr_ExceptionMatches(PyExc_StopAsyncIteration)); } + /* Avoid holding on to the reference to the awaiter any longer than + necessary */ + Py_CLEAR(gen->gi_awaiter); + /* generator can't be rerun, so release the frame */ /* first clean reference cycle through stored exception traceback */ _PyErr_ClearExcState(&gen->gi_exc_state); @@ -808,6 +824,7 @@ static PyAsyncMethods gen_as_async = { 0, /* am_aiter */ 0, /* am_anext */ (sendfunc)PyGen_am_send, /* am_send */ + 0, /* am_set_awaiter */ }; @@ -882,6 +899,7 @@ make_gen(PyTypeObject *type, PyFunctionObject *func) gen->gi_name = Py_NewRef(func->func_name); assert(func->func_qualname != NULL); gen->gi_qualname = Py_NewRef(func->func_qualname); + gen->gi_awaiter = NULL; _PyObject_GC_TRACK(gen); return (PyObject *)gen; } @@ -968,6 +986,7 @@ gen_new_with_qualname(PyTypeObject *type, PyFrameObject *f, gen->gi_qualname = Py_NewRef(qualname); else gen->gi_qualname = Py_NewRef(_PyGen_GetCode(gen)->co_qualname); + gen->gi_awaiter = NULL; _PyObject_GC_TRACK(gen); return (PyObject *)gen; } @@ -1080,6 +1099,33 @@ coro_get_cr_await(PyCoroObject *coro, void *Py_UNUSED(ignored)) return yf; } +/* Awaiters are only set on coroutines or async generators */ +static PyObject * +get_awaiter(PyGenObject *gen, void *Py_UNUSED(ignored)) +{ + PyObject *awaiter = gen->gi_awaiter; + if (awaiter == NULL) { + Py_RETURN_NONE; + } + Py_INCREF(awaiter); + return awaiter; +} + +static int +set_awaiter(PyGenObject *gen, PyObject *awaiter) +{ + // awaiter must be null, an async generator, a coroutine, or None + if ((awaiter != NULL) && !(PyAsyncGen_CheckExact(awaiter) || PyCoro_CheckExact(awaiter) || (awaiter == Py_None))) { + PyErr_Format(PyExc_TypeError, "awaiter must be None, a coroutine, or an async generator, not %R", Py_TYPE(awaiter)); + return -1; + } + if (gen->gi_frame_state < FRAME_COMPLETED) { + Py_XINCREF(awaiter); + Py_XSETREF(gen->gi_awaiter, awaiter); + } + return 0; +} + static PyObject * cr_getsuspended(PyCoroObject *coro, void *Py_UNUSED(ignored)) { @@ -1122,6 +1168,7 @@ static PyGetSetDef coro_getsetlist[] = { {"cr_frame", (getter)cr_getframe, NULL, NULL}, {"cr_code", (getter)cr_getcode, NULL, NULL}, {"cr_suspended", (getter)cr_getsuspended, NULL, NULL}, + {"cr_awaiter", (getter)get_awaiter, NULL, NULL}, {NULL} /* Sentinel */ }; @@ -1160,6 +1207,7 @@ static PyAsyncMethods coro_as_async = { 0, /* am_aiter */ 0, /* am_anext */ (sendfunc)PyGen_am_send, /* am_send */ + (setawaiterfunc)set_awaiter, /* am_set_awaiter */ }; PyTypeObject PyCoro_Type = { @@ -1539,6 +1587,7 @@ static PyGetSetDef async_gen_getsetlist[] = { {"ag_frame", (getter)ag_getframe, NULL, NULL}, {"ag_code", (getter)ag_getcode, NULL, NULL}, {"ag_suspended", (getter)ag_getsuspended, NULL, NULL}, + {"ag_awaiter", (getter)get_awaiter, NULL, NULL}, {NULL} /* Sentinel */ }; @@ -1578,6 +1627,7 @@ static PyAsyncMethods async_gen_as_async = { PyObject_SelfIter, /* am_aiter */ (unaryfunc)async_gen_anext, /* am_anext */ (sendfunc)PyGen_am_send, /* am_send */ + (setawaiterfunc)set_awaiter, /* am_set_awaiter */ }; @@ -1844,12 +1894,18 @@ static PyMethodDef async_gen_asend_methods[] = { {NULL, NULL} /* Sentinel */ }; +static int +async_gen_asend_set_awaiter(PyAsyncGenASend *o, PyObject *awaiter) +{ + return set_awaiter((PyGenObject *) o->ags_gen, awaiter); +} static PyAsyncMethods async_gen_asend_as_async = { PyObject_SelfIter, /* am_await */ 0, /* am_aiter */ 0, /* am_anext */ 0, /* am_send */ + (setawaiterfunc)async_gen_asend_set_awaiter, /* am_set_awaiter */ }; @@ -2267,6 +2323,7 @@ static PyAsyncMethods async_gen_athrow_as_async = { 0, /* am_aiter */ 0, /* am_anext */ 0, /* am_send */ + 0, /* am_set_awaiter */ }; diff --git a/Objects/iterobject.c b/Objects/iterobject.c index 7cb17a6ca4ab56..e041d7341d45db 100644 --- a/Objects/iterobject.c +++ b/Objects/iterobject.c @@ -461,6 +461,7 @@ static PyAsyncMethods anextawaitable_as_async = { 0, /* am_aiter */ 0, /* am_anext */ 0, /* am_send */ + 0, /* am_set_awaiter */ }; PyTypeObject _PyAnextAwaitable_Type = { diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 38b99315457a58..1e5aeeb7d4ba38 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6379,6 +6379,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) COPYASYNC(am_await); COPYASYNC(am_aiter); COPYASYNC(am_anext); + COPYASYNC(am_set_awaiter); } if (type->tp_as_sequence != NULL && base->tp_as_sequence != NULL) { @@ -8577,6 +8578,40 @@ slot_am_anext(PyObject *self) return NULL; } +static PyObject * +wrap_setawaiterfunc(PyObject *self, PyObject *args, void *wrapped) +{ + setawaiterfunc func = (setawaiterfunc)wrapped; + PyObject *other; + + if (!check_num_args(args, 1)) + return NULL; + other = PyTuple_GET_ITEM(args, 0); + if ((*func)(self, other) < 0) { + return NULL; + } + Py_RETURN_NONE; +} + + +static PyObject * +slot_am_set_awaiter(PyObject *self, PyObject *awaiter) +{ + int unbound; + PyObject *func = NULL, *res = NULL; + func = lookup_maybe_method(self, &_Py_ID(__set_awaiter__), &unbound); + if (func != NULL) { + PyObject *args[2] = {self, awaiter}; + res = vectorcall_unbound(_PyThreadState_GET(), unbound, func, args, 2); + Py_DECREF(func); + return res; + } + PyErr_Format(PyExc_AttributeError, + "object %.50s does not have __set_awaiter__ method", + Py_TYPE(self)->tp_name); + return NULL; +} + /* Table mapping __foo__ names to tp_foo offsets and slot_tp_foo wrapper functions. @@ -8696,6 +8731,8 @@ static pytype_slotdef slotdefs[] = { "__aiter__($self, /)\n--\n\nReturn an awaitable, that resolves in asynchronous iterator."), AMSLOT(__anext__, am_anext, slot_am_anext, wrap_unaryfunc, "__anext__($self, /)\n--\n\nReturn a value or raise StopAsyncIteration."), + AMSLOT(__set_awaiter__, am_set_awaiter, slot_am_set_awaiter, wrap_setawaiterfunc, + "__set_awaiter__($self, awaiter)\n--\n\nSet or forward awaiter."), BINSLOT(__add__, nb_add, slot_nb_add, "+"), diff --git a/Objects/typeslots.inc b/Objects/typeslots.inc index 896daa7d8066b7..2b6c6a9e98c72d 100644 --- a/Objects/typeslots.inc +++ b/Objects/typeslots.inc @@ -80,3 +80,4 @@ {offsetof(PyAsyncMethods, am_anext), offsetof(PyTypeObject, tp_as_async)}, {-1, offsetof(PyTypeObject, tp_finalize)}, {offsetof(PyAsyncMethods, am_send), offsetof(PyTypeObject, tp_as_async)}, +{offsetof(PyAsyncMethods, am_set_awaiter), offsetof(PyTypeObject, tp_as_async)}, diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 9de0d92e382d3d..f6513d31ad678e 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -813,6 +813,13 @@ dummy_func( }; inst(SEND, (unused/1, receiver, v -- receiver, retval)) { + if ((frame->owner == FRAME_OWNED_BY_GENERATOR) && + (frame->f_code->co_flags & (CO_COROUTINE | CO_ASYNC_GENERATOR))) { + int st = _PyAwaitable_SetAwaiter(receiver, (PyObject *) _PyFrame_GetGenerator(frame)); + if (st < 0) { + goto error; + } + } #if ENABLE_SPECIALIZATION _PySendCache *cache = (_PySendCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -865,6 +872,12 @@ dummy_func( DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type, SEND); DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, SEND); + if (PyCoro_CheckExact(receiver)) { + int st = _PyAwaitable_SetAwaiter(receiver, (PyObject *) _PyFrame_GetGenerator(frame)); + if (st < 0) { + goto error; + } + } STAT_INC(SEND, hit); _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; frame->return_offset = oparg; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 864a4f7bcaff0f..1e14267ba3a88f 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -1131,6 +1131,13 @@ PyObject *receiver = stack_pointer[-2]; PyObject *retval; #line 816 "Python/bytecodes.c" + if ((frame->owner == FRAME_OWNED_BY_GENERATOR) && + (frame->f_code->co_flags & (CO_COROUTINE | CO_ASYNC_GENERATOR))) { + int st = _PyAwaitable_SetAwaiter(receiver, (PyObject *) _PyFrame_GetGenerator(frame)); + if (st < 0) { + goto error; + } + } #if ENABLE_SPECIALIZATION _PySendCache *cache = (_PySendCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1176,7 +1183,7 @@ } } Py_DECREF(v); - #line 1180 "Python/generated_cases.c.h" + #line 1187 "Python/generated_cases.c.h" stack_pointer[-1] = retval; next_instr += 1; DISPATCH(); @@ -1185,11 +1192,17 @@ TARGET(SEND_GEN) { PyObject *v = stack_pointer[-1]; PyObject *receiver = stack_pointer[-2]; - #line 864 "Python/bytecodes.c" + #line 871 "Python/bytecodes.c" PyGenObject *gen = (PyGenObject *)receiver; DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type, SEND); DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, SEND); + if (PyCoro_CheckExact(receiver)) { + int st = _PyAwaitable_SetAwaiter(receiver, (PyObject *) _PyFrame_GetGenerator(frame)); + if (st < 0) { + goto error; + } + } STAT_INC(SEND, hit); _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; frame->return_offset = oparg; @@ -1200,12 +1213,12 @@ tstate->exc_info = &gen->gi_exc_state; JUMPBY(INLINE_CACHE_ENTRIES_SEND); DISPATCH_INLINED(gen_frame); - #line 1204 "Python/generated_cases.c.h" + #line 1217 "Python/generated_cases.c.h" } TARGET(INSTRUMENTED_YIELD_VALUE) { PyObject *retval = stack_pointer[-1]; - #line 881 "Python/bytecodes.c" + #line 894 "Python/bytecodes.c" assert(frame != &entry_frame); PyGenObject *gen = _PyFrame_GetGenerator(frame); gen->gi_frame_state = FRAME_SUSPENDED; @@ -1222,12 +1235,12 @@ gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); goto resume_frame; - #line 1226 "Python/generated_cases.c.h" + #line 1239 "Python/generated_cases.c.h" } TARGET(YIELD_VALUE) { PyObject *retval = stack_pointer[-1]; - #line 900 "Python/bytecodes.c" + #line 913 "Python/bytecodes.c" // NOTE: It's important that YIELD_VALUE never raises an exception! // The compiler treats any exception raised here as a failed close() // or throw() call. @@ -1243,15 +1256,15 @@ gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); goto resume_frame; - #line 1247 "Python/generated_cases.c.h" + #line 1260 "Python/generated_cases.c.h" } TARGET(POP_EXCEPT) { PyObject *exc_value = stack_pointer[-1]; - #line 918 "Python/bytecodes.c" + #line 931 "Python/bytecodes.c" _PyErr_StackItem *exc_info = tstate->exc_info; Py_XSETREF(exc_info->exc_value, exc_value); - #line 1255 "Python/generated_cases.c.h" + #line 1268 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } @@ -1259,7 +1272,7 @@ TARGET(RERAISE) { PyObject *exc = stack_pointer[-1]; PyObject **values = (stack_pointer - (1 + oparg)); - #line 923 "Python/bytecodes.c" + #line 936 "Python/bytecodes.c" assert(oparg >= 0 && oparg <= 2); if (oparg) { PyObject *lasti = values[0]; @@ -1277,26 +1290,26 @@ Py_INCREF(exc); _PyErr_SetRaisedException(tstate, exc); goto exception_unwind; - #line 1281 "Python/generated_cases.c.h" + #line 1294 "Python/generated_cases.c.h" } TARGET(END_ASYNC_FOR) { PyObject *exc = stack_pointer[-1]; PyObject *awaitable = stack_pointer[-2]; - #line 943 "Python/bytecodes.c" + #line 956 "Python/bytecodes.c" assert(exc && PyExceptionInstance_Check(exc)); if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) { - #line 1290 "Python/generated_cases.c.h" + #line 1303 "Python/generated_cases.c.h" Py_DECREF(awaitable); Py_DECREF(exc); - #line 946 "Python/bytecodes.c" + #line 959 "Python/bytecodes.c" } else { Py_INCREF(exc); _PyErr_SetRaisedException(tstate, exc); goto exception_unwind; } - #line 1300 "Python/generated_cases.c.h" + #line 1313 "Python/generated_cases.c.h" STACK_SHRINK(2); DISPATCH(); } @@ -1307,23 +1320,23 @@ PyObject *sub_iter = stack_pointer[-3]; PyObject *none; PyObject *value; - #line 955 "Python/bytecodes.c" + #line 968 "Python/bytecodes.c" assert(throwflag); assert(exc_value && PyExceptionInstance_Check(exc_value)); if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { value = Py_NewRef(((PyStopIterationObject *)exc_value)->value); - #line 1316 "Python/generated_cases.c.h" + #line 1329 "Python/generated_cases.c.h" Py_DECREF(sub_iter); Py_DECREF(last_sent_val); Py_DECREF(exc_value); - #line 960 "Python/bytecodes.c" + #line 973 "Python/bytecodes.c" none = Py_NewRef(Py_None); } else { _PyErr_SetRaisedException(tstate, Py_NewRef(exc_value)); goto exception_unwind; } - #line 1327 "Python/generated_cases.c.h" + #line 1340 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = value; stack_pointer[-2] = none; @@ -1332,9 +1345,9 @@ TARGET(LOAD_ASSERTION_ERROR) { PyObject *value; - #line 969 "Python/bytecodes.c" + #line 982 "Python/bytecodes.c" value = Py_NewRef(PyExc_AssertionError); - #line 1338 "Python/generated_cases.c.h" + #line 1351 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = value; DISPATCH(); @@ -1342,7 +1355,7 @@ TARGET(LOAD_BUILD_CLASS) { PyObject *bc; - #line 973 "Python/bytecodes.c" + #line 986 "Python/bytecodes.c" if (PyDict_CheckExact(BUILTINS())) { bc = _PyDict_GetItemWithError(BUILTINS(), &_Py_ID(__build_class__)); @@ -1364,7 +1377,7 @@ if (true) goto error; } } - #line 1368 "Python/generated_cases.c.h" + #line 1381 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = bc; DISPATCH(); @@ -1372,33 +1385,33 @@ TARGET(STORE_NAME) { PyObject *v = stack_pointer[-1]; - #line 997 "Python/bytecodes.c" + #line 1010 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); PyObject *ns = LOCALS(); int err; if (ns == NULL) { _PyErr_Format(tstate, PyExc_SystemError, "no locals found when storing %R", name); - #line 1383 "Python/generated_cases.c.h" + #line 1396 "Python/generated_cases.c.h" Py_DECREF(v); - #line 1004 "Python/bytecodes.c" + #line 1017 "Python/bytecodes.c" if (true) goto pop_1_error; } if (PyDict_CheckExact(ns)) err = PyDict_SetItem(ns, name, v); else err = PyObject_SetItem(ns, name, v); - #line 1392 "Python/generated_cases.c.h" + #line 1405 "Python/generated_cases.c.h" Py_DECREF(v); - #line 1011 "Python/bytecodes.c" + #line 1024 "Python/bytecodes.c" if (err) goto pop_1_error; - #line 1396 "Python/generated_cases.c.h" + #line 1409 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(DELETE_NAME) { - #line 1015 "Python/bytecodes.c" + #line 1028 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); PyObject *ns = LOCALS(); int err; @@ -1415,7 +1428,7 @@ name); goto error; } - #line 1419 "Python/generated_cases.c.h" + #line 1432 "Python/generated_cases.c.h" DISPATCH(); } @@ -1423,7 +1436,7 @@ PREDICTED(UNPACK_SEQUENCE); static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size"); PyObject *seq = stack_pointer[-1]; - #line 1041 "Python/bytecodes.c" + #line 1054 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1436,11 +1449,11 @@ #endif /* ENABLE_SPECIALIZATION */ PyObject **top = stack_pointer + oparg - 1; int res = unpack_iterable(tstate, seq, oparg, -1, top); - #line 1440 "Python/generated_cases.c.h" + #line 1453 "Python/generated_cases.c.h" Py_DECREF(seq); - #line 1054 "Python/bytecodes.c" + #line 1067 "Python/bytecodes.c" if (res == 0) goto pop_1_error; - #line 1444 "Python/generated_cases.c.h" + #line 1457 "Python/generated_cases.c.h" STACK_SHRINK(1); STACK_GROW(oparg); next_instr += 1; @@ -1450,14 +1463,14 @@ TARGET(UNPACK_SEQUENCE_TWO_TUPLE) { PyObject *seq = stack_pointer[-1]; PyObject **values = stack_pointer - (1); - #line 1058 "Python/bytecodes.c" + #line 1071 "Python/bytecodes.c" DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE); assert(oparg == 2); STAT_INC(UNPACK_SEQUENCE, hit); values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1)); values[1] = Py_NewRef(PyTuple_GET_ITEM(seq, 0)); - #line 1461 "Python/generated_cases.c.h" + #line 1474 "Python/generated_cases.c.h" Py_DECREF(seq); STACK_SHRINK(1); STACK_GROW(oparg); @@ -1468,7 +1481,7 @@ TARGET(UNPACK_SEQUENCE_TUPLE) { PyObject *seq = stack_pointer[-1]; PyObject **values = stack_pointer - (1); - #line 1068 "Python/bytecodes.c" + #line 1081 "Python/bytecodes.c" DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); STAT_INC(UNPACK_SEQUENCE, hit); @@ -1476,7 +1489,7 @@ for (int i = oparg; --i >= 0; ) { *values++ = Py_NewRef(items[i]); } - #line 1480 "Python/generated_cases.c.h" + #line 1493 "Python/generated_cases.c.h" Py_DECREF(seq); STACK_SHRINK(1); STACK_GROW(oparg); @@ -1487,7 +1500,7 @@ TARGET(UNPACK_SEQUENCE_LIST) { PyObject *seq = stack_pointer[-1]; PyObject **values = stack_pointer - (1); - #line 1079 "Python/bytecodes.c" + #line 1092 "Python/bytecodes.c" DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE); DEOPT_IF(PyList_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); STAT_INC(UNPACK_SEQUENCE, hit); @@ -1495,7 +1508,7 @@ for (int i = oparg; --i >= 0; ) { *values++ = Py_NewRef(items[i]); } - #line 1499 "Python/generated_cases.c.h" + #line 1512 "Python/generated_cases.c.h" Py_DECREF(seq); STACK_SHRINK(1); STACK_GROW(oparg); @@ -1505,15 +1518,15 @@ TARGET(UNPACK_EX) { PyObject *seq = stack_pointer[-1]; - #line 1090 "Python/bytecodes.c" + #line 1103 "Python/bytecodes.c" int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); PyObject **top = stack_pointer + totalargs - 1; int res = unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top); - #line 1513 "Python/generated_cases.c.h" + #line 1526 "Python/generated_cases.c.h" Py_DECREF(seq); - #line 1094 "Python/bytecodes.c" + #line 1107 "Python/bytecodes.c" if (res == 0) goto pop_1_error; - #line 1517 "Python/generated_cases.c.h" + #line 1530 "Python/generated_cases.c.h" STACK_GROW((oparg & 0xFF) + (oparg >> 8)); DISPATCH(); } @@ -1524,7 +1537,7 @@ PyObject *owner = stack_pointer[-1]; PyObject *v = stack_pointer[-2]; uint16_t counter = read_u16(&next_instr[0].cache); - #line 1105 "Python/bytecodes.c" + #line 1118 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { PyObject *name = GETITEM(frame->f_code->co_names, oparg); @@ -1540,12 +1553,12 @@ #endif /* ENABLE_SPECIALIZATION */ PyObject *name = GETITEM(frame->f_code->co_names, oparg); int err = PyObject_SetAttr(owner, name, v); - #line 1544 "Python/generated_cases.c.h" + #line 1557 "Python/generated_cases.c.h" Py_DECREF(v); Py_DECREF(owner); - #line 1121 "Python/bytecodes.c" + #line 1134 "Python/bytecodes.c" if (err) goto pop_2_error; - #line 1549 "Python/generated_cases.c.h" + #line 1562 "Python/generated_cases.c.h" STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -1553,34 +1566,34 @@ TARGET(DELETE_ATTR) { PyObject *owner = stack_pointer[-1]; - #line 1125 "Python/bytecodes.c" + #line 1138 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); int err = PyObject_SetAttr(owner, name, (PyObject *)NULL); - #line 1560 "Python/generated_cases.c.h" + #line 1573 "Python/generated_cases.c.h" Py_DECREF(owner); - #line 1128 "Python/bytecodes.c" + #line 1141 "Python/bytecodes.c" if (err) goto pop_1_error; - #line 1564 "Python/generated_cases.c.h" + #line 1577 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(STORE_GLOBAL) { PyObject *v = stack_pointer[-1]; - #line 1132 "Python/bytecodes.c" + #line 1145 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); int err = PyDict_SetItem(GLOBALS(), name, v); - #line 1574 "Python/generated_cases.c.h" + #line 1587 "Python/generated_cases.c.h" Py_DECREF(v); - #line 1135 "Python/bytecodes.c" + #line 1148 "Python/bytecodes.c" if (err) goto pop_1_error; - #line 1578 "Python/generated_cases.c.h" + #line 1591 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(DELETE_GLOBAL) { - #line 1139 "Python/bytecodes.c" + #line 1152 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); int err; err = PyDict_DelItem(GLOBALS(), name); @@ -1592,13 +1605,13 @@ } goto error; } - #line 1596 "Python/generated_cases.c.h" + #line 1609 "Python/generated_cases.c.h" DISPATCH(); } TARGET(LOAD_NAME) { PyObject *v; - #line 1153 "Python/bytecodes.c" + #line 1166 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); PyObject *locals = LOCALS(); if (locals == NULL) { @@ -1657,7 +1670,7 @@ } } } - #line 1661 "Python/generated_cases.c.h" + #line 1674 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = v; DISPATCH(); @@ -1668,7 +1681,7 @@ static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size"); PyObject *null = NULL; PyObject *v; - #line 1220 "Python/bytecodes.c" + #line 1233 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1720,7 +1733,7 @@ } } null = NULL; - #line 1724 "Python/generated_cases.c.h" + #line 1737 "Python/generated_cases.c.h" STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = v; @@ -1734,7 +1747,7 @@ PyObject *res; uint16_t index = read_u16(&next_instr[1].cache); uint16_t version = read_u16(&next_instr[2].cache); - #line 1274 "Python/bytecodes.c" + #line 1287 "Python/bytecodes.c" DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); PyDictObject *dict = (PyDictObject *)GLOBALS(); DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); @@ -1745,7 +1758,7 @@ Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; - #line 1749 "Python/generated_cases.c.h" + #line 1762 "Python/generated_cases.c.h" STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -1760,7 +1773,7 @@ uint16_t index = read_u16(&next_instr[1].cache); uint16_t mod_version = read_u16(&next_instr[2].cache); uint16_t bltn_version = read_u16(&next_instr[3].cache); - #line 1287 "Python/bytecodes.c" + #line 1300 "Python/bytecodes.c" DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL); PyDictObject *mdict = (PyDictObject *)GLOBALS(); @@ -1775,7 +1788,7 @@ Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; - #line 1779 "Python/generated_cases.c.h" + #line 1792 "Python/generated_cases.c.h" STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -1785,16 +1798,16 @@ } TARGET(DELETE_FAST) { - #line 1304 "Python/bytecodes.c" + #line 1317 "Python/bytecodes.c" PyObject *v = GETLOCAL(oparg); if (v == NULL) goto unbound_local_error; SETLOCAL(oparg, NULL); - #line 1793 "Python/generated_cases.c.h" + #line 1806 "Python/generated_cases.c.h" DISPATCH(); } TARGET(MAKE_CELL) { - #line 1310 "Python/bytecodes.c" + #line 1323 "Python/bytecodes.c" // "initial" is probably NULL but not if it's an arg (or set // via PyFrame_LocalsToFast() before MAKE_CELL has run). PyObject *initial = GETLOCAL(oparg); @@ -1803,12 +1816,12 @@ goto resume_with_error; } SETLOCAL(oparg, cell); - #line 1807 "Python/generated_cases.c.h" + #line 1820 "Python/generated_cases.c.h" DISPATCH(); } TARGET(DELETE_DEREF) { - #line 1321 "Python/bytecodes.c" + #line 1334 "Python/bytecodes.c" PyObject *cell = GETLOCAL(oparg); PyObject *oldobj = PyCell_GET(cell); // Can't use ERROR_IF here. @@ -1819,13 +1832,13 @@ } PyCell_SET(cell, NULL); Py_DECREF(oldobj); - #line 1823 "Python/generated_cases.c.h" + #line 1836 "Python/generated_cases.c.h" DISPATCH(); } TARGET(LOAD_CLASSDEREF) { PyObject *value; - #line 1334 "Python/bytecodes.c" + #line 1347 "Python/bytecodes.c" PyObject *name, *locals = LOCALS(); assert(locals); assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus); @@ -1857,7 +1870,7 @@ } Py_INCREF(value); } - #line 1861 "Python/generated_cases.c.h" + #line 1874 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = value; DISPATCH(); @@ -1865,7 +1878,7 @@ TARGET(LOAD_DEREF) { PyObject *value; - #line 1368 "Python/bytecodes.c" + #line 1381 "Python/bytecodes.c" PyObject *cell = GETLOCAL(oparg); value = PyCell_GET(cell); if (value == NULL) { @@ -1873,7 +1886,7 @@ if (true) goto error; } Py_INCREF(value); - #line 1877 "Python/generated_cases.c.h" + #line 1890 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = value; DISPATCH(); @@ -1881,18 +1894,18 @@ TARGET(STORE_DEREF) { PyObject *v = stack_pointer[-1]; - #line 1378 "Python/bytecodes.c" + #line 1391 "Python/bytecodes.c" PyObject *cell = GETLOCAL(oparg); PyObject *oldobj = PyCell_GET(cell); PyCell_SET(cell, v); Py_XDECREF(oldobj); - #line 1890 "Python/generated_cases.c.h" + #line 1903 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(COPY_FREE_VARS) { - #line 1385 "Python/bytecodes.c" + #line 1398 "Python/bytecodes.c" /* Copy closure variables to free variables */ PyCodeObject *co = frame->f_code; assert(PyFunction_Check(frame->f_funcobj)); @@ -1903,22 +1916,22 @@ PyObject *o = PyTuple_GET_ITEM(closure, i); frame->localsplus[offset + i] = Py_NewRef(o); } - #line 1907 "Python/generated_cases.c.h" + #line 1920 "Python/generated_cases.c.h" DISPATCH(); } TARGET(BUILD_STRING) { PyObject **pieces = (stack_pointer - oparg); PyObject *str; - #line 1398 "Python/bytecodes.c" + #line 1411 "Python/bytecodes.c" str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg); - #line 1916 "Python/generated_cases.c.h" + #line 1929 "Python/generated_cases.c.h" for (int _i = oparg; --_i >= 0;) { Py_DECREF(pieces[_i]); } - #line 1400 "Python/bytecodes.c" + #line 1413 "Python/bytecodes.c" if (str == NULL) { STACK_SHRINK(oparg); goto error; } - #line 1922 "Python/generated_cases.c.h" + #line 1935 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = str; @@ -1928,10 +1941,10 @@ TARGET(BUILD_TUPLE) { PyObject **values = (stack_pointer - oparg); PyObject *tup; - #line 1404 "Python/bytecodes.c" + #line 1417 "Python/bytecodes.c" tup = _PyTuple_FromArraySteal(values, oparg); if (tup == NULL) { STACK_SHRINK(oparg); goto error; } - #line 1935 "Python/generated_cases.c.h" + #line 1948 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = tup; @@ -1941,10 +1954,10 @@ TARGET(BUILD_LIST) { PyObject **values = (stack_pointer - oparg); PyObject *list; - #line 1409 "Python/bytecodes.c" + #line 1422 "Python/bytecodes.c" list = _PyList_FromArraySteal(values, oparg); if (list == NULL) { STACK_SHRINK(oparg); goto error; } - #line 1948 "Python/generated_cases.c.h" + #line 1961 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = list; @@ -1954,7 +1967,7 @@ TARGET(LIST_EXTEND) { PyObject *iterable = stack_pointer[-1]; PyObject *list = stack_pointer[-(2 + (oparg-1))]; - #line 1414 "Python/bytecodes.c" + #line 1427 "Python/bytecodes.c" PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); if (none_val == NULL) { if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && @@ -1965,13 +1978,13 @@ "Value after * must be an iterable, not %.200s", Py_TYPE(iterable)->tp_name); } - #line 1969 "Python/generated_cases.c.h" + #line 1982 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 1425 "Python/bytecodes.c" + #line 1438 "Python/bytecodes.c" if (true) goto pop_1_error; } Py_DECREF(none_val); - #line 1975 "Python/generated_cases.c.h" + #line 1988 "Python/generated_cases.c.h" Py_DECREF(iterable); STACK_SHRINK(1); DISPATCH(); @@ -1980,13 +1993,13 @@ TARGET(SET_UPDATE) { PyObject *iterable = stack_pointer[-1]; PyObject *set = stack_pointer[-(2 + (oparg-1))]; - #line 1432 "Python/bytecodes.c" + #line 1445 "Python/bytecodes.c" int err = _PySet_Update(set, iterable); - #line 1986 "Python/generated_cases.c.h" + #line 1999 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 1434 "Python/bytecodes.c" + #line 1447 "Python/bytecodes.c" if (err < 0) goto pop_1_error; - #line 1990 "Python/generated_cases.c.h" + #line 2003 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } @@ -1994,7 +2007,7 @@ TARGET(BUILD_SET) { PyObject **values = (stack_pointer - oparg); PyObject *set; - #line 1438 "Python/bytecodes.c" + #line 1451 "Python/bytecodes.c" set = PySet_New(NULL); if (set == NULL) goto error; @@ -2009,7 +2022,7 @@ Py_DECREF(set); if (true) { STACK_SHRINK(oparg); goto error; } } - #line 2013 "Python/generated_cases.c.h" + #line 2026 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = set; @@ -2019,7 +2032,7 @@ TARGET(BUILD_MAP) { PyObject **values = (stack_pointer - oparg*2); PyObject *map; - #line 1455 "Python/bytecodes.c" + #line 1468 "Python/bytecodes.c" map = _PyDict_FromItems( values, 2, values+1, 2, @@ -2027,13 +2040,13 @@ if (map == NULL) goto error; - #line 2031 "Python/generated_cases.c.h" + #line 2044 "Python/generated_cases.c.h" for (int _i = oparg*2; --_i >= 0;) { Py_DECREF(values[_i]); } - #line 1463 "Python/bytecodes.c" + #line 1476 "Python/bytecodes.c" if (map == NULL) { STACK_SHRINK(oparg*2); goto error; } - #line 2037 "Python/generated_cases.c.h" + #line 2050 "Python/generated_cases.c.h" STACK_SHRINK(oparg*2); STACK_GROW(1); stack_pointer[-1] = map; @@ -2041,7 +2054,7 @@ } TARGET(SETUP_ANNOTATIONS) { - #line 1467 "Python/bytecodes.c" + #line 1480 "Python/bytecodes.c" int err; PyObject *ann_dict; if (LOCALS() == NULL) { @@ -2081,7 +2094,7 @@ Py_DECREF(ann_dict); } } - #line 2085 "Python/generated_cases.c.h" + #line 2098 "Python/generated_cases.c.h" DISPATCH(); } @@ -2089,7 +2102,7 @@ PyObject *keys = stack_pointer[-1]; PyObject **values = (stack_pointer - (1 + oparg)); PyObject *map; - #line 1509 "Python/bytecodes.c" + #line 1522 "Python/bytecodes.c" if (!PyTuple_CheckExact(keys) || PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { _PyErr_SetString(tstate, PyExc_SystemError, @@ -2099,14 +2112,14 @@ map = _PyDict_FromItems( &PyTuple_GET_ITEM(keys, 0), 1, values, 1, oparg); - #line 2103 "Python/generated_cases.c.h" + #line 2116 "Python/generated_cases.c.h" for (int _i = oparg; --_i >= 0;) { Py_DECREF(values[_i]); } Py_DECREF(keys); - #line 1519 "Python/bytecodes.c" + #line 1532 "Python/bytecodes.c" if (map == NULL) { STACK_SHRINK(oparg); goto pop_1_error; } - #line 2110 "Python/generated_cases.c.h" + #line 2123 "Python/generated_cases.c.h" STACK_SHRINK(oparg); stack_pointer[-1] = map; DISPATCH(); @@ -2114,7 +2127,7 @@ TARGET(DICT_UPDATE) { PyObject *update = stack_pointer[-1]; - #line 1523 "Python/bytecodes.c" + #line 1536 "Python/bytecodes.c" PyObject *dict = PEEK(oparg + 1); // update is still on the stack if (PyDict_Update(dict, update) < 0) { if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { @@ -2122,12 +2135,12 @@ "'%.200s' object is not a mapping", Py_TYPE(update)->tp_name); } - #line 2126 "Python/generated_cases.c.h" + #line 2139 "Python/generated_cases.c.h" Py_DECREF(update); - #line 1531 "Python/bytecodes.c" + #line 1544 "Python/bytecodes.c" if (true) goto pop_1_error; } - #line 2131 "Python/generated_cases.c.h" + #line 2144 "Python/generated_cases.c.h" Py_DECREF(update); STACK_SHRINK(1); DISPATCH(); @@ -2135,17 +2148,17 @@ TARGET(DICT_MERGE) { PyObject *update = stack_pointer[-1]; - #line 1537 "Python/bytecodes.c" + #line 1550 "Python/bytecodes.c" PyObject *dict = PEEK(oparg + 1); // update is still on the stack if (_PyDict_MergeEx(dict, update, 2) < 0) { format_kwargs_error(tstate, PEEK(3 + oparg), update); - #line 2144 "Python/generated_cases.c.h" + #line 2157 "Python/generated_cases.c.h" Py_DECREF(update); - #line 1542 "Python/bytecodes.c" + #line 1555 "Python/bytecodes.c" if (true) goto pop_1_error; } - #line 2149 "Python/generated_cases.c.h" + #line 2162 "Python/generated_cases.c.h" Py_DECREF(update); STACK_SHRINK(1); PREDICT(CALL_FUNCTION_EX); @@ -2155,13 +2168,13 @@ TARGET(MAP_ADD) { PyObject *value = stack_pointer[-1]; PyObject *key = stack_pointer[-2]; - #line 1549 "Python/bytecodes.c" + #line 1562 "Python/bytecodes.c" PyObject *dict = PEEK(oparg + 2); // key, value are still on the stack assert(PyDict_CheckExact(dict)); /* dict[key] = value */ // Do not DECREF INPUTS because the function steals the references if (_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0) goto pop_2_error; - #line 2165 "Python/generated_cases.c.h" + #line 2178 "Python/generated_cases.c.h" STACK_SHRINK(2); PREDICT(JUMP_BACKWARD); DISPATCH(); @@ -2175,7 +2188,7 @@ PyObject *global_super = stack_pointer[-3]; PyObject *res2 = NULL; PyObject *res; - #line 1563 "Python/bytecodes.c" + #line 1576 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2); int load_method = oparg & 1; #if ENABLE_SPECIALIZATION @@ -2193,16 +2206,16 @@ // handle any case whose performance we care about PyObject *stack[] = {class, self}; PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL); - #line 2197 "Python/generated_cases.c.h" + #line 2210 "Python/generated_cases.c.h" Py_DECREF(global_super); Py_DECREF(class); Py_DECREF(self); - #line 1581 "Python/bytecodes.c" + #line 1594 "Python/bytecodes.c" if (super == NULL) goto pop_3_error; res = PyObject_GetAttr(super, name); Py_DECREF(super); if (res == NULL) goto pop_3_error; - #line 2206 "Python/generated_cases.c.h" + #line 2219 "Python/generated_cases.c.h" STACK_SHRINK(2); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2220,7 +2233,7 @@ uint32_t class_version = read_u32(&next_instr[1].cache); uint32_t self_type_version = read_u32(&next_instr[3].cache); PyObject *method = read_obj(&next_instr[5].cache); - #line 1588 "Python/bytecodes.c" + #line 1601 "Python/bytecodes.c" DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); DEOPT_IF(((PyTypeObject *)class)->tp_version_tag != class_version, LOAD_SUPER_ATTR); @@ -2231,7 +2244,7 @@ Py_INCREF(res2); Py_DECREF(global_super); Py_DECREF(class); - #line 2235 "Python/generated_cases.c.h" + #line 2248 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; stack_pointer[-2] = res2; @@ -2245,7 +2258,7 @@ PyObject *owner = stack_pointer[-1]; PyObject *res2 = NULL; PyObject *res; - #line 1615 "Python/bytecodes.c" + #line 1628 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyAttrCache *cache = (_PyAttrCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -2279,9 +2292,9 @@ NULL | meth | arg1 | ... | argN */ - #line 2283 "Python/generated_cases.c.h" + #line 2296 "Python/generated_cases.c.h" Py_DECREF(owner); - #line 1649 "Python/bytecodes.c" + #line 1662 "Python/bytecodes.c" if (meth == NULL) goto pop_1_error; res2 = NULL; res = meth; @@ -2290,12 +2303,12 @@ else { /* Classic, pushes one value. */ res = PyObject_GetAttr(owner, name); - #line 2294 "Python/generated_cases.c.h" + #line 2307 "Python/generated_cases.c.h" Py_DECREF(owner); - #line 1658 "Python/bytecodes.c" + #line 1671 "Python/bytecodes.c" if (res == NULL) goto pop_1_error; } - #line 2299 "Python/generated_cases.c.h" + #line 2312 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -2309,7 +2322,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1663 "Python/bytecodes.c" + #line 1676 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); @@ -2322,7 +2335,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2326 "Python/generated_cases.c.h" + #line 2339 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2337,7 +2350,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1679 "Python/bytecodes.c" + #line 1692 "Python/bytecodes.c" DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR); PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; assert(dict != NULL); @@ -2350,7 +2363,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2354 "Python/generated_cases.c.h" + #line 2367 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2365,7 +2378,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1695 "Python/bytecodes.c" + #line 1708 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); @@ -2392,7 +2405,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2396 "Python/generated_cases.c.h" + #line 2409 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2407,7 +2420,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1725 "Python/bytecodes.c" + #line 1738 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); @@ -2417,7 +2430,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2421 "Python/generated_cases.c.h" + #line 2434 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2432,7 +2445,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 1738 "Python/bytecodes.c" + #line 1751 "Python/bytecodes.c" DEOPT_IF(!PyType_Check(cls), LOAD_ATTR); DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version, @@ -2444,7 +2457,7 @@ res = descr; assert(res != NULL); Py_INCREF(res); - #line 2448 "Python/generated_cases.c.h" + #line 2461 "Python/generated_cases.c.h" Py_DECREF(cls); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2458,7 +2471,7 @@ uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t func_version = read_u32(&next_instr[3].cache); PyObject *fget = read_obj(&next_instr[5].cache); - #line 1753 "Python/bytecodes.c" + #line 1766 "Python/bytecodes.c" DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); PyTypeObject *cls = Py_TYPE(owner); @@ -2482,7 +2495,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 2486 "Python/generated_cases.c.h" + #line 2499 "Python/generated_cases.c.h" } TARGET(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) { @@ -2490,7 +2503,7 @@ uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t func_version = read_u32(&next_instr[3].cache); PyObject *getattribute = read_obj(&next_instr[5].cache); - #line 1779 "Python/bytecodes.c" + #line 1792 "Python/bytecodes.c" DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); PyTypeObject *cls = Py_TYPE(owner); DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); @@ -2516,7 +2529,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 2520 "Python/generated_cases.c.h" + #line 2533 "Python/generated_cases.c.h" } TARGET(STORE_ATTR_INSTANCE_VALUE) { @@ -2524,7 +2537,7 @@ PyObject *value = stack_pointer[-2]; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1807 "Python/bytecodes.c" + #line 1820 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); @@ -2542,7 +2555,7 @@ Py_DECREF(old_value); } Py_DECREF(owner); - #line 2546 "Python/generated_cases.c.h" + #line 2559 "Python/generated_cases.c.h" STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -2553,7 +2566,7 @@ PyObject *value = stack_pointer[-2]; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t hint = read_u16(&next_instr[3].cache); - #line 1827 "Python/bytecodes.c" + #line 1840 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); @@ -2592,7 +2605,7 @@ /* PEP 509 */ dict->ma_version_tag = new_version; Py_DECREF(owner); - #line 2596 "Python/generated_cases.c.h" + #line 2609 "Python/generated_cases.c.h" STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -2603,7 +2616,7 @@ PyObject *value = stack_pointer[-2]; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1868 "Python/bytecodes.c" + #line 1881 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); @@ -2613,7 +2626,7 @@ *(PyObject **)addr = value; Py_XDECREF(old_value); Py_DECREF(owner); - #line 2617 "Python/generated_cases.c.h" + #line 2630 "Python/generated_cases.c.h" STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -2625,7 +2638,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 1887 "Python/bytecodes.c" + #line 1900 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -2638,12 +2651,12 @@ #endif /* ENABLE_SPECIALIZATION */ assert((oparg >> 4) <= Py_GE); res = PyObject_RichCompare(left, right, oparg>>4); - #line 2642 "Python/generated_cases.c.h" + #line 2655 "Python/generated_cases.c.h" Py_DECREF(left); Py_DECREF(right); - #line 1900 "Python/bytecodes.c" + #line 1913 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 2647 "Python/generated_cases.c.h" + #line 2660 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2654,7 +2667,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 1904 "Python/bytecodes.c" + #line 1917 "Python/bytecodes.c" DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP); STAT_INC(COMPARE_OP, hit); @@ -2666,7 +2679,7 @@ _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); res = (sign_ish & oparg) ? Py_True : Py_False; Py_INCREF(res); - #line 2670 "Python/generated_cases.c.h" + #line 2683 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2677,7 +2690,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 1919 "Python/bytecodes.c" + #line 1932 "Python/bytecodes.c" DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyLong_CheckExact(right), COMPARE_OP); DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left), COMPARE_OP); @@ -2693,7 +2706,7 @@ _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); res = (sign_ish & oparg) ? Py_True : Py_False; Py_INCREF(res); - #line 2697 "Python/generated_cases.c.h" + #line 2710 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2704,7 +2717,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 1938 "Python/bytecodes.c" + #line 1951 "Python/bytecodes.c" DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP); STAT_INC(COMPARE_OP, hit); @@ -2717,7 +2730,7 @@ assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS); res = ((COMPARISON_NOT_EQUALS + eq) & oparg) ? Py_True : Py_False; Py_INCREF(res); - #line 2721 "Python/generated_cases.c.h" + #line 2734 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2728,14 +2741,14 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *b; - #line 1953 "Python/bytecodes.c" + #line 1966 "Python/bytecodes.c" int res = Py_Is(left, right) ^ oparg; - #line 2734 "Python/generated_cases.c.h" + #line 2747 "Python/generated_cases.c.h" Py_DECREF(left); Py_DECREF(right); - #line 1955 "Python/bytecodes.c" + #line 1968 "Python/bytecodes.c" b = Py_NewRef(res ? Py_True : Py_False); - #line 2739 "Python/generated_cases.c.h" + #line 2752 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = b; DISPATCH(); @@ -2745,15 +2758,15 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *b; - #line 1959 "Python/bytecodes.c" + #line 1972 "Python/bytecodes.c" int res = PySequence_Contains(right, left); - #line 2751 "Python/generated_cases.c.h" + #line 2764 "Python/generated_cases.c.h" Py_DECREF(left); Py_DECREF(right); - #line 1961 "Python/bytecodes.c" + #line 1974 "Python/bytecodes.c" if (res < 0) goto pop_2_error; b = Py_NewRef((res^oparg) ? Py_True : Py_False); - #line 2757 "Python/generated_cases.c.h" + #line 2770 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = b; DISPATCH(); @@ -2764,12 +2777,12 @@ PyObject *exc_value = stack_pointer[-2]; PyObject *rest; PyObject *match; - #line 1966 "Python/bytecodes.c" + #line 1979 "Python/bytecodes.c" if (check_except_star_type_valid(tstate, match_type) < 0) { - #line 2770 "Python/generated_cases.c.h" + #line 2783 "Python/generated_cases.c.h" Py_DECREF(exc_value); Py_DECREF(match_type); - #line 1968 "Python/bytecodes.c" + #line 1981 "Python/bytecodes.c" if (true) goto pop_2_error; } @@ -2777,10 +2790,10 @@ rest = NULL; int res = exception_group_match(exc_value, match_type, &match, &rest); - #line 2781 "Python/generated_cases.c.h" + #line 2794 "Python/generated_cases.c.h" Py_DECREF(exc_value); Py_DECREF(match_type); - #line 1976 "Python/bytecodes.c" + #line 1989 "Python/bytecodes.c" if (res < 0) goto pop_2_error; assert((match == NULL) == (rest == NULL)); @@ -2789,7 +2802,7 @@ if (!Py_IsNone(match)) { PyErr_SetHandledException(match); } - #line 2793 "Python/generated_cases.c.h" + #line 2806 "Python/generated_cases.c.h" stack_pointer[-1] = match; stack_pointer[-2] = rest; DISPATCH(); @@ -2799,21 +2812,21 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *b; - #line 1987 "Python/bytecodes.c" + #line 2000 "Python/bytecodes.c" assert(PyExceptionInstance_Check(left)); if (check_except_type_valid(tstate, right) < 0) { - #line 2806 "Python/generated_cases.c.h" + #line 2819 "Python/generated_cases.c.h" Py_DECREF(right); - #line 1990 "Python/bytecodes.c" + #line 2003 "Python/bytecodes.c" if (true) goto pop_1_error; } int res = PyErr_GivenExceptionMatches(left, right); - #line 2813 "Python/generated_cases.c.h" + #line 2826 "Python/generated_cases.c.h" Py_DECREF(right); - #line 1995 "Python/bytecodes.c" + #line 2008 "Python/bytecodes.c" b = Py_NewRef(res ? Py_True : Py_False); - #line 2817 "Python/generated_cases.c.h" + #line 2830 "Python/generated_cases.c.h" stack_pointer[-1] = b; DISPATCH(); } @@ -2822,15 +2835,15 @@ PyObject *fromlist = stack_pointer[-1]; PyObject *level = stack_pointer[-2]; PyObject *res; - #line 1999 "Python/bytecodes.c" + #line 2012 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); res = import_name(tstate, frame, name, fromlist, level); - #line 2829 "Python/generated_cases.c.h" + #line 2842 "Python/generated_cases.c.h" Py_DECREF(level); Py_DECREF(fromlist); - #line 2002 "Python/bytecodes.c" + #line 2015 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 2834 "Python/generated_cases.c.h" + #line 2847 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; DISPATCH(); @@ -2839,29 +2852,29 @@ TARGET(IMPORT_FROM) { PyObject *from = stack_pointer[-1]; PyObject *res; - #line 2006 "Python/bytecodes.c" + #line 2019 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); res = import_from(tstate, from, name); if (res == NULL) goto error; - #line 2847 "Python/generated_cases.c.h" + #line 2860 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; DISPATCH(); } TARGET(JUMP_FORWARD) { - #line 2012 "Python/bytecodes.c" + #line 2025 "Python/bytecodes.c" JUMPBY(oparg); - #line 2856 "Python/generated_cases.c.h" + #line 2869 "Python/generated_cases.c.h" DISPATCH(); } TARGET(JUMP_BACKWARD) { PREDICTED(JUMP_BACKWARD); - #line 2016 "Python/bytecodes.c" + #line 2029 "Python/bytecodes.c" assert(oparg < INSTR_OFFSET()); JUMPBY(-oparg); - #line 2865 "Python/generated_cases.c.h" + #line 2878 "Python/generated_cases.c.h" CHECK_EVAL_BREAKER(); DISPATCH(); } @@ -2869,7 +2882,7 @@ TARGET(POP_JUMP_IF_FALSE) { PREDICTED(POP_JUMP_IF_FALSE); PyObject *cond = stack_pointer[-1]; - #line 2022 "Python/bytecodes.c" + #line 2035 "Python/bytecodes.c" if (Py_IsTrue(cond)) { _Py_DECREF_NO_DEALLOC(cond); } @@ -2879,9 +2892,9 @@ } else { int err = PyObject_IsTrue(cond); - #line 2883 "Python/generated_cases.c.h" + #line 2896 "Python/generated_cases.c.h" Py_DECREF(cond); - #line 2032 "Python/bytecodes.c" + #line 2045 "Python/bytecodes.c" if (err == 0) { JUMPBY(oparg); } @@ -2889,14 +2902,14 @@ if (err < 0) goto pop_1_error; } } - #line 2893 "Python/generated_cases.c.h" + #line 2906 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_TRUE) { PyObject *cond = stack_pointer[-1]; - #line 2042 "Python/bytecodes.c" + #line 2055 "Python/bytecodes.c" if (Py_IsFalse(cond)) { _Py_DECREF_NO_DEALLOC(cond); } @@ -2906,9 +2919,9 @@ } else { int err = PyObject_IsTrue(cond); - #line 2910 "Python/generated_cases.c.h" + #line 2923 "Python/generated_cases.c.h" Py_DECREF(cond); - #line 2052 "Python/bytecodes.c" + #line 2065 "Python/bytecodes.c" if (err > 0) { JUMPBY(oparg); } @@ -2916,67 +2929,67 @@ if (err < 0) goto pop_1_error; } } - #line 2920 "Python/generated_cases.c.h" + #line 2933 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_NOT_NONE) { PyObject *value = stack_pointer[-1]; - #line 2062 "Python/bytecodes.c" + #line 2075 "Python/bytecodes.c" if (!Py_IsNone(value)) { - #line 2929 "Python/generated_cases.c.h" + #line 2942 "Python/generated_cases.c.h" Py_DECREF(value); - #line 2064 "Python/bytecodes.c" + #line 2077 "Python/bytecodes.c" JUMPBY(oparg); } else { _Py_DECREF_NO_DEALLOC(value); } - #line 2937 "Python/generated_cases.c.h" + #line 2950 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_NONE) { PyObject *value = stack_pointer[-1]; - #line 2072 "Python/bytecodes.c" + #line 2085 "Python/bytecodes.c" if (Py_IsNone(value)) { _Py_DECREF_NO_DEALLOC(value); JUMPBY(oparg); } else { - #line 2950 "Python/generated_cases.c.h" + #line 2963 "Python/generated_cases.c.h" Py_DECREF(value); - #line 2078 "Python/bytecodes.c" + #line 2091 "Python/bytecodes.c" } - #line 2954 "Python/generated_cases.c.h" + #line 2967 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(JUMP_BACKWARD_NO_INTERRUPT) { - #line 2082 "Python/bytecodes.c" + #line 2095 "Python/bytecodes.c" /* This bytecode is used in the `yield from` or `await` loop. * If there is an interrupt, we want it handled in the innermost * generator or coroutine, so we deliberately do not check it here. * (see bpo-30039). */ JUMPBY(-oparg); - #line 2967 "Python/generated_cases.c.h" + #line 2980 "Python/generated_cases.c.h" DISPATCH(); } TARGET(GET_LEN) { PyObject *obj = stack_pointer[-1]; PyObject *len_o; - #line 2091 "Python/bytecodes.c" + #line 2104 "Python/bytecodes.c" // PUSH(len(TOS)) Py_ssize_t len_i = PyObject_Length(obj); if (len_i < 0) goto error; len_o = PyLong_FromSsize_t(len_i); if (len_o == NULL) goto error; - #line 2980 "Python/generated_cases.c.h" + #line 2993 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = len_o; DISPATCH(); @@ -2987,16 +3000,16 @@ PyObject *type = stack_pointer[-2]; PyObject *subject = stack_pointer[-3]; PyObject *attrs; - #line 2099 "Python/bytecodes.c" + #line 2112 "Python/bytecodes.c" // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or // None on failure. assert(PyTuple_CheckExact(names)); attrs = match_class(tstate, subject, type, oparg, names); - #line 2996 "Python/generated_cases.c.h" + #line 3009 "Python/generated_cases.c.h" Py_DECREF(subject); Py_DECREF(type); Py_DECREF(names); - #line 2104 "Python/bytecodes.c" + #line 2117 "Python/bytecodes.c" if (attrs) { assert(PyTuple_CheckExact(attrs)); // Success! } @@ -3004,7 +3017,7 @@ if (_PyErr_Occurred(tstate)) goto pop_3_error; attrs = Py_NewRef(Py_None); // Failure! } - #line 3008 "Python/generated_cases.c.h" + #line 3021 "Python/generated_cases.c.h" STACK_SHRINK(2); stack_pointer[-1] = attrs; DISPATCH(); @@ -3013,10 +3026,10 @@ TARGET(MATCH_MAPPING) { PyObject *subject = stack_pointer[-1]; PyObject *res; - #line 2114 "Python/bytecodes.c" + #line 2127 "Python/bytecodes.c" int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; res = Py_NewRef(match ? Py_True : Py_False); - #line 3020 "Python/generated_cases.c.h" + #line 3033 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; PREDICT(POP_JUMP_IF_FALSE); @@ -3026,10 +3039,10 @@ TARGET(MATCH_SEQUENCE) { PyObject *subject = stack_pointer[-1]; PyObject *res; - #line 2120 "Python/bytecodes.c" + #line 2133 "Python/bytecodes.c" int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; res = Py_NewRef(match ? Py_True : Py_False); - #line 3033 "Python/generated_cases.c.h" + #line 3046 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; PREDICT(POP_JUMP_IF_FALSE); @@ -3040,11 +3053,11 @@ PyObject *keys = stack_pointer[-1]; PyObject *subject = stack_pointer[-2]; PyObject *values_or_none; - #line 2126 "Python/bytecodes.c" + #line 2139 "Python/bytecodes.c" // On successful match, PUSH(values). Otherwise, PUSH(None). values_or_none = match_keys(tstate, subject, keys); if (values_or_none == NULL) goto error; - #line 3048 "Python/generated_cases.c.h" + #line 3061 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = values_or_none; DISPATCH(); @@ -3053,14 +3066,14 @@ TARGET(GET_ITER) { PyObject *iterable = stack_pointer[-1]; PyObject *iter; - #line 2132 "Python/bytecodes.c" + #line 2145 "Python/bytecodes.c" /* before: [obj]; after [getiter(obj)] */ iter = PyObject_GetIter(iterable); - #line 3060 "Python/generated_cases.c.h" + #line 3073 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 2135 "Python/bytecodes.c" + #line 2148 "Python/bytecodes.c" if (iter == NULL) goto pop_1_error; - #line 3064 "Python/generated_cases.c.h" + #line 3077 "Python/generated_cases.c.h" stack_pointer[-1] = iter; DISPATCH(); } @@ -3068,7 +3081,7 @@ TARGET(GET_YIELD_FROM_ITER) { PyObject *iterable = stack_pointer[-1]; PyObject *iter; - #line 2139 "Python/bytecodes.c" + #line 2152 "Python/bytecodes.c" /* before: [obj]; after [getiter(obj)] */ if (PyCoro_CheckExact(iterable)) { /* `iterable` is a coroutine */ @@ -3091,11 +3104,11 @@ if (iter == NULL) { goto error; } - #line 3095 "Python/generated_cases.c.h" + #line 3108 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 2162 "Python/bytecodes.c" + #line 2175 "Python/bytecodes.c" } - #line 3099 "Python/generated_cases.c.h" + #line 3112 "Python/generated_cases.c.h" stack_pointer[-1] = iter; PREDICT(LOAD_CONST); DISPATCH(); @@ -3106,7 +3119,7 @@ static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2181 "Python/bytecodes.c" + #line 2194 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyForIterCache *cache = (_PyForIterCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -3137,7 +3150,7 @@ DISPATCH(); } // Common case: no jump, leave it to the code generator - #line 3141 "Python/generated_cases.c.h" + #line 3154 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3145,7 +3158,7 @@ } TARGET(INSTRUMENTED_FOR_ITER) { - #line 2214 "Python/bytecodes.c" + #line 2227 "Python/bytecodes.c" _Py_CODEUNIT *here = next_instr-1; _Py_CODEUNIT *target; PyObject *iter = TOP(); @@ -3171,14 +3184,14 @@ target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1; } INSTRUMENTED_JUMP(here, target, PY_MONITORING_EVENT_BRANCH); - #line 3175 "Python/generated_cases.c.h" + #line 3188 "Python/generated_cases.c.h" DISPATCH(); } TARGET(FOR_ITER_LIST) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2242 "Python/bytecodes.c" + #line 2255 "Python/bytecodes.c" DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER); _PyListIterObject *it = (_PyListIterObject *)iter; STAT_INC(FOR_ITER, hit); @@ -3198,7 +3211,7 @@ DISPATCH(); end_for_iter_list: // Common case: no jump, leave it to the code generator - #line 3202 "Python/generated_cases.c.h" + #line 3215 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3208,7 +3221,7 @@ TARGET(FOR_ITER_TUPLE) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2264 "Python/bytecodes.c" + #line 2277 "Python/bytecodes.c" _PyTupleIterObject *it = (_PyTupleIterObject *)iter; DEOPT_IF(Py_TYPE(it) != &PyTupleIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); @@ -3228,7 +3241,7 @@ DISPATCH(); end_for_iter_tuple: // Common case: no jump, leave it to the code generator - #line 3232 "Python/generated_cases.c.h" + #line 3245 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3238,7 +3251,7 @@ TARGET(FOR_ITER_RANGE) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2286 "Python/bytecodes.c" + #line 2299 "Python/bytecodes.c" _PyRangeIterObject *r = (_PyRangeIterObject *)iter; DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); @@ -3256,7 +3269,7 @@ if (next == NULL) { goto error; } - #line 3260 "Python/generated_cases.c.h" + #line 3273 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3265,7 +3278,7 @@ TARGET(FOR_ITER_GEN) { PyObject *iter = stack_pointer[-1]; - #line 2306 "Python/bytecodes.c" + #line 2319 "Python/bytecodes.c" PyGenObject *gen = (PyGenObject *)iter; DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER); DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, FOR_ITER); @@ -3280,14 +3293,14 @@ assert(next_instr[oparg].op.code == END_FOR || next_instr[oparg].op.code == INSTRUMENTED_END_FOR); DISPATCH_INLINED(gen_frame); - #line 3284 "Python/generated_cases.c.h" + #line 3297 "Python/generated_cases.c.h" } TARGET(BEFORE_ASYNC_WITH) { PyObject *mgr = stack_pointer[-1]; PyObject *exit; PyObject *res; - #line 2323 "Python/bytecodes.c" + #line 2336 "Python/bytecodes.c" PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__)); if (enter == NULL) { if (!_PyErr_Occurred(tstate)) { @@ -3310,16 +3323,16 @@ Py_DECREF(enter); goto error; } - #line 3314 "Python/generated_cases.c.h" + #line 3327 "Python/generated_cases.c.h" Py_DECREF(mgr); - #line 2346 "Python/bytecodes.c" + #line 2359 "Python/bytecodes.c" res = _PyObject_CallNoArgs(enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); if (true) goto pop_1_error; } - #line 3323 "Python/generated_cases.c.h" + #line 3336 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; stack_pointer[-2] = exit; @@ -3331,7 +3344,7 @@ PyObject *mgr = stack_pointer[-1]; PyObject *exit; PyObject *res; - #line 2356 "Python/bytecodes.c" + #line 2369 "Python/bytecodes.c" /* pop the context manager, push its __exit__ and the * value returned from calling its __enter__ */ @@ -3357,16 +3370,16 @@ Py_DECREF(enter); goto error; } - #line 3361 "Python/generated_cases.c.h" + #line 3374 "Python/generated_cases.c.h" Py_DECREF(mgr); - #line 2382 "Python/bytecodes.c" + #line 2395 "Python/bytecodes.c" res = _PyObject_CallNoArgs(enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); if (true) goto pop_1_error; } - #line 3370 "Python/generated_cases.c.h" + #line 3383 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; stack_pointer[-2] = exit; @@ -3378,7 +3391,7 @@ PyObject *lasti = stack_pointer[-3]; PyObject *exit_func = stack_pointer[-4]; PyObject *res; - #line 2391 "Python/bytecodes.c" + #line 2404 "Python/bytecodes.c" /* At the top of the stack are 4 values: - val: TOP = exc_info() - unused: SECOND = previous exception @@ -3399,7 +3412,7 @@ res = PyObject_Vectorcall(exit_func, stack + 1, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); if (res == NULL) goto error; - #line 3403 "Python/generated_cases.c.h" + #line 3416 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; DISPATCH(); @@ -3408,7 +3421,7 @@ TARGET(PUSH_EXC_INFO) { PyObject *new_exc = stack_pointer[-1]; PyObject *prev_exc; - #line 2414 "Python/bytecodes.c" + #line 2427 "Python/bytecodes.c" _PyErr_StackItem *exc_info = tstate->exc_info; if (exc_info->exc_value != NULL) { prev_exc = exc_info->exc_value; @@ -3418,7 +3431,7 @@ } assert(PyExceptionInstance_Check(new_exc)); exc_info->exc_value = Py_NewRef(new_exc); - #line 3422 "Python/generated_cases.c.h" + #line 3435 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = new_exc; stack_pointer[-2] = prev_exc; @@ -3432,7 +3445,7 @@ uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t keys_version = read_u32(&next_instr[3].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2426 "Python/bytecodes.c" + #line 2439 "Python/bytecodes.c" /* Cached method object */ PyTypeObject *self_cls = Py_TYPE(self); assert(type_version != 0); @@ -3449,7 +3462,7 @@ assert(_PyType_HasFeature(Py_TYPE(res2), Py_TPFLAGS_METHOD_DESCRIPTOR)); res = self; assert(oparg & 1); - #line 3453 "Python/generated_cases.c.h" + #line 3466 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3463,7 +3476,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2445 "Python/bytecodes.c" + #line 2458 "Python/bytecodes.c" PyTypeObject *self_cls = Py_TYPE(self); DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); assert(self_cls->tp_dictoffset == 0); @@ -3473,7 +3486,7 @@ res2 = Py_NewRef(descr); res = self; assert(oparg & 1); - #line 3477 "Python/generated_cases.c.h" + #line 3490 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3487,7 +3500,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2457 "Python/bytecodes.c" + #line 2470 "Python/bytecodes.c" PyTypeObject *self_cls = Py_TYPE(self); DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); Py_ssize_t dictoffset = self_cls->tp_dictoffset; @@ -3501,7 +3514,7 @@ res2 = Py_NewRef(descr); res = self; assert(oparg & 1); - #line 3505 "Python/generated_cases.c.h" + #line 3518 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3510,16 +3523,16 @@ } TARGET(KW_NAMES) { - #line 2473 "Python/bytecodes.c" + #line 2486 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg < PyTuple_GET_SIZE(frame->f_code->co_consts)); kwnames = GETITEM(frame->f_code->co_consts, oparg); - #line 3518 "Python/generated_cases.c.h" + #line 3531 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_CALL) { - #line 2479 "Python/bytecodes.c" + #line 2492 "Python/bytecodes.c" int is_meth = PEEK(oparg+2) != NULL; int total_args = oparg + is_meth; PyObject *function = PEEK(total_args + 1); @@ -3532,7 +3545,7 @@ _PyCallCache *cache = (_PyCallCache *)next_instr; INCREMENT_ADAPTIVE_COUNTER(cache->counter); GO_TO_INSTRUCTION(CALL); - #line 3536 "Python/generated_cases.c.h" + #line 3549 "Python/generated_cases.c.h" } TARGET(CALL) { @@ -3542,7 +3555,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2524 "Python/bytecodes.c" + #line 2537 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -3624,7 +3637,7 @@ Py_DECREF(args[i]); } if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3628 "Python/generated_cases.c.h" + #line 3641 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3636,7 +3649,7 @@ TARGET(CALL_BOUND_METHOD_EXACT_ARGS) { PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; - #line 2612 "Python/bytecodes.c" + #line 2625 "Python/bytecodes.c" DEOPT_IF(method != NULL, CALL); DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL); STAT_INC(CALL, hit); @@ -3646,7 +3659,7 @@ PEEK(oparg + 2) = Py_NewRef(meth); // method Py_DECREF(callable); GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS); - #line 3650 "Python/generated_cases.c.h" + #line 3663 "Python/generated_cases.c.h" } TARGET(CALL_PY_EXACT_ARGS) { @@ -3655,7 +3668,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; uint32_t func_version = read_u32(&next_instr[1].cache); - #line 2624 "Python/bytecodes.c" + #line 2637 "Python/bytecodes.c" assert(kwnames == NULL); DEOPT_IF(tstate->interp->eval_frame, CALL); int is_meth = method != NULL; @@ -3681,7 +3694,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 3685 "Python/generated_cases.c.h" + #line 3698 "Python/generated_cases.c.h" } TARGET(CALL_PY_WITH_DEFAULTS) { @@ -3689,7 +3702,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; uint32_t func_version = read_u32(&next_instr[1].cache); - #line 2652 "Python/bytecodes.c" + #line 2665 "Python/bytecodes.c" assert(kwnames == NULL); DEOPT_IF(tstate->interp->eval_frame, CALL); int is_meth = method != NULL; @@ -3725,7 +3738,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 3729 "Python/generated_cases.c.h" + #line 3742 "Python/generated_cases.c.h" } TARGET(CALL_NO_KW_TYPE_1) { @@ -3733,7 +3746,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2690 "Python/bytecodes.c" + #line 2703 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3743,7 +3756,7 @@ res = Py_NewRef(Py_TYPE(obj)); Py_DECREF(obj); Py_DECREF(&PyType_Type); // I.e., callable - #line 3747 "Python/generated_cases.c.h" + #line 3760 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3756,7 +3769,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2702 "Python/bytecodes.c" + #line 2715 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3767,7 +3780,7 @@ Py_DECREF(arg); Py_DECREF(&PyUnicode_Type); // I.e., callable if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3771 "Python/generated_cases.c.h" + #line 3784 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3781,7 +3794,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2716 "Python/bytecodes.c" + #line 2729 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3792,7 +3805,7 @@ Py_DECREF(arg); Py_DECREF(&PyTuple_Type); // I.e., tuple if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3796 "Python/generated_cases.c.h" + #line 3809 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3806,7 +3819,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2730 "Python/bytecodes.c" + #line 2743 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -3828,7 +3841,7 @@ } Py_DECREF(tp); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3832 "Python/generated_cases.c.h" + #line 3845 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3842,7 +3855,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2755 "Python/bytecodes.c" + #line 2768 "Python/bytecodes.c" /* Builtin METH_O functions */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -3870,7 +3883,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3874 "Python/generated_cases.c.h" + #line 3887 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3884,7 +3897,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2786 "Python/bytecodes.c" + #line 2799 "Python/bytecodes.c" /* Builtin METH_FASTCALL functions, without keywords */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -3916,7 +3929,7 @@ 'invalid'). In those cases an exception is set, so we must handle it. */ - #line 3920 "Python/generated_cases.c.h" + #line 3933 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3930,7 +3943,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2821 "Python/bytecodes.c" + #line 2834 "Python/bytecodes.c" /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ int is_meth = method != NULL; int total_args = oparg; @@ -3962,7 +3975,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3966 "Python/generated_cases.c.h" + #line 3979 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3976,7 +3989,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2856 "Python/bytecodes.c" + #line 2869 "Python/bytecodes.c" assert(kwnames == NULL); /* len(o) */ int is_meth = method != NULL; @@ -4001,7 +4014,7 @@ Py_DECREF(callable); Py_DECREF(arg); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4005 "Python/generated_cases.c.h" + #line 4018 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4014,7 +4027,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2883 "Python/bytecodes.c" + #line 2896 "Python/bytecodes.c" assert(kwnames == NULL); /* isinstance(o, o2) */ int is_meth = method != NULL; @@ -4041,7 +4054,7 @@ Py_DECREF(cls); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4045 "Python/generated_cases.c.h" + #line 4058 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4053,7 +4066,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *self = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; - #line 2913 "Python/bytecodes.c" + #line 2926 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); assert(method != NULL); @@ -4071,14 +4084,14 @@ JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1); assert(next_instr[-1].op.code == POP_TOP); DISPATCH(); - #line 4075 "Python/generated_cases.c.h" + #line 4088 "Python/generated_cases.c.h" } TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) { PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2933 "Python/bytecodes.c" + #line 2946 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4109,7 +4122,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4113 "Python/generated_cases.c.h" + #line 4126 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4122,7 +4135,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2967 "Python/bytecodes.c" + #line 2980 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -4151,7 +4164,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4155 "Python/generated_cases.c.h" + #line 4168 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4164,7 +4177,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2999 "Python/bytecodes.c" + #line 3012 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 0 || oparg == 1); int is_meth = method != NULL; @@ -4193,7 +4206,7 @@ Py_DECREF(self); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4197 "Python/generated_cases.c.h" + #line 4210 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4206,7 +4219,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3031 "Python/bytecodes.c" + #line 3044 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4234,7 +4247,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4238 "Python/generated_cases.c.h" + #line 4251 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4244,9 +4257,9 @@ } TARGET(INSTRUMENTED_CALL_FUNCTION_EX) { - #line 3062 "Python/bytecodes.c" + #line 3075 "Python/bytecodes.c" GO_TO_INSTRUCTION(CALL_FUNCTION_EX); - #line 4250 "Python/generated_cases.c.h" + #line 4263 "Python/generated_cases.c.h" } TARGET(CALL_FUNCTION_EX) { @@ -4255,7 +4268,7 @@ PyObject *callargs = stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))]; PyObject *func = stack_pointer[-(2 + ((oparg & 1) ? 1 : 0))]; PyObject *result; - #line 3066 "Python/bytecodes.c" + #line 3079 "Python/bytecodes.c" // DICT_MERGE is called before this opcode if there are kwargs. // It converts all dict subtypes in kwargs into regular dicts. assert(kwargs == NULL || PyDict_CheckExact(kwargs)); @@ -4298,14 +4311,14 @@ else { result = PyObject_Call(func, callargs, kwargs); } - #line 4302 "Python/generated_cases.c.h" + #line 4315 "Python/generated_cases.c.h" Py_DECREF(func); Py_DECREF(callargs); Py_XDECREF(kwargs); - #line 3109 "Python/bytecodes.c" + #line 3122 "Python/bytecodes.c" assert(PEEK(3 + (oparg & 1)) == NULL); if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; } - #line 4309 "Python/generated_cases.c.h" + #line 4322 "Python/generated_cases.c.h" STACK_SHRINK(((oparg & 1) ? 1 : 0)); STACK_SHRINK(2); stack_pointer[-1] = result; @@ -4320,7 +4333,7 @@ PyObject *kwdefaults = (oparg & 0x02) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0))] : NULL; PyObject *defaults = (oparg & 0x01) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x01) ? 1 : 0))] : NULL; PyObject *func; - #line 3119 "Python/bytecodes.c" + #line 3132 "Python/bytecodes.c" PyFunctionObject *func_obj = (PyFunctionObject *) PyFunction_New(codeobj, GLOBALS()); @@ -4349,14 +4362,14 @@ func_obj->func_version = ((PyCodeObject *)codeobj)->co_version; func = (PyObject *)func_obj; - #line 4353 "Python/generated_cases.c.h" + #line 4366 "Python/generated_cases.c.h" STACK_SHRINK(((oparg & 0x01) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x08) ? 1 : 0)); stack_pointer[-1] = func; DISPATCH(); } TARGET(RETURN_GENERATOR) { - #line 3150 "Python/bytecodes.c" + #line 3163 "Python/bytecodes.c" assert(PyFunction_Check(frame->f_funcobj)); PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); @@ -4377,7 +4390,7 @@ frame = cframe.current_frame = prev; _PyFrame_StackPush(frame, (PyObject *)gen); goto resume_frame; - #line 4381 "Python/generated_cases.c.h" + #line 4394 "Python/generated_cases.c.h" } TARGET(BUILD_SLICE) { @@ -4385,15 +4398,15 @@ PyObject *stop = stack_pointer[-(1 + ((oparg == 3) ? 1 : 0))]; PyObject *start = stack_pointer[-(2 + ((oparg == 3) ? 1 : 0))]; PyObject *slice; - #line 3173 "Python/bytecodes.c" + #line 3186 "Python/bytecodes.c" slice = PySlice_New(start, stop, step); - #line 4391 "Python/generated_cases.c.h" + #line 4404 "Python/generated_cases.c.h" Py_DECREF(start); Py_DECREF(stop); Py_XDECREF(step); - #line 3175 "Python/bytecodes.c" + #line 3188 "Python/bytecodes.c" if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; } - #line 4397 "Python/generated_cases.c.h" + #line 4410 "Python/generated_cases.c.h" STACK_SHRINK(((oparg == 3) ? 1 : 0)); STACK_SHRINK(1); stack_pointer[-1] = slice; @@ -4404,7 +4417,7 @@ PyObject *fmt_spec = ((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? stack_pointer[-((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))] : NULL; PyObject *value = stack_pointer[-(1 + (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))]; PyObject *result; - #line 3179 "Python/bytecodes.c" + #line 3192 "Python/bytecodes.c" /* Handles f-string value formatting. */ PyObject *(*conv_fn)(PyObject *); int which_conversion = oparg & FVC_MASK; @@ -4439,7 +4452,7 @@ Py_DECREF(value); Py_XDECREF(fmt_spec); if (result == NULL) { STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); goto pop_1_error; } - #line 4443 "Python/generated_cases.c.h" + #line 4456 "Python/generated_cases.c.h" STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); stack_pointer[-1] = result; DISPATCH(); @@ -4448,10 +4461,10 @@ TARGET(COPY) { PyObject *bottom = stack_pointer[-(1 + (oparg-1))]; PyObject *top; - #line 3216 "Python/bytecodes.c" + #line 3229 "Python/bytecodes.c" assert(oparg > 0); top = Py_NewRef(bottom); - #line 4455 "Python/generated_cases.c.h" + #line 4468 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = top; DISPATCH(); @@ -4463,7 +4476,7 @@ PyObject *rhs = stack_pointer[-1]; PyObject *lhs = stack_pointer[-2]; PyObject *res; - #line 3221 "Python/bytecodes.c" + #line 3234 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -4478,12 +4491,12 @@ assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); assert(binary_ops[oparg]); res = binary_ops[oparg](lhs, rhs); - #line 4482 "Python/generated_cases.c.h" + #line 4495 "Python/generated_cases.c.h" Py_DECREF(lhs); Py_DECREF(rhs); - #line 3236 "Python/bytecodes.c" + #line 3249 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 4487 "Python/generated_cases.c.h" + #line 4500 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -4493,16 +4506,16 @@ TARGET(SWAP) { PyObject *top = stack_pointer[-1]; PyObject *bottom = stack_pointer[-(2 + (oparg-2))]; - #line 3241 "Python/bytecodes.c" + #line 3254 "Python/bytecodes.c" assert(oparg >= 2); - #line 4499 "Python/generated_cases.c.h" + #line 4512 "Python/generated_cases.c.h" stack_pointer[-1] = bottom; stack_pointer[-(2 + (oparg-2))] = top; DISPATCH(); } TARGET(INSTRUMENTED_LINE) { - #line 3245 "Python/bytecodes.c" + #line 3258 "Python/bytecodes.c" _Py_CODEUNIT *here = next_instr-1; _PyFrame_SetStackPointer(frame, stack_pointer); int original_opcode = _Py_call_instrumentation_line( @@ -4522,11 +4535,11 @@ } opcode = original_opcode; DISPATCH_GOTO(); - #line 4526 "Python/generated_cases.c.h" + #line 4539 "Python/generated_cases.c.h" } TARGET(INSTRUMENTED_INSTRUCTION) { - #line 3267 "Python/bytecodes.c" + #line 3280 "Python/bytecodes.c" int next_opcode = _Py_call_instrumentation_instruction( tstate, frame, next_instr-1); if (next_opcode < 0) goto error; @@ -4538,26 +4551,26 @@ assert(next_opcode > 0 && next_opcode < 256); opcode = next_opcode; DISPATCH_GOTO(); - #line 4542 "Python/generated_cases.c.h" + #line 4555 "Python/generated_cases.c.h" } TARGET(INSTRUMENTED_JUMP_FORWARD) { - #line 3281 "Python/bytecodes.c" + #line 3294 "Python/bytecodes.c" INSTRUMENTED_JUMP(next_instr-1, next_instr+oparg, PY_MONITORING_EVENT_JUMP); - #line 4548 "Python/generated_cases.c.h" + #line 4561 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_JUMP_BACKWARD) { - #line 3285 "Python/bytecodes.c" + #line 3298 "Python/bytecodes.c" INSTRUMENTED_JUMP(next_instr-1, next_instr-oparg, PY_MONITORING_EVENT_JUMP); - #line 4555 "Python/generated_cases.c.h" + #line 4568 "Python/generated_cases.c.h" CHECK_EVAL_BREAKER(); DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_TRUE) { - #line 3290 "Python/bytecodes.c" + #line 3303 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4566,12 +4579,12 @@ assert(err == 0 || err == 1); int offset = err*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4570 "Python/generated_cases.c.h" + #line 4583 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_FALSE) { - #line 3301 "Python/bytecodes.c" + #line 3314 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4580,12 +4593,12 @@ assert(err == 0 || err == 1); int offset = (1-err)*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4584 "Python/generated_cases.c.h" + #line 4597 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) { - #line 3312 "Python/bytecodes.c" + #line 3325 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4598,12 +4611,12 @@ offset = 0; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4602 "Python/generated_cases.c.h" + #line 4615 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NOT_NONE) { - #line 3327 "Python/bytecodes.c" + #line 3340 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4616,30 +4629,30 @@ offset = oparg; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4620 "Python/generated_cases.c.h" + #line 4633 "Python/generated_cases.c.h" DISPATCH(); } TARGET(EXTENDED_ARG) { - #line 3342 "Python/bytecodes.c" + #line 3355 "Python/bytecodes.c" assert(oparg); opcode = next_instr->op.code; oparg = oparg << 8 | next_instr->op.arg; PRE_DISPATCH_GOTO(); DISPATCH_GOTO(); - #line 4631 "Python/generated_cases.c.h" + #line 4644 "Python/generated_cases.c.h" } TARGET(CACHE) { - #line 3350 "Python/bytecodes.c" + #line 3363 "Python/bytecodes.c" assert(0 && "Executing a cache."); Py_UNREACHABLE(); - #line 4638 "Python/generated_cases.c.h" + #line 4651 "Python/generated_cases.c.h" } TARGET(RESERVED) { - #line 3355 "Python/bytecodes.c" + #line 3368 "Python/bytecodes.c" assert(0 && "Executing RESERVED instruction."); Py_UNREACHABLE(); - #line 4645 "Python/generated_cases.c.h" + #line 4658 "Python/generated_cases.c.h" } diff --git a/Tools/build/generate_global_objects.py b/Tools/build/generate_global_objects.py index c27817702bf97d..f9adf509e9e133 100644 --- a/Tools/build/generate_global_objects.py +++ b/Tools/build/generate_global_objects.py @@ -113,6 +113,7 @@ '__rtruediv__', '__rxor__', '__set__', + '__set_awaiter__', '__setattr__', '__setitem__', '__str__', From 975bd293ed3db6492dbbb3e80d23835f9953aa56 Mon Sep 17 00:00:00 2001 From: Matt Page Date: Fri, 28 Apr 2023 11:11:46 -0700 Subject: [PATCH 2/7] Fix formatting of blurb --- .../2023-04-28-08-59-23.gh-issue-91048.IghN67.rst | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-04-28-08-59-23.gh-issue-91048.IghN67.rst b/Misc/NEWS.d/next/Core and Builtins/2023-04-28-08-59-23.gh-issue-91048.IghN67.rst index 28d594375aa19a..4294c580a5c2ba 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2023-04-28-08-59-23.gh-issue-91048.IghN67.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2023-04-28-08-59-23.gh-issue-91048.IghN67.rst @@ -2,10 +2,16 @@ When profiling an async Python application it's useful to see both the stack for the currently executing task as well as the chain of coroutines that are transitively awaiting the task. Consider the following example, where T represents a task, C represents a coroutine, and A '->' B indicates A is -awaiting B. +awaiting B:: -T0 +---> T1 | | | C0 | C2 | | -| v | v C1 | C3 | | +-----| + T0 +---> T1 + | | | + C0 | C2 + | | | + v | v + C1 | C3 + | | + +-----| The async stack from C3 would be C3, C2, C1, C0. In contrast, the synchronous call stack while C3 is executing is only C3, C2. It's possible From 669fe718e16bd689e91f7542aefeca7102605ff9 Mon Sep 17 00:00:00 2001 From: Matt Page Date: Fri, 28 Apr 2023 11:20:22 -0700 Subject: [PATCH 3/7] Fix style for `_PyAwaitable_SetAwaiter` --- Include/cpython/genobject.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Include/cpython/genobject.h b/Include/cpython/genobject.h index eda1fea6298f58..db2fdf0fc11e4b 100644 --- a/Include/cpython/genobject.h +++ b/Include/cpython/genobject.h @@ -7,7 +7,8 @@ extern "C" { #endif -static inline int _PyAwaitable_SetAwaiter(PyObject *receiver, PyObject *awaiter) { +static inline int +_PyAwaitable_SetAwaiter(PyObject *receiver, PyObject *awaiter) { PyTypeObject *ty = Py_TYPE(receiver); PyAsyncMethods *am = (PyAsyncMethods *) ty->tp_as_async; if ((am != NULL) && (am->am_set_awaiter != NULL)) { From 9e234bb92e8e48da8a0d972c8a751f516de377c0 Mon Sep 17 00:00:00 2001 From: Matt Page Date: Fri, 28 Apr 2023 11:27:46 -0700 Subject: [PATCH 4/7] Revert newline removal --- Include/cpython/genobject.h | 3 ++- Modules/_asynciomodule.c | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Include/cpython/genobject.h b/Include/cpython/genobject.h index db2fdf0fc11e4b..501af0528a9c1e 100644 --- a/Include/cpython/genobject.h +++ b/Include/cpython/genobject.h @@ -8,7 +8,8 @@ extern "C" { #endif static inline int -_PyAwaitable_SetAwaiter(PyObject *receiver, PyObject *awaiter) { +_PyAwaitable_SetAwaiter(PyObject *receiver, PyObject *awaiter) +{ PyTypeObject *ty = Py_TYPE(receiver); PyAsyncMethods *am = (PyAsyncMethods *) ty->tp_as_async; if ((am != NULL) && (am->am_set_awaiter != NULL)) { diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 2a9002b111d907..6f8e9f4e7dd49e 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -3342,6 +3342,7 @@ _asyncio_current_task_impl(PyObject *module, PyObject *loop) return ret; } + /*********************** Module **************************/ From 34e674e4e0d69754f2863096ade137e9f7b84e55 Mon Sep 17 00:00:00 2001 From: Matt Page Date: Fri, 28 Apr 2023 11:44:31 -0700 Subject: [PATCH 5/7] Fix inline literal syntax in blurb --- .../2023-04-28-08-59-23.gh-issue-91048.IghN67.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-04-28-08-59-23.gh-issue-91048.IghN67.rst b/Misc/NEWS.d/next/Core and Builtins/2023-04-28-08-59-23.gh-issue-91048.IghN67.rst index 4294c580a5c2ba..4bfeb298de3ad0 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2023-04-28-08-59-23.gh-issue-91048.IghN67.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2023-04-28-08-59-23.gh-issue-91048.IghN67.rst @@ -18,6 +18,6 @@ synchronous call stack while C3 is executing is only C3, C2. It's possible to reconstruct this view in most cases using what is currently available in CPython, however it's difficult to do so efficiently, and would be very challenging to do so, let alone efficiently, in an out of process profiler -that leverages eBPF. This adds a new field `{cr,ag}_awaiter` to coroutines +that leverages eBPF. This adds a new field ``{cr,ag}_awaiter`` to coroutines and async generators, respectively, that allows one to efficiently reconstruct the chain of suspended coroutines. From c8c348af85d4959b8520c9d3440ea8ba794ef840 Mon Sep 17 00:00:00 2001 From: Matt Page Date: Mon, 1 May 2023 10:58:09 -0700 Subject: [PATCH 6/7] Move awaiter setting after specialization block and fix check in `SEND_GEN` --- Python/bytecodes.c | 19 +- Python/generated_cases.c.h | 705 +++++++++++++++++++------------------ 2 files changed, 363 insertions(+), 361 deletions(-) diff --git a/Python/bytecodes.c b/Python/bytecodes.c index f6513d31ad678e..8070bf10d916a0 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -813,13 +813,6 @@ dummy_func( }; inst(SEND, (unused/1, receiver, v -- receiver, retval)) { - if ((frame->owner == FRAME_OWNED_BY_GENERATOR) && - (frame->f_code->co_flags & (CO_COROUTINE | CO_ASYNC_GENERATOR))) { - int st = _PyAwaitable_SetAwaiter(receiver, (PyObject *) _PyFrame_GetGenerator(frame)); - if (st < 0) { - goto error; - } - } #if ENABLE_SPECIALIZATION _PySendCache *cache = (_PySendCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -831,6 +824,13 @@ dummy_func( DECREMENT_ADAPTIVE_COUNTER(cache->counter); #endif /* ENABLE_SPECIALIZATION */ assert(frame != &entry_frame); + if ((frame->owner == FRAME_OWNED_BY_GENERATOR) && + (frame->f_code->co_flags & (CO_COROUTINE | CO_ASYNC_GENERATOR))) { + int st = _PyAwaitable_SetAwaiter(receiver, (PyObject *) _PyFrame_GetGenerator(frame)); + if (st < 0) { + goto error; + } + } if ((Py_TYPE(receiver) == &PyGen_Type || Py_TYPE(receiver) == &PyCoro_Type) && ((PyGenObject *)receiver)->gi_frame_state < FRAME_EXECUTING) { @@ -872,13 +872,14 @@ dummy_func( DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type, SEND); DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, SEND); - if (PyCoro_CheckExact(receiver)) { + STAT_INC(SEND, hit); + if ((frame->owner == FRAME_OWNED_BY_GENERATOR) && + (frame->f_code->co_flags & (CO_COROUTINE | CO_ASYNC_GENERATOR))) { int st = _PyAwaitable_SetAwaiter(receiver, (PyObject *) _PyFrame_GetGenerator(frame)); if (st < 0) { goto error; } } - STAT_INC(SEND, hit); _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; frame->return_offset = oparg; STACK_SHRINK(1); diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 1e14267ba3a88f..3ad31843b76dc2 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -1131,13 +1131,6 @@ PyObject *receiver = stack_pointer[-2]; PyObject *retval; #line 816 "Python/bytecodes.c" - if ((frame->owner == FRAME_OWNED_BY_GENERATOR) && - (frame->f_code->co_flags & (CO_COROUTINE | CO_ASYNC_GENERATOR))) { - int st = _PyAwaitable_SetAwaiter(receiver, (PyObject *) _PyFrame_GetGenerator(frame)); - if (st < 0) { - goto error; - } - } #if ENABLE_SPECIALIZATION _PySendCache *cache = (_PySendCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1149,6 +1142,13 @@ DECREMENT_ADAPTIVE_COUNTER(cache->counter); #endif /* ENABLE_SPECIALIZATION */ assert(frame != &entry_frame); + if ((frame->owner == FRAME_OWNED_BY_GENERATOR) && + (frame->f_code->co_flags & (CO_COROUTINE | CO_ASYNC_GENERATOR))) { + int st = _PyAwaitable_SetAwaiter(receiver, (PyObject *) _PyFrame_GetGenerator(frame)); + if (st < 0) { + goto error; + } + } if ((Py_TYPE(receiver) == &PyGen_Type || Py_TYPE(receiver) == &PyCoro_Type) && ((PyGenObject *)receiver)->gi_frame_state < FRAME_EXECUTING) { @@ -1197,13 +1197,14 @@ DEOPT_IF(Py_TYPE(gen) != &PyGen_Type && Py_TYPE(gen) != &PyCoro_Type, SEND); DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, SEND); - if (PyCoro_CheckExact(receiver)) { + STAT_INC(SEND, hit); + if ((frame->owner == FRAME_OWNED_BY_GENERATOR) && + (frame->f_code->co_flags & (CO_COROUTINE | CO_ASYNC_GENERATOR))) { int st = _PyAwaitable_SetAwaiter(receiver, (PyObject *) _PyFrame_GetGenerator(frame)); if (st < 0) { goto error; } } - STAT_INC(SEND, hit); _PyInterpreterFrame *gen_frame = (_PyInterpreterFrame *)gen->gi_iframe; frame->return_offset = oparg; STACK_SHRINK(1); @@ -1213,12 +1214,12 @@ tstate->exc_info = &gen->gi_exc_state; JUMPBY(INLINE_CACHE_ENTRIES_SEND); DISPATCH_INLINED(gen_frame); - #line 1217 "Python/generated_cases.c.h" + #line 1218 "Python/generated_cases.c.h" } TARGET(INSTRUMENTED_YIELD_VALUE) { PyObject *retval = stack_pointer[-1]; - #line 894 "Python/bytecodes.c" + #line 895 "Python/bytecodes.c" assert(frame != &entry_frame); PyGenObject *gen = _PyFrame_GetGenerator(frame); gen->gi_frame_state = FRAME_SUSPENDED; @@ -1235,12 +1236,12 @@ gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); goto resume_frame; - #line 1239 "Python/generated_cases.c.h" + #line 1240 "Python/generated_cases.c.h" } TARGET(YIELD_VALUE) { PyObject *retval = stack_pointer[-1]; - #line 913 "Python/bytecodes.c" + #line 914 "Python/bytecodes.c" // NOTE: It's important that YIELD_VALUE never raises an exception! // The compiler treats any exception raised here as a failed close() // or throw() call. @@ -1256,15 +1257,15 @@ gen_frame->previous = NULL; _PyFrame_StackPush(frame, retval); goto resume_frame; - #line 1260 "Python/generated_cases.c.h" + #line 1261 "Python/generated_cases.c.h" } TARGET(POP_EXCEPT) { PyObject *exc_value = stack_pointer[-1]; - #line 931 "Python/bytecodes.c" + #line 932 "Python/bytecodes.c" _PyErr_StackItem *exc_info = tstate->exc_info; Py_XSETREF(exc_info->exc_value, exc_value); - #line 1268 "Python/generated_cases.c.h" + #line 1269 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } @@ -1272,7 +1273,7 @@ TARGET(RERAISE) { PyObject *exc = stack_pointer[-1]; PyObject **values = (stack_pointer - (1 + oparg)); - #line 936 "Python/bytecodes.c" + #line 937 "Python/bytecodes.c" assert(oparg >= 0 && oparg <= 2); if (oparg) { PyObject *lasti = values[0]; @@ -1290,26 +1291,26 @@ Py_INCREF(exc); _PyErr_SetRaisedException(tstate, exc); goto exception_unwind; - #line 1294 "Python/generated_cases.c.h" + #line 1295 "Python/generated_cases.c.h" } TARGET(END_ASYNC_FOR) { PyObject *exc = stack_pointer[-1]; PyObject *awaitable = stack_pointer[-2]; - #line 956 "Python/bytecodes.c" + #line 957 "Python/bytecodes.c" assert(exc && PyExceptionInstance_Check(exc)); if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) { - #line 1303 "Python/generated_cases.c.h" + #line 1304 "Python/generated_cases.c.h" Py_DECREF(awaitable); Py_DECREF(exc); - #line 959 "Python/bytecodes.c" + #line 960 "Python/bytecodes.c" } else { Py_INCREF(exc); _PyErr_SetRaisedException(tstate, exc); goto exception_unwind; } - #line 1313 "Python/generated_cases.c.h" + #line 1314 "Python/generated_cases.c.h" STACK_SHRINK(2); DISPATCH(); } @@ -1320,23 +1321,23 @@ PyObject *sub_iter = stack_pointer[-3]; PyObject *none; PyObject *value; - #line 968 "Python/bytecodes.c" + #line 969 "Python/bytecodes.c" assert(throwflag); assert(exc_value && PyExceptionInstance_Check(exc_value)); if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) { value = Py_NewRef(((PyStopIterationObject *)exc_value)->value); - #line 1329 "Python/generated_cases.c.h" + #line 1330 "Python/generated_cases.c.h" Py_DECREF(sub_iter); Py_DECREF(last_sent_val); Py_DECREF(exc_value); - #line 973 "Python/bytecodes.c" + #line 974 "Python/bytecodes.c" none = Py_NewRef(Py_None); } else { _PyErr_SetRaisedException(tstate, Py_NewRef(exc_value)); goto exception_unwind; } - #line 1340 "Python/generated_cases.c.h" + #line 1341 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = value; stack_pointer[-2] = none; @@ -1345,9 +1346,9 @@ TARGET(LOAD_ASSERTION_ERROR) { PyObject *value; - #line 982 "Python/bytecodes.c" + #line 983 "Python/bytecodes.c" value = Py_NewRef(PyExc_AssertionError); - #line 1351 "Python/generated_cases.c.h" + #line 1352 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = value; DISPATCH(); @@ -1355,7 +1356,7 @@ TARGET(LOAD_BUILD_CLASS) { PyObject *bc; - #line 986 "Python/bytecodes.c" + #line 987 "Python/bytecodes.c" if (PyDict_CheckExact(BUILTINS())) { bc = _PyDict_GetItemWithError(BUILTINS(), &_Py_ID(__build_class__)); @@ -1377,7 +1378,7 @@ if (true) goto error; } } - #line 1381 "Python/generated_cases.c.h" + #line 1382 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = bc; DISPATCH(); @@ -1385,33 +1386,33 @@ TARGET(STORE_NAME) { PyObject *v = stack_pointer[-1]; - #line 1010 "Python/bytecodes.c" + #line 1011 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); PyObject *ns = LOCALS(); int err; if (ns == NULL) { _PyErr_Format(tstate, PyExc_SystemError, "no locals found when storing %R", name); - #line 1396 "Python/generated_cases.c.h" + #line 1397 "Python/generated_cases.c.h" Py_DECREF(v); - #line 1017 "Python/bytecodes.c" + #line 1018 "Python/bytecodes.c" if (true) goto pop_1_error; } if (PyDict_CheckExact(ns)) err = PyDict_SetItem(ns, name, v); else err = PyObject_SetItem(ns, name, v); - #line 1405 "Python/generated_cases.c.h" + #line 1406 "Python/generated_cases.c.h" Py_DECREF(v); - #line 1024 "Python/bytecodes.c" + #line 1025 "Python/bytecodes.c" if (err) goto pop_1_error; - #line 1409 "Python/generated_cases.c.h" + #line 1410 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(DELETE_NAME) { - #line 1028 "Python/bytecodes.c" + #line 1029 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); PyObject *ns = LOCALS(); int err; @@ -1428,7 +1429,7 @@ name); goto error; } - #line 1432 "Python/generated_cases.c.h" + #line 1433 "Python/generated_cases.c.h" DISPATCH(); } @@ -1436,7 +1437,7 @@ PREDICTED(UNPACK_SEQUENCE); static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size"); PyObject *seq = stack_pointer[-1]; - #line 1054 "Python/bytecodes.c" + #line 1055 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1449,11 +1450,11 @@ #endif /* ENABLE_SPECIALIZATION */ PyObject **top = stack_pointer + oparg - 1; int res = unpack_iterable(tstate, seq, oparg, -1, top); - #line 1453 "Python/generated_cases.c.h" + #line 1454 "Python/generated_cases.c.h" Py_DECREF(seq); - #line 1067 "Python/bytecodes.c" + #line 1068 "Python/bytecodes.c" if (res == 0) goto pop_1_error; - #line 1457 "Python/generated_cases.c.h" + #line 1458 "Python/generated_cases.c.h" STACK_SHRINK(1); STACK_GROW(oparg); next_instr += 1; @@ -1463,14 +1464,14 @@ TARGET(UNPACK_SEQUENCE_TWO_TUPLE) { PyObject *seq = stack_pointer[-1]; PyObject **values = stack_pointer - (1); - #line 1071 "Python/bytecodes.c" + #line 1072 "Python/bytecodes.c" DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE); assert(oparg == 2); STAT_INC(UNPACK_SEQUENCE, hit); values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1)); values[1] = Py_NewRef(PyTuple_GET_ITEM(seq, 0)); - #line 1474 "Python/generated_cases.c.h" + #line 1475 "Python/generated_cases.c.h" Py_DECREF(seq); STACK_SHRINK(1); STACK_GROW(oparg); @@ -1481,7 +1482,7 @@ TARGET(UNPACK_SEQUENCE_TUPLE) { PyObject *seq = stack_pointer[-1]; PyObject **values = stack_pointer - (1); - #line 1081 "Python/bytecodes.c" + #line 1082 "Python/bytecodes.c" DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE); DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); STAT_INC(UNPACK_SEQUENCE, hit); @@ -1489,7 +1490,7 @@ for (int i = oparg; --i >= 0; ) { *values++ = Py_NewRef(items[i]); } - #line 1493 "Python/generated_cases.c.h" + #line 1494 "Python/generated_cases.c.h" Py_DECREF(seq); STACK_SHRINK(1); STACK_GROW(oparg); @@ -1500,7 +1501,7 @@ TARGET(UNPACK_SEQUENCE_LIST) { PyObject *seq = stack_pointer[-1]; PyObject **values = stack_pointer - (1); - #line 1092 "Python/bytecodes.c" + #line 1093 "Python/bytecodes.c" DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE); DEOPT_IF(PyList_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE); STAT_INC(UNPACK_SEQUENCE, hit); @@ -1508,7 +1509,7 @@ for (int i = oparg; --i >= 0; ) { *values++ = Py_NewRef(items[i]); } - #line 1512 "Python/generated_cases.c.h" + #line 1513 "Python/generated_cases.c.h" Py_DECREF(seq); STACK_SHRINK(1); STACK_GROW(oparg); @@ -1518,15 +1519,15 @@ TARGET(UNPACK_EX) { PyObject *seq = stack_pointer[-1]; - #line 1103 "Python/bytecodes.c" + #line 1104 "Python/bytecodes.c" int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8); PyObject **top = stack_pointer + totalargs - 1; int res = unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top); - #line 1526 "Python/generated_cases.c.h" + #line 1527 "Python/generated_cases.c.h" Py_DECREF(seq); - #line 1107 "Python/bytecodes.c" + #line 1108 "Python/bytecodes.c" if (res == 0) goto pop_1_error; - #line 1530 "Python/generated_cases.c.h" + #line 1531 "Python/generated_cases.c.h" STACK_GROW((oparg & 0xFF) + (oparg >> 8)); DISPATCH(); } @@ -1537,7 +1538,7 @@ PyObject *owner = stack_pointer[-1]; PyObject *v = stack_pointer[-2]; uint16_t counter = read_u16(&next_instr[0].cache); - #line 1118 "Python/bytecodes.c" + #line 1119 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION if (ADAPTIVE_COUNTER_IS_ZERO(counter)) { PyObject *name = GETITEM(frame->f_code->co_names, oparg); @@ -1553,12 +1554,12 @@ #endif /* ENABLE_SPECIALIZATION */ PyObject *name = GETITEM(frame->f_code->co_names, oparg); int err = PyObject_SetAttr(owner, name, v); - #line 1557 "Python/generated_cases.c.h" + #line 1558 "Python/generated_cases.c.h" Py_DECREF(v); Py_DECREF(owner); - #line 1134 "Python/bytecodes.c" + #line 1135 "Python/bytecodes.c" if (err) goto pop_2_error; - #line 1562 "Python/generated_cases.c.h" + #line 1563 "Python/generated_cases.c.h" STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -1566,34 +1567,34 @@ TARGET(DELETE_ATTR) { PyObject *owner = stack_pointer[-1]; - #line 1138 "Python/bytecodes.c" + #line 1139 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); int err = PyObject_SetAttr(owner, name, (PyObject *)NULL); - #line 1573 "Python/generated_cases.c.h" + #line 1574 "Python/generated_cases.c.h" Py_DECREF(owner); - #line 1141 "Python/bytecodes.c" + #line 1142 "Python/bytecodes.c" if (err) goto pop_1_error; - #line 1577 "Python/generated_cases.c.h" + #line 1578 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(STORE_GLOBAL) { PyObject *v = stack_pointer[-1]; - #line 1145 "Python/bytecodes.c" + #line 1146 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); int err = PyDict_SetItem(GLOBALS(), name, v); - #line 1587 "Python/generated_cases.c.h" + #line 1588 "Python/generated_cases.c.h" Py_DECREF(v); - #line 1148 "Python/bytecodes.c" + #line 1149 "Python/bytecodes.c" if (err) goto pop_1_error; - #line 1591 "Python/generated_cases.c.h" + #line 1592 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(DELETE_GLOBAL) { - #line 1152 "Python/bytecodes.c" + #line 1153 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); int err; err = PyDict_DelItem(GLOBALS(), name); @@ -1605,13 +1606,13 @@ } goto error; } - #line 1609 "Python/generated_cases.c.h" + #line 1610 "Python/generated_cases.c.h" DISPATCH(); } TARGET(LOAD_NAME) { PyObject *v; - #line 1166 "Python/bytecodes.c" + #line 1167 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); PyObject *locals = LOCALS(); if (locals == NULL) { @@ -1670,7 +1671,7 @@ } } } - #line 1674 "Python/generated_cases.c.h" + #line 1675 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = v; DISPATCH(); @@ -1681,7 +1682,7 @@ static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size"); PyObject *null = NULL; PyObject *v; - #line 1233 "Python/bytecodes.c" + #line 1234 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -1733,7 +1734,7 @@ } } null = NULL; - #line 1737 "Python/generated_cases.c.h" + #line 1738 "Python/generated_cases.c.h" STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = v; @@ -1747,7 +1748,7 @@ PyObject *res; uint16_t index = read_u16(&next_instr[1].cache); uint16_t version = read_u16(&next_instr[2].cache); - #line 1287 "Python/bytecodes.c" + #line 1288 "Python/bytecodes.c" DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); PyDictObject *dict = (PyDictObject *)GLOBALS(); DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL); @@ -1758,7 +1759,7 @@ Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; - #line 1762 "Python/generated_cases.c.h" + #line 1763 "Python/generated_cases.c.h" STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -1773,7 +1774,7 @@ uint16_t index = read_u16(&next_instr[1].cache); uint16_t mod_version = read_u16(&next_instr[2].cache); uint16_t bltn_version = read_u16(&next_instr[3].cache); - #line 1300 "Python/bytecodes.c" + #line 1301 "Python/bytecodes.c" DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL); DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL); PyDictObject *mdict = (PyDictObject *)GLOBALS(); @@ -1788,7 +1789,7 @@ Py_INCREF(res); STAT_INC(LOAD_GLOBAL, hit); null = NULL; - #line 1792 "Python/generated_cases.c.h" + #line 1793 "Python/generated_cases.c.h" STACK_GROW(1); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -1798,16 +1799,16 @@ } TARGET(DELETE_FAST) { - #line 1317 "Python/bytecodes.c" + #line 1318 "Python/bytecodes.c" PyObject *v = GETLOCAL(oparg); if (v == NULL) goto unbound_local_error; SETLOCAL(oparg, NULL); - #line 1806 "Python/generated_cases.c.h" + #line 1807 "Python/generated_cases.c.h" DISPATCH(); } TARGET(MAKE_CELL) { - #line 1323 "Python/bytecodes.c" + #line 1324 "Python/bytecodes.c" // "initial" is probably NULL but not if it's an arg (or set // via PyFrame_LocalsToFast() before MAKE_CELL has run). PyObject *initial = GETLOCAL(oparg); @@ -1816,12 +1817,12 @@ goto resume_with_error; } SETLOCAL(oparg, cell); - #line 1820 "Python/generated_cases.c.h" + #line 1821 "Python/generated_cases.c.h" DISPATCH(); } TARGET(DELETE_DEREF) { - #line 1334 "Python/bytecodes.c" + #line 1335 "Python/bytecodes.c" PyObject *cell = GETLOCAL(oparg); PyObject *oldobj = PyCell_GET(cell); // Can't use ERROR_IF here. @@ -1832,13 +1833,13 @@ } PyCell_SET(cell, NULL); Py_DECREF(oldobj); - #line 1836 "Python/generated_cases.c.h" + #line 1837 "Python/generated_cases.c.h" DISPATCH(); } TARGET(LOAD_CLASSDEREF) { PyObject *value; - #line 1347 "Python/bytecodes.c" + #line 1348 "Python/bytecodes.c" PyObject *name, *locals = LOCALS(); assert(locals); assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus); @@ -1870,7 +1871,7 @@ } Py_INCREF(value); } - #line 1874 "Python/generated_cases.c.h" + #line 1875 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = value; DISPATCH(); @@ -1878,7 +1879,7 @@ TARGET(LOAD_DEREF) { PyObject *value; - #line 1381 "Python/bytecodes.c" + #line 1382 "Python/bytecodes.c" PyObject *cell = GETLOCAL(oparg); value = PyCell_GET(cell); if (value == NULL) { @@ -1886,7 +1887,7 @@ if (true) goto error; } Py_INCREF(value); - #line 1890 "Python/generated_cases.c.h" + #line 1891 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = value; DISPATCH(); @@ -1894,18 +1895,18 @@ TARGET(STORE_DEREF) { PyObject *v = stack_pointer[-1]; - #line 1391 "Python/bytecodes.c" + #line 1392 "Python/bytecodes.c" PyObject *cell = GETLOCAL(oparg); PyObject *oldobj = PyCell_GET(cell); PyCell_SET(cell, v); Py_XDECREF(oldobj); - #line 1903 "Python/generated_cases.c.h" + #line 1904 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(COPY_FREE_VARS) { - #line 1398 "Python/bytecodes.c" + #line 1399 "Python/bytecodes.c" /* Copy closure variables to free variables */ PyCodeObject *co = frame->f_code; assert(PyFunction_Check(frame->f_funcobj)); @@ -1916,22 +1917,22 @@ PyObject *o = PyTuple_GET_ITEM(closure, i); frame->localsplus[offset + i] = Py_NewRef(o); } - #line 1920 "Python/generated_cases.c.h" + #line 1921 "Python/generated_cases.c.h" DISPATCH(); } TARGET(BUILD_STRING) { PyObject **pieces = (stack_pointer - oparg); PyObject *str; - #line 1411 "Python/bytecodes.c" + #line 1412 "Python/bytecodes.c" str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg); - #line 1929 "Python/generated_cases.c.h" + #line 1930 "Python/generated_cases.c.h" for (int _i = oparg; --_i >= 0;) { Py_DECREF(pieces[_i]); } - #line 1413 "Python/bytecodes.c" + #line 1414 "Python/bytecodes.c" if (str == NULL) { STACK_SHRINK(oparg); goto error; } - #line 1935 "Python/generated_cases.c.h" + #line 1936 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = str; @@ -1941,10 +1942,10 @@ TARGET(BUILD_TUPLE) { PyObject **values = (stack_pointer - oparg); PyObject *tup; - #line 1417 "Python/bytecodes.c" + #line 1418 "Python/bytecodes.c" tup = _PyTuple_FromArraySteal(values, oparg); if (tup == NULL) { STACK_SHRINK(oparg); goto error; } - #line 1948 "Python/generated_cases.c.h" + #line 1949 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = tup; @@ -1954,10 +1955,10 @@ TARGET(BUILD_LIST) { PyObject **values = (stack_pointer - oparg); PyObject *list; - #line 1422 "Python/bytecodes.c" + #line 1423 "Python/bytecodes.c" list = _PyList_FromArraySteal(values, oparg); if (list == NULL) { STACK_SHRINK(oparg); goto error; } - #line 1961 "Python/generated_cases.c.h" + #line 1962 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = list; @@ -1967,7 +1968,7 @@ TARGET(LIST_EXTEND) { PyObject *iterable = stack_pointer[-1]; PyObject *list = stack_pointer[-(2 + (oparg-1))]; - #line 1427 "Python/bytecodes.c" + #line 1428 "Python/bytecodes.c" PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); if (none_val == NULL) { if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && @@ -1978,13 +1979,13 @@ "Value after * must be an iterable, not %.200s", Py_TYPE(iterable)->tp_name); } - #line 1982 "Python/generated_cases.c.h" + #line 1983 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 1438 "Python/bytecodes.c" + #line 1439 "Python/bytecodes.c" if (true) goto pop_1_error; } Py_DECREF(none_val); - #line 1988 "Python/generated_cases.c.h" + #line 1989 "Python/generated_cases.c.h" Py_DECREF(iterable); STACK_SHRINK(1); DISPATCH(); @@ -1993,13 +1994,13 @@ TARGET(SET_UPDATE) { PyObject *iterable = stack_pointer[-1]; PyObject *set = stack_pointer[-(2 + (oparg-1))]; - #line 1445 "Python/bytecodes.c" + #line 1446 "Python/bytecodes.c" int err = _PySet_Update(set, iterable); - #line 1999 "Python/generated_cases.c.h" + #line 2000 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 1447 "Python/bytecodes.c" + #line 1448 "Python/bytecodes.c" if (err < 0) goto pop_1_error; - #line 2003 "Python/generated_cases.c.h" + #line 2004 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } @@ -2007,7 +2008,7 @@ TARGET(BUILD_SET) { PyObject **values = (stack_pointer - oparg); PyObject *set; - #line 1451 "Python/bytecodes.c" + #line 1452 "Python/bytecodes.c" set = PySet_New(NULL); if (set == NULL) goto error; @@ -2022,7 +2023,7 @@ Py_DECREF(set); if (true) { STACK_SHRINK(oparg); goto error; } } - #line 2026 "Python/generated_cases.c.h" + #line 2027 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_GROW(1); stack_pointer[-1] = set; @@ -2032,7 +2033,7 @@ TARGET(BUILD_MAP) { PyObject **values = (stack_pointer - oparg*2); PyObject *map; - #line 1468 "Python/bytecodes.c" + #line 1469 "Python/bytecodes.c" map = _PyDict_FromItems( values, 2, values+1, 2, @@ -2040,13 +2041,13 @@ if (map == NULL) goto error; - #line 2044 "Python/generated_cases.c.h" + #line 2045 "Python/generated_cases.c.h" for (int _i = oparg*2; --_i >= 0;) { Py_DECREF(values[_i]); } - #line 1476 "Python/bytecodes.c" + #line 1477 "Python/bytecodes.c" if (map == NULL) { STACK_SHRINK(oparg*2); goto error; } - #line 2050 "Python/generated_cases.c.h" + #line 2051 "Python/generated_cases.c.h" STACK_SHRINK(oparg*2); STACK_GROW(1); stack_pointer[-1] = map; @@ -2054,7 +2055,7 @@ } TARGET(SETUP_ANNOTATIONS) { - #line 1480 "Python/bytecodes.c" + #line 1481 "Python/bytecodes.c" int err; PyObject *ann_dict; if (LOCALS() == NULL) { @@ -2094,7 +2095,7 @@ Py_DECREF(ann_dict); } } - #line 2098 "Python/generated_cases.c.h" + #line 2099 "Python/generated_cases.c.h" DISPATCH(); } @@ -2102,7 +2103,7 @@ PyObject *keys = stack_pointer[-1]; PyObject **values = (stack_pointer - (1 + oparg)); PyObject *map; - #line 1522 "Python/bytecodes.c" + #line 1523 "Python/bytecodes.c" if (!PyTuple_CheckExact(keys) || PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) { _PyErr_SetString(tstate, PyExc_SystemError, @@ -2112,14 +2113,14 @@ map = _PyDict_FromItems( &PyTuple_GET_ITEM(keys, 0), 1, values, 1, oparg); - #line 2116 "Python/generated_cases.c.h" + #line 2117 "Python/generated_cases.c.h" for (int _i = oparg; --_i >= 0;) { Py_DECREF(values[_i]); } Py_DECREF(keys); - #line 1532 "Python/bytecodes.c" + #line 1533 "Python/bytecodes.c" if (map == NULL) { STACK_SHRINK(oparg); goto pop_1_error; } - #line 2123 "Python/generated_cases.c.h" + #line 2124 "Python/generated_cases.c.h" STACK_SHRINK(oparg); stack_pointer[-1] = map; DISPATCH(); @@ -2127,7 +2128,7 @@ TARGET(DICT_UPDATE) { PyObject *update = stack_pointer[-1]; - #line 1536 "Python/bytecodes.c" + #line 1537 "Python/bytecodes.c" PyObject *dict = PEEK(oparg + 1); // update is still on the stack if (PyDict_Update(dict, update) < 0) { if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) { @@ -2135,12 +2136,12 @@ "'%.200s' object is not a mapping", Py_TYPE(update)->tp_name); } - #line 2139 "Python/generated_cases.c.h" + #line 2140 "Python/generated_cases.c.h" Py_DECREF(update); - #line 1544 "Python/bytecodes.c" + #line 1545 "Python/bytecodes.c" if (true) goto pop_1_error; } - #line 2144 "Python/generated_cases.c.h" + #line 2145 "Python/generated_cases.c.h" Py_DECREF(update); STACK_SHRINK(1); DISPATCH(); @@ -2148,17 +2149,17 @@ TARGET(DICT_MERGE) { PyObject *update = stack_pointer[-1]; - #line 1550 "Python/bytecodes.c" + #line 1551 "Python/bytecodes.c" PyObject *dict = PEEK(oparg + 1); // update is still on the stack if (_PyDict_MergeEx(dict, update, 2) < 0) { format_kwargs_error(tstate, PEEK(3 + oparg), update); - #line 2157 "Python/generated_cases.c.h" + #line 2158 "Python/generated_cases.c.h" Py_DECREF(update); - #line 1555 "Python/bytecodes.c" + #line 1556 "Python/bytecodes.c" if (true) goto pop_1_error; } - #line 2162 "Python/generated_cases.c.h" + #line 2163 "Python/generated_cases.c.h" Py_DECREF(update); STACK_SHRINK(1); PREDICT(CALL_FUNCTION_EX); @@ -2168,13 +2169,13 @@ TARGET(MAP_ADD) { PyObject *value = stack_pointer[-1]; PyObject *key = stack_pointer[-2]; - #line 1562 "Python/bytecodes.c" + #line 1563 "Python/bytecodes.c" PyObject *dict = PEEK(oparg + 2); // key, value are still on the stack assert(PyDict_CheckExact(dict)); /* dict[key] = value */ // Do not DECREF INPUTS because the function steals the references if (_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0) goto pop_2_error; - #line 2178 "Python/generated_cases.c.h" + #line 2179 "Python/generated_cases.c.h" STACK_SHRINK(2); PREDICT(JUMP_BACKWARD); DISPATCH(); @@ -2188,7 +2189,7 @@ PyObject *global_super = stack_pointer[-3]; PyObject *res2 = NULL; PyObject *res; - #line 1576 "Python/bytecodes.c" + #line 1577 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2); int load_method = oparg & 1; #if ENABLE_SPECIALIZATION @@ -2206,16 +2207,16 @@ // handle any case whose performance we care about PyObject *stack[] = {class, self}; PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL); - #line 2210 "Python/generated_cases.c.h" + #line 2211 "Python/generated_cases.c.h" Py_DECREF(global_super); Py_DECREF(class); Py_DECREF(self); - #line 1594 "Python/bytecodes.c" + #line 1595 "Python/bytecodes.c" if (super == NULL) goto pop_3_error; res = PyObject_GetAttr(super, name); Py_DECREF(super); if (res == NULL) goto pop_3_error; - #line 2219 "Python/generated_cases.c.h" + #line 2220 "Python/generated_cases.c.h" STACK_SHRINK(2); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2233,7 +2234,7 @@ uint32_t class_version = read_u32(&next_instr[1].cache); uint32_t self_type_version = read_u32(&next_instr[3].cache); PyObject *method = read_obj(&next_instr[5].cache); - #line 1601 "Python/bytecodes.c" + #line 1602 "Python/bytecodes.c" DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR); DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR); DEOPT_IF(((PyTypeObject *)class)->tp_version_tag != class_version, LOAD_SUPER_ATTR); @@ -2244,7 +2245,7 @@ Py_INCREF(res2); Py_DECREF(global_super); Py_DECREF(class); - #line 2248 "Python/generated_cases.c.h" + #line 2249 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; stack_pointer[-2] = res2; @@ -2258,7 +2259,7 @@ PyObject *owner = stack_pointer[-1]; PyObject *res2 = NULL; PyObject *res; - #line 1628 "Python/bytecodes.c" + #line 1629 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyAttrCache *cache = (_PyAttrCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -2292,9 +2293,9 @@ NULL | meth | arg1 | ... | argN */ - #line 2296 "Python/generated_cases.c.h" + #line 2297 "Python/generated_cases.c.h" Py_DECREF(owner); - #line 1662 "Python/bytecodes.c" + #line 1663 "Python/bytecodes.c" if (meth == NULL) goto pop_1_error; res2 = NULL; res = meth; @@ -2303,12 +2304,12 @@ else { /* Classic, pushes one value. */ res = PyObject_GetAttr(owner, name); - #line 2307 "Python/generated_cases.c.h" + #line 2308 "Python/generated_cases.c.h" Py_DECREF(owner); - #line 1671 "Python/bytecodes.c" + #line 1672 "Python/bytecodes.c" if (res == NULL) goto pop_1_error; } - #line 2312 "Python/generated_cases.c.h" + #line 2313 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -2322,7 +2323,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1676 "Python/bytecodes.c" + #line 1677 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); @@ -2335,7 +2336,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2339 "Python/generated_cases.c.h" + #line 2340 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2350,7 +2351,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1692 "Python/bytecodes.c" + #line 1693 "Python/bytecodes.c" DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR); PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict; assert(dict != NULL); @@ -2363,7 +2364,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2367 "Python/generated_cases.c.h" + #line 2368 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2378,7 +2379,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1708 "Python/bytecodes.c" + #line 1709 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); @@ -2405,7 +2406,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2409 "Python/generated_cases.c.h" + #line 2410 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2420,7 +2421,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1738 "Python/bytecodes.c" + #line 1739 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR); @@ -2430,7 +2431,7 @@ STAT_INC(LOAD_ATTR, hit); Py_INCREF(res); res2 = NULL; - #line 2434 "Python/generated_cases.c.h" + #line 2435 "Python/generated_cases.c.h" Py_DECREF(owner); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2445,7 +2446,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 1751 "Python/bytecodes.c" + #line 1752 "Python/bytecodes.c" DEOPT_IF(!PyType_Check(cls), LOAD_ATTR); DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version, @@ -2457,7 +2458,7 @@ res = descr; assert(res != NULL); Py_INCREF(res); - #line 2461 "Python/generated_cases.c.h" + #line 2462 "Python/generated_cases.c.h" Py_DECREF(cls); STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; @@ -2471,7 +2472,7 @@ uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t func_version = read_u32(&next_instr[3].cache); PyObject *fget = read_obj(&next_instr[5].cache); - #line 1766 "Python/bytecodes.c" + #line 1767 "Python/bytecodes.c" DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); PyTypeObject *cls = Py_TYPE(owner); @@ -2495,7 +2496,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 2499 "Python/generated_cases.c.h" + #line 2500 "Python/generated_cases.c.h" } TARGET(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) { @@ -2503,7 +2504,7 @@ uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t func_version = read_u32(&next_instr[3].cache); PyObject *getattribute = read_obj(&next_instr[5].cache); - #line 1792 "Python/bytecodes.c" + #line 1793 "Python/bytecodes.c" DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR); PyTypeObject *cls = Py_TYPE(owner); DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR); @@ -2529,7 +2530,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 2533 "Python/generated_cases.c.h" + #line 2534 "Python/generated_cases.c.h" } TARGET(STORE_ATTR_INSTANCE_VALUE) { @@ -2537,7 +2538,7 @@ PyObject *value = stack_pointer[-2]; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1820 "Python/bytecodes.c" + #line 1821 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); @@ -2555,7 +2556,7 @@ Py_DECREF(old_value); } Py_DECREF(owner); - #line 2559 "Python/generated_cases.c.h" + #line 2560 "Python/generated_cases.c.h" STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -2566,7 +2567,7 @@ PyObject *value = stack_pointer[-2]; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t hint = read_u16(&next_instr[3].cache); - #line 1840 "Python/bytecodes.c" + #line 1841 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); @@ -2605,7 +2606,7 @@ /* PEP 509 */ dict->ma_version_tag = new_version; Py_DECREF(owner); - #line 2609 "Python/generated_cases.c.h" + #line 2610 "Python/generated_cases.c.h" STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -2616,7 +2617,7 @@ PyObject *value = stack_pointer[-2]; uint32_t type_version = read_u32(&next_instr[1].cache); uint16_t index = read_u16(&next_instr[3].cache); - #line 1881 "Python/bytecodes.c" + #line 1882 "Python/bytecodes.c" PyTypeObject *tp = Py_TYPE(owner); assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); @@ -2626,7 +2627,7 @@ *(PyObject **)addr = value; Py_XDECREF(old_value); Py_DECREF(owner); - #line 2630 "Python/generated_cases.c.h" + #line 2631 "Python/generated_cases.c.h" STACK_SHRINK(2); next_instr += 4; DISPATCH(); @@ -2638,7 +2639,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 1900 "Python/bytecodes.c" + #line 1901 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -2651,12 +2652,12 @@ #endif /* ENABLE_SPECIALIZATION */ assert((oparg >> 4) <= Py_GE); res = PyObject_RichCompare(left, right, oparg>>4); - #line 2655 "Python/generated_cases.c.h" + #line 2656 "Python/generated_cases.c.h" Py_DECREF(left); Py_DECREF(right); - #line 1913 "Python/bytecodes.c" + #line 1914 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 2660 "Python/generated_cases.c.h" + #line 2661 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2667,7 +2668,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 1917 "Python/bytecodes.c" + #line 1918 "Python/bytecodes.c" DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP); STAT_INC(COMPARE_OP, hit); @@ -2679,7 +2680,7 @@ _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc); res = (sign_ish & oparg) ? Py_True : Py_False; Py_INCREF(res); - #line 2683 "Python/generated_cases.c.h" + #line 2684 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2690,7 +2691,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 1932 "Python/bytecodes.c" + #line 1933 "Python/bytecodes.c" DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyLong_CheckExact(right), COMPARE_OP); DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left), COMPARE_OP); @@ -2706,7 +2707,7 @@ _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free); res = (sign_ish & oparg) ? Py_True : Py_False; Py_INCREF(res); - #line 2710 "Python/generated_cases.c.h" + #line 2711 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2717,7 +2718,7 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *res; - #line 1951 "Python/bytecodes.c" + #line 1952 "Python/bytecodes.c" DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP); DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP); STAT_INC(COMPARE_OP, hit); @@ -2730,7 +2731,7 @@ assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS); res = ((COMPARISON_NOT_EQUALS + eq) & oparg) ? Py_True : Py_False; Py_INCREF(res); - #line 2734 "Python/generated_cases.c.h" + #line 2735 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -2741,14 +2742,14 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *b; - #line 1966 "Python/bytecodes.c" + #line 1967 "Python/bytecodes.c" int res = Py_Is(left, right) ^ oparg; - #line 2747 "Python/generated_cases.c.h" + #line 2748 "Python/generated_cases.c.h" Py_DECREF(left); Py_DECREF(right); - #line 1968 "Python/bytecodes.c" + #line 1969 "Python/bytecodes.c" b = Py_NewRef(res ? Py_True : Py_False); - #line 2752 "Python/generated_cases.c.h" + #line 2753 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = b; DISPATCH(); @@ -2758,15 +2759,15 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *b; - #line 1972 "Python/bytecodes.c" + #line 1973 "Python/bytecodes.c" int res = PySequence_Contains(right, left); - #line 2764 "Python/generated_cases.c.h" + #line 2765 "Python/generated_cases.c.h" Py_DECREF(left); Py_DECREF(right); - #line 1974 "Python/bytecodes.c" + #line 1975 "Python/bytecodes.c" if (res < 0) goto pop_2_error; b = Py_NewRef((res^oparg) ? Py_True : Py_False); - #line 2770 "Python/generated_cases.c.h" + #line 2771 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = b; DISPATCH(); @@ -2777,12 +2778,12 @@ PyObject *exc_value = stack_pointer[-2]; PyObject *rest; PyObject *match; - #line 1979 "Python/bytecodes.c" + #line 1980 "Python/bytecodes.c" if (check_except_star_type_valid(tstate, match_type) < 0) { - #line 2783 "Python/generated_cases.c.h" + #line 2784 "Python/generated_cases.c.h" Py_DECREF(exc_value); Py_DECREF(match_type); - #line 1981 "Python/bytecodes.c" + #line 1982 "Python/bytecodes.c" if (true) goto pop_2_error; } @@ -2790,10 +2791,10 @@ rest = NULL; int res = exception_group_match(exc_value, match_type, &match, &rest); - #line 2794 "Python/generated_cases.c.h" + #line 2795 "Python/generated_cases.c.h" Py_DECREF(exc_value); Py_DECREF(match_type); - #line 1989 "Python/bytecodes.c" + #line 1990 "Python/bytecodes.c" if (res < 0) goto pop_2_error; assert((match == NULL) == (rest == NULL)); @@ -2802,7 +2803,7 @@ if (!Py_IsNone(match)) { PyErr_SetHandledException(match); } - #line 2806 "Python/generated_cases.c.h" + #line 2807 "Python/generated_cases.c.h" stack_pointer[-1] = match; stack_pointer[-2] = rest; DISPATCH(); @@ -2812,21 +2813,21 @@ PyObject *right = stack_pointer[-1]; PyObject *left = stack_pointer[-2]; PyObject *b; - #line 2000 "Python/bytecodes.c" + #line 2001 "Python/bytecodes.c" assert(PyExceptionInstance_Check(left)); if (check_except_type_valid(tstate, right) < 0) { - #line 2819 "Python/generated_cases.c.h" + #line 2820 "Python/generated_cases.c.h" Py_DECREF(right); - #line 2003 "Python/bytecodes.c" + #line 2004 "Python/bytecodes.c" if (true) goto pop_1_error; } int res = PyErr_GivenExceptionMatches(left, right); - #line 2826 "Python/generated_cases.c.h" + #line 2827 "Python/generated_cases.c.h" Py_DECREF(right); - #line 2008 "Python/bytecodes.c" + #line 2009 "Python/bytecodes.c" b = Py_NewRef(res ? Py_True : Py_False); - #line 2830 "Python/generated_cases.c.h" + #line 2831 "Python/generated_cases.c.h" stack_pointer[-1] = b; DISPATCH(); } @@ -2835,15 +2836,15 @@ PyObject *fromlist = stack_pointer[-1]; PyObject *level = stack_pointer[-2]; PyObject *res; - #line 2012 "Python/bytecodes.c" + #line 2013 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); res = import_name(tstate, frame, name, fromlist, level); - #line 2842 "Python/generated_cases.c.h" + #line 2843 "Python/generated_cases.c.h" Py_DECREF(level); Py_DECREF(fromlist); - #line 2015 "Python/bytecodes.c" + #line 2016 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 2847 "Python/generated_cases.c.h" + #line 2848 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; DISPATCH(); @@ -2852,29 +2853,29 @@ TARGET(IMPORT_FROM) { PyObject *from = stack_pointer[-1]; PyObject *res; - #line 2019 "Python/bytecodes.c" + #line 2020 "Python/bytecodes.c" PyObject *name = GETITEM(frame->f_code->co_names, oparg); res = import_from(tstate, from, name); if (res == NULL) goto error; - #line 2860 "Python/generated_cases.c.h" + #line 2861 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; DISPATCH(); } TARGET(JUMP_FORWARD) { - #line 2025 "Python/bytecodes.c" + #line 2026 "Python/bytecodes.c" JUMPBY(oparg); - #line 2869 "Python/generated_cases.c.h" + #line 2870 "Python/generated_cases.c.h" DISPATCH(); } TARGET(JUMP_BACKWARD) { PREDICTED(JUMP_BACKWARD); - #line 2029 "Python/bytecodes.c" + #line 2030 "Python/bytecodes.c" assert(oparg < INSTR_OFFSET()); JUMPBY(-oparg); - #line 2878 "Python/generated_cases.c.h" + #line 2879 "Python/generated_cases.c.h" CHECK_EVAL_BREAKER(); DISPATCH(); } @@ -2882,7 +2883,7 @@ TARGET(POP_JUMP_IF_FALSE) { PREDICTED(POP_JUMP_IF_FALSE); PyObject *cond = stack_pointer[-1]; - #line 2035 "Python/bytecodes.c" + #line 2036 "Python/bytecodes.c" if (Py_IsTrue(cond)) { _Py_DECREF_NO_DEALLOC(cond); } @@ -2892,9 +2893,9 @@ } else { int err = PyObject_IsTrue(cond); - #line 2896 "Python/generated_cases.c.h" + #line 2897 "Python/generated_cases.c.h" Py_DECREF(cond); - #line 2045 "Python/bytecodes.c" + #line 2046 "Python/bytecodes.c" if (err == 0) { JUMPBY(oparg); } @@ -2902,14 +2903,14 @@ if (err < 0) goto pop_1_error; } } - #line 2906 "Python/generated_cases.c.h" + #line 2907 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_TRUE) { PyObject *cond = stack_pointer[-1]; - #line 2055 "Python/bytecodes.c" + #line 2056 "Python/bytecodes.c" if (Py_IsFalse(cond)) { _Py_DECREF_NO_DEALLOC(cond); } @@ -2919,9 +2920,9 @@ } else { int err = PyObject_IsTrue(cond); - #line 2923 "Python/generated_cases.c.h" + #line 2924 "Python/generated_cases.c.h" Py_DECREF(cond); - #line 2065 "Python/bytecodes.c" + #line 2066 "Python/bytecodes.c" if (err > 0) { JUMPBY(oparg); } @@ -2929,67 +2930,67 @@ if (err < 0) goto pop_1_error; } } - #line 2933 "Python/generated_cases.c.h" + #line 2934 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_NOT_NONE) { PyObject *value = stack_pointer[-1]; - #line 2075 "Python/bytecodes.c" + #line 2076 "Python/bytecodes.c" if (!Py_IsNone(value)) { - #line 2942 "Python/generated_cases.c.h" + #line 2943 "Python/generated_cases.c.h" Py_DECREF(value); - #line 2077 "Python/bytecodes.c" + #line 2078 "Python/bytecodes.c" JUMPBY(oparg); } else { _Py_DECREF_NO_DEALLOC(value); } - #line 2950 "Python/generated_cases.c.h" + #line 2951 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(POP_JUMP_IF_NONE) { PyObject *value = stack_pointer[-1]; - #line 2085 "Python/bytecodes.c" + #line 2086 "Python/bytecodes.c" if (Py_IsNone(value)) { _Py_DECREF_NO_DEALLOC(value); JUMPBY(oparg); } else { - #line 2963 "Python/generated_cases.c.h" + #line 2964 "Python/generated_cases.c.h" Py_DECREF(value); - #line 2091 "Python/bytecodes.c" + #line 2092 "Python/bytecodes.c" } - #line 2967 "Python/generated_cases.c.h" + #line 2968 "Python/generated_cases.c.h" STACK_SHRINK(1); DISPATCH(); } TARGET(JUMP_BACKWARD_NO_INTERRUPT) { - #line 2095 "Python/bytecodes.c" + #line 2096 "Python/bytecodes.c" /* This bytecode is used in the `yield from` or `await` loop. * If there is an interrupt, we want it handled in the innermost * generator or coroutine, so we deliberately do not check it here. * (see bpo-30039). */ JUMPBY(-oparg); - #line 2980 "Python/generated_cases.c.h" + #line 2981 "Python/generated_cases.c.h" DISPATCH(); } TARGET(GET_LEN) { PyObject *obj = stack_pointer[-1]; PyObject *len_o; - #line 2104 "Python/bytecodes.c" + #line 2105 "Python/bytecodes.c" // PUSH(len(TOS)) Py_ssize_t len_i = PyObject_Length(obj); if (len_i < 0) goto error; len_o = PyLong_FromSsize_t(len_i); if (len_o == NULL) goto error; - #line 2993 "Python/generated_cases.c.h" + #line 2994 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = len_o; DISPATCH(); @@ -3000,16 +3001,16 @@ PyObject *type = stack_pointer[-2]; PyObject *subject = stack_pointer[-3]; PyObject *attrs; - #line 2112 "Python/bytecodes.c" + #line 2113 "Python/bytecodes.c" // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or // None on failure. assert(PyTuple_CheckExact(names)); attrs = match_class(tstate, subject, type, oparg, names); - #line 3009 "Python/generated_cases.c.h" + #line 3010 "Python/generated_cases.c.h" Py_DECREF(subject); Py_DECREF(type); Py_DECREF(names); - #line 2117 "Python/bytecodes.c" + #line 2118 "Python/bytecodes.c" if (attrs) { assert(PyTuple_CheckExact(attrs)); // Success! } @@ -3017,7 +3018,7 @@ if (_PyErr_Occurred(tstate)) goto pop_3_error; attrs = Py_NewRef(Py_None); // Failure! } - #line 3021 "Python/generated_cases.c.h" + #line 3022 "Python/generated_cases.c.h" STACK_SHRINK(2); stack_pointer[-1] = attrs; DISPATCH(); @@ -3026,10 +3027,10 @@ TARGET(MATCH_MAPPING) { PyObject *subject = stack_pointer[-1]; PyObject *res; - #line 2127 "Python/bytecodes.c" + #line 2128 "Python/bytecodes.c" int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING; res = Py_NewRef(match ? Py_True : Py_False); - #line 3033 "Python/generated_cases.c.h" + #line 3034 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; PREDICT(POP_JUMP_IF_FALSE); @@ -3039,10 +3040,10 @@ TARGET(MATCH_SEQUENCE) { PyObject *subject = stack_pointer[-1]; PyObject *res; - #line 2133 "Python/bytecodes.c" + #line 2134 "Python/bytecodes.c" int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE; res = Py_NewRef(match ? Py_True : Py_False); - #line 3046 "Python/generated_cases.c.h" + #line 3047 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; PREDICT(POP_JUMP_IF_FALSE); @@ -3053,11 +3054,11 @@ PyObject *keys = stack_pointer[-1]; PyObject *subject = stack_pointer[-2]; PyObject *values_or_none; - #line 2139 "Python/bytecodes.c" + #line 2140 "Python/bytecodes.c" // On successful match, PUSH(values). Otherwise, PUSH(None). values_or_none = match_keys(tstate, subject, keys); if (values_or_none == NULL) goto error; - #line 3061 "Python/generated_cases.c.h" + #line 3062 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = values_or_none; DISPATCH(); @@ -3066,14 +3067,14 @@ TARGET(GET_ITER) { PyObject *iterable = stack_pointer[-1]; PyObject *iter; - #line 2145 "Python/bytecodes.c" + #line 2146 "Python/bytecodes.c" /* before: [obj]; after [getiter(obj)] */ iter = PyObject_GetIter(iterable); - #line 3073 "Python/generated_cases.c.h" + #line 3074 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 2148 "Python/bytecodes.c" + #line 2149 "Python/bytecodes.c" if (iter == NULL) goto pop_1_error; - #line 3077 "Python/generated_cases.c.h" + #line 3078 "Python/generated_cases.c.h" stack_pointer[-1] = iter; DISPATCH(); } @@ -3081,7 +3082,7 @@ TARGET(GET_YIELD_FROM_ITER) { PyObject *iterable = stack_pointer[-1]; PyObject *iter; - #line 2152 "Python/bytecodes.c" + #line 2153 "Python/bytecodes.c" /* before: [obj]; after [getiter(obj)] */ if (PyCoro_CheckExact(iterable)) { /* `iterable` is a coroutine */ @@ -3104,11 +3105,11 @@ if (iter == NULL) { goto error; } - #line 3108 "Python/generated_cases.c.h" + #line 3109 "Python/generated_cases.c.h" Py_DECREF(iterable); - #line 2175 "Python/bytecodes.c" + #line 2176 "Python/bytecodes.c" } - #line 3112 "Python/generated_cases.c.h" + #line 3113 "Python/generated_cases.c.h" stack_pointer[-1] = iter; PREDICT(LOAD_CONST); DISPATCH(); @@ -3119,7 +3120,7 @@ static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size"); PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2194 "Python/bytecodes.c" + #line 2195 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyForIterCache *cache = (_PyForIterCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -3150,7 +3151,7 @@ DISPATCH(); } // Common case: no jump, leave it to the code generator - #line 3154 "Python/generated_cases.c.h" + #line 3155 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3158,7 +3159,7 @@ } TARGET(INSTRUMENTED_FOR_ITER) { - #line 2227 "Python/bytecodes.c" + #line 2228 "Python/bytecodes.c" _Py_CODEUNIT *here = next_instr-1; _Py_CODEUNIT *target; PyObject *iter = TOP(); @@ -3184,14 +3185,14 @@ target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1; } INSTRUMENTED_JUMP(here, target, PY_MONITORING_EVENT_BRANCH); - #line 3188 "Python/generated_cases.c.h" + #line 3189 "Python/generated_cases.c.h" DISPATCH(); } TARGET(FOR_ITER_LIST) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2255 "Python/bytecodes.c" + #line 2256 "Python/bytecodes.c" DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER); _PyListIterObject *it = (_PyListIterObject *)iter; STAT_INC(FOR_ITER, hit); @@ -3211,7 +3212,7 @@ DISPATCH(); end_for_iter_list: // Common case: no jump, leave it to the code generator - #line 3215 "Python/generated_cases.c.h" + #line 3216 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3221,7 +3222,7 @@ TARGET(FOR_ITER_TUPLE) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2277 "Python/bytecodes.c" + #line 2278 "Python/bytecodes.c" _PyTupleIterObject *it = (_PyTupleIterObject *)iter; DEOPT_IF(Py_TYPE(it) != &PyTupleIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); @@ -3241,7 +3242,7 @@ DISPATCH(); end_for_iter_tuple: // Common case: no jump, leave it to the code generator - #line 3245 "Python/generated_cases.c.h" + #line 3246 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3251,7 +3252,7 @@ TARGET(FOR_ITER_RANGE) { PyObject *iter = stack_pointer[-1]; PyObject *next; - #line 2299 "Python/bytecodes.c" + #line 2300 "Python/bytecodes.c" _PyRangeIterObject *r = (_PyRangeIterObject *)iter; DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER); STAT_INC(FOR_ITER, hit); @@ -3269,7 +3270,7 @@ if (next == NULL) { goto error; } - #line 3273 "Python/generated_cases.c.h" + #line 3274 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = next; next_instr += 1; @@ -3278,7 +3279,7 @@ TARGET(FOR_ITER_GEN) { PyObject *iter = stack_pointer[-1]; - #line 2319 "Python/bytecodes.c" + #line 2320 "Python/bytecodes.c" PyGenObject *gen = (PyGenObject *)iter; DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER); DEOPT_IF(gen->gi_frame_state >= FRAME_EXECUTING, FOR_ITER); @@ -3293,14 +3294,14 @@ assert(next_instr[oparg].op.code == END_FOR || next_instr[oparg].op.code == INSTRUMENTED_END_FOR); DISPATCH_INLINED(gen_frame); - #line 3297 "Python/generated_cases.c.h" + #line 3298 "Python/generated_cases.c.h" } TARGET(BEFORE_ASYNC_WITH) { PyObject *mgr = stack_pointer[-1]; PyObject *exit; PyObject *res; - #line 2336 "Python/bytecodes.c" + #line 2337 "Python/bytecodes.c" PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__)); if (enter == NULL) { if (!_PyErr_Occurred(tstate)) { @@ -3323,16 +3324,16 @@ Py_DECREF(enter); goto error; } - #line 3327 "Python/generated_cases.c.h" + #line 3328 "Python/generated_cases.c.h" Py_DECREF(mgr); - #line 2359 "Python/bytecodes.c" + #line 2360 "Python/bytecodes.c" res = _PyObject_CallNoArgs(enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); if (true) goto pop_1_error; } - #line 3336 "Python/generated_cases.c.h" + #line 3337 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; stack_pointer[-2] = exit; @@ -3344,7 +3345,7 @@ PyObject *mgr = stack_pointer[-1]; PyObject *exit; PyObject *res; - #line 2369 "Python/bytecodes.c" + #line 2370 "Python/bytecodes.c" /* pop the context manager, push its __exit__ and the * value returned from calling its __enter__ */ @@ -3370,16 +3371,16 @@ Py_DECREF(enter); goto error; } - #line 3374 "Python/generated_cases.c.h" + #line 3375 "Python/generated_cases.c.h" Py_DECREF(mgr); - #line 2395 "Python/bytecodes.c" + #line 2396 "Python/bytecodes.c" res = _PyObject_CallNoArgs(enter); Py_DECREF(enter); if (res == NULL) { Py_DECREF(exit); if (true) goto pop_1_error; } - #line 3383 "Python/generated_cases.c.h" + #line 3384 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; stack_pointer[-2] = exit; @@ -3391,7 +3392,7 @@ PyObject *lasti = stack_pointer[-3]; PyObject *exit_func = stack_pointer[-4]; PyObject *res; - #line 2404 "Python/bytecodes.c" + #line 2405 "Python/bytecodes.c" /* At the top of the stack are 4 values: - val: TOP = exc_info() - unused: SECOND = previous exception @@ -3412,7 +3413,7 @@ res = PyObject_Vectorcall(exit_func, stack + 1, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); if (res == NULL) goto error; - #line 3416 "Python/generated_cases.c.h" + #line 3417 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = res; DISPATCH(); @@ -3421,7 +3422,7 @@ TARGET(PUSH_EXC_INFO) { PyObject *new_exc = stack_pointer[-1]; PyObject *prev_exc; - #line 2427 "Python/bytecodes.c" + #line 2428 "Python/bytecodes.c" _PyErr_StackItem *exc_info = tstate->exc_info; if (exc_info->exc_value != NULL) { prev_exc = exc_info->exc_value; @@ -3431,7 +3432,7 @@ } assert(PyExceptionInstance_Check(new_exc)); exc_info->exc_value = Py_NewRef(new_exc); - #line 3435 "Python/generated_cases.c.h" + #line 3436 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = new_exc; stack_pointer[-2] = prev_exc; @@ -3445,7 +3446,7 @@ uint32_t type_version = read_u32(&next_instr[1].cache); uint32_t keys_version = read_u32(&next_instr[3].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2439 "Python/bytecodes.c" + #line 2440 "Python/bytecodes.c" /* Cached method object */ PyTypeObject *self_cls = Py_TYPE(self); assert(type_version != 0); @@ -3462,7 +3463,7 @@ assert(_PyType_HasFeature(Py_TYPE(res2), Py_TPFLAGS_METHOD_DESCRIPTOR)); res = self; assert(oparg & 1); - #line 3466 "Python/generated_cases.c.h" + #line 3467 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3476,7 +3477,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2458 "Python/bytecodes.c" + #line 2459 "Python/bytecodes.c" PyTypeObject *self_cls = Py_TYPE(self); DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); assert(self_cls->tp_dictoffset == 0); @@ -3486,7 +3487,7 @@ res2 = Py_NewRef(descr); res = self; assert(oparg & 1); - #line 3490 "Python/generated_cases.c.h" + #line 3491 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3500,7 +3501,7 @@ PyObject *res; uint32_t type_version = read_u32(&next_instr[1].cache); PyObject *descr = read_obj(&next_instr[5].cache); - #line 2470 "Python/bytecodes.c" + #line 2471 "Python/bytecodes.c" PyTypeObject *self_cls = Py_TYPE(self); DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR); Py_ssize_t dictoffset = self_cls->tp_dictoffset; @@ -3514,7 +3515,7 @@ res2 = Py_NewRef(descr); res = self; assert(oparg & 1); - #line 3518 "Python/generated_cases.c.h" + #line 3519 "Python/generated_cases.c.h" STACK_GROW(((oparg & 1) ? 1 : 0)); stack_pointer[-1] = res; if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; } @@ -3523,16 +3524,16 @@ } TARGET(KW_NAMES) { - #line 2486 "Python/bytecodes.c" + #line 2487 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg < PyTuple_GET_SIZE(frame->f_code->co_consts)); kwnames = GETITEM(frame->f_code->co_consts, oparg); - #line 3531 "Python/generated_cases.c.h" + #line 3532 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_CALL) { - #line 2492 "Python/bytecodes.c" + #line 2493 "Python/bytecodes.c" int is_meth = PEEK(oparg+2) != NULL; int total_args = oparg + is_meth; PyObject *function = PEEK(total_args + 1); @@ -3545,7 +3546,7 @@ _PyCallCache *cache = (_PyCallCache *)next_instr; INCREMENT_ADAPTIVE_COUNTER(cache->counter); GO_TO_INSTRUCTION(CALL); - #line 3549 "Python/generated_cases.c.h" + #line 3550 "Python/generated_cases.c.h" } TARGET(CALL) { @@ -3555,7 +3556,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2537 "Python/bytecodes.c" + #line 2538 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -3637,7 +3638,7 @@ Py_DECREF(args[i]); } if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3641 "Python/generated_cases.c.h" + #line 3642 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3649,7 +3650,7 @@ TARGET(CALL_BOUND_METHOD_EXACT_ARGS) { PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; - #line 2625 "Python/bytecodes.c" + #line 2626 "Python/bytecodes.c" DEOPT_IF(method != NULL, CALL); DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL); STAT_INC(CALL, hit); @@ -3659,7 +3660,7 @@ PEEK(oparg + 2) = Py_NewRef(meth); // method Py_DECREF(callable); GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS); - #line 3663 "Python/generated_cases.c.h" + #line 3664 "Python/generated_cases.c.h" } TARGET(CALL_PY_EXACT_ARGS) { @@ -3668,7 +3669,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; uint32_t func_version = read_u32(&next_instr[1].cache); - #line 2637 "Python/bytecodes.c" + #line 2638 "Python/bytecodes.c" assert(kwnames == NULL); DEOPT_IF(tstate->interp->eval_frame, CALL); int is_meth = method != NULL; @@ -3694,7 +3695,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 3698 "Python/generated_cases.c.h" + #line 3699 "Python/generated_cases.c.h" } TARGET(CALL_PY_WITH_DEFAULTS) { @@ -3702,7 +3703,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; uint32_t func_version = read_u32(&next_instr[1].cache); - #line 2665 "Python/bytecodes.c" + #line 2666 "Python/bytecodes.c" assert(kwnames == NULL); DEOPT_IF(tstate->interp->eval_frame, CALL); int is_meth = method != NULL; @@ -3738,7 +3739,7 @@ JUMPBY(INLINE_CACHE_ENTRIES_CALL); frame->return_offset = 0; DISPATCH_INLINED(new_frame); - #line 3742 "Python/generated_cases.c.h" + #line 3743 "Python/generated_cases.c.h" } TARGET(CALL_NO_KW_TYPE_1) { @@ -3746,7 +3747,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2703 "Python/bytecodes.c" + #line 2704 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3756,7 +3757,7 @@ res = Py_NewRef(Py_TYPE(obj)); Py_DECREF(obj); Py_DECREF(&PyType_Type); // I.e., callable - #line 3760 "Python/generated_cases.c.h" + #line 3761 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3769,7 +3770,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2715 "Python/bytecodes.c" + #line 2716 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3780,7 +3781,7 @@ Py_DECREF(arg); Py_DECREF(&PyUnicode_Type); // I.e., callable if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3784 "Python/generated_cases.c.h" + #line 3785 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3794,7 +3795,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *null = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2729 "Python/bytecodes.c" + #line 2730 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); DEOPT_IF(null != NULL, CALL); @@ -3805,7 +3806,7 @@ Py_DECREF(arg); Py_DECREF(&PyTuple_Type); // I.e., tuple if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3809 "Python/generated_cases.c.h" + #line 3810 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3819,7 +3820,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2743 "Python/bytecodes.c" + #line 2744 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -3841,7 +3842,7 @@ } Py_DECREF(tp); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3845 "Python/generated_cases.c.h" + #line 3846 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3855,7 +3856,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2768 "Python/bytecodes.c" + #line 2769 "Python/bytecodes.c" /* Builtin METH_O functions */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -3883,7 +3884,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3887 "Python/generated_cases.c.h" + #line 3888 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3897,7 +3898,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2799 "Python/bytecodes.c" + #line 2800 "Python/bytecodes.c" /* Builtin METH_FASTCALL functions, without keywords */ assert(kwnames == NULL); int is_meth = method != NULL; @@ -3929,7 +3930,7 @@ 'invalid'). In those cases an exception is set, so we must handle it. */ - #line 3933 "Python/generated_cases.c.h" + #line 3934 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3943,7 +3944,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2834 "Python/bytecodes.c" + #line 2835 "Python/bytecodes.c" /* Builtin METH_FASTCALL | METH_KEYWORDS functions */ int is_meth = method != NULL; int total_args = oparg; @@ -3975,7 +3976,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 3979 "Python/generated_cases.c.h" + #line 3980 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -3989,7 +3990,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2869 "Python/bytecodes.c" + #line 2870 "Python/bytecodes.c" assert(kwnames == NULL); /* len(o) */ int is_meth = method != NULL; @@ -4014,7 +4015,7 @@ Py_DECREF(callable); Py_DECREF(arg); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4018 "Python/generated_cases.c.h" + #line 4019 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4027,7 +4028,7 @@ PyObject *callable = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2896 "Python/bytecodes.c" + #line 2897 "Python/bytecodes.c" assert(kwnames == NULL); /* isinstance(o, o2) */ int is_meth = method != NULL; @@ -4054,7 +4055,7 @@ Py_DECREF(cls); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4058 "Python/generated_cases.c.h" + #line 4059 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4066,7 +4067,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *self = stack_pointer[-(1 + oparg)]; PyObject *method = stack_pointer[-(2 + oparg)]; - #line 2926 "Python/bytecodes.c" + #line 2927 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 1); assert(method != NULL); @@ -4084,14 +4085,14 @@ JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1); assert(next_instr[-1].op.code == POP_TOP); DISPATCH(); - #line 4088 "Python/generated_cases.c.h" + #line 4089 "Python/generated_cases.c.h" } TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) { PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2946 "Python/bytecodes.c" + #line 2947 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4122,7 +4123,7 @@ Py_DECREF(arg); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4126 "Python/generated_cases.c.h" + #line 4127 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4135,7 +4136,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 2980 "Python/bytecodes.c" + #line 2981 "Python/bytecodes.c" int is_meth = method != NULL; int total_args = oparg; if (is_meth) { @@ -4164,7 +4165,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4168 "Python/generated_cases.c.h" + #line 4169 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4177,7 +4178,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3012 "Python/bytecodes.c" + #line 3013 "Python/bytecodes.c" assert(kwnames == NULL); assert(oparg == 0 || oparg == 1); int is_meth = method != NULL; @@ -4206,7 +4207,7 @@ Py_DECREF(self); Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4210 "Python/generated_cases.c.h" + #line 4211 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4219,7 +4220,7 @@ PyObject **args = (stack_pointer - oparg); PyObject *method = stack_pointer[-(2 + oparg)]; PyObject *res; - #line 3044 "Python/bytecodes.c" + #line 3045 "Python/bytecodes.c" assert(kwnames == NULL); int is_meth = method != NULL; int total_args = oparg; @@ -4247,7 +4248,7 @@ } Py_DECREF(callable); if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; } - #line 4251 "Python/generated_cases.c.h" + #line 4252 "Python/generated_cases.c.h" STACK_SHRINK(oparg); STACK_SHRINK(1); stack_pointer[-1] = res; @@ -4257,9 +4258,9 @@ } TARGET(INSTRUMENTED_CALL_FUNCTION_EX) { - #line 3075 "Python/bytecodes.c" + #line 3076 "Python/bytecodes.c" GO_TO_INSTRUCTION(CALL_FUNCTION_EX); - #line 4263 "Python/generated_cases.c.h" + #line 4264 "Python/generated_cases.c.h" } TARGET(CALL_FUNCTION_EX) { @@ -4268,7 +4269,7 @@ PyObject *callargs = stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))]; PyObject *func = stack_pointer[-(2 + ((oparg & 1) ? 1 : 0))]; PyObject *result; - #line 3079 "Python/bytecodes.c" + #line 3080 "Python/bytecodes.c" // DICT_MERGE is called before this opcode if there are kwargs. // It converts all dict subtypes in kwargs into regular dicts. assert(kwargs == NULL || PyDict_CheckExact(kwargs)); @@ -4311,14 +4312,14 @@ else { result = PyObject_Call(func, callargs, kwargs); } - #line 4315 "Python/generated_cases.c.h" + #line 4316 "Python/generated_cases.c.h" Py_DECREF(func); Py_DECREF(callargs); Py_XDECREF(kwargs); - #line 3122 "Python/bytecodes.c" + #line 3123 "Python/bytecodes.c" assert(PEEK(3 + (oparg & 1)) == NULL); if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; } - #line 4322 "Python/generated_cases.c.h" + #line 4323 "Python/generated_cases.c.h" STACK_SHRINK(((oparg & 1) ? 1 : 0)); STACK_SHRINK(2); stack_pointer[-1] = result; @@ -4333,7 +4334,7 @@ PyObject *kwdefaults = (oparg & 0x02) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0))] : NULL; PyObject *defaults = (oparg & 0x01) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x01) ? 1 : 0))] : NULL; PyObject *func; - #line 3132 "Python/bytecodes.c" + #line 3133 "Python/bytecodes.c" PyFunctionObject *func_obj = (PyFunctionObject *) PyFunction_New(codeobj, GLOBALS()); @@ -4362,14 +4363,14 @@ func_obj->func_version = ((PyCodeObject *)codeobj)->co_version; func = (PyObject *)func_obj; - #line 4366 "Python/generated_cases.c.h" + #line 4367 "Python/generated_cases.c.h" STACK_SHRINK(((oparg & 0x01) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x08) ? 1 : 0)); stack_pointer[-1] = func; DISPATCH(); } TARGET(RETURN_GENERATOR) { - #line 3163 "Python/bytecodes.c" + #line 3164 "Python/bytecodes.c" assert(PyFunction_Check(frame->f_funcobj)); PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj; PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func); @@ -4390,7 +4391,7 @@ frame = cframe.current_frame = prev; _PyFrame_StackPush(frame, (PyObject *)gen); goto resume_frame; - #line 4394 "Python/generated_cases.c.h" + #line 4395 "Python/generated_cases.c.h" } TARGET(BUILD_SLICE) { @@ -4398,15 +4399,15 @@ PyObject *stop = stack_pointer[-(1 + ((oparg == 3) ? 1 : 0))]; PyObject *start = stack_pointer[-(2 + ((oparg == 3) ? 1 : 0))]; PyObject *slice; - #line 3186 "Python/bytecodes.c" + #line 3187 "Python/bytecodes.c" slice = PySlice_New(start, stop, step); - #line 4404 "Python/generated_cases.c.h" + #line 4405 "Python/generated_cases.c.h" Py_DECREF(start); Py_DECREF(stop); Py_XDECREF(step); - #line 3188 "Python/bytecodes.c" + #line 3189 "Python/bytecodes.c" if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; } - #line 4410 "Python/generated_cases.c.h" + #line 4411 "Python/generated_cases.c.h" STACK_SHRINK(((oparg == 3) ? 1 : 0)); STACK_SHRINK(1); stack_pointer[-1] = slice; @@ -4417,7 +4418,7 @@ PyObject *fmt_spec = ((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? stack_pointer[-((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))] : NULL; PyObject *value = stack_pointer[-(1 + (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))]; PyObject *result; - #line 3192 "Python/bytecodes.c" + #line 3193 "Python/bytecodes.c" /* Handles f-string value formatting. */ PyObject *(*conv_fn)(PyObject *); int which_conversion = oparg & FVC_MASK; @@ -4452,7 +4453,7 @@ Py_DECREF(value); Py_XDECREF(fmt_spec); if (result == NULL) { STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); goto pop_1_error; } - #line 4456 "Python/generated_cases.c.h" + #line 4457 "Python/generated_cases.c.h" STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); stack_pointer[-1] = result; DISPATCH(); @@ -4461,10 +4462,10 @@ TARGET(COPY) { PyObject *bottom = stack_pointer[-(1 + (oparg-1))]; PyObject *top; - #line 3229 "Python/bytecodes.c" + #line 3230 "Python/bytecodes.c" assert(oparg > 0); top = Py_NewRef(bottom); - #line 4468 "Python/generated_cases.c.h" + #line 4469 "Python/generated_cases.c.h" STACK_GROW(1); stack_pointer[-1] = top; DISPATCH(); @@ -4476,7 +4477,7 @@ PyObject *rhs = stack_pointer[-1]; PyObject *lhs = stack_pointer[-2]; PyObject *res; - #line 3234 "Python/bytecodes.c" + #line 3235 "Python/bytecodes.c" #if ENABLE_SPECIALIZATION _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr; if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) { @@ -4491,12 +4492,12 @@ assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops)); assert(binary_ops[oparg]); res = binary_ops[oparg](lhs, rhs); - #line 4495 "Python/generated_cases.c.h" + #line 4496 "Python/generated_cases.c.h" Py_DECREF(lhs); Py_DECREF(rhs); - #line 3249 "Python/bytecodes.c" + #line 3250 "Python/bytecodes.c" if (res == NULL) goto pop_2_error; - #line 4500 "Python/generated_cases.c.h" + #line 4501 "Python/generated_cases.c.h" STACK_SHRINK(1); stack_pointer[-1] = res; next_instr += 1; @@ -4506,16 +4507,16 @@ TARGET(SWAP) { PyObject *top = stack_pointer[-1]; PyObject *bottom = stack_pointer[-(2 + (oparg-2))]; - #line 3254 "Python/bytecodes.c" + #line 3255 "Python/bytecodes.c" assert(oparg >= 2); - #line 4512 "Python/generated_cases.c.h" + #line 4513 "Python/generated_cases.c.h" stack_pointer[-1] = bottom; stack_pointer[-(2 + (oparg-2))] = top; DISPATCH(); } TARGET(INSTRUMENTED_LINE) { - #line 3258 "Python/bytecodes.c" + #line 3259 "Python/bytecodes.c" _Py_CODEUNIT *here = next_instr-1; _PyFrame_SetStackPointer(frame, stack_pointer); int original_opcode = _Py_call_instrumentation_line( @@ -4535,11 +4536,11 @@ } opcode = original_opcode; DISPATCH_GOTO(); - #line 4539 "Python/generated_cases.c.h" + #line 4540 "Python/generated_cases.c.h" } TARGET(INSTRUMENTED_INSTRUCTION) { - #line 3280 "Python/bytecodes.c" + #line 3281 "Python/bytecodes.c" int next_opcode = _Py_call_instrumentation_instruction( tstate, frame, next_instr-1); if (next_opcode < 0) goto error; @@ -4551,26 +4552,26 @@ assert(next_opcode > 0 && next_opcode < 256); opcode = next_opcode; DISPATCH_GOTO(); - #line 4555 "Python/generated_cases.c.h" + #line 4556 "Python/generated_cases.c.h" } TARGET(INSTRUMENTED_JUMP_FORWARD) { - #line 3294 "Python/bytecodes.c" + #line 3295 "Python/bytecodes.c" INSTRUMENTED_JUMP(next_instr-1, next_instr+oparg, PY_MONITORING_EVENT_JUMP); - #line 4561 "Python/generated_cases.c.h" + #line 4562 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_JUMP_BACKWARD) { - #line 3298 "Python/bytecodes.c" + #line 3299 "Python/bytecodes.c" INSTRUMENTED_JUMP(next_instr-1, next_instr-oparg, PY_MONITORING_EVENT_JUMP); - #line 4568 "Python/generated_cases.c.h" + #line 4569 "Python/generated_cases.c.h" CHECK_EVAL_BREAKER(); DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_TRUE) { - #line 3303 "Python/bytecodes.c" + #line 3304 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4579,12 +4580,12 @@ assert(err == 0 || err == 1); int offset = err*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4583 "Python/generated_cases.c.h" + #line 4584 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_FALSE) { - #line 3314 "Python/bytecodes.c" + #line 3315 "Python/bytecodes.c" PyObject *cond = POP(); int err = PyObject_IsTrue(cond); Py_DECREF(cond); @@ -4593,12 +4594,12 @@ assert(err == 0 || err == 1); int offset = (1-err)*oparg; INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4597 "Python/generated_cases.c.h" + #line 4598 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) { - #line 3325 "Python/bytecodes.c" + #line 3326 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4611,12 +4612,12 @@ offset = 0; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4615 "Python/generated_cases.c.h" + #line 4616 "Python/generated_cases.c.h" DISPATCH(); } TARGET(INSTRUMENTED_POP_JUMP_IF_NOT_NONE) { - #line 3340 "Python/bytecodes.c" + #line 3341 "Python/bytecodes.c" PyObject *value = POP(); _Py_CODEUNIT *here = next_instr-1; int offset; @@ -4629,30 +4630,30 @@ offset = oparg; } INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH); - #line 4633 "Python/generated_cases.c.h" + #line 4634 "Python/generated_cases.c.h" DISPATCH(); } TARGET(EXTENDED_ARG) { - #line 3355 "Python/bytecodes.c" + #line 3356 "Python/bytecodes.c" assert(oparg); opcode = next_instr->op.code; oparg = oparg << 8 | next_instr->op.arg; PRE_DISPATCH_GOTO(); DISPATCH_GOTO(); - #line 4644 "Python/generated_cases.c.h" + #line 4645 "Python/generated_cases.c.h" } TARGET(CACHE) { - #line 3363 "Python/bytecodes.c" + #line 3364 "Python/bytecodes.c" assert(0 && "Executing a cache."); Py_UNREACHABLE(); - #line 4651 "Python/generated_cases.c.h" + #line 4652 "Python/generated_cases.c.h" } TARGET(RESERVED) { - #line 3368 "Python/bytecodes.c" + #line 3369 "Python/bytecodes.c" assert(0 && "Executing RESERVED instruction."); Py_UNREACHABLE(); - #line 4658 "Python/generated_cases.c.h" + #line 4659 "Python/generated_cases.c.h" } From 5f633106ee26e2f5b62e5862b30795f9f0726b26 Mon Sep 17 00:00:00 2001 From: Matt Page Date: Mon, 1 May 2023 15:26:10 -0700 Subject: [PATCH 7/7] Handle case where the task's coroutine is NULL This can happen if task's coro completes eagerly --- Modules/_asynciomodule.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index c8953adf2e366d..461508c59b9a58 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -2643,6 +2643,9 @@ static void TaskObj_dealloc(PyObject *); /* Needs Task_CheckExact */ static int TaskObj_set_awaiter(TaskObj *task, PyObject *awaiter) { + if (task->task_coro == NULL) { + return 0; + } return _PyAwaitable_SetAwaiter(task->task_coro, awaiter); }