summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c205
1 files changed, 201 insertions, 4 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index fb7b5bc..3488b9c 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -669,12 +669,69 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
PUSH(w);
continue;
+ case ROT_FOUR:
+ u = POP();
+ v = POP();
+ w = POP();
+ x = POP();
+ PUSH(u);
+ PUSH(x);
+ PUSH(w);
+ PUSH(v);
+ continue;
+
case DUP_TOP:
v = TOP();
Py_INCREF(v);
PUSH(v);
continue;
+ case DUP_TOPX:
+ switch (oparg) {
+ case 5:
+ case 4:
+ case 3:
+ case 2:
+ case 1:
+ x = POP();
+ if (oparg == 1) break;
+ w = POP();
+ if (oparg == 2) break;
+ v = POP();
+ if (oparg == 3) break;
+ u = POP();
+ if (oparg == 4) break;
+ t = POP();
+ break;
+ default:
+ fprintf(stderr, "Invalid argument to DUP_TOPX: %d!\n", oparg);
+ PyErr_SetString(PyExc_SystemError,
+ "invalid argument to DUP_TOPX");
+ x = NULL;
+ }
+ if (x == NULL)
+ break;
+ switch (oparg) {
+ case 5: PUSH(t);
+ Py_INCREF(t); /* Fallthrough */
+ case 4: PUSH(u);
+ Py_INCREF(u); /* Fallthrough */
+ case 3: PUSH(v);
+ Py_INCREF(v); /* Fallthrough */
+ case 2: PUSH(w);
+ Py_INCREF(w); /* Fallthrough */
+ case 1: PUSH(x);
+ Py_INCREF(x); /* Fallthrough */
+ }
+ switch (oparg) {
+ case 5: PUSH(t); /* Fallthrough */
+ case 4: PUSH(u); /* Fallthrough */
+ case 3: PUSH(v); /* Fallthrough */
+ case 2: PUSH(w); /* Fallthrough */
+ case 1: PUSH(x); /* Fallthrough */
+ }
+ continue;
+
case UNARY_POSITIVE:
v = POP();
x = PyNumber_Positive(v);
@@ -890,7 +947,147 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
PUSH(x);
if (x != NULL) continue;
break;
+
+ case INPLACE_POWER:
+ w = POP();
+ v = POP();
+ x = PyNumber_InPlacePower(v, w, Py_None);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ PUSH(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_MULTIPLY:
+ w = POP();
+ v = POP();
+ x = PyNumber_InPlaceMultiply(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ PUSH(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_DIVIDE:
+ w = POP();
+ v = POP();
+ x = PyNumber_InPlaceDivide(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ PUSH(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_MODULO:
+ w = POP();
+ v = POP();
+ x = PyNumber_InPlaceRemainder(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ PUSH(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_ADD:
+ w = POP();
+ v = POP();
+ if (PyInt_Check(v) && PyInt_Check(w)) {
+ /* INLINE: int + int */
+ register long a, b, i;
+ a = PyInt_AS_LONG(v);
+ b = PyInt_AS_LONG(w);
+ i = a + b;
+ if ((i^a) < 0 && (i^b) < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "integer addition");
+ x = NULL;
+ }
+ else
+ x = PyInt_FromLong(i);
+ }
+ else
+ x = PyNumber_InPlaceAdd(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ PUSH(x);
+ if (x != NULL) continue;
+ break;
+ case INPLACE_SUBTRACT:
+ w = POP();
+ v = POP();
+ if (PyInt_Check(v) && PyInt_Check(w)) {
+ /* INLINE: int - int */
+ register long a, b, i;
+ a = PyInt_AS_LONG(v);
+ b = PyInt_AS_LONG(w);
+ i = a - b;
+ if ((i^a) < 0 && (i^~b) < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "integer subtraction");
+ x = NULL;
+ }
+ else
+ x = PyInt_FromLong(i);
+ }
+ else
+ x = PyNumber_InPlaceSubtract(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ PUSH(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_LSHIFT:
+ w = POP();
+ v = POP();
+ x = PyNumber_InPlaceLshift(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ PUSH(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_RSHIFT:
+ w = POP();
+ v = POP();
+ x = PyNumber_InPlaceRshift(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ PUSH(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_AND:
+ w = POP();
+ v = POP();
+ x = PyNumber_InPlaceAnd(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ PUSH(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_XOR:
+ w = POP();
+ v = POP();
+ x = PyNumber_InPlaceXor(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ PUSH(x);
+ if (x != NULL) continue;
+ break;
+
+ case INPLACE_OR:
+ w = POP();
+ v = POP();
+ x = PyNumber_InPlaceOr(v, w);
+ Py_DECREF(v);
+ Py_DECREF(w);
+ PUSH(x);
+ if (x != NULL) continue;
+ break;
+
case SLICE+0:
case SLICE+1:
case SLICE+2:
@@ -1063,6 +1260,10 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
stream = NULL;
break;
+
+#ifdef CASE_TOO_BIG
+ default: switch (opcode) {
+#endif
case BREAK_LOOP:
why = WHY_BREAK;
break;
@@ -1180,10 +1381,6 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
PyErr_SetObject(PyExc_NameError, w);
break;
-#ifdef CASE_TOO_BIG
- default: switch (opcode) {
-#endif
-
case UNPACK_SEQUENCE:
v = POP();
if (PyTuple_Check(v)) {