/////////////////////////////////////////////////////////////////////////// // Numeric interface inline CObject operator+ (const CObject& a) { PyObject* tmp_obj = PyNumber_Positive(a.Get()); if ( !tmp_obj ) { throw CArithmeticError("PyNumber_Positive"); } return CObject(tmp_obj, eTakeOwnership); }
static int fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts) { PyObject *newconst=NULL, *v; Py_ssize_t len_consts; int opcode; /* Pre-conditions */ assert(PyList_CheckExact(consts)); assert(codestr[0] == LOAD_CONST); /* Create new constant */ v = PyList_GET_ITEM(consts, GETARG(codestr, 0)); opcode = codestr[3]; switch (opcode) { case UNARY_NEGATIVE: /* Preserve the sign of -0.0 */ if (PyObject_IsTrue(v) == 1) newconst = PyNumber_Negative(v); break; case UNARY_INVERT: newconst = PyNumber_Invert(v); break; case UNARY_POSITIVE: newconst = PyNumber_Positive(v); break; default: /* Called with an unknown opcode */ PyErr_Format(PyExc_SystemError, "unexpected unary operation %d on a constant", opcode); return 0; } if (newconst == NULL) { if(!PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) PyErr_Clear(); return 0; } /* Append folded constant into consts table */ len_consts = PyList_GET_SIZE(consts); if (PyList_Append(consts, newconst)) { Py_DECREF(newconst); return 0; } Py_DECREF(newconst); /* Write NOP LOAD_CONST newconst */ codestr[0] = NOP; codestr[1] = LOAD_CONST; SETARG(codestr, 1, len_consts); return 1; }
static PyObject *Proxy_positive(ProxyObject *self) { Proxy__ENSURE_WRAPPED_OR_RETURN_NULL(self); return PyNumber_Positive(self->wrapped); }
/* Replace LOAD_CONST c1. LOAD_CONST c2 BINOP with LOAD_CONST binop(c1,c2) The consts table must still be in list form so that the new constant can be appended. Called with codestr pointing to the first LOAD_CONST. Abandons the transformation if the folding fails (i.e. 1+'a'). If the new constant is a sequence, only folds when the size is below a threshold value. That keeps pyc files from becoming large in the presence of code like: (None,)*1000. */ static int fold_binops_on_constants(unsigned char *codestr, PyObject *consts) { PyObject *newconst, *v, *w; Py_ssize_t len_consts, size; int opcode; /* Pre-conditions */ assert(PyList_CheckExact(consts)); assert(codestr[0] == LOAD_CONST); assert(codestr[3] == LOAD_CONST); /* Create new constant */ v = PyList_GET_ITEM(consts, GETARG(codestr, 0)); w = PyList_GET_ITEM(consts, GETARG(codestr, 3)); opcode = codestr[6]; switch (opcode) { case BINARY_POWER: newconst = PyNumber_Power(v, w, Py_None); break; case BINARY_MULTIPLY: newconst = PyNumber_Multiply(v, w); break; case BINARY_TRUE_DIVIDE: newconst = PyNumber_TrueDivide(v, w); break; case BINARY_FLOOR_DIVIDE: newconst = PyNumber_FloorDivide(v, w); break; case BINARY_MODULO: newconst = PyNumber_Remainder(v, w); break; case BINARY_ADD: newconst = PyNumber_Add(v, w); break; case BINARY_SUBTRACT: newconst = PyNumber_Subtract(v, w); break; case BINARY_SUBSCR: newconst = PyObject_GetItem(v, w); /* #5057: if v is unicode, there might be differences between wide and narrow builds in cases like '\U00012345'[0]. Wide builds will return a non-BMP char, whereas narrow builds will return a surrogate. In both the cases skip the optimization in order to produce compatible pycs. */ if (newconst != NULL && PyUnicode_Check(v) && PyUnicode_Check(newconst)) { Py_UNICODE ch = PyUnicode_AS_UNICODE(newconst)[0]; #ifdef Py_UNICODE_WIDE if (ch > 0xFFFF) { #else if (ch >= 0xD800 && ch <= 0xDFFF) { #endif Py_DECREF(newconst); return 0; } } break; case BINARY_LSHIFT: newconst = PyNumber_Lshift(v, w); break; case BINARY_RSHIFT: newconst = PyNumber_Rshift(v, w); break; case BINARY_AND: newconst = PyNumber_And(v, w); break; case BINARY_XOR: newconst = PyNumber_Xor(v, w); break; case BINARY_OR: newconst = PyNumber_Or(v, w); break; default: /* Called with an unknown opcode */ PyErr_Format(PyExc_SystemError, "unexpected binary operation %d on a constant", opcode); return 0; } if (newconst == NULL) { if(!PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) PyErr_Clear(); return 0; } size = PyObject_Size(newconst); if (size == -1) { if (PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) return 0; PyErr_Clear(); } else if (size > 20) { Py_DECREF(newconst); return 0; } /* Append folded constant into consts table */ len_consts = PyList_GET_SIZE(consts); if (PyList_Append(consts, newconst)) { Py_DECREF(newconst); return 0; } Py_DECREF(newconst); /* Write NOP NOP NOP NOP LOAD_CONST newconst */ memset(codestr, NOP, 4); codestr[4] = LOAD_CONST; SETARG(codestr, 4, len_consts); return 1; } static int fold_unaryops_on_constants(unsigned char *codestr, PyObject *consts) { PyObject *newconst=NULL, *v; Py_ssize_t len_consts; int opcode; /* Pre-conditions */ assert(PyList_CheckExact(consts)); assert(codestr[0] == LOAD_CONST); /* Create new constant */ v = PyList_GET_ITEM(consts, GETARG(codestr, 0)); opcode = codestr[3]; switch (opcode) { case UNARY_NEGATIVE: /* Preserve the sign of -0.0 */ if (PyObject_IsTrue(v) == 1) newconst = PyNumber_Negative(v); break; case UNARY_INVERT: newconst = PyNumber_Invert(v); break; case UNARY_POSITIVE: newconst = PyNumber_Positive(v); break; default: /* Called with an unknown opcode */ PyErr_Format(PyExc_SystemError, "unexpected unary operation %d on a constant", opcode); return 0; } if (newconst == NULL) { if(!PyErr_ExceptionMatches(PyExc_KeyboardInterrupt)) PyErr_Clear(); return 0; } /* Append folded constant into consts table */ len_consts = PyList_GET_SIZE(consts); if (PyList_Append(consts, newconst)) { Py_DECREF(newconst); return 0; } Py_DECREF(newconst); /* Write NOP LOAD_CONST newconst */ codestr[0] = NOP; codestr[1] = LOAD_CONST; SETARG(codestr, 1, len_consts); return 1; }