[pypy-svn] r15370 - in pypy/dist/pypy/translator/c: . test
arigo at codespeak.net
arigo at codespeak.net
Fri Jul 29 20:24:25 CEST 2005
Author: arigo
Date: Fri Jul 29 20:24:22 2005
New Revision: 15370
Modified:
pypy/dist/pypy/translator/c/database.py
pypy/dist/pypy/translator/c/genc.py
pypy/dist/pypy/translator/c/node.py
pypy/dist/pypy/translator/c/test/test_database.py
pypy/dist/pypy/translator/c/test/test_genc.py
Log:
Reordering of the StructDefNode.setup() and ArrayDefNode.setup().
This ensures that the C source code has the definitions in the correct order,
but it's a bit fragile and head-against-wall-banging kind of ordering issues.
Modified: pypy/dist/pypy/translator/c/database.py
==============================================================================
--- pypy/dist/pypy/translator/c/database.py (original)
+++ pypy/dist/pypy/translator/c/database.py Fri Jul 29 20:24:22 2005
@@ -16,7 +16,6 @@
def __init__(self, translator=None):
self.translator = translator
self.structdefnodes = {}
- self.structdeflist = []
self.containernodes = {}
self.containerlist = []
self.externalfuncs = {}
@@ -40,7 +39,6 @@
raise Exception("don't know about %r" % (T,))
self.structdefnodes[key] = node
node.setup()
- self.structdeflist.append(node)
return node
def gettype(self, T, varlength=1, who_asks=None, argnames=[]):
@@ -160,3 +158,17 @@
return exceptiondata.lltype_of_exception_value
else:
return Ptr(PyObject)
+
+ def getstructdeflist(self):
+ # return the StructDefNodes sorted according to dependencies
+ result = []
+ seen = {}
+ def produce(node):
+ if node not in seen:
+ for othernode in node.dependencies:
+ produce(othernode)
+ result.append(node)
+ seen[node] = True
+ for node in self.structdefnodes.values():
+ produce(node)
+ return result
Modified: pypy/dist/pypy/translator/c/genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/genc.py (original)
+++ pypy/dist/pypy/translator/c/genc.py Fri Jul 29 20:24:22 2005
@@ -55,11 +55,12 @@
#
# All declarations
#
+ structdeflist = database.getstructdeflist()
print >> f
print >> f, '/***********************************************************/'
print >> f, '/*** Structure definitions ***/'
print >> f
- for node in database.structdeflist:
+ for node in structdeflist:
for line in node.definition(phase=1):
print >> f, line
print >> f
@@ -82,7 +83,7 @@
print >> f, '#include "src/g_include.h"'
print >> f
blank = False
- for node in database.structdeflist:
+ for node in structdeflist:
for line in node.definition(phase=2):
print >> f, line
blank = True
@@ -138,7 +139,7 @@
print >> f, '/*** Debugging info ***/'
print >> f
print >> f, 'static int debuginfo_offsets[] = {'
- for node in database.structdeflist:
+ for node in database.structdefnodes.values():
for expr in symboltable.generate_type_info(database, node):
print >> f, '\t%s,' % expr
print >> f, '\t0 };'
Modified: pypy/dist/pypy/translator/c/node.py
==============================================================================
--- pypy/dist/pypy/translator/c/node.py (original)
+++ pypy/dist/pypy/translator/c/node.py Fri Jul 29 20:24:22 2005
@@ -30,11 +30,6 @@
self.STRUCT = STRUCT
self.LLTYPE = STRUCT
self.varlength = varlength
-
- def setup(self):
- db = self.db
- STRUCT = self.STRUCT
- varlength = self.varlength
if varlength == 1:
basename = STRUCT._name
with_number = True
@@ -44,15 +39,7 @@
with_number = False
self.name = db.namespace.uniquename(basename, with_number=with_number)
self.dependencies = {}
- self.fields = []
self.prefix = somelettersfrom(STRUCT._name) + '_'
- for name in STRUCT._names:
- T = self.c_struct_field_type(name)
- if name == STRUCT._arrayfld:
- typename = db.gettype(T, varlength=varlength, who_asks=self)
- else:
- typename = db.gettype(T, who_asks=self)
- self.fields.append((self.c_struct_field_name(name), typename))
# look up the reference counter field
if needs_refcount(STRUCT):
@@ -61,14 +48,29 @@
# refcount in the first field
T = self.c_struct_field_type(STRUCT._names[0])
assert isinstance(T, GC_CONTAINER)
- firstfieldname, firstfieldtype = self.fields[0]
firstdefnode = db.gettypedefnode(T)
+ firstfieldname = self.c_struct_field_name(STRUCT._names[0])
self.refcount = '%s.%s' % (firstfieldname, firstdefnode.refcount)
# check here that there is enough run-time type information to
# handle this case
getRuntimeTypeInfo(STRUCT)
getRuntimeTypeInfo(T)
+ def setup(self):
+ # this computes self.fields
+ self.fields = []
+ db = self.db
+ STRUCT = self.STRUCT
+ varlength = self.varlength
+ for name in STRUCT._names:
+ T = self.c_struct_field_type(name)
+ if name == STRUCT._arrayfld:
+ typename = db.gettype(T, varlength=self.varlength,
+ who_asks=self)
+ else:
+ typename = db.gettype(T, who_asks=self)
+ self.fields.append((self.c_struct_field_name(name), typename))
+
# do we need deallocator(s)?
if self.refcount and varlength == 1:
self.deallocator = db.namespace.uniquename('dealloc_'+self.name)
@@ -173,16 +175,11 @@
self.db = db
self.ARRAY = ARRAY
self.LLTYPE = ARRAY
- self.varlength = varlength
- self.original_varlength = varlength
+ original_varlength = varlength
if ARRAY is STR.chars:
- self.varlength += 1 # for the NULL char at the end of the string
-
- def setup(self):
- db = self.db
- ARRAY = self.ARRAY
- varlength = self.varlength
- if self.original_varlength == 1:
+ varlength += 1 # for the NULL char at the end of the string
+ self.varlength = varlength
+ if original_varlength == 1:
basename = 'array'
with_number = True
else:
@@ -191,12 +188,17 @@
with_number = False
self.name = db.namespace.uniquename(basename, with_number=with_number)
self.dependencies = {}
- self.itemtypename = db.gettype(ARRAY.OF, who_asks=self)
# look up the reference counter field
if needs_refcount(ARRAY):
self.refcount = 'refcount'
+ def setup(self):
+ db = self.db
+ ARRAY = self.ARRAY
+ varlength = self.varlength
+ self.itemtypename = db.gettype(ARRAY.OF, who_asks=self)
+
# is a specific deallocator needed?
if self.refcount and varlength == 1 and list(self.deallocator_lines('')):
self.deallocator = db.namespace.uniquename('dealloc_'+self.name)
Modified: pypy/dist/pypy/translator/c/test/test_database.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_database.py (original)
+++ pypy/dist/pypy/translator/c/test/test_database.py Fri Jul 29 20:24:22 2005
@@ -9,10 +9,11 @@
def dump_on_stdout(database):
print '/*********************************/'
- for node in database.structdeflist:
+ structdeflist = database.getstructdeflist()
+ for node in structdeflist:
for line in node.definition(phase=1):
print line
- for node in database.structdeflist:
+ for node in structdeflist:
for line in node.definition(phase=2):
print line
print
Modified: pypy/dist/pypy/translator/c/test/test_genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_genc.py (original)
+++ pypy/dist/pypy/translator/c/test/test_genc.py Fri Jul 29 20:24:22 2005
@@ -182,3 +182,20 @@
f1 = compile(fn, [int])
res = f1(1)
assert res == 'e'
+
+
+def test_recursive_struct():
+ # B has an A as its super field, and A has a pointer to B.
+ class A:
+ pass
+ class B(A):
+ pass
+ def fn(i):
+ a = A()
+ b = B()
+ a.b = b
+ b.i = i
+ return a.b.i
+ f1 = compile(fn, [int])
+ res = f1(42)
+ assert res == 42
More information about the Pypy-commit
mailing list