[pypy-svn] r8227 - in pypy/branch/src-pytest/pypy: appspace interpreter objspace/flow objspace/std tool translator translator/java translator/java/test translator/test translator/tool

pedronis at codespeak.net pedronis at codespeak.net
Wed Jan 12 15:31:13 CET 2005


Author: pedronis
Date: Wed Jan 12 15:31:13 2005
New Revision: 8227

Added:
   pypy/branch/src-pytest/pypy/appspace/struct.py
      - copied unchanged from r8225, pypy/trunk/src/pypy/appspace/struct.py
   pypy/branch/src-pytest/pypy/translator/geninterplevel.py   (props changed)
      - copied unchanged from r8225, pypy/trunk/src/pypy/translator/geninterplevel.py
   pypy/branch/src-pytest/pypy/translator/java/   (props changed)
      - copied from r8225, pypy/trunk/src/pypy/translator/java/
   pypy/branch/src-pytest/pypy/translator/java/PyBool.java   (props changed)
      - copied unchanged from r8225, pypy/trunk/src/pypy/translator/java/PyBool.java
   pypy/branch/src-pytest/pypy/translator/java/PyInt.java   (props changed)
      - copied unchanged from r8225, pypy/trunk/src/pypy/translator/java/PyInt.java
   pypy/branch/src-pytest/pypy/translator/java/PyList.java   (props changed)
      - copied unchanged from r8225, pypy/trunk/src/pypy/translator/java/PyList.java
   pypy/branch/src-pytest/pypy/translator/java/PyObject.java   (props changed)
      - copied unchanged from r8225, pypy/trunk/src/pypy/translator/java/PyObject.java
   pypy/branch/src-pytest/pypy/translator/java/PySequence.java   (props changed)
      - copied unchanged from r8225, pypy/trunk/src/pypy/translator/java/PySequence.java
   pypy/branch/src-pytest/pypy/translator/java/PyTuple.java   (props changed)
      - copied unchanged from r8225, pypy/trunk/src/pypy/translator/java/PyTuple.java
   pypy/branch/src-pytest/pypy/translator/java/TypeError.java   (props changed)
      - copied unchanged from r8225, pypy/trunk/src/pypy/translator/java/TypeError.java
   pypy/branch/src-pytest/pypy/translator/java/__init__.py   (props changed)
      - copied unchanged from r8225, pypy/trunk/src/pypy/translator/java/__init__.py
   pypy/branch/src-pytest/pypy/translator/java/autopath.py   (props changed)
      - copied unchanged from r8225, pypy/trunk/src/pypy/translator/java/autopath.py
   pypy/branch/src-pytest/pypy/translator/java/genjava.py   (props changed)
      - copied unchanged from r8225, pypy/trunk/src/pypy/translator/java/genjava.py
   pypy/branch/src-pytest/pypy/translator/java/test/   (props changed)
      - copied from r8225, pypy/trunk/src/pypy/translator/java/test/
   pypy/branch/src-pytest/pypy/translator/java/test/__init__.py
      - copied unchanged from r8225, pypy/trunk/src/pypy/translator/java/test/__init__.py
   pypy/branch/src-pytest/pypy/translator/java/test/autopath.py   (props changed)
      - copied unchanged from r8225, pypy/trunk/src/pypy/translator/java/test/autopath.py
   pypy/branch/src-pytest/pypy/translator/java/test/test_javatrans.py   (contents, props changed)
      - copied, changed from r8225, pypy/trunk/src/pypy/translator/java/test/test_javatrans.py
Modified:
   pypy/branch/src-pytest/pypy/appspace/_formatting.py
   pypy/branch/src-pytest/pypy/appspace/md5.py
   pypy/branch/src-pytest/pypy/interpreter/error.py
   pypy/branch/src-pytest/pypy/objspace/flow/model.py
   pypy/branch/src-pytest/pypy/objspace/flow/objspace.py
   pypy/branch/src-pytest/pypy/objspace/std/longobject.py
   pypy/branch/src-pytest/pypy/objspace/std/objspace.py
   pypy/branch/src-pytest/pypy/tool/hack.py
   pypy/branch/src-pytest/pypy/translator/genc.h
   pypy/branch/src-pytest/pypy/translator/genc.py
   pypy/branch/src-pytest/pypy/translator/gencl.py
   pypy/branch/src-pytest/pypy/translator/genrpy.py
   pypy/branch/src-pytest/pypy/translator/test/test_ctrans.py
   pypy/branch/src-pytest/pypy/translator/tool/buildpyxmodule.py
Log:
merged changes happened on the head into src-pytest branch


Modified: pypy/branch/src-pytest/pypy/appspace/_formatting.py
==============================================================================
--- pypy/branch/src-pytest/pypy/appspace/_formatting.py	(original)
+++ pypy/branch/src-pytest/pypy/appspace/_formatting.py	Wed Jan 12 15:31:13 2005
@@ -225,7 +225,7 @@
 class FloatFFormatter(FloatFormatter):
     def _format(self, v):
         if v/1e25 > 1e25:
