RCP<const Number> PyNumber::rpow(const Number &other) const { PyObject *other_p, *result; if (is_a<PyNumber>(other)) { other_p = static_cast<const PyNumber &>(other).pyobject_; result = PyNumber_Power(other_p, pyobject_, Py_None); } else { other_p = pymodule_->to_py_(other.rcp_from_this_cast<const Basic>()); result = PyNumber_Power(other_p, pyobject_, Py_None); Py_XDECREF(other_p); } return make_rcp<PyNumber>(result, pymodule_); }
static PyObject *Proxy_power(PyObject *o1, PyObject *o2, PyObject *modulo) { Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o1); Proxy__WRAPPED_REPLACE_OR_RETURN_NULL(o2); return PyNumber_Power(o1, o2, modulo); }
NUITKA_MAY_BE_UNUSED static PyObject *POWER_OPERATION( PyObject *operand1, PyObject *operand2 ) { PyObject *result = PyNumber_Power( operand1, operand2, Py_None ); if (unlikely( result == NULL )) { return NULL; } return result; }
static PyObject * Pympany_pow(PyObject *base, PyObject *exp, PyObject *mod) { #ifndef WITHMPFR PyObject *result = 0, *temp; #endif if (isInteger(base) && isInteger(exp)) return Pympz_pow(base, exp, mod); else if (isRational(base) && isRational(exp)) return Pympq_pow(base, exp, mod); #ifdef WITHMPFR else if (isReal(base) && isReal(exp)); return Pympfr2_pow(base, exp, mod); #else /* Support mpz**float and float**mpz. */ if (CHECK_MPZANY(base) && PyFloat_Check(exp)) { temp = PyFloat_FromDouble(mpz_get_d(Pympz_AS_MPZ(base))); if (temp) { result = PyNumber_Power(temp, exp, mod); Py_DECREF(temp); } return result; } if (CHECK_MPZANY(exp) && PyFloat_Check(base)) { temp = PyFloat_FromDouble(mpz_get_d(Pympz_AS_MPZ(exp))); if (temp) { result = PyNumber_Power(base, temp, mod); Py_DECREF(temp); } return result; } #endif Py_RETURN_NOTIMPLEMENTED; }
static PyObject * wrap_pow(PyObject *self, PyObject *other, PyObject *modulus) { PyObject *result = NULL; PyObject *object; if (Proxy_Check(self)) { object = Proxy_GET_OBJECT(self); result = PyNumber_Power(object, other, modulus); } else if (Proxy_Check(other)) { object = Proxy_GET_OBJECT(other); result = PyNumber_Power(self, object, modulus); } else if (modulus != NULL && Proxy_Check(modulus)) { object = Proxy_GET_OBJECT(modulus); result = PyNumber_Power(self, other, modulus); } else { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } return result; }
static PyObject* pyjnumber_power(PyObject *x, PyObject *y, PyObject *z) { PyObject *result = NULL; JNIEnv *env = pyembed_get_env(); TO_PYTHON_NUMBER(env, x); TO_PYTHON_NUMBER(env, y); if (z != Py_None) { TO_PYTHON_NUMBER(env, z); } result = PyNumber_Power(x, y, z); Py_DECREF(x); Py_DECREF(y); Py_DECREF(z); return result; }
/* 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: /* #5057: if v is unicode, there might be differences between wide and narrow builds in cases like '\U00012345'[0] or '\U00012345abcdef'[3], so it's better to skip the optimization in order to produce compatible pycs. */ if (PyUnicode_Check(v)) return 0; newconst = PyObject_GetItem(v, w); 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; }
/* 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 BINOP. 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 **objs) { PyObject *newconst, *v, *w; Py_ssize_t len_consts, size; int opcode; /* Pre-conditions */ assert(PyList_CheckExact(consts)); /* Create new constant */ v = objs[0]; w = objs[1]; opcode = codestr[0]; 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); 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 */ codestr[-2] = LOAD_CONST; SETARG(codestr, -2, len_consts); return 1; }
/* 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_DIVIDE: /* Cannot fold this operation statically since the result can depend on the run-time presence of the -Qnew flag */ return 0; 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 u'\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) { PyErr_Clear(); return 0; } size = PyObject_Size(newconst); if (size == -1) 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_CONVERT: newconst = PyObject_Repr(v); break; case UNARY_INVERT: newconst = PyNumber_Invert(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) { 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; }
/* 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_DIVIDE: /* Cannot fold this operation statically since the result can depend on the run-time presence of the -Qnew flag */ return 0; 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); 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) { PyErr_Clear(); return 0; } size = PyObject_Size(newconst); if (size == -1) 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; }