[pypy-svn] r13197 - in pypy/branch/translator-without-old-genc: . c c/test genc/test test

arigo at codespeak.net arigo at codespeak.net
Wed Jun 8 19:51:08 CEST 2005


Author: arigo
Date: Wed Jun  8 19:51:03 2005
New Revision: 13197

Added:
   pypy/branch/translator-without-old-genc/
      - copied from r13196, pypy/dist/pypy/translator/
Modified:
   pypy/branch/translator-without-old-genc/annrpython.py
   pypy/branch/translator-without-old-genc/c/database.py
   pypy/branch/translator-without-old-genc/c/funcgen.py
   pypy/branch/translator-without-old-genc/c/g_module.h
   pypy/branch/translator-without-old-genc/c/genc.py
   pypy/branch/translator-without-old-genc/c/node.py
   pypy/branch/translator-without-old-genc/c/pyobj.py
   pypy/branch/translator-without-old-genc/c/test/test_database.py
   pypy/branch/translator-without-old-genc/c/test/test_genc.py
   pypy/branch/translator-without-old-genc/c/wrapper.py
   pypy/branch/translator-without-old-genc/genc/test/test_lltyped.py
   pypy/branch/translator-without-old-genc/genc/test/test_typed.py
   pypy/branch/translator-without-old-genc/test/test_backends.py
   pypy/branch/translator-without-old-genc/transform.py
   pypy/branch/translator-without-old-genc/translator.py
   pypy/branch/translator-without-old-genc/unsimplify.py
Log:
Branching the pypy/translator subdirectory in an attempt to remove the old
GenC.  The point to branch this directory only is that in order to have all
the old GenC's tests pass again, some progress will be needed in
rpython/rtyper, and we want this to be done on the trunk.



Modified: pypy/branch/translator-without-old-genc/annrpython.py
==============================================================================
--- pypy/dist/pypy/translator/annrpython.py	(original)
+++ pypy/branch/translator-without-old-genc/annrpython.py	Wed Jun  8 19:51:03 2005
@@ -193,6 +193,13 @@
                 print "++-" * 20
             raise AnnotatorError('%d blocks are still blocked' %
                                  self.annotated.values().count(False))
+        # make sure that the return variables of all graphs is annotated
+        if self.translator is not None:
+            for graph in self.translator.flowgraphs.values():
+                v = graph.getreturnvar()
+                if v not in self.bindings:
+                    self.setbinding(v, annmodel.SomeImpossibleValue())
+        # policy-dependent computation
         self.policy.compute_at_fixpoint(self)
 
     def binding(self, arg, extquery=False):
@@ -305,12 +312,6 @@
         for graph in self.translator.flowgraphs.values(): 
             simplify.eliminate_empty_blocks(graph) 
 
-    def specialize(self, specializer=None):
-        if specializer is None:
-            from pypy.translator.genc import ctyper
-            specializer = ctyper.GenCSpecializer
-        specializer(self).specialize()
-
 
     #___ flowing annotations in blocks _____________________
 

Modified: pypy/branch/translator-without-old-genc/c/database.py
==============================================================================
--- pypy/dist/pypy/translator/c/database.py	(original)
+++ pypy/branch/translator-without-old-genc/c/database.py	Wed Jun  8 19:51:03 2005
@@ -13,13 +13,13 @@
 
 class LowLevelDatabase:
 
-    def __init__(self, rtyper=None):
+    def __init__(self, translator=None):
         self.structdefnodes = {}
         self.structdeflist = []
         self.containernodes = {}
         self.containerlist = []
         self.namespace = CNameManager()
-        self.pyobjmaker = PyObjMaker(self.namespace, self.get, rtyper)
+        self.pyobjmaker = PyObjMaker(self.namespace, self.get, translator)
 
     def gettypedefnode(self, T, varlength=1):
         if varlength <= 1:
@@ -37,6 +37,7 @@
             else:
                 raise Exception("don't know about %r" % (T,))
             self.structdefnodes[key] = node
+            node.setup()
             self.structdeflist.append(node)
         return node
 

Modified: pypy/branch/translator-without-old-genc/c/funcgen.py
==============================================================================
--- pypy/dist/pypy/translator/c/funcgen.py	(original)
+++ pypy/branch/translator-without-old-genc/c/funcgen.py	Wed Jun  8 19:51:03 2005
@@ -3,8 +3,9 @@
 from pypy.translator.c.support import llvalue_from_constant
 from pypy.objspace.flow.model import Variable, Constant, Block
 from pypy.objspace.flow.model import traverse, uniqueitems, last_exception
-from pypy.rpython.lltype import Ptr, PyObject, Void
+from pypy.rpython.lltype import Ptr, PyObject, Void, Bool
 from pypy.rpython.lltype import pyobjectptr, Struct, Array
+from pypy.translator.unsimplify import remove_direct_loops
 
 
 PyObjPtr = Ptr(PyObject)
@@ -17,6 +18,7 @@
 
     def __init__(self, graph, db):
         self.graph = graph
+        remove_direct_loops(None, graph)
         self.db = db
         self.lltypemap = self.collecttypes()
         self.typemap = {}