-            return floatGFormatter('g', self.flags, self.width,
+            return FloatGFormatter('g', self.flags, self.width,
                                    self.prec, self.value).format()
         ds, k = flonum2digits(v)
         digits = self.fDigits(ds, k)

Modified: pypy/branch/src-pytest/pypy/appspace/md5.py
==============================================================================
--- pypy/branch/src-pytest/pypy/appspace/md5.py	(original)
+++ pypy/branch/src-pytest/pypy/appspace/md5.py	Wed Jan 12 15:31:13 2005
@@ -32,6 +32,7 @@
 __date__    = '2004-11-17'
 __version__ = 0.91 # Modernised by J. Hallén and L. Creighton for Pypy
 
+__metaclass__ = type # or genrpy won't work
 
 import struct, copy
 

Modified: pypy/branch/src-pytest/pypy/interpreter/error.py
==============================================================================
--- pypy/branch/src-pytest/pypy/interpreter/error.py	(original)
+++ pypy/branch/src-pytest/pypy/interpreter/error.py	Wed Jan 12 15:31:13 2005
@@ -21,6 +21,7 @@
     """
 
     def __init__(self, w_type, w_value, tb=None):
+        assert w_type is not None, w_value
         self.w_type = w_type
         self.w_value = w_value
         self.application_traceback = tb

Modified: pypy/branch/src-pytest/pypy/objspace/flow/model.py
==============================================================================
--- pypy/branch/src-pytest/pypy/objspace/flow/model.py	(original)
+++ pypy/branch/src-pytest/pypy/objspace/flow/model.py	Wed Jan 12 15:31:13 2005
@@ -153,7 +153,7 @@
         if (r.startswith('<') and r.endswith('>') and
             hasattr(self.value, '__name__')):
             r = '%s %s' % (type(self.value).__name__, self.value.__name__)
-        elif len(r) > 30:
+        elif len(r) > 60 or (len(r) > 30 and type(self.value) is not str):
             r = r[:20] + '...' + r[-8:]
         return '(%s)' % r
 

Modified: pypy/branch/src-pytest/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/branch/src-pytest/pypy/objspace/flow/objspace.py	(original)
+++ pypy/branch/src-pytest/pypy/objspace/flow/objspace.py	Wed Jan 12 15:31:13 2005
@@ -34,6 +34,12 @@
                     AssertionError]:
             clsname = exc.__name__
             setattr(self, 'w_'+clsname, Constant(exc))
+        # the following exceptions are the ones that should not show up
+        # during flow graph construction; they are triggered by
+        # non-R-Pythonic constructs or real bugs like typos.
+        for exc in [NameError, UnboundLocalError]:
+            clsname = exc.__name__
+            setattr(self, 'w_'+clsname, None)
         self.specialcases = {}
         #self.make_builtins()
         #self.make_sys()

Modified: pypy/branch/src-pytest/pypy/objspace/std/longobject.py
==============================================================================
--- pypy/branch/src-pytest/pypy/objspace/std/longobject.py	(original)
+++ pypy/branch/src-pytest/pypy/objspace/std/longobject.py	Wed Jan 12 15:31:13 2005
@@ -19,29 +19,6 @@
 
 registerimplementation(W_LongObject)
 
-# int-to-long delegation
-def delegate__Int(space, w_intobj):
-    return W_LongObject(space, long(w_intobj.intval))
-delegate__Int.result_class = W_LongObject
-delegate__Int.priority = PRIORITY_CHANGE_TYPE
-
-# long-to-int delegation
-def delegate__Long(space, w_longobj):
-    if -sys.maxint-1 <= w_longobj.longval <= sys.maxint:
-        return W_IntObject(space, int(w_longobj.longval))
-    else:
-        # note the 'return' here -- hack
-        return FailedToImplement(space.w_OverflowError,
-                   space.wrap("long int too large to convert to int"))
-delegate__Long.result_class = W_IntObject
-delegate__Long.priority = PRIORITY_CHANGE_TYPE
-delegate__Long.can_fail = True
-
-## # long-to-float delegation
-## def delegate__Long(space, w_longobj):
-##     return W_FloatObject(space, float(w_longobj.longval))
-## delegate__Long.result_class = W_FloatObject
-## delegate__Long.priority = PRIORITY_CHANGE_TYPE
 
 # long__Long is supposed to do nothing, unless it has
 # a derived long object, where it should return
@@ -224,3 +201,36 @@
 
 
 register_all(vars())
+
+# delegations must be registered manually because we have more than one
+# long-to-something delegation
+
+# int-to-long delegation
+def delegate_from_int(space, w_intobj):
+    return W_LongObject(space, long(w_intobj.intval))
+delegate_from_int.result_class = W_LongObject
+delegate_from_int.priority = PRIORITY_CHANGE_TYPE
+
+StdObjSpace.delegate.register(delegate_from_int, W_IntObject)
+
+# long-to-int delegation
+def delegate_to_int(space, w_longobj):
+    if -sys.maxint-1 <= w_longobj.longval <= sys.maxint:
+        return W_IntObject(space, int(w_longobj.longval))
+    else:
+        # note the 'return' here -- hack
+        return FailedToImplement(space.w_OverflowError,
+                   space.wrap("long int too large to convert to int"))
+delegate_to_int.result_class = W_IntObject
+delegate_to_int.priority = PRIORITY_CHANGE_TYPE
+delegate_to_int.can_fail = True
+
+StdObjSpace.delegate.register(delegate_to_int, W_LongObject)
+
+# long-to-float delegation
+def delegate_to_float(space, w_longobj):
+    return W_FloatObject(space, float(w_longobj.longval))
+delegate_to_float.result_class = W_FloatObject
+delegate_to_float.priority = PRIORITY_CHANGE_TYPE
+
+StdObjSpace.delegate.register(delegate_to_float, W_LongObject)

Modified: pypy/branch/src-pytest/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/branch/src-pytest/pypy/objspace/std/objspace.py	(original)
+++ pypy/branch/src-pytest/pypy/objspace/std/objspace.py	Wed Jan 12 15:31:13 2005
@@ -243,12 +243,12 @@
             return W_ListObject(self, wrappeditems)
         if isinstance(x, long):
             return W_LongObject(self, x)
-        if isinstance(x, complex):
-            # XXX is this right?
-            c = self.getitem(self.w_builtins, self.wrap("complex"))
-            return self.call_function(c,
-                                      self.wrap(x.real), 
-                                      self.wrap(x.imag))
+##        if isinstance(x, complex):
+##            # XXX is this right?   YYY no, this is wrong right now  (CT)
+##            c = self.getitem(self.w_builtins, self.wrap("complex"))
+##            return self.call_function(c,
+##                                      self.wrap(x.real), 
+##                                      self.wrap(x.imag))
         if isinstance(x, BaseWrappable):
             w_result = x.__spacebind__(self)
             #print 'wrapping', x, '->', w_result

Modified: pypy/branch/src-pytest/pypy/tool/hack.py
==============================================================================
--- pypy/branch/src-pytest/pypy/tool/hack.py	(original)
+++ pypy/branch/src-pytest/pypy/tool/hack.py	Wed Jan 12 15:31:13 2005
@@ -2,7 +2,7 @@
 
 import new, sys
 
-if sys.version_info > (2, 2):
+if sys.version_info >= (2, 3):
 
     def func_with_new_name(func, newname):
         f = new.function(func.func_code, func.func_globals,

Modified: pypy/branch/src-pytest/pypy/translator/genc.h
==============================================================================
--- pypy/branch/src-pytest/pypy/translator/genc.h	(original)
+++ pypy/branch/src-pytest/pypy/translator/genc.h	Wed Jan 12 15:31:13 2005
@@ -199,6 +199,11 @@
 
 #if defined(USE_CALL_TRACE)
 
+#define TRACE_CALL       __f, __tstate,
+#define TRACE_ARGS       PyFrameObject *__f, PyThreadState *__tstate,
+#define TRACE_CALL_VOID  __f, __tstate
+#define TRACE_ARGS_VOID  PyFrameObject *__f, PyThreadState *__tstate
+
 #define FAIL(err) { __f->f_lineno = __f->f_code->co_firstlineno = __LINE__; goto err; }
 
 #define FUNCTION_HEAD(signature, self, args, names, file, line) \
@@ -215,6 +220,11 @@
 
 #else /* !defined(USE_CALL_TRACE) */
 
+#define TRACE_CALL       /* nothing */
+#define TRACE_ARGS       /* nothing */
+#define TRACE_CALL_VOID  /* nothing */
+#define TRACE_ARGS_VOID  void
+
 #define FAIL(err) { goto err; }
 
 #define FUNCTION_HEAD(signature, self, args, names, file, line)

Modified: pypy/branch/src-pytest/pypy/translator/genc.py
==============================================================================
--- pypy/branch/src-pytest/pypy/translator/genc.py	(original)
+++ pypy/branch/src-pytest/pypy/translator/genc.py	Wed Jan 12 15:31:13 2005
@@ -38,8 +38,6 @@
 
 class GenC:
     MODNAMES = {}
-    # XXX - I don't know how to make a macro do this.. so..
-    USE_CALL_TRACE = True
 
     def __init__(self, f, translator, modname=None, f2=None, f2name=None):
         self.f = f
@@ -454,8 +452,6 @@
             'entrypoint': self.nameof(self.translator.functions[0]),
             }
         # header
-        if self.USE_CALL_TRACE:
-            print >> f, '#define USE_CALL_TRACE'
         print >> f, self.C_HEADER
 
         # function implementations
@@ -510,9 +506,9 @@
         self.gen_global_declarations()
 
         # print header
-        name = self.nameof(func)
-        assert name.startswith('gfunc_')
-        f_name = 'f_' + name[6:]
+        cname = self.nameof(func)
+        assert cname.startswith('gfunc_')
+        f_name = 'f_' + cname[6:]
 
         # collect all the local variables
         graph = self.translator.getflowgraph(func)
@@ -540,22 +536,31 @@
         fast_set = dict(zip(fast_args, fast_args))
 
         declare_fast_args = [('PyObject *' + a) for a in fast_args]
-        if self.USE_CALL_TRACE:
-            declare_fast_args[:0] = ['PyFrameObject *__f', 'PyThreadState *__tstate']
+        if declare_fast_args:
+            declare_fast_args = 'TRACE_ARGS ' + ', '.join(declare_fast_args)
+        else:
+            declare_fast_args = 'TRACE_ARGS_VOID'
+        fast_function_header = ('static PyObject *\n'
+                                '%s(%s)' % (fast_name, declare_fast_args))
 
-        print >> f, 'static PyObject *'
-        print >> f, '%s(%s);' % (fast_name, ', '.join(declare_fast_args))
+        print >> f, fast_function_header + ';'  # forward
         print >> f
 
         print >> f, 'static PyObject *'
-        print >> f, '%s(PyObject* self, PyObject* args)' % (f_name,)
+        print >> f, '%s(PyObject* self, PyObject* args, PyObject* kwds)' % (
+            f_name,)
         print >> f, '{'
         print >> f, '\tFUNCTION_HEAD(%s, %s, args, %s, __FILE__, __LINE__ - 2)' % (
-            c_string('%s(%s)' % (name, ', '.join(name_of_defaults))),
-            name,
+            c_string('%s(%s)' % (cname, ', '.join(name_of_defaults))),
+            cname,
             '(%s)' % (', '.join(map(c_string, name_of_defaults) + ['NULL']),),
         )
 
+        kwlist = ['"%s"' % name for name in
+                      func.func_code.co_varnames[:func.func_code.co_argcount]]
+        kwlist.append('0')
+        print >> f, '\tstatic char* kwlist[] = {%s};' % (', '.join(kwlist),)
+
         if fast_args:
             print >> f, '\tPyObject *%s;' % (', *'.join(fast_args))
         print >> f
@@ -586,24 +591,27 @@
             print >> f, '\t%s = %s;' % (
                 positional_args[min_number_of_args+i],
                 name_of_defaults[i])
-        lst = ['args',
-               '"%s"' % func.__name__,
-               '%d' % min_number_of_args,
-               '%d' % len(positional_args),
+        fmt = 'O'*min_number_of_args
+        if min_number_of_args < len(positional_args):
+            fmt += '|' + 'O'*(len(positional_args)-min_number_of_args)
+        lst = ['args', 'kwds',
+               '"%s:%s"' % (fmt, func.__name__),
+               'kwlist',
                ]
         lst += ['&' + a.name for a in positional_args]
-        print >> f, '\tif (!PyArg_UnpackTuple(%s))' % ', '.join(lst),
+        print >> f, '\tif (!PyArg_ParseTupleAndKeywords(%s))' % ', '.join(lst),
         print >> f, tail
 
         call_fast_args = list(fast_args)
-        if self.USE_CALL_TRACE:
-            call_fast_args[:0] = ['__f', '__tstate']
-        print >> f, '\treturn %s(%s);' % (fast_name, ', '.join(call_fast_args))
+        if call_fast_args:
+            call_fast_args = 'TRACE_CALL ' + ', '.join(call_fast_args)
+        else:
+            call_fast_args = 'TRACE_CALL_VOID'
+        print >> f, '\treturn %s(%s);' % (fast_name, call_fast_args)
         print >> f, '}'
         print >> f
 
-        print >> f, 'static PyObject *'
-        print >> f, '%s(%s)' % (fast_name, ', '.join(declare_fast_args))
+        print >> f, fast_function_header
         print >> f, '{'
 
         fast_locals = [arg for arg in localnames if arg not in fast_set]
@@ -630,8 +638,9 @@
         print >> f, '}'
 
         # print the PyMethodDef
-        print >> f, 'static PyMethodDef ml_%s = { "%s", %s, METH_VARARGS };' % (
-            name, func.__name__, f_name)
+        print >> f, ('static PyMethodDef ml_%s = {\n'
+            '    "%s", (PyCFunction)%s, METH_VARARGS|METH_KEYWORDS };' % (
+            cname, func.__name__, f_name))
         print >> f
 
         if not self.translator.frozen:

Modified: pypy/branch/src-pytest/pypy/translator/gencl.py
==============================================================================
--- pypy/branch/src-pytest/pypy/translator/gencl.py	(original)
+++ pypy/branch/src-pytest/pypy/translator/gencl.py	Wed Jan 12 15:31:13 2005
@@ -193,7 +193,7 @@
             return "'last-exc-value"
         else:
             return "#<%r>" % (val,)
-    def emitcode(self):
+    def emitcode(self, public=True):
         import sys
         from cStringIO import StringIO
         out = StringIO()

Modified: pypy/branch/src-pytest/pypy/translator/genrpy.py
==============================================================================
--- pypy/branch/src-pytest/pypy/translator/genrpy.py	(original)
+++ pypy/branch/src-pytest/pypy/translator/genrpy.py	Wed Jan 12 15:31:13 2005
@@ -10,22 +10,53 @@
 that globals are constants, for instance. This definition is not
 exact and might change.
 
-This module is very much under construction and not yet usable for much
-more than testing.
+This module appears to be already quite usable.
+But I need to ask how we want to integrate it.
+
+XXX open questions:
+- do we wantamoduleperapp-spaceoperation?
+- do we want to auto-generate stuff?
+- do we want to create code that is more similar to the app code?
+- do we want to create specialized code for constants?
+- do we want to use small tail-functions instead of goto?
+- do we want to inline small functions?
+- do we want to translate non-rpythonic code as well?
 """
 
-from pypy.objspace.flow.model import traverse
-from pypy.objspace.flow import FlowObjSpace
-from pypy.objspace.flow.model import FunctionGraph, Block, Link, Variable, Constant
+from __future__ import generators
+import autopath, os, sys, exceptions
+from pypy.objspace.flow.model import Variable, Constant, SpaceOperation
+from pypy.objspace.flow.model import FunctionGraph, Block, Link
 from pypy.objspace.flow.model import last_exception, last_exc_value
-from pypy.translator.simplify import simplify_graph
+from pypy.objspace.flow.model import traverse, uniqueitems, checkgraph
+from pypy.translator.simplify import remove_direct_loops
+from pypy.interpreter.pycode import CO_VARARGS
+from pypy.annotation import model as annmodel
+from types import FunctionType, CodeType
 from pypy.interpreter.error import OperationError
-from types import FunctionType
+from pypy.objspace.std.restricted_int import r_int, r_uint
 
 from pypy.translator.translator import Translator
+from pypy.objspace.std import StdObjSpace
+from pypy.objspace.flow import FlowObjSpace
+
+from pypy.interpreter.gateway import app2interp, interp2app
+
 
-import sys
+# ____________________________________________________________
 
+def c_string(s):
+    return '"%s"' % (s.replace('\\', '\\\\').replace('"', '\"'),)
+
+def uniquemodulename(name, SEEN={}):
+    # never reuse the same module name within a Python session!
+    i = 0
+    while True:
+        i += 1
+        result = '%s_%d' % (name, i)
+        if result not in SEEN:
+            SEEN[result] = True
+            return result
 
 def ordered_blocks(graph):
     # collect all blocks
@@ -49,65 +80,167 @@
     #    print ofs, txt, block
     return [block for ofs, txt, block in allblocks]
 
+class UniqueList(list):
+    def __init__(self, *args, **kwds):
+        list.__init__(self, *args, **kwds)
+        self.dic = {}
 
+    def append(self, arg):
+        try:
+            self.dic[arg]
+        except KeyError:
+            self.dic[arg] = 1
+            list.append(self, arg)
+        except TypeError: # not hashable
+            if arg not in self:
+                list.append(self, arg)
+            
 class GenRpy:
-    def __init__(self, f, translator, modname=None):
-        self.f = f
+    def __init__(self, translator, modname=None):
         self.translator = translator
-        self.modname = (modname or
-                        translator.functions[0].__name__)
-        self.rpynames = {Constant(None).key:  'w(None)',
-                         Constant(False).key: 'w(False)',
-                         Constant(True).key:  'w(True)',
+        self.modname = self.trans_funcname(modname or
+                        uniquemodulename(translator.functions[0].__name__))
+        self.rpynames = {Constant(None).key:  'space.w_None',
+                         Constant(False).key: 'space.w_False',
+                         Constant(True).key:  'space.w_True',
                        }
         
         self.seennames = {}
-        self.initcode = []     # list of lines for the module's initxxx()
-        self.latercode = []    # list of generators generating extra lines
+        u = UniqueList
+        self.initcode = u()    # list of lines for the module's initxxx()
+        self.latercode = u()   # list of generators generating extra lines
                                #   for later in initxxx() -- for recursive
                                #   objects
         self.globaldecl = []
         self.globalobjects = []
         self.pendingfunctions = []
+        self.currentfunc = None
+        self.debugstack = ()  # linked list of nested nameof()
 
         # special constructors:
         self.has_listarg = {}
         for name in "newtuple newlist newdict newstring".split():
             self.has_listarg[name] = name
 
-        self.current_globals = {}
-        self.glob_names = []
-        self.glob_values = []
-
-        self.gen_source()            
-
-    def adjust_namespace(self):
-        """ inspect the globals of self.current_func and build a searchable list
-            of the globals.
-        """
-        g = self.current_func.func_globals
-        if g is self.current_globals:
-            return
-        self.current_globals = g
-        order = [(value, key) for key, value in g.items()]
-        order.sort()
-        self.glob_names  = [key   for value, key in order]
-        self.glob_values = [value for value, key in order]
-
-    def find_global_name(self, obj):
-        for i in xrange(len(self.glob_values)):
-            if self.glob_values[i] is obj:
-                return self.glob_names[i]
-        return None
+        # XXX I guess it is cleaner to use the flow space?
+        # we just want to look into the operations,
+        # but we don't break into the implementation.
+        # Or should it be the base space, ARMIN?
+        #self.space = StdObjSpace() # for introspection
+        self.space = FlowObjSpace() # for introspection
         
-    def nameof(self, obj):
+        self.use_fast_call = False        
+        
+    def expr(self, v, localnames, wrapped = True):
+        if isinstance(v, Variable):
+            n = v.name
+            if n.startswith("v") and n[1:].isdigit():
+                ret = localnames.get(v.name)
+                if not ret:
+                    if wrapped:
+                        localnames[v.name] = ret = "w_%d" % len(localnames)
+                    else:
+                        localnames[v.name] = ret = "v%d" % len(localnames)
+                return ret
+        elif isinstance(v, Constant):
+            return self.nameof(v.value,
+                               debug=('Constant in the graph of', self.currentfunc))
+        else:
+            raise TypeError, "expr(%r)" % (v,)
+
+    def arglist(self, args, localnames):
+        res = [self.expr(arg, localnames) for arg in args]
+        return ", ".join(res)
+
+    def oper(self, op, localnames):
+        if op.opname == "simple_call":
+            v = op.args[0]
+            exv = self.expr(v, localnames)
+            if exv.startswith("space.") and not exv.startswith("space.w_"):
+                # it is a space method
+                fmt = "%(res)s = %(func)s(%(args)s)"
+            else:
+                # default for a spacecall:
+                fmt = ("_tup = space.newtuple([%(args)s])\n"
+                        "%(res)s = space.call(%(func)s, _tup)")
+                # see if we can optimize for a fast call.
+                # we justdo the very simple ones.
+                if self.use_fast_call and (isinstance(v, Constant)
+                                           and exv.startswith('gfunc_')):
+                    func = v.value
+                    if (not func.func_code.co_flags & CO_VARARGS) and (
+                        func.func_defaults is None):
+                        fmt = "%(res)s = fastf_%(func)s(space, %(args)s)"
+                        exv = exv[6:]
+            return fmt % {"res" : self.expr(op.result, localnames),
+                          "func": exv,
+                          "args": self.arglist(op.args[1:], localnames) }
+        if op.opname in self.has_listarg:
+            fmt = "%s = %s([%s])"
+        else:
+            fmt = "%s = %s(%s)"
+        # special case is_true
+        wrapped = op.opname != "is_true"
+        oper = "space.%s" % op.opname
+        return fmt % (self.expr(op.result, localnames, wrapped), oper,
+                      self.arglist(op.args, localnames))
+
+    def large_assignment(self, left, right, margin=65):
+        expr = "(%s) = (%s)" % (", ".join(left), ", ".join(right))
+        pieces = expr.split(",")
+        res = [pieces.pop(0)]
+        for piece in pieces:
+            if len(res[-1])+len(piece)+1 > margin:
+                res[-1] += ","
+                res.append(piece)
+            else:
+                res[-1] += (","+piece)
+        return res
+
+    def large_initialize(self, vars, margin=65):
+        res = []
+        nonestr = "None"
+        margin -= len(nonestr)
+        for var in vars:
+            ass = var+"="
+            if not res or len(res[-1]) >= margin:
+                res.append(ass)
+            res[-1] += ass
+        res = [line + nonestr for line in res]
+        return res
+
+    def gen_link(self, link, localvars, blocknum, block, linklocalvars=None):
+        "Generate the code to jump across the given Link."
+        linklocalvars = linklocalvars or {}
+        left, right = [], []
+        for a1, a2 in zip(link.args, link.target.inputargs):
+            if a1 in linklocalvars:
+                src = linklocalvars[a1]
+            else:
+                src = self.expr(a1, localvars)
+            left.append(self.expr(a2, localvars))
+            right.append(src)
+        txt = "%s = %s" % (", ".join(left), ", ".join(right))
+        if len(txt) <= 65: # arbitrary
+            yield txt
+        else:
+            for line in self.large_assignment(left, right):
+                yield line
+        goto = blocknum[link.target]
+        yield 'goto = %d' % goto
+        if goto <= blocknum[block]:
+            yield 'continue'
+
+    def nameof(self, obj, debug=None, namehint=None):
         key = Constant(obj).key
         try:
             return self.rpynames[key]
         except KeyError:
-            #name = "w(%s)" % str(obj)
-            #self.rpynames[key] = name
-            #return name
+            if debug:
+                stackentry = debug, obj
+            else:
+                stackentry = obj
+            self.debugstack = (self.debugstack, stackentry)
             if (type(obj).__module__ != '__builtin__' and
                 not isinstance(obj, type)):   # skip user-defined metaclasses
                 # assume it's a user defined thingy
@@ -120,26 +253,37 @@
                     if meth:
                         break
                 else:
-                    raise Exception, "nameof(%r) in %r" % (obj, self.current_func)
-                name = meth(obj)
+                    raise Exception, "nameof(%r)" % (obj,)
+
+                code=meth.im_func.func_code
+                if namehint and 'namehint' in code.co_varnames[:code.co_argcount]:
+                    name = meth(obj, namehint=namehint)
+                else:
+                    name = meth(obj)
+            self.debugstack, x = self.debugstack
+            assert x is stackentry
             self.rpynames[key] = name
             return name
 
     def uniquename(self, basename):
+        basename = basename.translate(C_IDENTIFIER)
         n = self.seennames.get(basename, 0)
         self.seennames[basename] = n+1
         if n == 0:
             self.globalobjects.append(basename)
-            self.globaldecl.append('static PyObject *%s;' % (basename,))
+            self.globaldecl.append('# global object %s' % (basename,))
             return basename
         else:
             return self.uniquename('%s_%d' % (basename, n))
 
     def nameof_object(self, value):
         if type(value) is not object:
-            raise Exception, "nameof(%r) in %r" % (value, self.current_func)
+            #raise Exception, "nameof(%r) in %r" % (value, self.currentfunc)
+            name = self.uniquename('g_unknown_%r' % value)
+            self.initcode.append('# cannot build %s as %r' % (name, object))
+            return name
         name = self.uniquename('g_object')
-        self.initcode.append('INITCHK(%s = PyObject_CallFunction((PyObject*)&PyBaseObject_Type, ""))'%name)
+        self.initcode.append('m.%s = object()'%name)
         return name
 
     def nameof_module(self, value):
@@ -148,44 +292,75 @@
                     value.__file__.endswith('.py') or
                     value.__file__.endswith('.pyo')), \
                "%r is not a builtin module (probably :)"%value
-        name = self.uniquename('mod%s'%value.__name__)
-        self.initcode.append('INITCHK(%s = PyImport_ImportModule("%s"))'%(name, value.__name__))
+        name = self.uniquename('mod_%s'%value.__name__)
+        self.initcode.append('import %s as _tmp' % value.__name__)
+        self.initcode.append('m.%s = space.wrap(_tmp)' % (name))
         return name
         
 
     def nameof_int(self, value):
-        return "w(%d)" % value
+        if value >= 0:
+            name = 'gi_%d' % value
+        else:
+            name = 'gim_%d' % abs(value)
+        name = self.uniquename(name)
+        self.initcode.append('m.%s = space.newint(%d)' % (name, value))
+        return name
 
     def nameof_long(self, value):
+        # allow short longs only, meaning they
+        # must fit into a machine word.
+        assert (sys.maxint*2+1)&value==value, "your literal long is too long"
         # assume we want them in hex most of the time
         if value < 256L:
-            return "%dL" % value
+            s = "%dL" % value
+        else:
+            s = "0x%08xL" % value
+        if value >= 0:
+            name = 'glong_%s' % s
         else:
-            return "0x%08xL" % value
+            name = 'glongm_%d' % abs(value)
+        name = self.uniquename(name)
+        self.initcode.append('m.%s = space.wrap(%s) # XXX implement long!' % (name, s))
+        return name
 
     def nameof_float(self, value):
-        return "w(%s)" % value
-
+        name = 'gfloat_%s' % value
+        name = (name.replace('-', 'minus')
+                    .replace('.', 'dot'))
+        name = self.uniquename(name)
+        self.initcode.append('m.%s = space.newfloat(%r)' % (name, value))
+        return name
+    
     def nameof_str(self, value):
-        name = self.find_global_name(value)
-        if name:
-            return "w(%s)" % name
-        return "w(%s)" % repr(value)
+        if [c for c in value if c<' ' or c>'~' or c=='"' or c=='\\']:
+            # non-printable string
+            namestr = repr(value)[1:-1]
+        else:
+            # printable string
+            namestr = value
+        if not namestr:
+            namestr = "_emptystr_"
+        name = self.uniquename('gs_' + namestr[:32])
+        # self.initcode.append('m.%s = space.newstring(%r)' % (name, value))
+        # ick! very unhandy
+        self.initcode.append('m.%s = space.wrap(%r)' % (name, value))
+        return name
 
     def skipped_function(self, func):
         # debugging only!  Generates a placeholder for missing functions
         # that raises an exception when called.
         name = self.uniquename('gskippedfunc_' + func.__name__)
-        self.globaldecl.append('static PyMethodDef ml_%s = { "%s", &skipped, METH_VARARGS };' % (name, name))
-        self.initcode.append('INITCHK(%s = PyCFunction_New('
-                             '&ml_%s, NULL))' % (name, name))
-        self.initcode.append('\tPy_INCREF(%s);' % name)
-        self.initcode.append('\tPyCFunction_GET_SELF(%s) = %s;' % (name, name))
+        self.globaldecl.append('# global decl %s' % (name, ))
+        self.initcode.append('# build func %s' % name)
         return name
 
-    def nameof_function(self, func):
+    def trans_funcname(self, s):
+        return s.translate(C_IDENTIFIER)
+
+    def nameof_function(self, func, namehint=''):
         printable_name = '(%s:%d) %s' % (
-            func.func_globals.get('__name__', '?'),
+            self.trans_funcname(func.func_globals.get('__name__', '?')),
             func.func_code.co_firstlineno,
             func.__name__)
         if self.translator.frozen:
@@ -197,10 +372,11 @@
                 func.func_doc.lstrip().startswith('NOT_RPYTHON')):
                 print "skipped", printable_name
                 return self.skipped_function(func)
