Skip to content

Commit 6a84d61

Browse files
authored
bpo-45636: Simplify BINARY_OP (GH-29565)
1 parent 55868f1 commit 6a84d61

File tree

4 files changed

+51
-83
lines changed

4 files changed

+51
-83
lines changed

Include/internal/pycore_abstract.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ _PyIndex_Check(PyObject *obj)
1616
return (tp_as_number != NULL && tp_as_number->nb_index != NULL);
1717
}
1818

19+
PyObject *_PyNumber_PowerNoMod(PyObject *lhs, PyObject *rhs);
20+
PyObject *_PyNumber_InPlacePowerNoMod(PyObject *lhs, PyObject *rhs);
21+
1922
#ifdef __cplusplus
2023
}
2124
#endif
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Simplify the implementation of :opcode:`BINARY_OP` by indexing into an array
2+
of function pointers (rather than switching on the oparg).

Objects/abstract.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,12 @@ PyNumber_Power(PyObject *v, PyObject *w, PyObject *z)
11521152
return ternary_op(v, w, z, NB_SLOT(nb_power), "** or pow()");
11531153
}
11541154

1155+
PyObject *
1156+
_PyNumber_PowerNoMod(PyObject *lhs, PyObject *rhs)
1157+
{
1158+
return PyNumber_Power(lhs, rhs, Py_None);
1159+
}
1160+
11551161
/* Binary in-place operators */
11561162

11571163
/* The in-place operators are defined to fall back to the 'normal',
@@ -1331,6 +1337,12 @@ PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z)
13311337
NB_SLOT(nb_power), "**=");
13321338
}
13331339

1340+
PyObject *
1341+
_PyNumber_InPlacePowerNoMod(PyObject *lhs, PyObject *rhs)
1342+
{
1343+
return PyNumber_InPlacePower(lhs, rhs, Py_None);
1344+
}
1345+
13341346

13351347
/* Unary operators and functions */
13361348

Python/ceval.c

Lines changed: 34 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,36 @@ _Py_CheckRecursiveCall(PyThreadState *tstate, const char *where)
835835
}
836836

837837

838+
static const binaryfunc binary_ops[] = {
839+
[NB_ADD] = PyNumber_Add,
840+
[NB_AND] = PyNumber_And,
841+
[NB_FLOOR_DIVIDE] = PyNumber_FloorDivide,
842+
[NB_LSHIFT] = PyNumber_Lshift,
843+
[NB_MATRIX_MULTIPLY] = PyNumber_MatrixMultiply,
844+
[NB_MULTIPLY] = PyNumber_Multiply,
845+
[NB_REMAINDER] = PyNumber_Remainder,
846+
[NB_OR] = PyNumber_Or,
847+
[NB_POWER] = _PyNumber_PowerNoMod,
848+
[NB_RSHIFT] = PyNumber_Rshift,
849+
[NB_SUBTRACT] = PyNumber_Subtract,
850+
[NB_TRUE_DIVIDE] = PyNumber_TrueDivide,
851+
[NB_XOR] = PyNumber_Xor,
852+
[NB_INPLACE_ADD] = PyNumber_InPlaceAdd,
853+
[NB_INPLACE_AND] = PyNumber_InPlaceAnd,
854+
[NB_INPLACE_FLOOR_DIVIDE] = PyNumber_InPlaceFloorDivide,
855+
[NB_INPLACE_LSHIFT] = PyNumber_InPlaceLshift,
856+
[NB_INPLACE_MATRIX_MULTIPLY] = PyNumber_InPlaceMatrixMultiply,
857+
[NB_INPLACE_MULTIPLY] = PyNumber_InPlaceMultiply,
858+
[NB_INPLACE_REMAINDER] = PyNumber_InPlaceRemainder,
859+
[NB_INPLACE_OR] = PyNumber_InPlaceOr,
860+
[NB_INPLACE_POWER] = _PyNumber_InPlacePowerNoMod,
861+
[NB_INPLACE_RSHIFT] = PyNumber_InPlaceRshift,
862+
[NB_INPLACE_SUBTRACT] = PyNumber_InPlaceSubtract,
863+
[NB_INPLACE_TRUE_DIVIDE] = PyNumber_InPlaceTrueDivide,
864+
[NB_INPLACE_XOR] = PyNumber_InPlaceXor,
865+
};
866+
867+
838868
// PEP 634: Structural Pattern Matching
839869

