Skip to content

Commit

Permalink
Add POP_JUMP_IF_NONE, POP_JUMP_IF_NOT_NONE opcodes
Browse files Browse the repository at this point in the history
This builds on top of python#25090
  • Loading branch information
gvanrossum committed Mar 31, 2021
1 parent 195e532 commit e8e979f
Show file tree
Hide file tree
Showing 9 changed files with 4,654 additions and 4,625 deletions.
6 changes: 4 additions & 2 deletions Include/opcode.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Lib/importlib/_bootstrap_external.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,8 @@ def _write_atomic(path, data, mode=0o666):
# Python 3.10a2 3432 (Function annotation for MAKE_FUNCTION is changed from dict to tuple bpo-42202)
# Python 3.10a2 3433 (RERAISE restores f_lasti if oparg != 0)
# Python 3.10a6 3434 (PEP 634: Structural Pattern Matching)
# Python 3.10a7 3435 (super-instructions)
# Python 3.10a7 3435 (ADD_INT)
# Python 3.10a7 3436 (POP_JUMP_IF_NONE, POP_JUMP_IF_NOT_NONE)
#
# MAGIC must change whenever the bytecode emitted by the compiler may no
# longer be understood by older implementations of the eval loop (usually
Expand All @@ -323,7 +324,7 @@ def _write_atomic(path, data, mode=0o666):
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated.

MAGIC_NUMBER = (3435).to_bytes(2, 'little') + b'\r\n'
MAGIC_NUMBER = (3436).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c

_PYCACHE = '__pycache__'
Expand Down
2 changes: 2 additions & 0 deletions Lib/opcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ def jabs_op(name, op):
haslocal.append(125)
def_op('DELETE_FAST', 126) # Local variable number
haslocal.append(126)
jabs_op('POP_JUMP_IF_NONE', 127)
jabs_op('POP_JUMP_IF_NOT_NONE', 128)

def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
def_op('CALL_FUNCTION', 131) # #args
Expand Down
22 changes: 22 additions & 0 deletions Python/ceval.c
Original file line number Diff line number Diff line change
Expand Up @@ -3811,6 +3811,28 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, PyFrameObject *f, int throwflag)
DISPATCH();
}

case TARGET(POP_JUMP_IF_NONE): {
PyObject *target = POP();
if (target == Py_None) {
Py_DECREF(target);
JUMPTO(oparg);
DISPATCH();
}
Py_DECREF(target);
DISPATCH();
}

case TARGET(POP_JUMP_IF_NOT_NONE): {
PyObject *target = POP();
if (target != Py_None) {
Py_DECREF(target);
JUMPTO(oparg);
DISPATCH();
}
Py_DECREF(target);
DISPATCH();
}

case TARGET(JUMP_IF_FALSE_OR_POP): {
PyObject *cond = TOP();
int err;
Expand Down
32 changes: 30 additions & 2 deletions Python/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,8 @@ stack_effect(int opcode, int oparg, int jump)

case POP_JUMP_IF_FALSE:
case POP_JUMP_IF_TRUE:
case POP_JUMP_IF_NONE:
case POP_JUMP_IF_NOT_NONE:
return -1;

case LOAD_GLOBAL:
Expand Down Expand Up @@ -6847,7 +6849,7 @@ optimize_basic_block(basicblock *bb, PyObject *consts)
}
switch (inst->i_opcode) {
/* Remove LOAD_CONST const; conditional jump */
/* Also optimize LOAD_CONST(small_int) + BINARY_ADD */
/* Also some other sequences starting with LOAD_CONST */
case LOAD_CONST:
{
PyObject* cnt;
Expand Down Expand Up @@ -6890,7 +6892,8 @@ optimize_basic_block(basicblock *bb, PyObject *consts)
break;
case BINARY_ADD:
cnt = PyList_GET_ITEM(consts, oparg);
if (PyLong_CheckExact(cnt) && inst->i_lineno == bb->b_instr[i+1].i_lineno) {
if (PyLong_CheckExact(cnt)
&& inst->i_lineno == bb->b_instr[i+1].i_lineno) {
int ovf = 0;
long val = PyLong_AsLongAndOverflow(cnt, &ovf);
// TODO: What about larger values?
Expand All @@ -6904,6 +6907,31 @@ optimize_basic_block(basicblock *bb, PyObject *consts)
}
}
break;
case IS_OP:
/* Look for LOAD_CONST(None), IS_OP, POP_JUMP_IF_XXX. */
cnt = PyList_GET_ITEM(consts, oparg);
if (cnt != Py_None
|| i+2 >= bb->b_iused
|| inst->i_lineno != bb->b_instr[i+1].i_lineno
|| inst->i_lineno != bb->b_instr[i+2].i_lineno)
{
break;
}
// IS_OP oparg is 0 for 'is', 1 for 'is not'
int is_op_arg = bb->b_instr[i+1].i_oparg;
int last_opcode = bb->b_instr[i+2].i_opcode;
switch (last_opcode) {
case POP_JUMP_IF_FALSE:
case POP_JUMP_IF_TRUE:
inst->i_opcode = NOP;
bb->b_instr[i+1].i_opcode = NOP;
bb->b_instr[i+2].i_opcode =
is_op_arg ^ (last_opcode == POP_JUMP_IF_TRUE)
? POP_JUMP_IF_NONE
: POP_JUMP_IF_NOT_NONE;
break;
}
break;
}
break;
}
Expand Down
Loading

0 comments on commit e8e979f

Please sign in to comment.