-        name = func.__name__
-        self.initcode.append('INITCHK(%s = PyCFunction_New('
-                             '&ml_%s, NULL))' % (name, name))
-        self.initcode.append('\t%s->ob_type = &PyGenCFunction_Type;' % name)
+        name = self.uniquename('gfunc_' + self.trans_funcname(
+            namehint + func.__name__))
+        f_name = 'f_' + name[6:]
+        self.initcode.append('from pypy.interpreter.gateway import interp2app')
+        self.initcode.append('m.%s = space.wrap(interp2app(%s))' % (name, f_name))
         self.pendingfunctions.append(func)
         return name
 
@@ -209,22 +385,20 @@
         func = sm.__get__(42.5)
         name = self.uniquename('gsm_' + func.__name__)
         functionname = self.nameof(func)
-        self.initcode.append('INITCHK(%s = PyCFunction_New('
-                             '&ml_%s, NULL))' % (name, functionname))
+        self.initcode.append('m.%s = space.wrap(%s)' % (name, functionname))
         return name
 
     def nameof_instancemethod(self, meth):
         if meth.im_self is None:
             # no error checking here
-            return self.nameof(meth.im_func)
+            return self.nameof(meth.im_func, namehint="%s_" % meth.im_class.__name__)
         else:
             ob = self.nameof(meth.im_self)
             func = self.nameof(meth.im_func)
             typ = self.nameof(meth.im_class)
             name = self.uniquename('gmeth_'+meth.im_func.__name__)
             self.initcode.append(
-                'INITCHK(%s = gencfunc_descr_get(%s, %s, %s))'%(
-                name, func, ob, typ))
+                '%s = space.getattr(%s, %s)'%(name, ob, func))
             return name
 
     def should_translate_attr(self, pbc, attr):