840870

@@ -4697,89 +4727,10 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
46974727
STAT_INC(BINARY_OP, unquickened);
46984728
PyObject *rhs = POP();
46994729
PyObject *lhs = TOP();
4700-
PyObject *res;
4701-
switch (oparg) {
4702-
case NB_ADD:
4703-
res = PyNumber_Add(lhs, rhs);
4704-
break;
4705-
case NB_AND:
4706-
res = PyNumber_And(lhs, rhs);
4707-
break;
4708-
case NB_FLOOR_DIVIDE:
4709-
res = PyNumber_FloorDivide(lhs, rhs);
4710-
break;
4711-
case NB_LSHIFT:
4712-
res = PyNumber_Lshift(lhs, rhs);
4713-
break;
4714-
case NB_MATRIX_MULTIPLY:
4715-
res = PyNumber_MatrixMultiply(lhs, rhs);
4716-
break;
4717-
case NB_MULTIPLY:
4718-
res = PyNumber_Multiply(lhs, rhs);
4719-
break;
4720-
case NB_REMAINDER:
4721-
res = PyNumber_Remainder(lhs, rhs);
4722-
break;
4723-
case NB_OR:
4724-
res = PyNumber_Or(lhs, rhs);
4725-
break;
4726-
case NB_POWER:
4727-
res = PyNumber_Power(lhs, rhs, Py_None);
4728-
break;
4729-
case NB_RSHIFT:
4730-
res = PyNumber_Rshift(lhs, rhs);
4731-
break;
4732-
case NB_SUBTRACT:
4733-
res = PyNumber_Subtract(lhs, rhs);
4734-
break;
4735-
case NB_TRUE_DIVIDE:
4736-
res = PyNumber_TrueDivide(lhs, rhs);
4737-
break;
4738-
case NB_XOR:
4739-
res = PyNumber_Xor(lhs, rhs);
4740-
break;
4741-
case NB_INPLACE_ADD:
4742-
res = PyNumber_InPlaceAdd(lhs, rhs);
4743-
break;
4744-
case NB_INPLACE_AND:
4745-
res = PyNumber_InPlaceAnd(lhs, rhs);
4746-
break;
4747-
case NB_INPLACE_FLOOR_DIVIDE:
4748-
res = PyNumber_InPlaceFloorDivide(lhs, rhs);
4749-
break;
4750-
case NB_INPLACE_LSHIFT:
4751-
res = PyNumber_InPlaceLshift(lhs, rhs);
4752-
break;
4753-
case NB_INPLACE_MATRIX_MULTIPLY:
4754-
res = PyNumber_InPlaceMatrixMultiply(lhs, rhs);
4755-
break;
4756-
case NB_INPLACE_MULTIPLY:
4757-
res = PyNumber_InPlaceMultiply(lhs, rhs);
4758-
break;
4759-
case NB_INPLACE_REMAINDER:
4760-
res = PyNumber_InPlaceRemainder(lhs, rhs);
4761-
break;
4762-
case NB_INPLACE_OR:
4763-
res = PyNumber_InPlaceOr(lhs, rhs);
4764-
break;
4765-
case NB_INPLACE_POWER:
4766-
res = PyNumber_InPlacePower(lhs, rhs, Py_None);
4767-
break;
4768-
case NB_INPLACE_RSHIFT:
4769-
res = PyNumber_InPlaceRshift(lhs, rhs);
4770-
break;
4771-
case NB_INPLACE_SUBTRACT:
4772-
res = PyNumber_InPlaceSubtract(lhs, rhs);
4773-
break;
4774-
case NB_INPLACE_TRUE_DIVIDE:
4775-
res = PyNumber_InPlaceTrueDivide(lhs, rhs);
4776-
break;
4777-
case NB_INPLACE_XOR:
4778-
res = PyNumber_InPlaceXor(lhs, rhs);
4779-
break;
4780-
default:
4781-
Py_UNREACHABLE();
4782-
}
4730+
assert(0 <= oparg);
4731+
assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops));
4732+
assert(binary_ops[oparg]);
4733+
PyObject *res = binary_ops[oparg](lhs, rhs);
47834734
Py_DECREF(lhs);
47844735
Py_DECREF(rhs);
47854736
SET_TOP(res);

0 commit comments

Comments
 (0)