@@ -34,7 +36,9 @@
                     result.extend(op.args)
                     result.append(op.result)
                 for link in block.exits:
+                    result.extend(link.getextravars())
                     result.extend(link.args)
+                    result.append(Constant(link.exitcase))
         traverse(visit, self.graph)
         resultvar = self.graph.getreturnvar()
         lltypemap = {resultvar: Void}   # default value, normally overridden
@@ -199,9 +203,16 @@
                     yield '\t\tPy_INCREF(Py_None);'
                     yield '\t}'
                     yield '\tPy_XDECREF(exc_tb);'
-                    for op in gen_link(link, {
-                                link.last_exception: 'exc_cls',
-                                link.last_exc_value: 'exc_value'}):
+                    d = {}
+                    if isinstance(link.last_exception, Variable):
+                        d[link.last_exception] = 'exc_cls'
+                    else:
+                        yield '\tPy_XDECREF(exc_cls);'
+                    if isinstance(link.last_exc_value, Variable):
+                        d[link.last_exc_value] = 'exc_value'
+                    else:
+                        yield '\tPy_XDECREF(exc_value);'
+                    for op in gen_link(link, d):
                         yield '\t' + op
                     yield '}'
                 err_reachable = True
@@ -211,8 +222,19 @@
                 for link in block.exits[:-1]:
                     assert link.exitcase in (False, True)
                     expr = self.expr(block.exitswitch)
-                    if not link.exitcase:
-                        expr = '!' + expr
+                    if TYPE == Bool:
+                        if not link.exitcase:
+                            expr = '!' + expr
+                    elif TYPE == PyObjPtr:
+                        yield 'assert(%s == Py_True || %s == Py_False);' % (
+                            expr, expr)
+                        if link.exitcase:
+                            expr = '%s == Py_True' % expr
+                        else:
+                            expr = '%s == Py_False' % expr
+                    else:
+                        raise TypeError("switches can only be on Bool or "
+                                        "PyObjPtr.  Got %r" % (TYPE,))
                     yield 'if (%s) {' % expr
                     for op in gen_link(link):
                         yield '\t' + op

Modified: pypy/branch/translator-without-old-genc/c/g_module.h
==============================================================================
--- pypy/dist/pypy/translator/c/g_module.h	(original)
+++ pypy/branch/translator-without-old-genc/c/g_module.h	Wed Jun  8 19:51:03 2005
@@ -40,6 +40,7 @@
 
 typedef struct {
 	PyObject** p;
+	char* gfunc_name;
 	PyMethodDef ml;
 } globalfunctiondef_t;
 
@@ -64,8 +65,6 @@
 static int setup_globalfunctions(globalfunctiondef_t* def)
 {
 	PyObject* fn;
-	PyObject* name;
-	int len;
 
 	for (; def->p != NULL; def++) {
 		fn = PyCFunction_New(&def->ml, NULL);
@@ -74,17 +73,10 @@
 		fn->ob_type = &PyGenCFunction_Type;
 		*def->p = fn;   /* store the object ref in the global var */
 
-		len = 0;
-		while (def->ml.ml_name[len] != 0)
-			len++;
-		name = PyString_FromStringAndSize(NULL, 6+len);
-		if (name == NULL)
+		if (PyDict_SetItemString(this_module_globals,
+					 def->gfunc_name,
+					 fn) < 0)
 			return -1;
-		memcpy(PyString_AS_STRING(name), "gfunc_", 6);
-		memcpy(PyString_AS_STRING(name)+6, def->ml.ml_name, len);
-		if (PyDict_SetItem(this_module_globals, name, fn) < 0)
-			return -1;
-		Py_DECREF(name);
 	}
 	return 0;
 }

Modified: pypy/branch/translator-without-old-genc/c/genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/genc.py	(original)
+++ pypy/branch/translator-without-old-genc/c/genc.py	Wed Jun  8 19:51:03 2005
@@ -1,19 +1,48 @@
 import autopath
-import os
+import os, py
 from pypy.translator.c.node import PyObjectNode
+from pypy.translator.c.database import LowLevelDatabase
+from pypy.translator.gensupp import uniquemodulename
+from pypy.translator.tool.buildpyxmodule import make_module_from_c
+from pypy.rpython.lltype import pyobjectptr
+from pypy.tool.udir import udir
+
+
+def translator2database(translator):
+    pf = pyobjectptr(translator.entrypoint)
+    db = LowLevelDatabase(translator)
+    db.get(pf)
+    db.complete()
+    return db, pf
+
+
+def genc(translator, targetdir=None, modulename=None, compile=True):
+    """Generate C code starting at the translator's entry point.
+    The files are written to the targetdir if specified.
+    If 'compile' is True, compile and return the new module.
+    If 'compile' is False, just return the name of the main '.c' file.
+    """
+    db, pf = translator2database(translator)
+
+    if modulename is None:
+        modulename = uniquemodulename('testing')
+    if targetdir is None:
+        targetdir = udir.join(modulename)
+    elif isinstance(targetdir, str):
+        targetdir = py.path.local(targetdir)
+    targetdir.ensure(dir=1)
+    cfile = gen_source(db, modulename, targetdir,
+                       # defines={'COUNT_OP_MALLOCS': 1},
+                       exports = {translator.entrypoint.func_name: pf})
+    if not compile:
+        return cfile
+    m = make_module_from_c(cfile, include_dirs = [autopath.this_dir])
+    return m
 
 
-def gen_source(database, modulename, targetdir, defines={}):
-    filename = os.path.join(targetdir, modulename + '.c')
-    f = open(filename, 'w')
-
-    #
-    # Header
-    #
-    for key, value in defines.items():
-        print >> f, '#define %s %s' % (key, value)
-    print >> f, '#include "g_include.h"'
+# ____________________________________________________________
 