@@ -235,16 +409,13 @@
                 return False
             else:
                 return "probably"   # True
-        if attr in ann.getpbcattrs(pbc):
-            return True
         classdef = ann.getuserclasses().get(pbc.__class__)
-        if (classdef and
-            classdef.about_attribute(attr) != annmodel.SomeImpossibleValue()):
+        if classdef and classdef.about_attribute(attr) is not None:
             return True
         return False
 
     def later(self, gen):
-        self.latercode.append(gen)
+        self.latercode.append((gen, self.debugstack))
 
     def nameof_instance(self, instance):
         name = self.uniquename('ginst_' + instance.__class__.__name__)
@@ -254,24 +425,67 @@
             content.sort()
             for key, value in content:
                 if self.should_translate_attr(instance, key):
-                    yield 'INITCHK(SETUP_INSTANCE_ATTR(%s, "%s", %s))' % (
-                        name, key, self.nameof(value))
-        self.initcode.append('INITCHK(SETUP_INSTANCE(%s, %s))' % (
-            name, cls))
+                    yield 'space.setattr(%s, %s, %s)' % (
+                        name, self.nameof(key), self.nameof(value))
+        if isinstance(instance, Exception):
+            # specialcase for exception instances: wrap them directly
+            self.initcode.append('_ins = %s()\n'
+                                 'm.%s = space.wrap(_ins)' % (
+                instance.__class__.__name__, name))
+        else:
+            # this seems to hardly work with the faked stuff
+            self.initcode.append('from types import InstanceType')
+            self.initcode.append('w_InstanceType = space.wrap(InstanceType)')
+            self.initcode.append('_tup = space.newtuple([%s])\n'
+                                 'm.%s = space.call(w_InstanceType, _tup)' % (
+                cls, name))
         self.later(initinstance())
         return name
 
     def nameof_builtin_function_or_method(self, func):
