[pypy-dev] Restricted language
holger krekel
hpk at trillke.net
Mon Jan 20 04:40:04 CET 2003
[armin on using a simple PyObject emulation class ...]
> Let's compare this with a C compiler which must manage a complex data
> structure for every variable of the C program it compiles. The PyObject class
> is this data structure. If a variable of the C program is found to be a
> constant, then the C compiler will internally use a special structure which
> holds (among other management data) the constant immediate value as a
> C-compiler-level value. So let's call an "immediate" a C-program-level value
> which is directly implemented by a C-compiler-level value. Non-immediate
> values would be e.g. variables that are stored in the stack.
using Bengt's suggestion we could say that an "immediate"
C-program-level value is represented by a C-compiler-level value.
> Similarily, if we want to implement, say, dictionaries using real Python
> dictionaries, it is an application-level object that must be implemented using
> a more complex structure which holds, among other things, a real
> interpreter-level dictionary. It's just the same as immediates in C programs:
>
> class ImmediateObject(PyObject):
> def __init__(self, ob):
> ...
your class definition "tags" an CPython object as an "immediate"
object, right?
> An application-level dictionary (say created by the BUILD_DICT opcode) is
> constructed as "ImmediateObject({})". In a first phase we need only
> ImmediateObjects because (almost?) all application-level objects can be
> implemented this way.
ImmediateObjects would be tagged CPython objects.
I don't see immediate use, though :-)
> Now let's talk about exceptions. There are also application-level exceptions
> (the ones that can be caught by except: in the interpreted application) and
> interpreter-level exceptions (e.g. a bug in the interpreter raising some
> IndexError). The former must be emulated, not used directly at the
> interpreter-level. It is just a coincidence that an application-level
> exception generally also means the stack of calls made by the interpreter must
> be popped up to the main loop's block handlers. To perform the latter we need
> a new exception:
>
> class EPython(Exception):
> pass
>
> Then the immediate translation of the CPython code
>
> PyErr_SetString(PyExc_IndexError, "index out of bounds");
> return NULL;
>
> is
>
> SetException(ImmediateObject(IndexError),
> ImmediateObject("index out of bounds"))
> raise EPython
IMHO the python level interpreter should not deal with
exceptions like this.
E.g. CPython's BINARY_SUBSCR bytecode implementation raises
the above exception as an optimization to avoid calling the
generic PyObject_GetItem (which does lots of checks itself).
But i'd like to implement BINARY_SUBSCR like this:
def BINARY_SUBSCR(self):
w = self.valuestack.pop()
v = self.valuestack.pop()
self.valuestack.push(w.__getitem__(v))
With CPython this could raise an exception if 'v'
would be "out of bound" or 'w' doesn't implement
the getitem-protocol or whatever.
The tricky part (to me) is catching the (CPython-)
exception and executing the application-level
except/finally code in the current bytecodestring.
I have done some stuff with "exception/finally" handling
wrapped into an object in this CPython-Hack:
http://codespeak.net/moin/moin.cgi/IndentedExecution
It introduces an object (and strange xml-ish syntax :-)
which wraps except/finally handling so that the 'except:'
or 'finally:' code is *not* in the current bytecode-string.
If reading it, don't look at the namespace interaction bits,
they are distracting for our context.
I think i'd like to try out an approach where no bytecode
needs more than a few lines of python implementation and
exception handling is easy to understand. IMO it is
especially important to me that all the optimization stuff
(like in BINARY_SUBSCR) is removed. Hopefully only
the main dispatching loop will have to deal with
exceptions & their (re)presentation to the
application-level ...
cheers,
holger
More information about the Pypy-dev
mailing list