
Are you suggesting a test for LOAD_FAST before the switch,
e.g. if (opcode == LOAD_FAST) { // load fast } else switch (opcode) { // body }
Yes.
Hmm, I might even be able to do something like this: if (opcode >= LOAD_FAST_0) { oparg = opcode - LOAD_FAST_0; ... } else switch (opcode) { }
Yes, except that in the default case the code is placed after the first switch.
switch (opcode) { case COMMON_OP: goto nextInstruction; case COMMON_OP: ... goto nextInstruction; default: ; }
switch (opcode) { case UNCOMMON_OP: case UNCOMMON_OP: } goto nextInstruction;
Why would you do it as two consecutive switches, rather than two nested switches? The current ceval code has nested switches for when CASE_TOO_BIG is defined. Hmmm. I would guess that the handling of default within a switch is probably highly optimised by the compiler, using if/then range tests. If we structured the opcodes so that uncommon ops were a two-byte opcode, we could do something like this: switch (opcode) { default: load_fast(opcode - LOAD_FAST_0); goto nextInstruction; case COMMON_OP1: ... goto nextInstruction; case COMMON_OP2: ... goto nextInstruction; case UNCOMMON_OP: break; } opcode = NEXTBYTE(); switch(opcode) { case UNCOMMON_OP1: ... break; case UNCOMMON_OP2: ... break; } This would free up the opcode numeric space for fast/frequent ops with immediate args encoded into them.