[pypy-svn] r24103 - pypy/dist/pypy/translator/c

ericvrp at codespeak.net ericvrp at codespeak.net
Wed Mar 8 14:34:31 CET 2006


Author: ericvrp
Date: Wed Mar  8 14:34:29 2006
New Revision: 24103

Modified:
   pypy/dist/pypy/translator/c/database.py
   pypy/dist/pypy/translator/c/external.py
   pypy/dist/pypy/translator/c/funcgen.py
   pypy/dist/pypy/translator/c/genc.py
   pypy/dist/pypy/translator/c/node.py
   pypy/dist/pypy/translator/c/stackless.py
Log:
Allow multiple function generators to be attached to a FuncNode.
I will use this to experiment with generate two version of
functions that need stackless support. A first version will not
have resume support while the second version will have both unwind
and resume support.


Modified: pypy/dist/pypy/translator/c/database.py
==============================================================================
--- pypy/dist/pypy/translator/c/database.py	(original)
+++ pypy/dist/pypy/translator/c/database.py	Wed Mar  8 14:34:29 2006
@@ -192,7 +192,7 @@
             if self.latercontainerlist:
                 work_to_do = True
                 for node in self.latercontainerlist:
-                    node.make_funcgen()
+                    node.make_funcgens()
                     self.containerlist.append(node)
                 self.latercontainerlist = []
         self.completed = True

Modified: pypy/dist/pypy/translator/c/external.py
==============================================================================
--- pypy/dist/pypy/translator/c/external.py	(original)
+++ pypy/dist/pypy/translator/c/external.py	Wed Mar  8 14:34:29 2006
@@ -16,6 +16,9 @@
         self.argtypenames = [db.gettype(T) for T in self.FUNCTYPE.ARGS]
         self.resulttypename = db.gettype(self.FUNCTYPE.RESULT)
 
+    def name(self, cname):  #virtual
+        return cname
+
     def argnames(self):
         return ['%s%d' % (somelettersfrom(self.argtypenames[i]), i)
                 for i in range(len(self.argtypenames))]

Modified: pypy/dist/pypy/translator/c/funcgen.py
==============================================================================
--- pypy/dist/pypy/translator/c/funcgen.py	(original)
+++ pypy/dist/pypy/translator/c/funcgen.py	Wed Mar  8 14:34:29 2006
@@ -82,6 +82,9 @@
         self.vars = uniquemix
         self.lltypes = None
 
+    def name(self, cname):  #virtual
+        return cname
+
     def implementation_begin(self):
         db = self.db
         lltypes = {}

Modified: pypy/dist/pypy/translator/c/genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/genc.py	(original)
+++ pypy/dist/pypy/translator/c/genc.py	Wed Mar  8 14:34:29 2006
@@ -728,5 +728,5 @@
 \t$(CC) $(CFLAGS) -o $@ -c $< $(INCLUDEDIRS)
 
 clean:
-\trm -f $(OBJECTS)
+\trm -f $(OBJECTS) $(TARGET)
 '''

Modified: pypy/dist/pypy/translator/c/node.py
==============================================================================
--- pypy/dist/pypy/translator/c/node.py	(original)
+++ pypy/dist/pypy/translator/c/node.py	Wed Mar  8 14:34:29 2006
@@ -421,7 +421,7 @@
 class FuncNode(ContainerNode):
     nodekind = 'func'
     if USESLOTS:
-        __slots__ = """funcgen""".split()
+        __slots__ = """funcgens""".split()
 
     def __init__(self, db, T, obj):
         self.globalcontainer = True
@@ -435,37 +435,38 @@
             self.includes = ()
             self.name = db.namespace.uniquename('g_' + self.basename())
         if not getattr(obj, 'isgchelper', False):
-            self.make_funcgen()
+            self.make_funcgens()
         #self.dependencies = {}
         self.typename = db.gettype(T)  #, who_asks=self)
         self.ptrname = self.name
 
-    def make_funcgen(self):
-        self.funcgen = select_function_code_generator(self.obj, self.db, self.name)
-        if self.funcgen:
-            argnames = self.funcgen.argnames()
+    def make_funcgens(self):
+        self.funcgens = select_function_code_generators(self.obj, self.db, self.name)
+        if self.funcgens:
+            argnames = self.funcgens[0].argnames()  #Assume identical for all funcgens
             self.implementationtypename = self.db.gettype(self.T, argnames=argnames)
 
     def basename(self):
         return self.obj._name
 
     def enum_dependencies(self):
-        if self.funcgen is None:
+        if not self.funcgens:
             return []
-        return self.funcgen.allconstantvalues()
+        return self.funcgens[0].allconstantvalues() #Assume identical for all funcgens
 
     def forward_declaration(self):
-        if self.funcgen:
-            return ContainerNode.forward_declaration(self)
-        else:
-            return []
+        for funcgen in self.funcgens:
+            yield '%s;' % (
+                cdecl(self.implementationtypename, funcgen.name(self.name)))
 
     def implementation(self):
-        funcgen = self.funcgen
-        if funcgen is None:
-            return
+        for funcgen in self.funcgens:
+            for s in self.funcgen_implementation(funcgen):
+                yield s
+
+    def funcgen_implementation(self, funcgen):
         funcgen.implementation_begin()
-        yield '%s {' % cdecl(self.implementationtypename, self.name)
+        yield '%s {' % cdecl(self.implementationtypename, funcgen.name(self.name))
         #
         # declare the local variables
         #
@@ -508,30 +509,36 @@
 
 assert not USESLOTS or '__dict__' not in dir(FuncNode)
 
-def select_function_code_generator(fnobj, db, functionname):
+def select_function_code_generators(fnobj, db, functionname):
     if fnobj._callable in extfunc.EXTERNALS:
         # 'fnobj' is one of the ll_xyz() functions with the suggested_primitive
         # flag in pypy.rpython.module.*.  The corresponding C wrappers are
         # written by hand in src/ll_*.h, and declared in extfunc.EXTERNALS.
         db.externalfuncs[fnobj._callable] = fnobj
-        return None
+        return []
     elif getattr(fnobj._callable, 'suggested_primitive', False):
         raise ValueError, "trying to compile suggested primitive %r" % (
             fnobj._callable,)
     elif hasattr(fnobj, 'graph'):
         cpython_exc = getattr(fnobj, 'exception_policy', None) == "CPython"
         if hasattr(db, 'stacklessdata') and not db.use_stackless_transformation:
-            from pypy.translator.c.stackless import SlpFunctionCodeGenerator
-            gencls = SlpFunctionCodeGenerator
+            split_slp_function = False
+            if split_slp_function:
+                from pypy.translator.c.stackless import SlpSaveOnlyFunctionCodeGenerator, \
+                                                        SlpResumeFunctionCodeGenerator
+                return [SlpSaveOnlyFunctionCodeGenerator(fnobj.graph, db, cpython_exc, functionname),
+                        SlpResumeFunctionCodeGenerator(fnobj.graph, db, cpython_exc, functionname)]
+            else:
+                from pypy.translator.c.stackless import SlpFunctionCodeGenerator
+                return [SlpFunctionCodeGenerator(fnobj.graph, db, cpython_exc, functionname)]
         else:
-            gencls = FunctionCodeGenerator
-        return gencls(fnobj.graph, db, cpython_exc, functionname)
+            return [FunctionCodeGenerator(fnobj.graph, db, cpython_exc, functionname)]
     elif getattr(fnobj, 'external', None) == 'C':
         # deprecated case
         if getattr(fnobj, 'includes', None):
-            return None   # assume no wrapper needed
+            return []   # assume no wrapper needed
         else:
-            return CExternalFunctionCodeGenerator(fnobj, db)
+            return [CExternalFunctionCodeGenerator(fnobj, db)]
     else:
         raise ValueError, "don't know how to generate code for %r" % (fnobj,)
 

Modified: pypy/dist/pypy/translator/c/stackless.py
==============================================================================
--- pypy/dist/pypy/translator/c/stackless.py	(original)
+++ pypy/dist/pypy/translator/c/stackless.py	Wed Mar  8 14:34:29 2006
@@ -211,6 +211,7 @@
 
 
 class SlpFunctionCodeGenerator(FunctionCodeGenerator):
+    needs_resume = True
 
     def cfunction_body(self):
         # lists filled by check_directcall_result() from super.cfunction_body()
@@ -219,13 +220,16 @@
         body = list(super(SlpFunctionCodeGenerator, self).cfunction_body())
         #
         if self.savelines:   # header (if we need to resume)
-            yield 'if (slp_frame_stack_top) goto resume;'
+            if self.needs_resume:
+                yield 'if (slp_frame_stack_top) goto resume;'
         for line in body:    # regular body
             yield line
         if self.savelines:
             yield ''
             for line in self.savelines:  # save-state-away lines
                 yield line
+            if not self.needs_resume:
+                return
             yield ''
             yield 'resume:'    # resume-state blocks
             yield '{'
@@ -247,7 +251,7 @@
             argtypes = [T for T in argtypes if T is not lltype.Void]
             rettype = signature_type(self.lltypemap(self.graph.getreturnvar()))
             FUNC = lltype.FuncType(argtypes, rettype)
-            slpdata.registerunwindable(self.functionname, FUNC,
+            slpdata.registerunwindable(self.name(self.functionname), FUNC,
                                        resume_points = len(self.resumeblocks))
 
         del self.savelines
@@ -346,6 +350,17 @@
         return line
 
 
+class SlpSaveOnlyFunctionCodeGenerator(SlpFunctionCodeGenerator):
+    needs_resume = False
+
+
+class SlpResumeFunctionCodeGenerator(SlpFunctionCodeGenerator):
+    needs_resume = True
+
+    def name(self, cname):
+        return cname + '_SlpResume'
+        
+
 def signature_type(T):
     """Return T unless it's a pointer type, in which case we return a general
     basic pointer type.



More information about the Pypy-commit mailing list