-        return "w(%s)" % func.__name__
+        if func.__self__ is None:
+            # builtin function
+            if hasattr(self.space, func.__name__):
+                return "space.%s" % func.__name__
+            # where does it come from? Python2.2 doesn't have func.__module__
+            for modname, module in sys.modules.items():
+                if hasattr(module, '__file__'):
+                    if (module.__file__.endswith('.py') or
+                        module.__file__.endswith('.pyc') or
+                        module.__file__.endswith('.pyo')):
+                        continue    # skip non-builtin modules
+                if func is getattr(module, func.__name__, None):
+                    break
+            else:
+                raise Exception, '%r not found in any built-in module' % (func,)
+            name = self.uniquename('gbltin_' + func.__name__)
+            if modname == '__builtin__':
+                self.initcode.append('m.%s = space.getattr(space.w_builtin, %s)'% (
+                    name, self.nameof(func.__name__)))
+            else:
+                self.initcode.append('m.%s = space.getattr(%s, %s)' % (
+                    name, self.nameof(module), self.nameof(func.__name__)))
+        else:
+            # builtin (bound) method
+            name = self.uniquename('gbltinmethod_' + func.__name__)
+            self.initcode.append('m.%s = space.getattr(%s, %s)' % (
+                name, self.nameof(func.__self__), self.nameof(func.__name__)))
+        return name
 
     def nameof_classobj(self, cls):
         if cls.__doc__ and cls.__doc__.lstrip().startswith('NOT_RPYTHON'):
             raise Exception, "%r should never be reached" % (cls,)
 
-        metaclass = "&PyType_Type"
+        metaclass = "space.w_type"
+        name = self.uniquename('gcls_' + cls.__name__)
         if issubclass(cls, Exception):
             if cls.__module__ == 'exceptions':
-                return 'w(%s)'%cls.__name__
+                if hasattr(self.space, "w_%s" % cls.__name__):
+                    return 'space.w_%s'%cls.__name__
+                else:
+                    self.initcode.append('m.%s = space.wrap(%s)' % (
+                                         name, cls.__name__))
+                    return name
             #else:
             #    # exceptions must be old-style classes (grr!)
             #    metaclass = "&PyClass_Type"
@@ -279,9 +493,13 @@
         # pypy source uses old-style classes, to avoid strange problems.
         if not isinstance(cls, type):
             assert type(cls) is type(Exception)
-            metaclass = "&PyClass_Type"
+            # self.initcode.append("import types\n"
+            #                      "m.classtype = space.wrap(types.ClassType)\n")
+            # metaclass = "m.classtype"
+            # XXX I cannot instantiate these.
+            # XXX using type instead, since we still inherit from exception
+            # XXX what is the future of classes in pypy?
 
-        name = self.uniquename('gcls_' + cls.__name__)
         basenames = [self.nameof(base) for base in cls.__bases__]
         def initclassobj():
             content = cls.__dict__.items()
@@ -293,34 +511,83 @@
                         continue
                     # XXX some __NAMES__ are important... nicer solution sought
                     #raise Exception, "unexpected name %r in class %s"%(key, cls)
+
+                # redirect value through class interface, in order to
+                # get methods instead of functions.
+                value = getattr(cls, key)
+
                 if isinstance(value, staticmethod) and value.__get__(1) not in self.translator.flowgraphs and self.translator.frozen:
-                    print value
+                    print "skipped staticmethod:", value
                     continue
                 if isinstance(value, FunctionType) and value not in self.translator.flowgraphs and self.translator.frozen:
-                    print value
+                    print "skippedfunction:", value
                     continue
                     
-                yield 'INITCHK(SETUP_CLASS_ATTR(%s, "%s", %s))' % (
-                    name, key, self.nameof(value))
+                yield 'space.setattr(%s, %s, %s)' % (
+                    name, self.nameof(key), self.nameof(value))
 
         baseargs = ", ".join(basenames)
-        if baseargs:
-            baseargs = ', '+baseargs
-        self.initcode.append('INITCHK(%s = PyObject_CallFunction((PyObject*) %s,'
-                             %(name, metaclass))
-        self.initcode.append('\t\t"s(%s){}", "%s"%s))'
-                             %("O"*len(basenames), cls.__name__, baseargs))
+        self.initcode.append('_dic = space.newdict([])\n'
+                             '_bases = space.newtuple([%(bases)s])\n'
+                             '_args = space.newtuple([%(name)s, _bases, _dic])\n'
+                             'm.%(klass)s = space.call(%(meta)s, _args)'
+                             % {"bases": baseargs,
+                                "klass": name,
+                                "name" : self.nameof(cls.__name__),
+                                "meta" : metaclass} )
         
         self.later(initclassobj())
         return name
 
     nameof_class = nameof_classobj   # for Python 2.2
 
+    typename_mapping = {
+        object: 'space.w_object',
+        int:    'space.w_int',
+        long:   'space.w_long',
+        bool:   'space.w_bool',
+        list:   'space.w_list',
+        tuple:  'space.w_tuple',
+        dict:   'space.w_dict',
+        str:    'space.w_str',
+        float:  'space.w_float',
+        type(Exception()): 'space.wrap(types.InstanceType)',
+        type:   'space.w_type',
+        complex:'space.wrap(types.ComplexType)',
+        unicode:'space.w_unicode',
+        file:   'space.wrap(file)',
+        type(None): 'space.wrap(types.NoneType)',
+        CodeType: 'space.wrap(types.CodeType)',
+
+        ##r_int:  'space.w_int',
+        ##r_uint: 'space.w_int',
+
+        # XXX we leak 5 references here, but that's the least of the
+        #     problems with this section of code
+        # type 'builtin_function_or_method':
+        type(len): 'space.wrap(types.FunctionType)',
+        # type 'method_descriptor':
+        # XXX small problem here:
+        # XXX with space.eval, we get <W_TypeObject(method)>
+        # XXX but with wrap, we get <W_TypeObject(instancemethod)>
+        type(list.append): 'eval_helper(space, "list.append")',
+        # type 'wrapper_descriptor':
+        type(type(None).__repr__): 'eval_helper(space, ".type(None).__repr__")',
+        # type 'getset_descriptor':
+        # XXX here we get <W_TypeObject(FakeDescriptor)>,
+        # while eval gives us <W_TypeObject(GetSetProperty)>
+        type(type.__dict__['__dict__']): 'eval_helper(space,'\
+            ' "type(type.__dict__[\'__dict__\'])")',
+        # type 'member_descriptor':
+        # XXX this does not work in eval!
+        # type(type.__dict__['__basicsize__']): "cannot eval type(type.__dict__['__basicsize__'])",
+        # XXX there seems to be no working support for member descriptors ???
+        type(type.__dict__['__basicsize__']): "space.wrap(type(type.__dict__['__basicsize__']))",
+        }
 
     def nameof_type(self, cls):
-        return "w(%s)" % cls.__name__ ##??
         if cls in self.typename_mapping:
-            return '(PyObject*) %s' % self.typename_mapping[cls]
+            return self.typename_mapping[cls]
         assert cls.__module__ != '__builtin__', \
             "built-in class %r not found in typename_mapping" % (cls,)
         return self.nameof_classobj(cls)
@@ -328,9 +595,8 @@
     def nameof_tuple(self, tup):
         name = self.uniquename('g%dtuple' % len(tup))
         args = [self.nameof(x) for x in tup]
-        args.insert(0, '%d' % len(tup))
         args = ', '.join(args)
-        self.initcode.append('INITCHK(%s = PyTuple_Pack(%s))' % (name, args))
+        self.initcode.append('m.%s = space.newtuple([%s])' % (name, args))
         return name
 
     def nameof_list(self, lis):
@@ -338,32 +604,23 @@
         def initlist():
             for i in range(len(lis)):
                 item = self.nameof(lis[i])
-                yield '\tPy_INCREF(%s);' % item
-                yield '\tPyList_SET_ITEM(%s, %d, %s);' % (name, i, item)
-        self.initcode.append('INITCHK(%s = PyList_New(%d))' % (name, len(lis)))
+                yield 'space.setitem(%s, %s, %s);' % (
+                    name, self.nameof(i), self.nameof(item))
+        self.initcode.append('m.%s = space.newlist(%s)' % (name, self.nameof(0)))
+        self.initcode.append('m.%s = space.mul(%s, %s)' % (name, name, self.nameof(len(lis))))
         self.later(initlist())
         return name
 
     def nameof_dict(self, dic):
