[pypy-dev] Restricted language

Armin Rigo arigo at tunes.org
Sun Jan 19 20:51:59 CET 2003


Hello Christian,

On Sun, Jan 19, 2003 at 03:16:55PM +0100, Christian Tismer wrote:
> > Redoing the basic types can be deferred IMO. 
> > Basically we need to do typeobject.c in python, right?
> 
> I thought so, too, but I'm not sure if my
> overview of the whole thing is good enough
> to judge this early.

I'm not sure typeobject.c has a special role to play here.  We might at first
just rely on built-in Python objects to implement all our classes, including
type objects.

> > I am still thinking about Roccos issue of how to 
> > "differentiate" host system (CPython) exceptions from
> > exception of the code we interprete in python.  My first 
> > take is to catch any exception, rewrite the traceback 
> > information (using the python-frames) and reraise it. 

Here we are confusing the two levels of Python.  Let's call them the
interpreter-level and the application-level.  Each application-level object is
emulated by an interpreter-level instance of a class like

class PyObject:
  v_ob_type = property(...)
  ...

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.

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):
    ...

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.

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

where the ImmediateObject()s are here because an application-level exception
stores application-level values.  The main loop catches EPython exceptions.

If we want to follow the C code less closely but be more Pythonic, we can drop
the above SetException() which would store information into something like
CPython's PyThreadState.  Instead, we can directly embed this information into
the EPython class:

class EPython(Exception):
  def __init__(self, v_type, v_value):
    ...

I prefix the argument names with 'v_' to remind us that an application-level
object is expected (i.e. an instance of PyObject), not e.g. ValueError or a
string.  Then the code becomes

   raise EPython(ImmediateObject(IndexError), 
                 ImmediateObject("index out of bounds"))

which I believe clearly shows the distinction between application-level and
interpreter-level exceptions.

Oh, and if you got it right, you must see why the 'v_ob_type' property of
'class PyObject' earlier in this mail must never hold a real type like 'int'
or 'list', but instead an application-level type object like
'ImmediateObject(int)' or 'ImmediateObject(list)'.


A bientot,

Armin.



More information about the Pypy-dev mailing list