[pypy-svn] r38717 - pypy/dist/pypy/doc

pedronis at codespeak.net pedronis at codespeak.net
Tue Feb 13 17:09:18 CET 2007


Author: pedronis
Date: Tue Feb 13 17:09:16 2007
New Revision: 38717

Modified:
   pypy/dist/pypy/doc/geninterp.txt
Log:
update, add some more explanation, use current output in the example.



Modified: pypy/dist/pypy/doc/geninterp.txt
==============================================================================
--- pypy/dist/pypy/doc/geninterp.txt	(original)
+++ pypy/dist/pypy/doc/geninterp.txt	Tue Feb 13 17:09:16 2007
@@ -32,14 +32,18 @@
 Solution
 ++++++++
 
-This bootstrap issue is solved by invoking a new bytecode interpreter which
-runs on FlowObjspace. FlowObjspace is complete without complicated
-initialization. It is able to do abstract interpretation of any
-Rpythonic code, without actually implementing anything. It just
+This bootstrap issue is solved by invoking a new bytecode interpreter
+which runs on FlowObjspace. FlowObjspace is complete without
+complicated initialization. It is able to do abstract interpretation
+of any Rpythonic code, without actually implementing anything. It just
 records all the operations the bytecode interpreter would have done by
 building flowgraphs for all the code. What the Python backend does is
 just to produce correct Python code from these flowgraphs and return
-it as source code.
+it as source code. In the produced code Python operations recorded in
+the original flowgraphs are replaced by calls to the corresponding
+methods in the `object space`_ interface.
+
+.. _`object space`: objspace.html
 
 Example
 +++++++
@@ -67,88 +71,79 @@
 recorded every possible codepath into a flowgraph, and then rendered the
 following source code:: 
 
-    >>> print source
     #!/bin/env python
     # -*- coding: LATIN-1 -*-
 
     def initapp2interpexec(space):
       """NOT_RPYTHON"""
 
-      def g(space, __args__):
-        funcname = "g"
-        signature = ['n'], None, None
-        defaults_w = []
-        w_n_2, = __args__.parse(funcname, signature, defaults_w)
-        return fastf_g(space, w_n_2)
-
-      f_g = g
-
-      def g(space, w_n_2):
+      def g(space, w_n_1):
         goto = 3 # startblock
         while True:
 
             if goto == 1:
                 v0 = space.is_true(w_n)
                 if v0 == True:
-                    w_n_1, w_0 = w_n, w_i
                     goto = 2
                 else:
-                    assert v0 == False
-                    w_1 = w_i
                     goto = 4
 
             if goto == 2:
-                w_2 = space.add(w_0, w_n_1)
-                w_3 = space.sub(w_n_1, space.w_True)
-                w_n, w_i = w_3, w_2
+                w_1 = space.add(w_0, w_n)
+                w_2 = space.sub(w_n, gi_1)
+                w_n, w_0 = w_2, w_1
                 goto = 1
                 continue
 
             if goto == 3:
-                w_n, w_i = w_n_2, space.w_False
+                w_n, w_0 = w_n_1, gi_0
                 goto = 1
                 continue
 
             if goto == 4:
-                return w_1
+                return w_0
 
       fastf_g = g
 
-      g3dict = space.newdict([])
-      gs___name__ = space.wrap('__name__')
-      gs_app2interpexec = space.wrap('app2interpexec')
+      g3dict = space.newdict()
+      gs___name__ = space.new_interned_str('__name__')
+      gs_app2interpexec = space.new_interned_str('app2interpexec')
       space.setitem(g3dict, gs___name__, gs_app2interpexec)
-      gs_g = space.wrap('g')
+      gs_g = space.new_interned_str('g')
       from pypy.interpreter import gateway
-      gfunc_g = space.wrap(gateway.interp2app(f_g, unwrap_spec=[gateway.ObjSpace, gateway.Arguments]))
+      gfunc_g = space.wrap(gateway.interp2app(fastf_g, unwrap_spec=[gateway.ObjSpace, gateway.W_Root]))
       space.setitem(g3dict, gs_g, gfunc_g)
+      gi_1 = space.wrap(1)
+      gi_0 = space.wrap(0)
       return g3dict
 
-You see that actually a single function is produced: ``initapp2interpexec``. This is the
-function that you will call with a space as argument. It defines a few functions and then
-does a number of initialization steps, builds the global objects the function need,
-and produces the interface function ``gfunc_g`` to be called from interpreter level.
-
-The return value is ``g3dict``, which contains a module name and the function we asked for.
-
-Let's have a look at the body of this code: The first definition of ``g`` is just
-for the argument parsing and is used as ``f_g`` in the ``gateway.interp2app``.
-We look at the second definition, ``fastf_g``, which does the actual
-computation. Comparing to the flowgraph,
-you see a code block for every block in the graph.
-Since Python has no goto statement, the jumps between the blocks are implemented
-by a loop that switches over a ``goto`` variable.
+You see that actually a single function is produced:
+``initapp2interpexec``. This is the function that you will call with a
+space as argument. It defines a few functions and then does a number
+of initialization steps, builds the global objects the function need,
+and produces the PyPy function object ``gfunc_g``.
+
+The return value is ``g3dict``, which contains a module name and the
+function we asked for.
+
+Let's have a look at the body of this code: The definition of ``g`` is
+used as ``fast_g`` in the ``gateway.interp2app`` which constructs a
+PyPy function object which takes care of argument unboxing (based on
+the ``unwrap_spec``), and of invoking the original ``g``.
+
+We look at the definition of ``g`` itself which does the actual
+computation. Comparing to the flowgraph, you see a code block for
+every block in the graph.  Since Python has no goto statement, the
+jumps between the blocks are implemented by a loop that switches over
+a ``goto`` variable.
 
 ::
 
     .       if goto == 1:
                 v0 = space.is_true(w_n)
                 if v0 == True:
-                    w_n_1, w_0 = w_n, w_i
                     goto = 2
                 else:
-                    assert v0 == False
-                    w_1 = w_i
                     goto = 4
 
 This is the implementation of the "``while n:``". There is no implicit state,
@@ -160,16 +155,16 @@
 ::
 
     .       if goto == 2:
-                w_2 = space.add(w_0, w_n_1)
-                w_3 = space.sub(w_n_1, space.w_True)
-                w_n, w_i = w_3, w_2
+                w_1 = space.add(w_0, w_n)
+                w_2 = space.sub(w_n, gi_1)
+                w_n, w_0 = w_2, w_1
                 goto = 1
                 continue
 
 The "``i = i + n``" and "``n = n - 1``" instructions.
 You see how every instruction produces a new variable.
 The state is again shuffled around by assigning to the
-input variables ``w_n`` and ``w_i`` of the next target, block 1.
+input variables ``w_n`` and ``w_0`` of the next target, block 1.
 
 Note that it is possible to rewrite this by re-using variables,
 trying to produce nested blocks instead of the goto construction
@@ -200,11 +195,3 @@
 a cached code snippet clear by double-clicking it. Note also that
 the auto-generated __init__.py file wipes the whole directory
 when executed.
-
-XXX this should go into some interpreter.doc, where gateway should be explained
-
-
-How it works
-++++++++++++
-
-XXX to be added later



More information about the Pypy-commit mailing list