[Python-Dev] Parrot -- should life imitate satire?

Tim Peters tim.one@home.com
Wed, 1 Aug 2001 00:42:42 -0400


[Guido]
> Actually, this may not be as big a deal as I thought before.  The PVM
> doesn't have a lot of knowledge about types built into its instruction
> set.  It knows a bit about classes, lists, dicts, but not e.g. about
> ints and strings.  The opcodes are mostly very abstract: BINARY_ADD etc.

I agree overall, but you picked an unfortunate example.  BINARY_DIVIDE is a
perfect example:

		case BINARY_DIVIDE:
			w = POP();
			v = POP();
			x = PyNumber_Divide(v, w);
			Py_DECREF(v);
			Py_DECREF(w);
			PUSH(x);
			if (x != NULL) continue;
			break;

(For Perl'ers, an operation in Python returns a PyObject*, and returns NULL
iff the operation wants to raise an exception; the "continue" if x != NULL
tells it to go straight back to the top of the eval loop (to fetch the next
opcode) if there is no exception; else control flows out of the switch stmt,
and masses of code figure out what to *do* with the exception.)

That code works unchanged for any pair of objects whatsoever that think they
know what to do with an infix "/", since all the intelligence is in
PyNumber_Divide().

But BINARY_ADD knows everything there is to know about Python ints, and
that's an important speed optimization:

		case BINARY_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_Add(v, w);
			Py_DECREF(v);
			Py_DECREF(w);
			PUSH(x);
			if (x != NULL) continue;
			break;

While we don't peek under the covers often in the eval loop, the places we
do were huge benefit/effort wins.