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