+def gen_readable_parts_of_main_c_file(f, database):
     #
     # All declarations
     #
@@ -22,7 +51,10 @@
     print >> f, '/***  Structure definitions                              ***/'
     print >> f
     for node in database.structdeflist:
-        for line in node.definition():
+        for line in node.definition(phase=1):
+            print >> f, line
+    for node in database.structdeflist:
+        for line in node.definition(phase=2):
             print >> f, line
     print >> f
     print >> f, '/***********************************************************/'
@@ -31,17 +63,40 @@
     for node in database.globalcontainers():
         for line in node.forward_declaration():
             print >> f, line
-
     #
     # Implementation of functions and global structures and arrays
     #
     print >> f
     print >> f, '/***********************************************************/'
     print >> f, '/***  Implementations                                    ***/'
+    blank = True
     for node in database.globalcontainers():
-        print >> f
+        if blank:
+            print >> f
+            blank = False
         for line in node.implementation():
             print >> f, line
+            blank = True
+
+
+def gen_source(database, modulename, targetdir, defines={}, exports={}):
+    if isinstance(targetdir, str):
+        targetdir = py.path.local(targetdir)
+    filename = targetdir.join(modulename + '.c')
+    f = filename.open('w')
+
+    #
+    # Header
+    #
+    for key, value in defines.items():
+        print >> f, '#define %s %s' % (key, value)
+    print >> f, '#include "g_include.h"'
+
+    #
+    # 1) All declarations
+    # 2) Implementation of functions and global structures and arrays
+    #
+    gen_readable_parts_of_main_c_file(f, database)
 
     #
     # PyObject support (strange) code
@@ -67,9 +122,10 @@
     wrappers = pyobjmaker.wrappers.items()
     wrappers.sort()
     for globalobject_name, (base_name, wrapper_name) in wrappers:
