Python/ceval.c (part 20)
Source:
cpython 3.14 @ ab2d84fe1023/Python/ceval.c
This annotation covers comparison and conditional jump specializations. See python_ceval19_detail for binary operator specializations.
Map
| Lines | Symbol | Role |
|---|---|---|
| 1-80 | COMPARE_OP_INT | int < int direct comparison without tp_richcompare |
| 81-160 | COMPARE_OP_FLOAT | float < float direct ob_fval comparison |
| 161-260 | COMPARE_OP_STR | str == str using interned-pointer shortcut |
| 261-380 | IS_OP / CONTAINS_OP | Identity check; in operator dispatch |
| 381-500 | POP_JUMP_IF_NONE / POP_JUMP_IF_NOT_NONE | None-check branch without boolean coercion |
Reading
COMPARE_OP_INT
// CPython: Python/ceval.c:2720 COMPARE_OP_INT
inst(COMPARE_OP_INT, (left, right -- res)) {
DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP);
DEOPT_IF(!PyLong_CheckExact(right), COMPARE_OP);
DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left), COMPARE_OP);
DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)right), COMPARE_OP);
Py_ssize_t lv = _PyLong_CompactValue((PyLongObject *)left);
Py_ssize_t rv = _PyLong_CompactValue((PyLongObject *)right);
int sign = (lv > rv) - (lv < rv);
res = PyBool_FromLong(COMPARISON_TRUTH(oparg, sign));
DECREMENT_ADAPTIVE_COUNTER(this_instr[-1].cache);
}
COMPARISON_TRUTH maps the oparg comparison code (LT, LE, EQ, NE, GT, GE) to a boolean using the sign (-1, 0, 1). This avoids calling long_richcompare and the full tp_richcompare dispatch. Only works for compact integers.
COMPARE_OP_STR
// CPython: Python/ceval.c:2820 COMPARE_OP_STR
inst(COMPARE_OP_STR, (left, right -- res)) {
DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP);
DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP);
int eq;
if (left == right) {
eq = 1; /* Interned strings: identity implies equality */
} else {
eq = (PyUnicode_Compare(left, right) == 0);
}
/* Only EQ and NE are supported in this specialization */
DEOPT_IF(oparg != Py_EQ && oparg != Py_NE, COMPARE_OP);
res = (eq ^ (oparg == Py_NE)) ? Py_True : Py_False;
Py_INCREF(res);
}
String equality is the most common comparison in dict lookups and match statements. The pointer identity check (left == right) is a fast path for interned strings.
IS_OP
// CPython: Python/ceval.c:2900 IS_OP
inst(IS_OP, (left, right -- b)) {
int res = Py_Is(left, right) ^ oparg;
/* oparg=0: 'is', oparg=1: 'is not' */
b = res ? Py_True : Py_False;
Py_INCREF(b);
DECREF_INPUTS();
}
x is y compiles to IS_OP with oparg=0; x is not y uses oparg=1. The XOR with oparg flips the result for is not. Py_Is is a pointer comparison.
POP_JUMP_IF_NONE
// CPython: Python/ceval.c:2980 POP_JUMP_IF_NONE
inst(POP_JUMP_IF_NONE, (val --)) {
if (!Py_IsNone(val)) {
JUMPBY(oparg);
}
Py_DECREF(val);
}
if x is None: ... compiles to LOAD_FAST x + POP_JUMP_IF_NOT_NONE target. The specialized opcode avoids the overhead of PyObject_IsTrue (which would call __bool__ for non-trivial types) by checking val == &_Py_NoneStruct directly.
gopy notes
COMPARE_OP_INT is vm.CompareOpInt in vm/eval_specialize.go. COMPARE_OP_STR checks pointer equality first, then uses objects.UnicodeCompare. IS_OP calls objects.Is. POP_JUMP_IF_NONE uses objects.IsNone which checks identity against the singleton objects.None.