On Sat, Jun 19, 2021 at 5:13 PM Rob Cliffe via Python-list
<python-list@python.org> wrote:
>
>
>
> On 19/06/2021 07:50, Chris Angelico wrote:
> > On Sat, Jun 19, 2021 at 4:16 PM Rob Cliffe via Python-list
> > <python-list@python.org> wrote:
> >>
> >>
> >> On 18/06/2021 11:04, Chris Angelico wrote:
> >>>>>> sys.version
> >>> '3.10.0b2+ (heads/3.10:33a7a24288, Jun  9 2021, 20:47:39) [GCC 8.3.0]'
> >>>>>> def chk(x):
> >>> ...     if not(0 < x < 10): raise Exception
> >>> ...
> >>>>>> dis.dis(chk)
> >>>     2           0 LOAD_CONST               1 (0)
> >>>                 2 LOAD_FAST                0 (x)
> >>>                 4 DUP_TOP
> >>>                 6 ROT_THREE
> >>>                 8 COMPARE_OP               0 (<)
> >>>                10 POP_JUMP_IF_FALSE       11 (to 22)
> >>>                12 LOAD_CONST               2 (10)
> >>>                14 COMPARE_OP               0 (<)
> >>>                16 POP_JUMP_IF_TRUE        14 (to 28)
> >>>                18 LOAD_GLOBAL              0 (Exception)
> >>>                20 RAISE_VARARGS            1
> >>>           >>   22 POP_TOP
> >>>                24 LOAD_GLOBAL              0 (Exception)
> >>>                26 RAISE_VARARGS            1
> >>>           >>   28 LOAD_CONST               0 (None)
> >>>                30 RETURN_VALUE
> >>> Why are there two separate bytecode blocks for the "raise Exception"?
> >>> I'd have thought that the double condition would still be evaluated as
> >>> one thing, or at least that the jump destinations for both the
> >>> early-abort and the main evaluation should be the same.
> >>>
> >>> ChrisA
> >> As an ornery human I could refactor this to avoid the code duplication as
> >>
> >>     2           0 LOAD_CONST               1 (0)
> >>                 2 LOAD_FAST                0 (x)
> >>                 4 DUP_TOP
> >>                 6 ROT_THREE
> >>                 8 COMPARE_OP               0 (<)
> >>                10 POP_JUMP_IF_TRUE        10 (to 18)
> >>                12 POP_TOP
> >>           >>   14 LOAD_GLOBAL              0 (Exception)
> >>                16 RAISE_VARARGS            1
> >>           >>   18 LOAD_CONST               2 (10)
> >>                20 COMPARE_OP               0 (<)
> >>                22 POP_JUMP_IF_FALSE       21 (to 14)
> >>                24 LOAD_CONST               0 (None)
> >>                26 RETURN_VALUE
> >>   >>>
> >>
> >> (there may be mistakes in this) but this is probably too much to expect
> >> of the compiler.
> > Hmm, I think that depends too much on knowing that the raise won't
> > return. That might be a neat optimization (effectively a form of dead
> > code removal), but otherwise, the best you could do would be to also
> > have it jump out after the raise.
> >
> > ChrisA
> Er, doesn't your original dis output make the same assumption?
> Otherwise, after this line
>
>                20 RAISE_VARARGS            1
>
> it would attempt to do an extra pop, then raise a second time.

In my original, I expected to see a single RAISE, with a jump over the
POP. The thing that surprised me was duplicating the RAISE to avoid
the jump. Either way, the behaviour would be the same, though.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to