-        print >> f, ('\t{&%s, {"%s", (PyCFunction)%s, '
+        print >> f, ('\t{&%s, "%s", {"%s", (PyCFunction)%s, '
                      'METH_VARARGS|METH_KEYWORDS}},' % (
             globalobject_name,
+            globalobject_name,
             base_name,
             wrapper_name))
     print >> f, '\t{ NULL }\t/* Sentinel */'
@@ -80,7 +136,7 @@
     print >> f
     print >> f, 'static char *frozen_initcode[] = {"\\'
     bytecode, originalsource = database.pyobjmaker.getfrozenbytecode()
-    g = open(os.path.join(targetdir, 'frozen.py'), 'w')
+    g = targetdir.join('frozen.py').open('w')
     g.write(originalsource)
     g.close()
     def char_repr(c):
@@ -104,7 +160,11 @@
     print >> f, 'MODULE_INITFUNC(%s)' % modulename
     print >> f, '{'
     print >> f, '\tSETUP_MODULE(%s)' % modulename
-    #print >> f, '\tPyModule_AddObject(m, "%(entrypointname)s", %(entrypoint)s);'
+    for publicname, pyobjptr in exports.items():
+        # some fishing needed to find the name of the obj
+        pyobjnode = database.containernodes[pyobjptr._obj]
+        print >> f, '\tPyModule_AddObject(m, "%s", %s);' % (publicname,
+                                                            pyobjnode.name)
     print >> f, '}'
     f.close()
 
@@ -112,10 +172,12 @@
     # Generate a setup.py while we're at it
     #
     pypy_include_dir = autopath.this_dir
-    f = open(os.path.join(targetdir, 'setup.py'), 'w')
+    f = targetdir.join('setup.py').open('w')
     f.write(SETUP_PY % locals())
     f.close()
 
+    return filename
+
 
 SETUP_PY = '''
 from distutils.core import setup

Modified: pypy/branch/translator-without-old-genc/c/node.py
==============================================================================
--- pypy/dist/pypy/translator/c/node.py	(original)
+++ pypy/branch/translator-without-old-genc/c/node.py	Wed Jun  8 19:51:03 2005
@@ -22,6 +22,12 @@
     def __init__(self, db, STRUCT, varlength=1):
         self.db = db
         self.STRUCT = STRUCT
+        self.varlength = varlength
+
+    def setup(self):
+        db = self.db
+        STRUCT = self.STRUCT
+        varlength = self.varlength
         if varlength == 1:
             basename = STRUCT._name
         else:
@@ -64,14 +70,15 @@
         fldname = self.c_struct_field_name(fldname)
         return '%s.%s' % (baseexpr, fldname)
 
-    def definition(self):
-        yield 'struct %s {' % self.name
-        if needs_refcount(self.STRUCT):
-            yield '\tlong refcount;'
-        for name, typename in self.fields:
-            yield '\t%s;' % cdecl(typename, name)
-        yield '};'
-        if self.deallocator:
+    def definition(self, phase):
+        if phase == 1:
+            yield 'struct %s {' % self.name
+            if needs_refcount(self.STRUCT):
+                yield '\tlong refcount;'
+            for name, typename in self.fields:
+                yield '\t%s;' % cdecl(typename, name)
+            yield '};'
+        elif phase == 2 and self.deallocator:
             yield 'void %s(struct %s *p) {' % (self.deallocator, self.name)
             for line in self.deallocator_lines('p->'):
                 yield '\t' + line
@@ -101,6 +108,12 @@
     def __init__(self, db, ARRAY, varlength=1):
         self.db = db
         self.ARRAY = ARRAY
+        self.varlength = varlength
+
+    def setup(self):
+        db = self.db
+        ARRAY = self.ARRAY
+        varlength = self.varlength
         if varlength == 1:
             basename = 'array'
         else:
@@ -109,7 +122,6 @@
         self.name = db.namespace.uniquename(basename)
         self.dependencies = {}
         self.structname = db.gettype(ARRAY.OF, who_asks=self)
-        self.varlength = varlength
 
         # look up the reference counter field
         if needs_refcount(ARRAY):
@@ -122,14 +134,15 @@
     def access_expr(self, baseexpr, index):
         return '%s.items[%d]' % (baseexpr, index)
 
-    def definition(self):
-        yield 'struct %s {' % self.name
-        if needs_refcount(self.ARRAY):
-            yield '\tlong refcount;'
-        yield '\tlong length;'
-        yield '\t%s;' % cdecl(self.structname, 'items[%d]' % self.varlength)
-        yield '};'
-        if self.deallocator:
+    def definition(self, phase):
+        if phase == 1:
+            yield 'struct %s {' % self.name
+            if needs_refcount(self.ARRAY):
+                yield '\tlong refcount;'
+            yield '\tlong length;'
+            yield '\t%s;' % cdecl(self.structname, 'items[%d]' % self.varlength)
+            yield '};'
+        elif phase == 2 and self.deallocator:
             yield 'void %s(struct %s *a) {' % (self.deallocator, self.name)
             for line in self.deallocator_lines('a->'):
                 yield '\t' + line

Modified: pypy/branch/translator-without-old-genc/c/pyobj.py
==============================================================================
--- pypy/dist/pypy/translator/c/pyobj.py	(original)
+++ pypy/branch/translator-without-old-genc/c/pyobj.py	Wed Jun  8 19:51:03 2005
@@ -22,10 +22,10 @@
     reconstruct them.
     """
 
-    def __init__(self, namespace, getvalue, rtyper=None):
+    def __init__(self, namespace, getvalue, translator=None):
         self.namespace = namespace
         self.getvalue = getvalue
-        self.rtyper = rtyper
+        self.translator = translator
         self.initcode = [      # list of lines for the module's initxxx()
             'import new, types, sys',
             ]
@@ -81,14 +81,19 @@
 
     def nameof_NoneType(self, value):
         assert value is None
-        return 'Py_None'
+        name = self.uniquename('g_None')
+        self.initcode_python(name, "None")
+        return name
 
     def nameof_bool(self, value):
         assert value is False or value is True
         if value:
-            return 'Py_True'
+            name = 'True'
         else:
-            return 'Py_False'
+            name = 'False'
+        name = self.uniquename('g_' + name)
+        self.initcode_python(name, repr(value))
+        return name
 
     def nameof_module(self, value):
         assert value is os or not hasattr(value, "__file__") or \
@@ -155,13 +160,12 @@
         return name
 
     def nameof_function(self, func):
-        assert self.rtyper is not None, (
-            "for now, rtyper must be specified to build a PyObject "
+        assert self.translator is not None, (
+            "the Translator must be specified to build a PyObject "
             "wrapper for %r" % (func,))
         # look for skipped functions
-        a = self.rtyper.annotator
-        if a.translator.frozen:
-            if func not in a.translator.flowgraphs:
+        if self.translator.frozen:
+            if func not in self.translator.flowgraphs:
                 return self.skipped_function(func)
         else:
             if (func.func_doc and
@@ -169,7 +173,7 @@
                 return self.skipped_function(func)
 
         from pypy.translator.c.wrapper import gen_wrapper
-        fwrapper = gen_wrapper(func, self.rtyper)
+        fwrapper = gen_wrapper(func, self.translator)
         pycfunctionobj = self.uniquename('gfunc_' + func.__name__)
         self.wrappers[pycfunctionobj] = func.__name__, self.getvalue(fwrapper)
         return pycfunctionobj

Modified: pypy/branch/translator-without-old-genc/c/test/test_database.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_database.py	(original)
+++ pypy/branch/translator-without-old-genc/c/test/test_database.py	Wed Jun  8 19:51:03 2005
@@ -1,16 +1,19 @@
 import autopath, sys
 from pypy.rpython.lltype import *
-from pypy.rpython.rtyper import RPythonTyper
 from pypy.translator.translator import Translator
 from pypy.translator.c.database import LowLevelDatabase
 from pypy.objspace.flow.model import Constant, Variable, SpaceOperation
 from pypy.objspace.flow.model import Block, Link, FunctionGraph
+from pypy.rpython.rmodel import getfunctionptr
 
 
 def dump_on_stdout(database):
     print '/*********************************/'
     for node in database.structdeflist:
-        for line in node.definition():
+        for line in node.definition(phase=1):
+            print line
+    for node in database.structdeflist:
+        for line in node.definition(phase=2):
             print line
     print
     for node in database.globalcontainers():
@@ -171,12 +174,12 @@
     def f(x):
         return g(1, x)
     t = Translator(f)
-    a = t.annotate([int])
-    RPythonTyper(t.annotator).specialize()
+    t.annotate([int])
+    t.specialize()
 
     F = FuncType([Signed], Signed)
     f = functionptr(F, "f", graph=t.getflowgraph())
-    db = LowLevelDatabase()
+    db = LowLevelDatabase(t)
     db.get(f)
     db.complete()
     dump_on_stdout(db)
@@ -185,11 +188,10 @@
     def f(x):
         return x+1
     t = Translator(f)
-    a = t.annotate([int])
-    rtyper = RPythonTyper(t.annotator)
-    rtyper.specialize()
+    t.annotate([int])
+    t.specialize()
 
-    db = LowLevelDatabase(rtyper)
+    db = LowLevelDatabase(t)
     db.get(pyobjectptr(f))
     db.complete()
     dump_on_stdout(db)
@@ -203,11 +205,11 @@
         p.y = x+1
         return p.x * p.y
     t = Translator(ll_f)
-    a = t.annotate([int])
-    rtyper = RPythonTyper(t.annotator)
-    rtyper.specialize()
-    db = LowLevelDatabase(rtyper)
-    db.get(rtyper.getfunctionptr(ll_f))
+    t.annotate([int])
+    t.specialize()
+
+    db = LowLevelDatabase(t)
+    db.get(getfunctionptr(t, ll_f))
     db.complete()
     dump_on_stdout(db)
 
@@ -226,11 +228,11 @@
         s.ptr2 = ptr2
         return s.ptr1.x * s.ptr2.x
     t = Translator(ll_f)
-    a = t.annotate([int])
-    rtyper = RPythonTyper(t.annotator)
-    rtyper.specialize()
-    db = LowLevelDatabase(rtyper)
-    db.get(rtyper.getfunctionptr(ll_f))
+    t.annotate([int])
+    t.specialize()
+    
+    db = LowLevelDatabase(t)
+    db.get(getfunctionptr(t, ll_f))
     db.complete()
     dump_on_stdout(db)
 
@@ -247,11 +249,11 @@
         s.ptr2 = ptr2
         return s.head.x * s.ptr2.x
     t = Translator(ll_f)
-    a = t.annotate([int])
-    rtyper = RPythonTyper(t.annotator)
-    rtyper.specialize()
-    db = LowLevelDatabase(rtyper)
-    db.get(rtyper.getfunctionptr(ll_f))
+    t.annotate([int])
+    t.specialize()
+    
+    db = LowLevelDatabase(t)
+    db.get(getfunctionptr(t, ll_f))
     db.complete()
     dump_on_stdout(db)
 
@@ -262,3 +264,13 @@
     db.get(a)
     db.complete()
     dump_on_stdout(db)
+
+def test_recursive_struct():
+    S = GcForwardReference()
+    S.become(GcStruct('testing', ('p', Ptr(S))))
+    p = malloc(S)
+    p.p = p
+    db = LowLevelDatabase()
+    db.get(p)
+    db.complete()
+    dump_on_stdout(db)

Modified: pypy/branch/translator-without-old-genc/c/test/test_genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_genc.py	(original)
+++ pypy/branch/translator-without-old-genc/c/test/test_genc.py	Wed Jun  8 19:51:03 2005
@@ -1,6 +1,5 @@
 import autopath, sys, os, py
 from pypy.rpython.lltype import *
-from pypy.rpython.rtyper import RPythonTyper
 from pypy.translator.translator import Translator
 from pypy.translator.c.database import LowLevelDatabase
 from pypy.translator.c.genc import gen_source
@@ -11,8 +10,9 @@
 from pypy.translator.gensupp import uniquemodulename
 
 # XXX this tries to make compiling faster for full-scale testing
-from pypy.translator.tool import buildpyxmodule
-buildpyxmodule.enable_fast_compilation()
+# XXX tcc leaves some errors undetected! Bad!
+#from pypy.translator.tool import buildpyxmodule
+#buildpyxmodule.enable_fast_compilation()
 
 
 def compile_db(db):
@@ -45,11 +45,10 @@
     def f(x):
         return x*2
     t = Translator(f)
-    a = t.annotate([int])
-    rtyper = RPythonTyper(t.annotator)
-    rtyper.specialize()
+    t.annotate([int])
+    t.specialize()
 
-    db = LowLevelDatabase(rtyper)
+    db = LowLevelDatabase(t)
     entrypoint = db.get(pyobjectptr(f))
     db.complete()
     module = compile_db(db)
@@ -72,11 +71,10 @@
         l.append(x+1)
         return l[0] * l[-1]
     t = Translator(f)
-    a = t.annotate([int])
-    rtyper = RPythonTyper(t.annotator)
-    rtyper.specialize()
+    t.annotate([int])
+    t.specialize()
 
-    db = LowLevelDatabase(rtyper)
+    db = LowLevelDatabase(t)
     entrypoint = db.get(pyobjectptr(f))
     db.complete()
     #t.view()
@@ -102,11 +100,10 @@
         else:
             return -42
     t = Translator(f)
-    a = t.annotate([int])
-    rtyper = RPythonTyper(t.annotator)
-    rtyper.specialize()
+    t.annotate([int])
+    t.specialize()
 
-    db = LowLevelDatabase(rtyper)
+    db = LowLevelDatabase(t)
     entrypoint = db.get(pyobjectptr(f))
     db.complete()
     #t.view()

Modified: pypy/branch/translator-without-old-genc/c/wrapper.py
==============================================================================
--- pypy/dist/pypy/translator/c/wrapper.py	(original)
+++ pypy/branch/translator-without-old-genc/c/wrapper.py	Wed Jun  8 19:51:03 2005
@@ -3,14 +3,13 @@
 from pypy.annotation import model as annmodel
 from pypy.rpython.lltype import Ptr, PyObject, typeOf, Signed, Void
 from pypy.rpython.lltype import FuncType, functionptr
-from pypy.rpython.rtyper import LowLevelOpList, inputconst
+from pypy.rpython.rtyper import LowLevelOpList
+from pypy.rpython.rmodel import inputconst, getfunctionptr, PyObjPtr
 from pypy.rpython.robject import pyobj_repr
 from pypy.interpreter.pycode import CO_VARARGS
 
 
-PyObjPtr = Ptr(PyObject)
-
-def gen_wrapper(func, rtyper):
+def gen_wrapper(func, translator):
     """generate a wrapper function for 'func' that can be put in a
     PyCFunction object.  The wrapper has signature
 
@@ -23,11 +22,12 @@
     # get the fully typed low-level pointer to the function, if available
     nb_positional_args = func.func_code.co_argcount
     vararg = bool(func.func_code.co_flags & CO_VARARGS)
-    f = rtyper.getfunctionptr(func)
+
+    f = getfunctionptr(translator, func)
     FUNCTYPE = typeOf(f).TO
     assert len(FUNCTYPE.ARGS) == nb_positional_args + vararg
 
-    newops = LowLevelOpList(rtyper)
+    newops = LowLevelOpList(None)
 
     # "def wrapper(self, args, kwds)"
     vself = Variable('self')
@@ -82,21 +82,29 @@
     # use the rtyper to produce the conversions
     inputargs = f._obj.graph.getargs()
     for i in range(len(varguments)):
-        # "argument_i = type_conversion_operations(argument_i)"
-        r_arg = rtyper.bindingrepr(inputargs[i])
-        varguments[i] = newops.convertvar(varguments[i],
-                                          r_from = pyobj_repr,
-                                            r_to = r_arg)
+        if FUNCTYPE.ARGS[i] != PyObjPtr:
+            # "argument_i = type_conversion_operations(argument_i)"
+            rtyper = translator.rtyper
+            assert rtyper is not None, (
+                "needs the rtyper to perform argument conversions")
+            r_arg = rtyper.bindingrepr(inputargs[i])
+            varguments[i] = newops.convertvar(varguments[i],
+                                              r_from = pyobj_repr,
+                                                r_to = r_arg)
 
     # "result = direct_call(func, argument_0, argument_1, ..)"
     vlist = [inputconst(typeOf(f), f)] + varguments
     vresult = newops.genop('direct_call', vlist, resulttype=FUNCTYPE.RESULT)
 
-    # convert "result" back to a PyObject
-    r_result = rtyper.bindingrepr(f._obj.graph.getreturnvar())
-    vresult = newops.convertvar(vresult,
-                                r_from = r_result,
-                                  r_to = pyobj_repr)
+    if FUNCTYPE.RESULT != PyObjPtr:
+        # convert "result" back to a PyObject
+        rtyper = translator.rtyper
+        assert rtyper is not None, (
+            "needs the rtyper to perform function result conversions")
+        r_result = rtyper.bindingrepr(f._obj.graph.getreturnvar())
+        vresult = newops.convertvar(vresult,
+                                    r_from = r_result,
+                                      r_to = pyobj_repr)
 
     # "return result"
     block = Block([vself, vargs, vkwds])

Modified: pypy/branch/translator-without-old-genc/genc/test/test_lltyped.py
==============================================================================
--- pypy/dist/pypy/translator/genc/test/test_lltyped.py	(original)
+++ pypy/branch/translator-without-old-genc/genc/test/test_lltyped.py	Wed Jun  8 19:51:03 2005
@@ -1,7 +1,6 @@
 from pypy.rpython.lltype import *
 from pypy.translator.tool.buildpyxmodule import skip_missing_compiler
 from pypy.translator.translator import Translator
-from pypy.translator.genc.ctyper import GenCSpecializer
 
 
 class TestLowLevelType:
@@ -12,7 +11,7 @@
         # builds starting-types from func_defs 
         a = t.annotate(argstypelist)
         a.simplify()
-        GenCSpecializer(a).specialize()
+        t.specialize()
         t.checkgraphs()
         #t.view()
         return skip_missing_compiler(t.ccompile)

Modified: pypy/branch/translator-without-old-genc/genc/test/test_typed.py
==============================================================================
--- pypy/dist/pypy/translator/genc/test/test_typed.py	(original)
+++ pypy/branch/translator-without-old-genc/genc/test/test_typed.py	Wed Jun  8 19:51:03 2005
@@ -1,7 +1,6 @@
 import autopath
 import sys
 import py.test
-from pypy.translator.genc.ctyper import GenCSpecializer
 from pypy.translator.translator import Translator
 from pypy.translator.test import snippet 
 from pypy.translator.tool.buildpyxmodule import skip_missing_compiler
@@ -22,7 +21,7 @@
                 argstypelist.append(spec)
         a = t.annotate(argstypelist)
         a.simplify()
-        GenCSpecializer(a).specialize()
+        t.specialize()
         t.checkgraphs()
         return skip_missing_compiler(t.ccompile)
 

Modified: pypy/branch/translator-without-old-genc/test/test_backends.py
==============================================================================
--- pypy/dist/pypy/translator/test/test_backends.py	(original)
+++ pypy/branch/translator-without-old-genc/test/test_backends.py	Wed Jun  8 19:51:03 2005
@@ -13,8 +13,6 @@
 functions = 'forty_two'.split() #XXX add more functions here when RPythonTyper can handle them
 
 regenerate_code = '''def test_regenerate_%(function)s_%(backend)s():
-    if %(backend)r == "c":
-        py.test.skip("the old genc back-end is on the way out")
     t = Translator(%(function)s)
     t.simplify()
     a = t.annotate([])

Modified: pypy/branch/translator-without-old-genc/transform.py
==============================================================================
--- pypy/dist/pypy/translator/transform.py	(original)
+++ pypy/branch/translator-without-old-genc/transform.py	Wed Jun  8 19:51:03 2005
@@ -274,12 +274,6 @@
                 if len(block.exits) == 1:
                     block.exitswitch = None
                     block.exits[0].exitcase = None
-    # make sure that the return variables of all graphs is annotated
-    if self.translator is not None:
-        for graph in self.translator.flowgraphs.values():
-            v = graph.getreturnvar()
-            if v not in self.bindings:
-                self.setbinding(v, annmodel.SomeImpossibleValue())
 
 def cutoff_alwaysraising_block(self, block):
     "Fix a block whose end can never be reached at run-time."

Modified: pypy/branch/translator-without-old-genc/translator.py
==============================================================================
--- pypy/dist/pypy/translator/translator.py	(original)
+++ pypy/branch/translator-without-old-genc/translator.py	Wed Jun  8 19:51:03 2005
@@ -7,12 +7,7 @@
 import autopath, os, sys
 
 from pypy.objspace.flow.model import *
-from pypy.annotation.model import *
-from pypy.translator.annrpython import RPythonAnnotator
 from pypy.translator.simplify import simplify_graph
-from pypy.translator.pyrex.genpyrex import GenPyrex
-from pypy.translator.gencl import GenCL
-from pypy.translator.genc.genc import GenC
 from pypy.translator.gensupp import uniquemodulename
 from pypy.translator.tool.buildpyxmodule import make_module_from_pyxstring
 from pypy.translator.tool.buildpyxmodule import make_module_from_c
@@ -34,12 +29,13 @@
     def clear(self):
         """Clear all annotations and all flow graphs."""
         self.annotator = None
+        self.rtyper = None
         self.flowgraphs = {}  # {function: graph}
         self.functions = []   # the keys of self.flowgraphs, in creation order
         self.callgraph = {}   # {opaque_tag: (caller, callee)}
         self.frozen = False   # when frozen, no more flowgraphs can be generated
-        self.concretetypes = {}  # see getconcretetype()
-        self.ctlist = []         #  "
+        #self.concretetypes = {}  # see getconcretetype()
+        #self.ctlist = []         #  "
         if self.entrypoint:
             self.getflowgraph()
 
@@ -121,6 +117,7 @@
         """
         func = func or self.entrypoint
         if self.annotator is None:
+            from pypy.translator.annrpython import RPythonAnnotator
             self.annotator = RPythonAnnotator(self, policy=policy)
         graph = self.getflowgraph(func)
         self.annotator.build_types(graph, input_args_types, func)
@@ -130,6 +127,15 @@
         for graph in self.flowgraphs.itervalues():
             checkgraph(graph)
 
+    def specialize(self):
+        if self.annotator is None:
+            raise ValueError("you need to call annotate() first")
+        if self.rtyper is not None:
+            raise ValueError("cannot specialize() several times")
+        from pypy.rpython.rtyper import RPythonTyper
+        self.rtyper = RPythonTyper(self.annotator)
+        self.rtyper.specialize()
+
     def source(self, func=None):
         """Returns original Python source.
         
@@ -147,6 +153,7 @@
         returns type annotated translation. Subsequent calls are
         not affected by this.
         """
+        from pypy.translator.pyrex.genpyrex import GenPyrex
         return self.generatecode(GenPyrex, input_arg_types, func)
 
     def cl(self, input_arg_types=None, func=None):
@@ -156,6 +163,7 @@
         returns type annotated translation. Subsequent calls are
         not affected by this.
         """
+        from pypy.translator.gencl import GenCL
         return self.generatecode(GenCL, input_arg_types, func)
 
     def c(self):
@@ -163,10 +171,12 @@
         
         Returns C (CPython) translation.
         """
-        from StringIO import StringIO 
-        out = StringIO()
-        genc = GenC(out, self)
-        return out.getvalue()
+        from pypy.translator.c import genc
+        from cStringIO import StringIO
+        f = StringIO()
+        database, ignored = genc.translator2database(self)
+        genc.gen_readable_parts_of_main_c_file(f, database)
+        return f.getvalue()
 
     def llvm(self):
         """llvm(self) -> LLVM translation
@@ -183,6 +193,7 @@
         if input_arg_types is None:
             ann = self.annotator
         else:
+            from pypy.translator.annrpython import RPythonAnnotator
             ann = RPythonAnnotator(self)
         if func is None:
             codes = [self.generatecode1(gencls, input_arg_types,
@@ -228,22 +239,14 @@
     def ccompile(self, really_compile=True):
         """Returns compiled function, compiled using the C generator.
         """
-        from pypy.tool.udir import udir
+        from pypy.translator.c import genc
         if self.annotator is not None:
             self.frozen = True
-        name = uniquemodulename(self.entrypoint.func_name)
-        cfile = udir.join('%s.c' % name)
-        f = cfile.open('w')
-        f2 = udir.join('%s-init.py' % name).open('w+')
-        GenC(f, self, name, f2=f2)
-        f2.close()
-        f.close()
-        if not really_compile:
-            return cfile
-        mod = make_module_from_c(cfile,
-            include_dirs=[os.path.join(autopath.this_dir, 'genc')])
-        self.concretetypes.clear()
-        return getattr(mod, self.entrypoint.func_name)
+
+        result = genc.genc(self, compile=really_compile)
+        if really_compile:  # result is the module
+            result = getattr(result, self.entrypoint.func_name)
+        return result
 
     def llvmcompile(self, optimize=True):
         """llvmcompile(self, optimize=True) -> LLVM translation
@@ -276,15 +279,15 @@
 ##            # not actually start the analysis of the called function yet.
 ##            return impossiblevalue
 
-    def getconcretetype(self, cls, *args):
-        "DEPRECATED.  To be removed"
-        # Return a (cached) 'concrete type' object attached to this translator.
-        # Concrete types are what is put in the 'concretetype' attribute of
-        # the Variables and Constants of the flow graphs by typer.py to guide
-        # the code generators.
-        try:
-            return self.concretetypes[cls, args]
-        except KeyError:
-            result = self.concretetypes[cls, args] = cls(self, *args)
-            self.ctlist.append(result)
-            return result
+##    def getconcretetype(self, cls, *args):
+##        "DEPRECATED.  To be removed"
+##        # Return a (cached) 'concrete type' object attached to this translator.
+##        # Concrete types are what is put in the 'concretetype' attribute of
+##        # the Variables and Constants of the flow graphs by typer.py to guide
+##        # the code generators.
+##        try:
+##            return self.concretetypes[cls, args]
+##        except KeyError:
+##            result = self.concretetypes[cls, args] = cls(self, *args)
+##            self.ctlist.append(result)
+##            return result

Modified: pypy/branch/translator-without-old-genc/unsimplify.py
==============================================================================
--- pypy/dist/pypy/translator/unsimplify.py	(original)
+++ pypy/branch/translator-without-old-genc/unsimplify.py	Wed Jun  8 19:51:03 2005
@@ -4,9 +4,10 @@
     """Make a copy of the Variable v, preserving annotations and concretetype."""
     assert isinstance(v, Variable)
     newvar = Variable(v)
-    annotator = translator.annotator
-    if annotator is not None and v in annotator.bindings:
-        annotator.bindings[newvar] = annotator.bindings[v]
+    if translator is not None:
+        annotator = translator.annotator
+        if annotator is not None and v in annotator.bindings:
+            annotator.bindings[newvar] = annotator.bindings[v]
     if hasattr(v, 'concretetype'):
         newvar.concretetype = v.concretetype
     return newvar



More information about the Pypy-commit mailing list