[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.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4