Strange disassembly

Chris Angelico rosuav at gmail.com
Sat Jun 19 02:50:12 EDT 2021


On Sat, Jun 19, 2021 at 4:16 PM Rob Cliffe via Python-list
<python-list at 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


More information about the Python-list mailing list