From 6ee3f3814f17c72b96c424873de64a4602d9788a Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Thu, 17 Mar 2022 11:33:32 -0700 Subject: [PATCH 1/5] Handle return-during-throw in SEND --- Objects/genobject.c | 11 ++--------- Python/ceval.c | 7 +++++++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Objects/genobject.c b/Objects/genobject.c index 6551b939c4590c..18932991664fc1 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -485,15 +485,8 @@ _gen_throw(PyGenObject *gen, int close_on_genexit, ret = _PyFrame_StackPop((_PyInterpreterFrame *)gen->gi_iframe); assert(ret == yf); Py_DECREF(ret); - /* Termination repetition of SEND loop */ - assert(frame->f_lasti >= 0); - PyObject *bytecode = gen->gi_code->co_code; - unsigned char *code = (unsigned char *)PyBytes_AS_STRING(bytecode); - /* Backup to SEND */ - frame->f_lasti--; - assert(code[frame->f_lasti*sizeof(_Py_CODEUNIT)] == SEND); - int jump = code[frame->f_lasti*sizeof(_Py_CODEUNIT)+1]; - frame->f_lasti += jump; + // NULL tells SEND to quit sending: + _PyFrame_StackPush((_PyInterpreterFrame *)gen->gi_iframe, NULL); if (_PyGen_FetchStopIterationValue(&val) == 0) { ret = gen_send(gen, val); Py_DECREF(val); diff --git a/Python/ceval.c b/Python/ceval.c index 81759ad770b1e3..17b5045faa9e31 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2535,6 +2535,13 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int assert(STACK_LEVEL() >= 2); PyObject *v = POP(); PyObject *receiver = TOP(); + if (receiver == NULL) { + // Receiver completed during a throw() call. v is the return + // value: + SET_TOP(v); + JUMPBY(oparg); + DISPATCH(); + } PySendResult gen_status; PyObject *retval; if (tstate->c_tracefunc == NULL) { From dcf97b2e2a875e91c0a77fecb2a579cee1066586 Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Thu, 17 Mar 2022 11:33:55 -0700 Subject: [PATCH 2/5] Update the docs for SEND --- Doc/library/dis.rst | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 65e888dc86a194..1247a2cddbfa4a 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -1272,10 +1272,17 @@ iterations of the loop. .. versionadded:: 3.11 -.. opcode:: SEND - - Sends ``None`` to the sub-generator of this generator. - Used in ``yield from`` and ``await`` statements. +.. opcode:: SEND (delta) + + Equivalent to ``TOS = TOS1.send(TOS)``. Used in ``yield from`` and ``await`` + statements. + + If the call raises :exc:`StopIteration`, pop both values, push its return + value, and increment the bytecode counter by *delta*. + + If TOS1 is ``NULL`` (set when it raises :exc:`StopIteration` during a + ``throw()`` through the current frame), pop both values, push TOS (its + return value), and increment the bytecode counter by *delta*. .. versionadded:: 3.11 From fb649c73071b6c5f63e6ea81a238e50d2b0bbfa2 Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Thu, 17 Mar 2022 11:40:50 -0700 Subject: [PATCH 3/5] blurb add --- .../Core and Builtins/2022-03-17-11-40-20.bpo-46841.cU7e6B.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-03-17-11-40-20.bpo-46841.cU7e6B.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-03-17-11-40-20.bpo-46841.cU7e6B.rst b/Misc/NEWS.d/next/Core and Builtins/2022-03-17-11-40-20.bpo-46841.cU7e6B.rst new file mode 100644 index 00000000000000..a71ba26c107d55 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-03-17-11-40-20.bpo-46841.cU7e6B.rst @@ -0,0 +1,3 @@ +When a sub-iterator returns a value during a ``throw()`` call, perform the +resulting jump during the next :opcode:`SEND` instruction (rather than as +part of the ``throw()`` implementation). From acdf9848aa39a904f6322160e4bf87a01fcebaae Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Thu, 17 Mar 2022 12:30:48 -0700 Subject: [PATCH 4/5] Clean things up a bit --- Doc/library/dis.rst | 4 ++-- Python/ceval.c | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 1247a2cddbfa4a..4fcd6452a2cbc2 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -1276,10 +1276,10 @@ iterations of the loop. Equivalent to ``TOS = TOS1.send(TOS)``. Used in ``yield from`` and ``await`` statements. - + If the call raises :exc:`StopIteration`, pop both values, push its return value, and increment the bytecode counter by *delta*. - + If TOS1 is ``NULL`` (set when it raises :exc:`StopIteration` during a ``throw()`` through the current frame), pop both values, push TOS (its return value), and increment the bytecode counter by *delta*. diff --git a/Python/ceval.c b/Python/ceval.c index 17b5045faa9e31..a921d384316b50 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2536,8 +2536,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int PyObject *v = POP(); PyObject *receiver = TOP(); if (receiver == NULL) { - // Receiver completed during a throw() call. v is the return - // value: + // Receiver returned during a throw(). v is its return value: SET_TOP(v); JUMPBY(oparg); DISPATCH(); From 5aebc871e16938c5c2b40221147e9d545c89f211 Mon Sep 17 00:00:00 2001 From: Brandt Bucher Date: Wed, 8 Jun 2022 11:59:30 -0700 Subject: [PATCH 5/5] Minor doc edits --- Doc/library/dis.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst index 5c06461a4b9479..5a62193185e126 100644 --- a/Doc/library/dis.rst +++ b/Doc/library/dis.rst @@ -1321,12 +1321,15 @@ iterations of the loop. If the call raises :exc:`StopIteration`, pop both values, push its return value, and increment the bytecode counter by *delta*. - If TOS1 is ``NULL`` (set when it raises :exc:`StopIteration` during a - ``throw()`` through the current frame), pop both values, push TOS (its - return value), and increment the bytecode counter by *delta*. + If TOS1 is ``NULL`` (set when a ``throw()`` through the current frame + returns), pop both values, push TOS (its return value) back, and increment + the bytecode counter by *delta*. .. versionadded:: 3.11 + .. versionchanged:: 3.12 + Added ``NULL`` handling for subiterators that return during ``throw()``. + .. opcode:: ASYNC_GEN_WRAP pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy