diff options
author | Brandt Bucher <brandt@python.org> | 2021-11-11 06:56:22 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-11 06:56:22 (GMT) |
commit | 9178f533ff5ea7462a2ca22cfa67afd78dad433b (patch) | |
tree | 2341d2dbc7fbee0585e0d37a04c07b07c8036d57 /Python/ceval.c | |
parent | 1cbaa505d007e11c4a1f0d2073d72b6c02c7147c (diff) | |
download | cpython-9178f533ff5ea7462a2ca22cfa67afd78dad433b.zip cpython-9178f533ff5ea7462a2ca22cfa67afd78dad433b.tar.gz cpython-9178f533ff5ea7462a2ca22cfa67afd78dad433b.tar.bz2 |
bpo-45636: Merge all numeric operators (GH-29482)
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 604 |
1 files changed, 151 insertions, 453 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index fadb97a..030d983 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -92,8 +92,6 @@ static PyObject * import_from(PyThreadState *, PyObject *, PyObject *); static int import_all_from(PyThreadState *, PyObject *, PyObject *); static void format_exc_check_arg(PyThreadState *, PyObject *, const char *, PyObject *); static void format_exc_unbound(PyThreadState *tstate, PyCodeObject *co, int oparg); -static PyObject * unicode_concatenate(PyThreadState *, PyObject *, PyObject *, - InterpreterFrame *, const _Py_CODEUNIT *); static int check_args_iterable(PyThreadState *, PyObject *func, PyObject *vararg); static void format_kwargs_error(PyThreadState *, PyObject *func, PyObject *kwargs); static void format_awaitable_error(PyThreadState *, PyTypeObject *, int, int); @@ -1921,57 +1919,12 @@ check_eval_breaker: DISPATCH(); } - TARGET(BINARY_POWER) { - PyObject *exp = POP(); - PyObject *base = TOP(); - PyObject *res = PyNumber_Power(base, exp, Py_None); - Py_DECREF(base); - Py_DECREF(exp); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(BINARY_MULTIPLY) { - PREDICTED(BINARY_MULTIPLY); - STAT_INC(BINARY_MULTIPLY, unquickened); - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_Multiply(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) { - goto error; - } - DISPATCH(); - } - - TARGET(BINARY_MULTIPLY_ADAPTIVE) { - if (oparg == 0) { - PyObject *left = SECOND(); - PyObject *right = TOP(); - next_instr--; - if (_Py_Specialize_BinaryMultiply(left, right, next_instr) < 0) { - goto error; - } - DISPATCH(); - } - else { - STAT_INC(BINARY_MULTIPLY, deferred); - UPDATE_PREV_INSTR_OPARG(next_instr, oparg - 1); - STAT_DEC(BINARY_MULTIPLY, unquickened); - JUMP_TO_INSTRUCTION(BINARY_MULTIPLY); - } - } - - TARGET(BINARY_MULTIPLY_INT) { + TARGET(BINARY_OP_MULTIPLY_INT) { PyObject *left = SECOND(); PyObject *right = TOP(); - DEOPT_IF(!PyLong_CheckExact(left), BINARY_MULTIPLY); - DEOPT_IF(!PyLong_CheckExact(right), BINARY_MULTIPLY); - STAT_INC(BINARY_MULTIPLY, hit); + DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); PyObject *prod = _PyLong_Multiply((PyLongObject *)left, (PyLongObject *)right); SET_SECOND(prod); Py_DECREF(right); @@ -1983,12 +1936,12 @@ check_eval_breaker: DISPATCH(); } - TARGET(BINARY_MULTIPLY_FLOAT) { + TARGET(BINARY_OP_MULTIPLY_FLOAT) { PyObject *left = SECOND(); PyObject *right = TOP(); - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_MULTIPLY); - DEOPT_IF(!PyFloat_CheckExact(right), BINARY_MULTIPLY); - STAT_INC(BINARY_MULTIPLY, hit); + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP); + STAT_INC(BINARY_OP, hit); double dprod = ((PyFloatObject *)left)->ob_fval * ((PyFloatObject *)right)->ob_fval; PyObject *prod = PyFloat_FromDouble(dprod); @@ -2002,101 +1955,12 @@ check_eval_breaker: DISPATCH(); } - TARGET(BINARY_MATRIX_MULTIPLY) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_MatrixMultiply(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(BINARY_TRUE_DIVIDE) { - PyObject *divisor = POP(); - PyObject *dividend = TOP(); - PyObject *quotient = PyNumber_TrueDivide(dividend, divisor); - Py_DECREF(dividend); - Py_DECREF(divisor); - SET_TOP(quotient); - if (quotient == NULL) - goto error; - DISPATCH(); - } - - TARGET(BINARY_FLOOR_DIVIDE) { - PyObject *divisor = POP(); - PyObject *dividend = TOP(); - PyObject *quotient = PyNumber_FloorDivide(dividend, divisor); - Py_DECREF(dividend); - Py_DECREF(divisor); - SET_TOP(quotient); - if (quotient == NULL) - goto error; - DISPATCH(); - } - - TARGET(BINARY_MODULO) { - PyObject *divisor = POP(); - PyObject *dividend = TOP(); - PyObject *res; - if (PyUnicode_CheckExact(dividend) && ( - !PyUnicode_Check(divisor) || PyUnicode_CheckExact(divisor))) { - // fast path; string formatting, but not if the RHS is a str subclass - // (see issue28598) - res = PyUnicode_Format(dividend, divisor); - } else { - res = PyNumber_Remainder(dividend, divisor); - } - Py_DECREF(divisor); - Py_DECREF(dividend); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(BINARY_ADD) { - PREDICTED(BINARY_ADD); - STAT_INC(BINARY_ADD, unquickened); - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *sum = PyNumber_Add(left, right); - SET_TOP(sum); - Py_DECREF(left); - Py_DECREF(right); - if (sum == NULL) { - goto error; - } - DISPATCH(); - } - - TARGET(BINARY_ADD_ADAPTIVE) { - if (oparg == 0) { - PyObject *left = SECOND(); - PyObject *right = TOP(); - next_instr--; - if (_Py_Specialize_BinaryAdd(left, right, next_instr) < 0) { - goto error; - } - DISPATCH(); - } - else { - STAT_INC(BINARY_ADD, deferred); - UPDATE_PREV_INSTR_OPARG(next_instr, oparg - 1); - STAT_DEC(BINARY_ADD, unquickened); - JUMP_TO_INSTRUCTION(BINARY_ADD); - } - } - - TARGET(BINARY_ADD_UNICODE) { + TARGET(BINARY_OP_ADD_UNICODE) { PyObject *left = SECOND(); PyObject *right = TOP(); - DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_ADD); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_ADD); - STAT_INC(BINARY_ADD, hit); + DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + STAT_INC(BINARY_OP, hit); PyObject *res = PyUnicode_Concat(left, right); STACK_SHRINK(1); SET_TOP(res); @@ -2108,12 +1972,12 @@ check_eval_breaker: DISPATCH(); } - TARGET(BINARY_ADD_UNICODE_INPLACE_FAST) { + TARGET(BINARY_OP_INPLACE_ADD_UNICODE) { PyObject *left = SECOND(); PyObject *right = TOP(); - DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_ADD); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_ADD); - DEOPT_IF(Py_REFCNT(left) != 2, BINARY_ADD); + DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + DEOPT_IF(Py_REFCNT(left) != 2, BINARY_OP); int next_oparg = _Py_OPARG(*next_instr); assert(_Py_OPCODE(*next_instr) == STORE_FAST); /* In the common case, there are 2 references to the value @@ -2123,8 +1987,8 @@ check_eval_breaker: * the refcnt to 1. */ PyObject *var = GETLOCAL(next_oparg); - DEOPT_IF(var != left, BINARY_ADD); - STAT_INC(BINARY_ADD, hit); + DEOPT_IF(var != left, BINARY_OP); + STAT_INC(BINARY_OP, hit); GETLOCAL(next_oparg) = NULL; Py_DECREF(left); STACK_SHRINK(1); @@ -2136,12 +2000,12 @@ check_eval_breaker: DISPATCH(); } - TARGET(BINARY_ADD_FLOAT) { + TARGET(BINARY_OP_ADD_FLOAT) { PyObject *left = SECOND(); PyObject *right = TOP(); - DEOPT_IF(!PyFloat_CheckExact(left), BINARY_ADD); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_ADD); - STAT_INC(BINARY_ADD, hit); + DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + STAT_INC(BINARY_OP, hit); double dsum = ((PyFloatObject *)left)->ob_fval + ((PyFloatObject *)right)->ob_fval; PyObject *sum = PyFloat_FromDouble(dsum); @@ -2155,12 +2019,12 @@ check_eval_breaker: DISPATCH(); } - TARGET(BINARY_ADD_INT) { + TARGET(BINARY_OP_ADD_INT) { PyObject *left = SECOND(); PyObject *right = TOP(); - DEOPT_IF(!PyLong_CheckExact(left), BINARY_ADD); - DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_ADD); - STAT_INC(BINARY_ADD, hit); + DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP); + DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP); + STAT_INC(BINARY_OP, hit); PyObject *sum = _PyLong_Add((PyLongObject *)left, (PyLongObject *)right); SET_SECOND(sum); Py_DECREF(right); @@ -2172,18 +2036,6 @@ check_eval_breaker: DISPATCH(); } - TARGET(BINARY_SUBTRACT) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *diff = PyNumber_Subtract(left, right); - Py_DECREF(right); - Py_DECREF(left); - SET_TOP(diff); - if (diff == NULL) - goto error; - DISPATCH(); - } - TARGET(BINARY_SUBSCR) { PREDICTED(BINARY_SUBSCR); STAT_INC(BINARY_SUBSCR, unquickened); @@ -2282,66 +2134,6 @@ check_eval_breaker: DISPATCH(); } - TARGET(BINARY_LSHIFT) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_Lshift(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(BINARY_RSHIFT) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_Rshift(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(BINARY_AND) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_And(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(BINARY_XOR) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_Xor(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(BINARY_OR) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_Or(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - TARGET(LIST_APPEND) { PyObject *v = POP(); PyObject *list = PEEK(oparg); @@ -2366,169 +2158,6 @@ check_eval_breaker: DISPATCH(); } - TARGET(INPLACE_POWER) { - PyObject *exp = POP(); - PyObject *base = TOP(); - PyObject *res = PyNumber_InPlacePower(base, exp, Py_None); - Py_DECREF(base); - Py_DECREF(exp); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(INPLACE_MULTIPLY) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_InPlaceMultiply(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(INPLACE_MATRIX_MULTIPLY) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_InPlaceMatrixMultiply(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(INPLACE_TRUE_DIVIDE) { - PyObject *divisor = POP(); - PyObject *dividend = TOP(); - PyObject *quotient = PyNumber_InPlaceTrueDivide(dividend, divisor); - Py_DECREF(dividend); - Py_DECREF(divisor); - SET_TOP(quotient); - if (quotient == NULL) - goto error; - DISPATCH(); - } - - TARGET(INPLACE_FLOOR_DIVIDE) { - PyObject *divisor = POP(); - PyObject *dividend = TOP(); - PyObject *quotient = PyNumber_InPlaceFloorDivide(dividend, divisor); - Py_DECREF(dividend); - Py_DECREF(divisor); - SET_TOP(quotient); - if (quotient == NULL) - goto error; - DISPATCH(); - } - - TARGET(INPLACE_MODULO) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *mod = PyNumber_InPlaceRemainder(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(mod); - if (mod == NULL) - goto error; - DISPATCH(); - } - - TARGET(INPLACE_ADD) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *sum; - if (PyUnicode_CheckExact(left) && PyUnicode_CheckExact(right)) { - sum = unicode_concatenate(tstate, left, right, frame, next_instr); - /* unicode_concatenate consumed the ref to left */ - } - else { - sum = PyNumber_InPlaceAdd(left, right); - Py_DECREF(left); - } - Py_DECREF(right); - SET_TOP(sum); - if (sum == NULL) - goto error; - DISPATCH(); - } - - TARGET(INPLACE_SUBTRACT) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *diff = PyNumber_InPlaceSubtract(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(diff); - if (diff == NULL) - goto error; - DISPATCH(); - } - - TARGET(INPLACE_LSHIFT) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_InPlaceLshift(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(INPLACE_RSHIFT) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_InPlaceRshift(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(INPLACE_AND) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_InPlaceAnd(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(INPLACE_XOR) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_InPlaceXor(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - - TARGET(INPLACE_OR) { - PyObject *right = POP(); - PyObject *left = TOP(); - PyObject *res = PyNumber_InPlaceOr(left, right); - Py_DECREF(left); - Py_DECREF(right); - SET_TOP(res); - if (res == NULL) - goto error; - DISPATCH(); - } - TARGET(STORE_SUBSCR) { PyObject *sub = TOP(); PyObject *container = SECOND(); @@ -5032,6 +4661,130 @@ check_eval_breaker: DISPATCH(); } + TARGET(BINARY_OP) { + PREDICTED(BINARY_OP); + STAT_INC(BINARY_OP, unquickened); + PyObject *rhs = POP(); + PyObject *lhs = TOP(); + PyObject *res; + switch (oparg) { + case NB_ADD: + res = PyNumber_Add(lhs, rhs); + break; + case NB_AND: + res = PyNumber_And(lhs, rhs); + break; + case NB_FLOOR_DIVIDE: + res = PyNumber_FloorDivide(lhs, rhs); + break; + case NB_LSHIFT: + res = PyNumber_Lshift(lhs, rhs); + break; + case NB_MATRIX_MULTIPLY: + res = PyNumber_MatrixMultiply(lhs, rhs); + break; + case NB_MULTIPLY: + res = PyNumber_Multiply(lhs, rhs); + break; + case NB_REMAINDER: + if (PyUnicode_CheckExact(lhs) && + (!PyUnicode_Check(rhs) || PyUnicode_CheckExact(rhs))) + { + // bpo-28598: Fast path for string formatting (but not + // if the RHS is a str subclass). + res = PyUnicode_Format(lhs, rhs); + break; + } + res = PyNumber_Remainder(lhs, rhs); + break; + case NB_OR: + res = PyNumber_Or(lhs, rhs); + break; + case NB_POWER: + res = PyNumber_Power(lhs, rhs, Py_None); + break; + case NB_RSHIFT: + res = PyNumber_Rshift(lhs, rhs); + break; + case NB_SUBTRACT: + res = PyNumber_Subtract(lhs, rhs); + break; + case NB_TRUE_DIVIDE: + res = PyNumber_TrueDivide(lhs, rhs); + break; + case NB_XOR: + res = PyNumber_Xor(lhs, rhs); + break; + case NB_INPLACE_ADD: + res = PyNumber_InPlaceAdd(lhs, rhs); + break; + case NB_INPLACE_AND: + res = PyNumber_InPlaceAnd(lhs, rhs); + break; + case NB_INPLACE_FLOOR_DIVIDE: + res = PyNumber_InPlaceFloorDivide(lhs, rhs); + break; + case NB_INPLACE_LSHIFT: + res = PyNumber_InPlaceLshift(lhs, rhs); + break; + case NB_INPLACE_MATRIX_MULTIPLY: + res = PyNumber_InPlaceMatrixMultiply(lhs, rhs); + break; + case NB_INPLACE_MULTIPLY: + res = PyNumber_InPlaceMultiply(lhs, rhs); + break; + case NB_INPLACE_REMAINDER: + res = PyNumber_InPlaceRemainder(lhs, rhs); + break; + case NB_INPLACE_OR: + res = PyNumber_InPlaceOr(lhs, rhs); + break; + case NB_INPLACE_POWER: + res = PyNumber_InPlacePower(lhs, rhs, Py_None); + break; + case NB_INPLACE_RSHIFT: + res = PyNumber_InPlaceRshift(lhs, rhs); + break; + case NB_INPLACE_SUBTRACT: + res = PyNumber_InPlaceSubtract(lhs, rhs); + break; + case NB_INPLACE_TRUE_DIVIDE: + res = PyNumber_InPlaceTrueDivide(lhs, rhs); + break; + case NB_INPLACE_XOR: + res = PyNumber_InPlaceXor(lhs, rhs); + break; + default: + Py_UNREACHABLE(); + } + Py_DECREF(lhs); + Py_DECREF(rhs); + SET_TOP(res); + if (res == NULL) { + goto error; + } + DISPATCH(); + } + + TARGET(BINARY_OP_ADAPTIVE) { + assert(cframe.use_tracing == 0); + SpecializedCacheEntry *cache = GET_CACHE(); + if (cache->adaptive.counter == 0) { + PyObject *lhs = SECOND(); + PyObject *rhs = TOP(); + next_instr--; + _Py_Specialize_BinaryOp(lhs, rhs, next_instr, cache); + DISPATCH(); + } + else { + STAT_INC(BINARY_OP, deferred); + cache->adaptive.counter--; + oparg = cache->adaptive.original_oparg; + STAT_DEC(BINARY_OP, unquickened); + JUMP_TO_INSTRUCTION(BINARY_OP); + } + } + TARGET(EXTENDED_ARG) { int oldoparg = oparg; NEXTOPARG(); @@ -5137,9 +4890,8 @@ MISS_WITH_CACHE(STORE_ATTR) MISS_WITH_CACHE(LOAD_GLOBAL) MISS_WITH_CACHE(LOAD_METHOD) MISS_WITH_CACHE(CALL_FUNCTION) +MISS_WITH_CACHE(BINARY_OP) MISS_WITH_OPARG_COUNTER(BINARY_SUBSCR) -MISS_WITH_OPARG_COUNTER(BINARY_ADD) -MISS_WITH_OPARG_COUNTER(BINARY_MULTIPLY) binary_subscr_dict_error: { @@ -7173,60 +6925,6 @@ format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int prevprevop } } -static PyObject * -unicode_concatenate(PyThreadState *tstate, PyObject *v, PyObject *w, - InterpreterFrame *frame, const _Py_CODEUNIT *next_instr) -{ - PyObject *res; - if (Py_REFCNT(v) == 2) { - /* In the common case, there are 2 references to the value - * stored in 'variable' when the += is performed: one on the - * value stack (in 'v') and one still stored in the - * 'variable'. We try to delete the variable now to reduce - * the refcnt to 1. - */ - int opcode, oparg; - NEXTOPARG(); - next_instr++; - switch (opcode) { - case STORE_FAST: - { - if (GETLOCAL(oparg) == v) - SETLOCAL(oparg, NULL); - break; - } - case STORE_DEREF: - { - PyObject *c = _PyFrame_GetLocalsArray(frame)[oparg]; - if (PyCell_GET(c) == v) { - PyCell_SET(c, NULL); - Py_DECREF(v); - } - break; - } - case STORE_NAME: - { - PyObject *names = frame->f_code->co_names; - PyObject *name = GETITEM(names, oparg); - PyObject *locals = frame->f_locals; - if (locals && PyDict_CheckExact(locals)) { - PyObject *w = PyDict_GetItemWithError(locals, name); - if ((w == v && PyDict_DelItem(locals, name) != 0) || - (w == NULL && _PyErr_Occurred(tstate))) - { - Py_DECREF(v); - return NULL; - } - } - break; - } - } - } - res = v; - PyUnicode_Append(&res, w); - return res; -} - #ifdef DYNAMIC_EXECUTION_PROFILE static PyObject * |