-        name = self.find_global_name(dic)
-        if name:
-            return name
-        return 'space.newdict([w("sorry", "not yet"])'
         assert dic is not __builtins__
         assert '__builtins__' not in dic, 'Seems to be the globals of %s' % (
             dic.get('__name__', '?'),)
         name = self.uniquename('g%ddict' % len(dic))
         def initdict():
             for k in dic:
-                if type(k) is str:
-                    yield ('\tINITCHK(PyDict_SetItemString'
-                           '(%s, "%s", %s) >= 0)'%(
-                               name, k, self.nameof(dic[k])))
-                else:
-                    yield ('\tINITCHK(PyDict_SetItem'
-                           '(%s, %s, %s) >= 0)'%(
-                               name, self.nameof(k), self.nameof(dic[k])))
-        self.initcode.append('INITCHK(%s = PyDict_New())' % (name,))
+                yield ('space.setitem(%s, %s, %s)'%(
+                            name, self.nameof(k), self.nameof(dic[k])))
+        self.initcode.append('m.%s = space.newdict([])' % (name,))
         self.later(initdict())
         return name
 
@@ -373,11 +630,9 @@
         name = self.uniquename('gdescriptor_%s_%s' % (
             md.__objclass__.__name__, md.__name__))
         cls = self.nameof(md.__objclass__)
-        self.initcode.append('INITCHK(PyType_Ready((PyTypeObject*) %s) >= 0)' %
-                             cls)
-        self.initcode.append('INITCHK(%s = PyMapping_GetItemString('
-                             '((PyTypeObject*) %s)->tp_dict, "%s"))' %
-                                (name, cls, md.__name__))
+        # do I need to take the dict and then getitem???
+        self.initcode.append('m.%s = space.getattr(%s, %s)' %
+                                (name, cls, self.nameof(md.__name__)))
         return name
     nameof_getset_descriptor  = nameof_member_descriptor
     nameof_method_descriptor  = nameof_member_descriptor
@@ -392,103 +647,236 @@
             return 'PySys_GetObject("stderr")'
         raise Exception, 'Cannot translate an already-open file: %r' % (fil,)
 
-    def gen_source(self):
+    def gen_source(self, fname, ftmpname=None):
+        self.fname = fname
+        self.ftmpname = ftmpname
+
+        # generate unordered source file, first.
+        # I prefer this over ordering everything in memory.
+        fname = self.fname
+        if self.ftmpname:
+            fname = self.ftmpname
+        f = file(fname, "w")
+        # generate ordered source file
+        try:
+            self.f = f
+            self.gen_source_temp()
+        finally:
+            f.close()
+
+        def copyfile(source, target):
+            file(target, "w").write(file(source).read())
+
+        def order_sections(fname):
+            sep = "\n##SECTION##\n"
+            txt = file(fname).read()
+            pieces = txt.split(sep)
+            prelude = pieces.pop(0)
+            postlude = pieces.pop()
+            dic = {}
+            while pieces:
+                func = pieces.pop()
+                head = pieces.pop()
+                key = makekey(head, len(pieces))
+                dic[key] = head + sep + func
+            lis = dic.items()
+            lis.sort()
+            lis = [prelude] + [func for head, func in lis] + [postlude]
+            txt = sep.join(lis)
+            file(fname, "w").write(txt)
+
+        def makekey(txt, uniqueno):
+            dic = {}
+            for line in txt.split("\n"):
+                ign, name, value = line.split(None, 2)
+                dic[name] = eval(value)
+            key = dic["filename"], dic["firstlineno"], uniqueno
+            return key
+
+        order_sections(fname)
+        if self.ftmpname:
+            copyfile(self.ftmpname, self.fname)
+        
+    def gen_source_temp(self):
         f = self.f
         info = {
             'modname': self.modname,
-            'entrypointname': self.translator.functions[0].__name__,
+            'entrypointname': self.trans_funcname(
+                self.translator.functions[0].__name__),
             'entrypoint': self.nameof(self.translator.functions[0]),
             }
-
-        # make sure 
+        # header
+        print >> f, self.RPY_HEADER
 
         # function implementations
         while self.pendingfunctions:
-            func = self.current_func = self.pendingfunctions.pop()
-            self.adjust_namespace()
+            func = self.pendingfunctions.pop()
+            self.currentfunc = func
             self.gen_rpyfunction(func)
             # collect more of the latercode after each function
             while self.latercode:
-                #gen, self.debugstack = self.latercode.pop()
-                gen = self.latercode.pop()
+                gen, self.debugstack = self.latercode.pop()
                 #self.initcode.extend(gen) -- eats TypeError! bad CPython!
                 for line in gen:
                     self.initcode.append(line)
                 self.debugstack = ()
-            #self.gen_global_declarations()
-            print >> f
+            self.gen_global_declarations()
 
+        # set the final splitter
+        print >> f, "##SECTION##"
         # footer
-        # maybe not needed
-        return
-        print >> f, self.C_INIT_HEADER % info
-        if self.f2name is not None:
-            print >> f, '#include "%s"' % self.f2name
-        for codeline in self.initcode:
-            print >> f, '\t' + codeline
-        print >> f, self.C_INIT_FOOTER % info
+        print >> f, self.RPY_INIT_HEADER % info
+        for codelines in self.initcode:
+            for codeline in codelines.split("\n"):
+                print >> f, "    %s" % codeline
+        print >> f, self.RPY_INIT_FOOTER % info
+        f.close()
+
+    def gen_global_declarations(self):
+        g = self.globaldecl
+        if g:
+            f = self.f
+            print >> f, '# global declaration%s' % ('s'*(len(g)>1))
+            for line in g:
+                print >> f, line
+            print >> f
+            del g[:]
+        g = self.globalobjects
+        for name in g:
+            pass # self.initcode.append('# REGISTER_GLOBAL(%s)' % (name,))
+        del g[:]
 
     def gen_rpyfunction(self, func):
 
-        local_names = {}
+        f = self.f
+        print >> f, "##SECTION##" # simple to split, afterwards
+        print >> f, ("## filename    %r\n"
+                     "## function    %r\n"
+                     "## firstlineno %d") % (
+            func.func_code.co_filename,
+            func.func_code.co_name,
+            func.func_code.co_firstlineno)
+        print >> f, "##SECTION##"
+        locals = {}
+        body = list(self.rpyfunction_body(func, locals))
+        name_of_defaults = [self.nameof(x, debug=('Default argument of', func))
+                            for x in (func.func_defaults or ())]
+        self.gen_global_declarations()
+
+        # print header
+        cname = self.nameof(func)
+        assert cname.startswith('gfunc_')
+        f_name = 'f_' + cname[6:]
+
+        # collect all the local variables
+        graph = self.translator.getflowgraph(func)
+        localslst = []
+        def visit(node):
+            if isinstance(node, Block):
+                localslst.extend(node.getvariables())
+        traverse(visit, graph)
+        localnames = [self.expr(a, locals) for a in uniqueitems(localslst)]
+
+        # collect all the arguments
+        if func.func_code.co_flags & CO_VARARGS:
+            vararg = graph.getargs()[-1]
+            positional_args = graph.getargs()[:-1]
+        else:
+            vararg = None
+            positional_args = graph.getargs()
+        min_number_of_args = len(positional_args) - len(name_of_defaults)
+
+        fast_args = [self.expr(a, locals) for a in positional_args]
+        if vararg is not None:
+            fast_args.append(self.expr(vararg, locals))
+        fast_name = 'fast' + f_name
+
+        fast_set = dict(zip(fast_args, fast_args))
 
-        def expr(v, wrapped = True):
-            if isinstance(v, Variable):
-                n = v.name
-                if n.startswith("v") and n[1:].isdigit():
-                    ret = local_names.get(v.name)
-                    if not ret:
-                        if wrapped:
-                            local_names[v.name] = ret = "w_%d" % len(local_names)
-                        else:
-                            local_names[v.name] = ret = "v%d" % len(local_names)
-                    return ret
-                return v.name
-            elif isinstance(v, Constant):
-                return self.nameof(v.value)
-            else:
-                #raise TypeError, "expr(%r)" % (v,)
-                # XXX how do I resolve these?
-                return "space.%s" % str(v)
-
-        def arglist(args):
-            res = [expr(arg) for arg in args]
-            return ", ".join(res)
-        
-        def oper(op):
-            print op.opname, op.args
-            if op.opname == "simple_call":
-                v = op.args[0]
-                if isinstance(v, Constant) and self.find_global_name(v.value):
-                    fmt = "%s = %s(space, %s)"
-                else:
-                    fmt = "%s = space.call(%s, space.newtuple([%s]))"
-                return fmt % (expr(op.result), expr(op.args[0]), arglist(op.args[1:]))
-            if op.opname in self.has_listarg:
-                fmt = "%s = %s([%s])"
-            else:
-                fmt = "%s = %s(%s)"
-            # specialcase is_true
-            if op.opname == "is_true":
-                return fmt % (expr(op.result, False), expr(op.opname), arglist(op.args))    
-            return fmt % (expr(op.result), expr(op.opname), arglist(op.args))    
-
-        def gen_link(link, linklocalvars=None):
-            "Generate the code to jump across the given Link."
-            linklocalvars = linklocalvars or {}
-            left, right = [], []
-            for a1, a2 in zip(link.args, link.target.inputargs):
-                if a1 in linklocalvars:
-                    src = linklocalvars[a1]
-                else:
-                    src = expr(a1)
-                left.append(expr(a2))
-                right.append(src)
-            yield "%s = %s" % (", ".join(left), ", ".join(right))
-            goto = blocknum[link.target]
-            yield 'goto = %d' % goto
-            if goto <= blocknum[block]:
-                yield 'continue'
+        # create function declaration
+        name = func.__name__
+        argstr = ", ".join(fast_args)
+        fast_function_header = ('def %s(space, %s):'
+                                % (fast_name, argstr))
+
+        print >> f, 'def %s(space, *args_w):' % (f_name,)
+        kwlist = ['"%s"' % name for name in
+                      func.func_code.co_varnames[:func.func_code.co_argcount]]
+        print >> f, '    kwlist = [%s]' % (', '.join(kwlist),)
+
+        # argument unpacking
+        if vararg is not None:
+            varname = self.expr(vararg, locals)
+            lenargs = len(positional_args)
+            print >> f, '    %s = space.newtuple(list(args_w[%d:]))' % (
+                varname, lenargs)
+            print >> f, '    _args_w = args_w[:%d]' % (lenargs,)
+        else:
+            print >> f, '    _args_w = args_w'
+            varname = None
+
+        def tupstr(seq):
+            if len(seq) == 1:
+                fmt = '%s,'
+            else:
+                fmt = '%s'
+            return fmt % ', '.join(seq)
+
+        print >> f, '    defaults_w = (%s)' % tupstr(name_of_defaults)
+
+        theargs = [arg for arg in fast_args if arg != varname]
+        txt = ('from pypy.translator.genrpy import PyArg_ParseMini\n'
+               'm.PyArg_ParseMini = PyArg_ParseMini\n'
+               'from pypy.interpreter.error import OperationError\n'
+               'm.OperationError = OperationError')
+        self.initcode.append(txt)
+        print >> f, '    funcname = "%s"' % func.__name__
+        if theargs:
+            txt = '    %s = PyArg_ParseMini(space, funcname, %d, %d, _args_w, defaults_w)'
+            print >>f, txt % (tupstr(theargs),
+                              min_number_of_args, len(positional_args))
+        else:
+            txt = '    PyArg_ParseMini(space, funcname, %d, %d, _args_w, defaults_w)'
+            print >>f, txt % (min_number_of_args, len(positional_args))
+        print >> f, '    return %s(space, %s)' % (fast_name, ', '.join(fast_args))
+        print >> f
+
+        print >> f, fast_function_header
+
+        fast_locals = [arg for arg in localnames if arg not in fast_set]
+        if fast_locals:
+            print >> f
+            for line in self.large_initialize(fast_locals):
+                print >> f, "    %s" % line
+            print >> f
+        # generate an incref for each input argument
+        # skipped
+
+        # print the body
+        for line in body:
+            print >> f, line
+        print >> f
+
+        # print the PyMethodDef
+        # skipped
+
+        if not self.translator.frozen:
+            # this is only to keep the RAM consumption under control
+            del self.translator.flowgraphs[func]
+            Variable.instances.clear()
+
+    def rpyfunction_body(self, func, localvars):
+        try:
+            graph = self.translator.getflowgraph(func)
+        except Exception, e:
+            print 20*"*", e
+            print func
+            raise
+        # not needed, we use tuple assignment!
+        # remove_direct_loops(graph)
+        checkgraph(graph)
+
+        allblocks = []
         
         f = self.f
         t = self.translator
@@ -496,65 +884,68 @@
         graph = t.getflowgraph(func)
 
         start = graph.startblock
-        blocks = ordered_blocks(graph)
-        nblocks = len(blocks)
+        allblocks = ordered_blocks(graph)
+        nblocks = len(allblocks)
 
         blocknum = {}
-        for block in blocks:
+        for block in allblocks:
             blocknum[block] = len(blocknum)+1
 
-        # create function declaration
-        name = func.__name__  # change this
-        args = [expr(var) for var in start.inputargs]
-        argstr = ", ".join(args)
-        print >> f, "def %s(space, %s):" % (name, argstr)
-        print >> f, "    w = space.wrap"
-        print >> f, "    goto = %d # startblock" % blocknum[start]
-        print >> f, "    while True:"
-        
+        yield "    goto = %d # startblock" % blocknum[start]
+        yield "    while True:"
+                
         def render_block(block):
             catch_exception = block.exitswitch == Constant(last_exception)
             regular_op = len(block.operations) - catch_exception
             # render all but maybe the last op
             for op in block.operations[:regular_op]:
-                yield "%s" % oper(op)
+                for line in self.oper(op, localvars).split("\n"):
+                    yield "%s" % line
             # render the last op if it is exception handled
             for op in block.operations[regular_op:]:
                 yield "try:"
-                yield "    %s" % oper(op)
+                for line in self.oper(op, localvars).split("\n"):
+                    yield "    %s" % line
 
             if len(block.exits) == 0:
                 if len(block.inputargs) == 2:   # exc_cls, exc_value
                     # exceptional return block
-                    exc_cls = expr(block.inputargs[0])
-                    exc_val = expr(block.inputargs[1])
+                    exc_cls = self.expr(block.inputargs[0], localvars)
+                    exc_val = self.expr(block.inputargs[1], localvars)
                     yield "raise OperationError(%s, %s)" % (exc_cls, exc_val)
                 else:
                     # regular return block
-                    retval = expr(block.inputargs[0])
+                    retval = self.expr(block.inputargs[0], localvars)
                     yield "return %s" % retval
                 return
             elif block.exitswitch is None:
                 # single-exit block
                 assert len(block.exits) == 1
-                for op in gen_link(block.exits[0]):
+                for op in self.gen_link(block.exits[0], localvars, blocknum, block):
                     yield "%s" % op
             elif catch_exception:
                 # block catching the exceptions raised by its last operation
                 # we handle the non-exceptional case first
                 link = block.exits[0]
                 assert link.exitcase is None
-                for op in gen_link(link):
+                for op in self.gen_link(link, localvars, blocknum, block):
                     yield "    %s" % op
                 # we must catch the exception raised by the last operation,
                 # which goes to the last err%d_%d label written above.
+                # Since we only have OperationError, we need to select:
+                yield "except OperationError, e:"
+                q = "if"
                 for link in block.exits[1:]:
                     assert issubclass(link.exitcase, Exception)
-                    yield "except OperationError, e:"
-                    for op in gen_link(link, {
+                    # Exeption classes come unwrapped in link.exitcase
+                    yield "    %s space.is_true(space.issubtype(e.w_type, %s)):" % (q,
+                                            self.nameof(link.exitcase))
+                    q = "elif"
+                    for op in self.gen_link(link, localvars, blocknum, block, {
                                 Constant(last_exception): 'e.w_type',
                                 Constant(last_exc_value): 'e.w_value'}):
-                        yield "    %s" % op
+                        yield "        %s" % op
+                yield "    else:raise # unhandled case, should not happen"
             else:
                 # block ending in a switch on a value
                 exits = list(block.exits)
@@ -564,34 +955,101 @@
                     exits.reverse()
                 q = "if"
                 for link in exits[:-1]:
-                    yield "%s %s == %s:" % (q, expr(block.exitswitch),
+                    yield "%s %s == %s:" % (q, self.expr(block.exitswitch,
+                                                     localvars),
                                                      link.exitcase)
-                    for op in gen_link(link):
+                    for op in self.gen_link(link, localvars, blocknum, block):
                         yield "    %s" % op
                     q = "elif"
                 link = exits[-1]
                 yield "else:"
-                yield "    assert %s == %s" % (expr(block.exitswitch),
+                yield "    assert %s == %s" % (self.expr(block.exitswitch,
+                                                    localvars),
                                                     link.exitcase)
-                for op in gen_link(exits[-1]):
+                for op in self.gen_link(exits[-1], localvars, blocknum, block):
                     yield "    %s" % op
 
-        for block in blocks:
+        for block in allblocks:
             blockno = blocknum[block]
-            print >> f
-            print >> f, "        if goto == %d:" % blockno
+            yield ""
+            yield "        if goto == %d:" % blockno
             for line in render_block(block):
-                print >> f, "            %s" % line
+                yield "            %s" % line
+
+# ____________________________________________________________
+
+    RPY_HEADER = '#!/bin/env python\n# -*- coding: LATIN-1 -*-'
+
+    RPY_SEP = "#*************************************************************"
+
+    RPY_INIT_HEADER = RPY_SEP + '''
+
+def init%(modname)s(space):
+    """NOT_RPYTHON"""
+    class m: pass # fake module
+    m.__dict__ = globals()
+'''
+
+    RPY_INIT_FOOTER = '''
+# entry point: %(entrypointname)s, %(entrypoint)s)
+if __name__ == "__main__":
+    from pypy.objspace.std import StdObjSpace
+    space = StdObjSpace()
+    init%(modname)s(space)
+    print space.unwrap(space.call(
+            gfunc_%(entrypointname)s, space.newtuple([])))
+'''
+
+# a translation table suitable for str.translate() to remove
+# non-C characters from an identifier
+C_IDENTIFIER = ''.join([(('0' <= chr(i) <= '9' or
+                          'a' <= chr(i) <= 'z' or
+                          'A' <= chr(i) <= 'Z') and chr(i) or '_')
+                        for i in range(256)])
+
+# temporary arg parsing
+# what about keywords? Gateway doesn't support it.
+def PyArg_ParseMini(space, name, minargs, maxargs, args_w, defaults_w):
+    err = None
+    if len(args_w) < minargs:
+        txt = "%s() takes at least %d argument%s (%d given)"
+        plural = ['s', ''][minargs == 1]
+        err = (name, minargs, plural, len(args_w))
+    if len(args_w) > maxargs:
+        plural = ['s', ''][maxargs == 1]
+        if minargs == maxargs:
+            if minargs == 0:
+                txt = '%s() takes no arguments (%d given)'
+                err = (name, len(args_w))
+            elif minargs == 1:
+                txt = '%s() takes exactly %d argument%s (%d given)'
+                err = (name, maxargs, plural, len(args_w))
+        else:
+            txt = '%s() takes at most %d argument%s (%d given)'
+            err = (name, maxargs, plural, len(args_w))
+    if err:
+        w_txt = space.wrap(txt)
+        w_tup = space.wrap(err)
+        w_txt = space.mod(w_txt, w_tup)
+        raise OperationError(space.w_TypeError, w_txt)
+
+    # finally, we create the result ;-)
+    res_w = args_w + defaults_w[len(args_w) - minargs:]
+    assert len(res_w) == maxargs
+    return res_w
+# _____________________________________________________________________
+
+## this should go into some test file
 
 def somefunc(arg):
     pass
 
 def f(a,b):
-    print "start"
+##    print "start"
     a = []
     a.append(3)
     for i in range(3):
-        print i
+        pass#print i
     if a > b:
         try:
             if b == 123:
@@ -605,12 +1063,20 @@
         dummy = somefunc(23)
         return 42
 
-def ff(a, b):
+class TestClass:pass
+
+def ff(a, b, c=3,*rest):
     try:
-        raise SystemError, 42
-        return a+b
-    finally:
-        a = 7
+        try:
+            if rest:
+                raise SystemError, 42
+            return a+b
+        finally:
+            a = 7
+            if rest:
+                return len(rest),c
+    except TypeError:
+        print "eek"
 
 glob = 100
 def fff():
@@ -640,39 +1106,98 @@
     #import md5
     # how do I avoid the builtin module?
     from pypy.appspace import md5
-    digest = md5.new("hello")
+    digest = md5.new("hello").hexdigest()
+    return digest
 
 def test_mod():
     return app_mod__String_ANY("-%s-", ["hallo"])
 
-entry_point = (f, ff, fff, app_str_decode__String_ANY_ANY, test_mod, test_md5) [-2]
+def test_join():
+    return " ".join(["hi", "there"])
+
+# cannot nest local classes, yet
+# this appears to be a problem in flow space.
+class AnIterClass(object):
+    def __init__(self):
+        self.lis = [c for c in "test"]
+    def next(self):
+        if self.lis:
+            return self.lis.pop()
+        raise StopIteration
+    def __iter__(self):
+        return self
+    
+def test_iter():
+    res = []
+    for i in "hallo":
+        res.append(i)
+    for i in AnIterClass():
+        res.append(i)
+    return res
+
+def test_strutil():
+    from pypy.objspace.std import strutil
+    return (strutil.string_to_int("42"),
+            strutil.string_to_long("12345678901234567890"))
+
+def test_struct():
+    from pypy.appspace import struct
+    import struct as stru
+    res1 = stru.pack('f',1.23), struct.pack('f',1.23)
+    res2 = struct.unpack('f', struct.pack('f',1.23))
+    return res1, res2
+
+def all_entries():
+    res = [func() for func in entry_points[:-1]]
+    return res
+
+entry_points = (lambda: f(2, 3),
+                lambda: ff(2, 3, 5),
+                fff,
+                lambda: app_str_decode__String_ANY_ANY("hugo"),
+                test_mod,
+                test_md5,
+                test_join,
+                test_iter,
+                test_strutil,
+                test_struct,
+               all_entries)
+entry_point = entry_points[-2]
+
+if __name__ == "__main__":
+    import os, sys
+    from pypy.interpreter import autopath
+    srcdir = os.path.dirname(autopath.pypydir)
+    appdir = os.path.join(autopath.pypydir, 'appspace')
+
+    if appdir not in sys.path:
+        sys.path.insert(0, appdir)
 
-import os, sys
-from pypy.interpreter import autopath
-srcdir = os.path.dirname(autopath.pypydir)
-appdir = os.path.join(autopath.pypydir, 'appspace')
-
-try:
-    hold = sys.path[:]
-    sys.path.insert(0, appdir)
     t = Translator(entry_point, verbose=False, simplifying=True)
-    if 0:
-        gen = GenRpy(sys.stdout, t)
-    else:
-        fil= file("d:/tmp/look.py", "w")
-        gen = GenRpy(fil, t)
-        print >> fil, \
-"""
-from pypy.objspace.std import StdObjSpace
-space = StdObjSpace()
-space.simple_call = space.call
-test_mod(space)
-"""
-        fil.close()
-finally:
-    sys.path[:] = hold
-#t.simplify()
-#t.view()
-# debugging
-graph = t.getflowgraph()
-ab = ordered_blocks(graph) # use ctrl-b in PyWin with ab
+    gen = GenRpy(t)
+    gen.use_fast_call = True
+    import pypy.appspace.generated as tmp
+    pth = os.path.dirname(tmp.__file__)
+    ftmpname = "d:/tmp/look.py"
+    fname = os.path.join(pth, gen.modname+".py")
+    gen.gen_source(fname, ftmpname)
+
+    #t.simplify()
+    #t.view()
+    # debugging
+    graph = t.getflowgraph()
+    ab = ordered_blocks(graph) # use ctrl-b in PyWin with ab
+
+def crazy_test():
+    """ this thingy is generating the whole interpreter in itself"""
+    # but doesn't work, my goto's give a problem for flow space
+    dic = {"__builtins__": __builtins__, "__name__": "__main__"}
+    execfile("d:/tmp/look.py", dic)
+    
+    def test():
+        f_ff(space, 2, 3)
+    test = type(test)(test.func_code, dic)
+        
+    t = Translator(test, verbose=False, simplifying=True)
+    gen = GenRpy(t)
+    gen.gen_source("d:/tmp/look2.py")

Copied: pypy/branch/src-pytest/pypy/translator/java/test/test_javatrans.py (from r8225, pypy/trunk/src/pypy/translator/java/test/test_javatrans.py)
==============================================================================
--- pypy/trunk/src/pypy/translator/java/test/test_javatrans.py	(original)
+++ pypy/branch/src-pytest/pypy/translator/java/test/test_javatrans.py	Wed Jan 12 15:31:13 2005
@@ -1,16 +1,14 @@
 import autopath, os
 from py.process import cmdexec 
-from pypy.tool import testit
 from pypy.tool.udir import udir
 from pypy.translator.java.genjava import GenJava
 from pypy.translator.test import snippet
 from pypy.translator.translator import Translator
 
 
-class NoTypeCGenTestCase(testit.IntTestCase):
+class TestNoTypeCGenTestCase:
 
-    def setUp(self):
-        self.space = testit.objspace('flow')
+    objspacename = 'flow'
 
     def build_jfunc(self, func):
         try: func = func.im_func
@@ -27,7 +25,7 @@
         try:
             os.chdir(str(self.jdir))
             cmdexec('javac *.java')
-            self.assertEquals(cmdexec('java test').strip(), 'OK')
+            assert cmdexec('java test').strip() == 'OK'
         finally:
             os.chdir(cwd)
 
@@ -48,7 +46,3 @@
     def test_sieve_of_eratosthenes(self):
         self.build_jfunc(snippet.sieve_of_eratosthenes)
         self.check([], 1028)
-
-
-if __name__ == '__main__':
-    testit.main()

Modified: pypy/branch/src-pytest/pypy/translator/test/test_ctrans.py
==============================================================================
--- pypy/branch/src-pytest/pypy/translator/test/test_ctrans.py	(original)
+++ pypy/branch/src-pytest/pypy/translator/test/test_ctrans.py	Wed Jan 12 15:31:13 2005
@@ -150,7 +150,7 @@
         raises(TypeError, call_with_star, [4,7,12,63])
         raises(TypeError, call_with_star, 521)
 
-    def XXX_test_call_with_keyword(self):
+    def test_call_with_keyword(self):
         call_with_keyword = self.build_cfunc(snippet.call_with_keyword)
         assert call_with_keyword(100) == 82
 

Modified: pypy/branch/src-pytest/pypy/translator/tool/buildpyxmodule.py
==============================================================================
--- pypy/branch/src-pytest/pypy/translator/tool/buildpyxmodule.py	(original)
+++ pypy/branch/src-pytest/pypy/translator/tool/buildpyxmodule.py	Wed Jan 12 15:31:13 2005
@@ -53,7 +53,7 @@
     lastdir = path.local()
     os.chdir(str(dirpath))
     try:
-        modname = cfile.purebasename 
+        modname = cfile.purebasename
         if debug: print "modname", modname
         c = stdoutcapture.Capture(mixed_out_err = True)
         try:



More information about the Pypy-commit mailing list