diff -rc Python-1.5.1/Include/listobject.h Python-1.5.1.new/Include/listobject.h *** Python-1.5.1/Include/listobject.h Mon Jan 6 17:42:00 1997 --- Python-1.5.1.new/Include/listobject.h Sun Jul 5 11:10:56 1998 *************** *** 76,81 **** --- 76,84 ---- #define PyList_GET_ITEM(op, i) (((PyListObject *)(op))->ob_item[i]) #define PyList_GET_SIZE(op) (((PyListObject *)(op))->ob_size) + /* Macro, *only* to be used to fill in brand new lists */ + #define PyList_SET_ITEM(op, i, v) (((PyListObject *)(op))->ob_item[i] = v) + #ifdef __cplusplus } #endif diff -rc Python-1.5.1/Python/ceval.c Python-1.5.1.new/Python/ceval.c *** Python-1.5.1/Python/ceval.c Fri Apr 10 18:25:29 1998 --- Python-1.5.1.new/Python/ceval.c Sun Jul 5 19:21:11 1998 *************** *** 392,400 **** --- 392,411 ---- #define STACK_LEVEL() (stack_pointer - f->f_valuestack) #define EMPTY() (STACK_LEVEL() == 0) #define TOP() (stack_pointer[-1]) + #define TOP2() (stack_pointer[-2]) + #define TOP3() (stack_pointer[-3]) #define BASIC_PUSH(v) (*stack_pointer++ = (v)) #define BASIC_POP() (*--stack_pointer) + /* when FAST_STACK is, defined the stack is implemented more directly, + using array operations wherever possible, and fewer temporaries are used + for intermediate values, instead of limiting operations to PUSH and POP. + This results in much less movement of stack_pointer, fewer memory accesses, + and speeds execution up substantially, at least on register-starved + machines like the Intel x86 family. (At least 13 local variables are + declared as "register". The Pentium can't keep them all in registers...) */ + #define FAST_STACK 1 /* uncomment to try more direct stack manipulation */ + #ifdef LLTRACE #define PUSH(v) (BASIC_PUSH(v), lltrace && prtrace(TOP(), "push")) #define POP() (lltrace && prtrace(TOP(), "pop"), BASIC_POP()) *************** *** 683,726 **** --- 694,772 ---- continue; case ROT_TWO: + #if !defined(FAST_STACK) v = POP(); w = POP(); PUSH(v); PUSH(w); + #else + v = TOP(); + TOP() = TOP2(); + TOP2() = v; + #endif continue; case ROT_THREE: + #if !defined(FAST_STACK) v = POP(); w = POP(); x = POP(); PUSH(v); PUSH(x); PUSH(w); + #else + v = TOP(); + TOP() = TOP2(); + TOP2() = TOP3(); + TOP3() = v; + #endif continue; case DUP_TOP: + #if !defined(FAST_STACK) v = TOP(); Py_INCREF(v); PUSH(v); + #else + Py_INCREF(TOP()); + PUSH(TOP()); + #endif continue; case UNARY_POSITIVE: + #if !defined(FAST_STACK) v = POP(); x = PyNumber_Positive(v); Py_DECREF(v); PUSH(x); if (x != NULL) continue; + #else + v = TOP(); + TOP() = PyNumber_Positive(v); + Py_DECREF(v); + if (TOP() != NULL) continue; + x = NULL; /* set for error handler */ + #endif break; case UNARY_NEGATIVE: + #if !defined(FAST_STACK) v = POP(); x = PyNumber_Negative(v); Py_DECREF(v); PUSH(x); if (x != NULL) continue; + #else + v = TOP(); + TOP() = PyNumber_Negative(v); + Py_DECREF(v); + if (TOP() != NULL) continue; + x = NULL; /* set for error handler */ + #endif break; case UNARY_NOT: + #if !defined(FAST_STACK) v = POP(); err = PyObject_IsTrue(v); Py_DECREF(v); *************** *** 735,759 **** err = 0; continue; } break; ! case UNARY_CONVERT: v = POP(); x = PyObject_Repr(v); Py_DECREF(v); PUSH(x); if (x != NULL) continue; break; case UNARY_INVERT: v = POP(); x = PyNumber_Invert(v); Py_DECREF(v); PUSH(x); if (x != NULL) continue; break; case BINARY_POWER: w = POP(); v = POP(); x = PyNumber_Power(v, w, Py_None); --- 781,839 ---- err = 0; continue; } + #else + v = TOP(); + err = PyObject_IsTrue(v); + Py_DECREF(v); + if (err == 0) { + Py_INCREF(Py_True); + TOP() = Py_True; + continue; + } + else if (err > 0) { + Py_INCREF(Py_False); + TOP() = Py_False; + err = 0; + continue; + } + POP(); + #endif break; ! case UNARY_CONVERT: + #if !defined(FAST_STACK) v = POP(); x = PyObject_Repr(v); Py_DECREF(v); PUSH(x); if (x != NULL) continue; + #else + v = TOP(); + TOP() = PyObject_Repr(v); + Py_DECREF(v); + if (TOP() != NULL) continue; + x = NULL; + #endif break; case UNARY_INVERT: + #if !defined(FAST_STACK) v = POP(); x = PyNumber_Invert(v); Py_DECREF(v); PUSH(x); if (x != NULL) continue; + #else + v = TOP(); + TOP() = PyNumber_Invert(v); + Py_DECREF(v); + if (TOP() != NULL) continue; + x = NULL; /* set for error handler */ + #endif break; case BINARY_POWER: + #if !defined(FAST_STACK) w = POP(); v = POP(); x = PyNumber_Power(v, w, Py_None); *************** *** 761,769 **** --- 841,859 ---- Py_DECREF(w); PUSH(x); if (x != NULL) continue; + #else + w = POP(); + v = TOP(); + TOP() = PyNumber_Power(v, w, Py_None); + Py_DECREF(v); + Py_DECREF(w); + if (TOP() != NULL) continue; + x = NULL; /* set for error handler */ + #endif break; case BINARY_MULTIPLY: + #if !defined(FAST_STACK) w = POP(); v = POP(); x = PyNumber_Multiply(v, w); *************** *** 771,779 **** --- 861,879 ---- Py_DECREF(w); PUSH(x); if (x != NULL) continue; + #else + w = POP(); + v = TOP(); + TOP() = PyNumber_Multiply(v, w); + Py_DECREF(v); + Py_DECREF(w); + if (TOP() != NULL) continue; + x = NULL; /* set for error handler */ + #endif break; case BINARY_DIVIDE: + #if !defined(FAST_STACK) w = POP(); v = POP(); x = PyNumber_Divide(v, w); *************** *** 781,789 **** --- 881,899 ---- Py_DECREF(w); PUSH(x); if (x != NULL) continue; + #else + w = POP(); + v = TOP(); + TOP() = PyNumber_Divide(v, w); + Py_DECREF(v); + Py_DECREF(w); + if (TOP() != NULL) continue; + x = NULL; /* set for error handler */ + #endif break; case BINARY_MODULO: + #if !defined(FAST_STACK) w = POP(); v = POP(); x = PyNumber_Remainder(v, w); *************** *** 791,799 **** --- 901,919 ---- Py_DECREF(w); PUSH(x); if (x != NULL) continue; + #else + w = POP(); + v = TOP(); + TOP() = PyNumber_Remainder(v, w); + Py_DECREF(v); + Py_DECREF(w); + if (TOP() != NULL) continue; + x = NULL; /* set for error handler */ + #endif break; case BINARY_ADD: + #if 1 || !defined(FAST_STACK) w = POP(); v = POP(); if (PyInt_Check(v) && PyInt_Check(w)) { *************** *** 816,824 **** --- 936,969 ---- Py_DECREF(w); PUSH(x); if (x != NULL) continue; + #else + w = POP(); + v = TOP(); + if (PyInt_Check(v) && PyInt_Check(w)) { + /* INLINE: int + int */ + register long a, b, i; + a = ((PyIntObject*) v)->ob_ival; + b = ((PyIntObject*) w)->ob_ival; + i = a + b; + if ((i^a) < 0 && (i^b) < 0) { + PyErr_SetString(PyExc_OverflowError, + "integer addition"); + TOP() = NULL; + } + else + TOP() = PyInt_FromLong(i); + } + else + TOP() = PyNumber_Add(v, w); + Py_DECREF(v); + Py_DECREF(w); + if (TOP() != NULL) continue; + x = NULL; /* set for error handler */ + #endif break; case BINARY_SUBTRACT: + #if !defined(FAST_STACK) w = POP(); v = POP(); if (PyInt_Check(v) && PyInt_Check(w)) { *************** *** 841,849 **** --- 986,1019 ---- Py_DECREF(w); PUSH(x); if (x != NULL) continue; + #else + w = POP(); + v = TOP(); + if (PyInt_Check(v) && PyInt_Check(w)) { + /* INLINE: int - int */ + register long a, b, i; + a = ((PyIntObject*) v)->ob_ival; + b = ((PyIntObject*) w)->ob_ival; + i = a - b; + if ((i^a) < 0 && (i^~b) < 0) { + PyErr_SetString(PyExc_OverflowError, + "integer subtraction"); + TOP() = NULL; + } + else + TOP() = PyInt_FromLong(i); + } + else + TOP() = PyNumber_Subtract(v, w); + Py_DECREF(v); + Py_DECREF(w); + if (TOP() != NULL) continue; + x = NULL; /* set for error handler */ + #endif break; case BINARY_SUBSCR: + #if !defined(FAST_STACK) w = POP(); v = POP(); if (PyList_Check(v) && PyInt_Check(w)) { *************** *** 868,876 **** --- 1038,1089 ---- Py_DECREF(w); PUSH(x); if (x != NULL) continue; + #else + w = POP(); + v = TOP(); + if (PyInt_Check(w)) { + if (PyList_Check(v)) { + /* INLINE: list[int] */ + long i = PyInt_AS_LONG(w); + if (i < 0) i += PyList_GET_SIZE(v); + if (i < 0 || i >= PyList_GET_SIZE(v)) { + PyErr_SetString(PyExc_IndexError, + "list index out of range"); + TOP() = NULL; + } + else { + TOP() = PyList_GET_ITEM(v, i); + Py_INCREF(TOP()); + } + } + else if (PyTuple_Check(v)) { + /* INLINE: tuple[int] */ + long i = PyInt_AS_LONG(w); + if (i < 0) i += PyTuple_GET_SIZE(v); + if (i < 0 || i >= PyTuple_GET_SIZE(v)) { + PyErr_SetString(PyExc_IndexError, + "list index out of range"); + TOP() = NULL; + } + else { + TOP() = PyTuple_GET_ITEM(v, i); + Py_INCREF(TOP()); + } + } + else + TOP() = PyObject_GetItem(v, w); + } + else + TOP() = PyObject_GetItem(v, w); + Py_DECREF(v); + Py_DECREF(w); + if (TOP() != NULL) continue; + x = NULL; /* set for error handler */ + #endif break; case BINARY_LSHIFT: + #if !defined(FAST_STACK) w = POP(); v = POP(); x = PyNumber_Lshift(v, w); *************** *** 878,886 **** --- 1091,1109 ---- Py_DECREF(w); PUSH(x); if (x != NULL) continue; + #else + w = POP(); + v = TOP(); + TOP() = PyNumber_Lshift(v, w); + Py_DECREF(v); + Py_DECREF(w); + if (TOP() != NULL) continue; + x = NULL; /* for error handler */ + #endif break; case BINARY_RSHIFT: + #if !defined(FAST_STACK) w = POP(); v = POP(); x = PyNumber_Rshift(v, w); *************** *** 888,896 **** --- 1111,1129 ---- Py_DECREF(w); PUSH(x); if (x != NULL) continue; + #else + w = POP(); + v = TOP(); + TOP() = PyNumber_Rshift(v, w); + Py_DECREF(v); + Py_DECREF(w); + if (TOP() != NULL) continue; + x = NULL; /* for error handler */ + #endif break; case BINARY_AND: + #if !defined(FAST_STACK) w = POP(); v = POP(); x = PyNumber_And(v, w); *************** *** 898,906 **** --- 1131,1149 ---- Py_DECREF(w); PUSH(x); if (x != NULL) continue; + #else + w = POP(); + v = TOP(); + TOP() = PyNumber_And(v, w); + Py_DECREF(v); + Py_DECREF(w); + if (TOP() != NULL) continue; + x = NULL; /* for error handler */ + #endif break; case BINARY_XOR: + #if !defined(FAST_STACK) w = POP(); v = POP(); x = PyNumber_Xor(v, w); *************** *** 908,916 **** --- 1151,1169 ---- Py_DECREF(w); PUSH(x); if (x != NULL) continue; + #else + w = POP(); + v = TOP(); + TOP() = PyNumber_Xor(v, w); + Py_DECREF(v); + Py_DECREF(w); + if (TOP() != NULL) continue; + x = NULL; /* for error handler */ + #endif break; case BINARY_OR: + #if !defined(FAST_STACK) w = POP(); v = POP(); x = PyNumber_Or(v, w); *************** *** 918,923 **** --- 1171,1185 ---- Py_DECREF(w); PUSH(x); if (x != NULL) continue; + #else + w = POP(); + v = TOP(); + TOP() = PyNumber_Or(v, w); + Py_DECREF(v); + Py_DECREF(w); + if (TOP() != NULL) continue; + x = NULL; /* for error handler */ + #endif break; case SLICE+0: *************** *** 1200,1206 **** case UNPACK_LIST: v = POP(); if (PyTuple_Check(v)) { ! if (PyTuple_Size(v) != oparg) { PyErr_SetString(PyExc_ValueError, "unpack tuple of wrong size"); why = WHY_EXCEPTION; --- 1462,1468 ---- case UNPACK_LIST: v = POP(); if (PyTuple_Check(v)) { ! if (PyTuple_GET_SIZE(v) != oparg) { PyErr_SetString(PyExc_ValueError, "unpack tuple of wrong size"); why = WHY_EXCEPTION; *************** *** 1214,1220 **** } } else if (PyList_Check(v)) { ! if (PyList_Size(v) != oparg) { PyErr_SetString(PyExc_ValueError, "unpack list of wrong size"); why = WHY_EXCEPTION; --- 1476,1482 ---- } } else if (PyList_Check(v)) { ! if (PyList_GET_SIZE(v) != oparg) { PyErr_SetString(PyExc_ValueError, "unpack list of wrong size"); why = WHY_EXCEPTION; *************** *** 1243,1269 **** --- 1505,1558 ---- break; case STORE_ATTR: + #if !defined(FAST_STACK) w = GETNAMEV(oparg); v = POP(); u = POP(); err = PyObject_SetAttr(v, w, u); /* v.w = u */ Py_DECREF(v); Py_DECREF(u); + #else + w = GETNAMEV(oparg); + v = TOP(); + u = TOP2(); + stack_pointer -= 2; + err = PyObject_SetAttr(v, w, u); /* v.w = u */ + Py_DECREF(v); + Py_DECREF(u); + if (!err) continue; + #endif break; case DELETE_ATTR: + #if !defined(FAST_STACK) w = GETNAMEV(oparg); v = POP(); err = PyObject_SetAttr(v, w, (PyObject *)NULL); /* del v.w */ Py_DECREF(v); + #else + v = POP(); + err = PyObject_SetAttr(v, GETNAMEV(oparg), + (PyObject *)NULL); + /* del v.w */ + Py_DECREF(v); + if (!err) continue; + #endif break; case STORE_GLOBAL: + #if !defined(FAST_STACK) w = GETNAMEV(oparg); v = POP(); err = PyDict_SetItem(f->f_globals, w, v); Py_DECREF(v); + #else + v = POP(); + err = PyDict_SetItem(f->f_globals, GETNAMEV(oparg), v); + Py_DECREF(v); + if (!err) continue; + #endif break; case DELETE_GLOBAL: *************** *** 1271,1284 **** if ((err = PyDict_DelItem(f->f_globals, w)) != 0) PyErr_SetObject(PyExc_NameError, w); break; ! case LOAD_CONST: x = GETCONST(oparg); Py_INCREF(x); PUSH(x); ! break; case LOAD_NAME: w = GETNAMEV(oparg); if ((x = f->f_locals) == NULL) { PyErr_SetString(PyExc_SystemError, --- 1560,1584 ---- if ((err = PyDict_DelItem(f->f_globals, w)) != 0) PyErr_SetObject(PyExc_NameError, w); break; ! case LOAD_CONST: + #if !defined(FAST_STACK) x = GETCONST(oparg); Py_INCREF(x); PUSH(x); ! #else ! PUSH(GETCONST(oparg)); ! Py_INCREF(TOP()); ! #endif ! continue; ! ! case LOAD_NONE: ! Py_INCREF(Py_None); ! PUSH(Py_None); ! continue; case LOAD_NAME: + #if !defined(FAST_STACK) w = GETNAMEV(oparg); if ((x = f->f_locals) == NULL) { PyErr_SetString(PyExc_SystemError, *************** *** 1302,1308 **** Py_INCREF(x); PUSH(x); break; ! case LOAD_GLOBAL: w = GETNAMEV(oparg); x = PyDict_GetItem(f->f_globals, w); --- 1602,1634 ---- Py_INCREF(x); PUSH(x); break; ! #else ! ! if ((x = f->f_locals) == NULL) { ! PyErr_SetString(PyExc_SystemError, ! "no locals"); ! break; ! } ! x = PyDict_GetItem(x, GETNAMEV(oparg)); ! if (x == NULL) { ! w = GETNAMEV(oparg); ! PyErr_Clear(); ! x = PyDict_GetItem(f->f_globals, w); ! if (x == NULL) { ! PyErr_Clear(); ! x = PyDict_GetItem(f->f_builtins, w); ! if (x == NULL) { ! PyErr_SetObject( ! PyExc_NameError, w); ! break; ! } ! } ! } ! Py_INCREF(x); ! PUSH(x); ! continue; ! #endif ! case LOAD_GLOBAL: w = GETNAMEV(oparg); x = PyDict_GetItem(f->f_globals, w); *************** *** 1328,1335 **** } Py_INCREF(x); PUSH(x); ! if (x != NULL) continue; ! break; case STORE_FAST: v = POP(); --- 1654,1660 ---- } Py_INCREF(x); PUSH(x); ! continue; case STORE_FAST: v = POP(); *************** *** 1353,1358 **** --- 1678,1684 ---- break; case BUILD_LIST: + #if !defined(FAST_STACK) x = PyList_New(oparg); if (x != NULL) { for (; --oparg >= 0;) { *************** *** 1364,1387 **** PUSH(x); continue; } break; case BUILD_MAP: x = PyDict_New(); PUSH(x); if (x != NULL) continue; break; case LOAD_ATTR: w = GETNAMEV(oparg); v = POP(); x = PyObject_GetAttr(v, w); Py_DECREF(v); PUSH(x); if (x != NULL) continue; break; ! case COMPARE_OP: w = POP(); v = POP(); if (PyInt_Check(v) && PyInt_Check(w)) { --- 1690,1738 ---- PUSH(x); continue; } + #else + x = PyList_New(oparg); + if (x != NULL) { + for (; --oparg >= 0;) { + PyList_SET_ITEM(x, oparg, POP()); + } + PUSH(x); + continue; + } + #endif break; case BUILD_MAP: + #if !defined(FAST_STACK) x = PyDict_New(); PUSH(x); if (x != NULL) continue; + #else + PUSH(PyDict_New()); + if (TOP() != NULL) continue; + x = NULL; /* set for error handler */ + #endif break; case LOAD_ATTR: + #if !defined(FAST_STACK) w = GETNAMEV(oparg); v = POP(); x = PyObject_GetAttr(v, w); Py_DECREF(v); PUSH(x); if (x != NULL) continue; + #else + v = TOP(); + TOP() = PyObject_GetAttr(v, GETNAMEV(oparg)); + Py_DECREF(v); + if (TOP() != NULL) continue; + x = NULL; /* set for error handler */ + #endif break; ! case COMPARE_OP: + #if !defined(FAST_STACK) w = POP(); v = POP(); if (PyInt_Check(v) && PyInt_Check(w)) { *************** *** 1412,1417 **** --- 1763,1798 ---- Py_DECREF(w); PUSH(x); if (x != NULL) continue; + #else + w = POP(); + v = TOP(); + if (PyInt_Check(v) && PyInt_Check(w)) { + /* INLINE: cmp(int, int) */ + register long a, b; + a = PyInt_AS_LONG(v); + b = PyInt_AS_LONG(w); + switch (oparg) { + case LT: x = (a < b) ? Py_True : Py_False; break; + case LE: x = (a <= b) ? Py_True : Py_False; break; + case EQ: x = (a == b) ? Py_True : Py_False; break; + case NE: x = (a != b) ? Py_True : Py_False; break; + case GT: x = (a > b) ? Py_True : Py_False; break; + case GE: x = (a >= b) ? Py_True : Py_False; break; + case IS: x = (v == w) ? Py_True : Py_False; break; + case IS_NOT: x = (v != w) ? Py_True : Py_False; break; + default: goto slow_compare; + } + Py_INCREF(x); + } + else { + slow_compare: + x = cmp_outcome(oparg, v, w); + } + Py_DECREF(v); + Py_DECREF(w); + TOP() = x; + if (x != NULL) continue; + #endif break; case IMPORT_NAME: