[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