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