diff -r d00a1c46fff7 Include/floatobject.h --- a/Include/floatobject.h Thu Feb 04 14:08:23 2016 -0500 +++ b/Include/floatobject.h Thu Feb 04 20:34:50 2016 -0500 @@ -122,6 +122,12 @@ Py_ssize_t end); #endif /* Py_LIMITED_API */ +PyAPI_FUNC(PyObject *) _PyFloat_Add(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyFloat_Sub(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyFloat_Mul(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyFloat_Div(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyFloat_FloorDiv(PyObject *, PyObject *); + #ifdef __cplusplus } #endif diff -r d00a1c46fff7 Include/longobject.h --- a/Include/longobject.h Thu Feb 04 14:08:23 2016 -0500 +++ b/Include/longobject.h Thu Feb 04 20:34:50 2016 -0500 @@ -209,6 +209,12 @@ /* For use by the gcd function in mathmodule.c */ PyAPI_FUNC(PyObject *) _PyLong_GCD(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyLong_Add(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyLong_Sub(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyLong_Mul(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyLong_Div(PyObject *, PyObject *); +PyAPI_FUNC(PyObject *) _PyLong_FloorDiv(PyObject *, PyObject *); + #ifdef __cplusplus } #endif diff -r d00a1c46fff7 Objects/floatobject.c --- a/Objects/floatobject.c Thu Feb 04 14:08:23 2016 -0500 +++ b/Objects/floatobject.c Thu Feb 04 20:34:50 2016 -0500 @@ -506,8 +506,8 @@ return _Py_HashDouble(v->ob_fval); } -static PyObject * -float_add(PyObject *v, PyObject *w) +PyObject * +_PyFloat_Add(PyObject *v, PyObject *w) { double a,b; CONVERT_TO_DOUBLE(v, a); @@ -518,8 +518,8 @@ return PyFloat_FromDouble(a); } -static PyObject * -float_sub(PyObject *v, PyObject *w) +PyObject * +_PyFloat_Sub(PyObject *v, PyObject *w) { double a,b; CONVERT_TO_DOUBLE(v, a); @@ -530,8 +530,8 @@ return PyFloat_FromDouble(a); } -static PyObject * -float_mul(PyObject *v, PyObject *w) +PyObject * +_PyFloat_Mul(PyObject *v, PyObject *w) { double a,b; CONVERT_TO_DOUBLE(v, a); @@ -542,8 +542,8 @@ return PyFloat_FromDouble(a); } -static PyObject * -float_div(PyObject *v, PyObject *w) +PyObject * +_PyFloat_Div(PyObject *v, PyObject *w) { double a,b; CONVERT_TO_DOUBLE(v, a); @@ -636,8 +636,8 @@ return Py_BuildValue("(dd)", floordiv, mod); } -static PyObject * -float_floor_div(PyObject *v, PyObject *w) +PyObject * +_PyFloat_FloorDiv(PyObject *v, PyObject *w) { PyObject *t, *r; @@ -1797,9 +1797,9 @@ static PyNumberMethods float_as_number = { - float_add, /*nb_add*/ - float_sub, /*nb_subtract*/ - float_mul, /*nb_multiply*/ + _PyFloat_Add, /*nb_add*/ + _PyFloat_Sub, /*nb_subtract*/ + _PyFloat_Mul, /*nb_multiply*/ float_rem, /*nb_remainder*/ float_divmod, /*nb_divmod*/ float_pow, /*nb_power*/ @@ -1826,8 +1826,8 @@ 0, /* nb_inplace_and */ 0, /* nb_inplace_xor */ 0, /* nb_inplace_or */ - float_floor_div, /* nb_floor_divide */ - float_div, /* nb_true_divide */ + _PyFloat_FloorDiv, /* nb_floor_divide */ + _PyFloat_Div, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ }; diff -r d00a1c46fff7 Objects/longobject.c --- a/Objects/longobject.c Thu Feb 04 14:08:23 2016 -0500 +++ b/Objects/longobject.c Thu Feb 04 20:34:50 2016 -0500 @@ -3000,9 +3000,11 @@ return long_normalize(z); } -static PyObject * -long_add(PyLongObject *a, PyLongObject *b) +PyObject * +_PyLong_Add(PyObject *left, PyObject *right) { + PyLongObject *a = (PyLongObject*) left; + PyLongObject *b = (PyLongObject*) right; PyLongObject *z; CHECK_BINOP(a, b); @@ -3030,9 +3032,11 @@ return (PyObject *)z; } -static PyObject * -long_sub(PyLongObject *a, PyLongObject *b) +PyObject * +_PyLong_Sub(PyObject *left, PyObject *right) { + PyLongObject *a = (PyLongObject*) left; + PyLongObject *b = (PyLongObject*) right; PyLongObject *z; CHECK_BINOP(a, b); @@ -3462,9 +3466,11 @@ return NULL; } -static PyObject * -long_mul(PyLongObject *a, PyLongObject *b) +PyObject * +_PyLong_Mul(PyObject *left, PyObject *right) { + PyLongObject *a = (PyLongObject*) left; + PyLongObject *b = (PyLongObject*) right; PyLongObject *z; CHECK_BINOP(a, b); @@ -3528,7 +3534,7 @@ (Py_SIZE(mod)> 0 && Py_SIZE(w) < 0)) { PyLongObject *temp; PyLongObject *one; - temp = (PyLongObject *) long_add(mod, w); + temp = (PyLongObject *) _PyLong_Add((PyObject*)mod, (PyObject*)w); Py_DECREF(mod); mod = temp; if (mod == NULL) { @@ -3537,7 +3543,8 @@ } one = (PyLongObject *) PyLong_FromLong(1L); if (one == NULL || - (temp = (PyLongObject *) long_sub(div, one)) == NULL) { + (temp = (PyLongObject *) _PyLong_Sub( + (PyObject*)div, (PyObject*)one)) == NULL) { Py_DECREF(mod); Py_DECREF(div); Py_XDECREF(one); @@ -3560,8 +3567,8 @@ return 0; } -static PyObject * -long_div(PyObject *a, PyObject *b) +PyObject * +_PyLong_FloorDiv(PyObject *a, PyObject *b) { PyLongObject *div; @@ -3576,8 +3583,8 @@ #define MANT_DIG_DIGITS (DBL_MANT_DIG / PyLong_SHIFT) #define MANT_DIG_BITS (DBL_MANT_DIG % PyLong_SHIFT) -static PyObject * -long_true_divide(PyObject *v, PyObject *w) +PyObject * +_PyLong_Div(PyObject *v, PyObject *w) { PyLongObject *a, *b, *x; Py_ssize_t a_size, b_size, shift, extra_bits, diff, x_size, x_bits; @@ -3993,7 +4000,7 @@ result = X*Y % c. If c is NULL, skip the mod. */ #define MULT(X, Y, result) \ do { \ - temp = (PyLongObject *)long_mul(X, Y); \ + temp = (PyLongObject *)_PyLong_Mul((PyObject*)X, (PyObject*)Y); \ if (temp == NULL) \ goto Error; \ Py_XDECREF(result); \ @@ -4036,7 +4043,7 @@ } if (negativeOutput && (Py_SIZE(z) != 0)) { - temp = (PyLongObject *)long_sub(z, c); + temp = (PyLongObject *)_PyLong_Sub((PyObject*)z, (PyObject*)c); if (temp == NULL) goto Error; Py_DECREF(z); @@ -4071,7 +4078,7 @@ w = (PyLongObject *)PyLong_FromLong(1L); if (w == NULL) return NULL; - x = (PyLongObject *) long_add(v, w); + x = (PyLongObject *) _PyLong_Add((PyObject*)v, (PyObject*)w); Py_DECREF(w); if (x == NULL) return NULL; @@ -4792,18 +4799,18 @@ if ((Py_SIZE(b) < 0 ? cmp < 0 : cmp> 0) || (cmp == 0 && quo_is_odd)) { /* fix up quotient */ if (quo_is_neg) - temp = long_sub(quo, (PyLongObject *)one); + temp = _PyLong_Sub((PyObject*)quo, one); else - temp = long_add(quo, (PyLongObject *)one); + temp = _PyLong_Add((PyObject*)quo, one); Py_DECREF(quo); quo = (PyLongObject *)temp; if (quo == NULL) goto error; /* and remainder */ if (quo_is_neg) - temp = long_add(rem, (PyLongObject *)b); + temp = _PyLong_Add((PyObject*)rem, b); else - temp = long_sub(rem, (PyLongObject *)b); + temp = _PyLong_Sub((PyObject*)rem, b); Py_DECREF(rem); rem = (PyLongObject *)temp; if (rem == NULL) @@ -4887,8 +4894,7 @@ if (result == NULL) return NULL; - temp = long_sub((PyLongObject *)self, - (PyLongObject *)PyTuple_GET_ITEM(result, 1)); + temp = _PyLong_Sub(self, PyTuple_GET_ITEM(result, 1)); Py_DECREF(result); result = temp; @@ -4935,7 +4941,7 @@ x = (PyLongObject *)PyLong_FromLong(PyLong_SHIFT); if (x == NULL) goto error; - y = (PyLongObject *)long_mul(result, x); + y = (PyLongObject *)_PyLong_Mul((PyObject*)result, (PyObject*)x); Py_DECREF(x); if (y == NULL) goto error; @@ -4945,7 +4951,7 @@ x = (PyLongObject *)PyLong_FromLong((long)msd_bits); if (x == NULL) goto error; - y = (PyLongObject *)long_add(result, x); + y = (PyLongObject *)_PyLong_Add((PyObject*)result, (PyObject*)x); Py_DECREF(x); if (y == NULL) goto error; @@ -5221,9 +5227,9 @@ 4"); static PyNumberMethods long_as_number = { - (binaryfunc)long_add, /*nb_add*/ - (binaryfunc)long_sub, /*nb_subtract*/ - (binaryfunc)long_mul, /*nb_multiply*/ + _PyLong_Add, /*nb_add*/ + _PyLong_Sub, /*nb_subtract*/ + _PyLong_Mul, /*nb_multiply*/ long_mod, /*nb_remainder*/ long_divmod, /*nb_divmod*/ long_pow, /*nb_power*/ @@ -5250,8 +5256,8 @@ 0, /* nb_inplace_and */ 0, /* nb_inplace_xor */ 0, /* nb_inplace_or */ - long_div, /* nb_floor_divide */ - long_true_divide, /* nb_true_divide */ + _PyLong_FloorDiv, /* nb_floor_divide */ + _PyLong_Div, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ long_long, /* nb_index */ diff -r d00a1c46fff7 Python/ceval.c --- a/Python/ceval.c Thu Feb 04 14:08:23 2016 -0500 +++ b/Python/ceval.c Thu Feb 04 20:34:50 2016 -0500 @@ -1118,6 +1118,34 @@ Py_XDECREF(traceback); \ } +#define MAYBE_DISPATCH_FAST_NUM_OP(OP, left, right) \ + { \ + PyObject *result; \ + int check = 0; \ + if (PyLong_CheckExact(left)) { \ + if (PyLong_CheckExact(right)) { \ + result = _PyLong_##OP(left, right); \ + check = 1; \ + } \ + else if (PyFloat_CheckExact(right)) { \ + result = _PyFloat_##OP(left, right); \ + check = 1; \ + } \ + } \ + else if (PyFloat_CheckExact(left) && \ + (PyFloat_CheckExact(right) || PyLong_CheckExact(right))) { \ + result = _PyFloat_##OP(left, right); \ + check = 1; \ + } \ + if (check) { \ + Py_DECREF(left); \ + Py_DECREF(right); \ + SET_TOP(result); \ + if (result == NULL) goto error; \ + DISPATCH(); \ + } \ + } + /* Start of code */ /* push frame */ @@ -1497,12 +1525,17 @@ TARGET(BINARY_MULTIPLY) { PyObject *right = POP(); PyObject *left = TOP(); - PyObject *res = PyNumber_Multiply(left, right); + PyObject *res; + + MAYBE_DISPATCH_FAST_NUM_OP(Mul, left, right); + + res = PyNumber_Multiply(left, right); Py_DECREF(left); Py_DECREF(right); SET_TOP(res); - if (res == NULL) + if (res == NULL) { goto error; + } DISPATCH(); } @@ -1521,24 +1554,36 @@ TARGET(BINARY_TRUE_DIVIDE) { PyObject *divisor = POP(); PyObject *dividend = TOP(); - PyObject *quotient = PyNumber_TrueDivide(dividend, divisor); + PyObject *quotient; + + MAYBE_DISPATCH_FAST_NUM_OP(Div, dividend, divisor); + + quotient = PyNumber_TrueDivide(dividend, divisor); Py_DECREF(dividend); Py_DECREF(divisor); + SET_TOP(quotient); - if (quotient == NULL) + if (quotient == NULL) { goto error; + } DISPATCH(); } TARGET(BINARY_FLOOR_DIVIDE) { PyObject *divisor = POP(); PyObject *dividend = TOP(); - PyObject *quotient = PyNumber_FloorDivide(dividend, divisor); + PyObject *quotient; + + MAYBE_DISPATCH_FAST_NUM_OP(FloorDiv, dividend, divisor); + + quotient = PyNumber_FloorDivide(dividend, divisor); Py_DECREF(dividend); Py_DECREF(divisor); + SET_TOP(quotient); - if (quotient == NULL) + if (quotient == NULL) { goto error; + } DISPATCH(); } @@ -1560,31 +1605,41 @@ PyObject *right = POP(); PyObject *left = TOP(); PyObject *sum; - if (PyUnicode_CheckExact(left) && - PyUnicode_CheckExact(right)) { + + if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { + /* fast path for string concatenation */ sum = unicode_concatenate(left, right, f, next_instr); - /* unicode_concatenate consumed the ref to v */ - } - else { + /* unicode_concatenate consumed the ref to left */ + } else { + MAYBE_DISPATCH_FAST_NUM_OP(Add, left, right); + sum = PyNumber_Add(left, right); Py_DECREF(left); } + Py_DECREF(right); SET_TOP(sum); - if (sum == NULL) + if (sum == NULL) { goto error; + } DISPATCH(); } TARGET(BINARY_SUBTRACT) { PyObject *right = POP(); PyObject *left = TOP(); - PyObject *diff = PyNumber_Subtract(left, right); + PyObject *diff; + + MAYBE_DISPATCH_FAST_NUM_OP(Sub, left, right); + + diff = PyNumber_Subtract(left, right); Py_DECREF(right); Py_DECREF(left); + SET_TOP(diff); - if (diff == NULL) + if (diff == NULL) { goto error; + } DISPATCH(); } @@ -1699,12 +1754,18 @@ TARGET(INPLACE_MULTIPLY) { PyObject *right = POP(); PyObject *left = TOP(); - PyObject *res = PyNumber_InPlaceMultiply(left, right); + PyObject *res; + + MAYBE_DISPATCH_FAST_NUM_OP(Mul, left, right); + + res = PyNumber_InPlaceMultiply(left, right); Py_DECREF(left); Py_DECREF(right); + SET_TOP(res); - if (res == NULL) + if (res == NULL) { goto error; + } DISPATCH(); } @@ -1723,24 +1784,36 @@ TARGET(INPLACE_TRUE_DIVIDE) { PyObject *divisor = POP(); PyObject *dividend = TOP(); - PyObject *quotient = PyNumber_InPlaceTrueDivide(dividend, divisor); + PyObject *quotient; + + MAYBE_DISPATCH_FAST_NUM_OP(Div, dividend, divisor); + + quotient = PyNumber_InPlaceTrueDivide(dividend, divisor); Py_DECREF(dividend); Py_DECREF(divisor); + SET_TOP(quotient); - if (quotient == NULL) + if (quotient == NULL) { goto error; + } DISPATCH(); } TARGET(INPLACE_FLOOR_DIVIDE) { PyObject *divisor = POP(); PyObject *dividend = TOP(); - PyObject *quotient = PyNumber_InPlaceFloorDivide(dividend, divisor); + PyObject *quotient; + + MAYBE_DISPATCH_FAST_NUM_OP(FloorDiv, dividend, divisor); + + quotient = PyNumber_InPlaceFloorDivide(dividend, divisor); Py_DECREF(dividend); Py_DECREF(divisor); + SET_TOP(quotient); - if (quotient == NULL) + if (quotient == NULL) { goto error; + } DISPATCH(); } @@ -1760,30 +1833,41 @@ PyObject *right = POP(); PyObject *left = TOP(); PyObject *sum; + if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { + /* fast path for string concatenation */ sum = unicode_concatenate(left, right, f, next_instr); - /* unicode_concatenate consumed the ref to v */ - } - else { + /* unicode_concatenate consumed the ref to left */ + } else { + MAYBE_DISPATCH_FAST_NUM_OP(Add, left, right); + sum = PyNumber_InPlaceAdd(left, right); Py_DECREF(left); } + Py_DECREF(right); SET_TOP(sum); - if (sum == NULL) + if (sum == NULL) { goto error; + } DISPATCH(); } TARGET(INPLACE_SUBTRACT) { PyObject *right = POP(); PyObject *left = TOP(); - PyObject *diff = PyNumber_InPlaceSubtract(left, right); + PyObject *diff; + + MAYBE_DISPATCH_FAST_NUM_OP(Sub, left, right); + + diff = PyNumber_InPlaceSubtract(left, right); Py_DECREF(left); Py_DECREF(right); + SET_TOP(diff); - if (diff == NULL) + if (diff == NULL) { goto error; + } DISPATCH(); }

AltStyle によって変換されたページ (->オリジナル) /