[pypy-svn] r6628 - pypy/trunk/src/pypy/translator

arigo at codespeak.net arigo at codespeak.net
Tue Sep 21 19:59:48 CEST 2004


Author: arigo
Date: Tue Sep 21 19:59:47 2004
New Revision: 6628

Modified:
   pypy/trunk/src/pypy/translator/genc.h
   pypy/trunk/src/pypy/translator/genc.py
   pypy/trunk/src/pypy/translator/genc_op.py
   pypy/trunk/src/pypy/translator/genc_repr.py
   pypy/trunk/src/pypy/translator/genc_typeset.py
Log:
Implement lists as arrays of C structs.  (Intermediate check-in with the new 
code disabled; many tests still failing)



Modified: pypy/trunk/src/pypy/translator/genc.h
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.h	(original)
+++ pypy/trunk/src/pypy/translator/genc.h	Tue Sep 21 19:59:47 2004
@@ -141,5 +141,10 @@
 #define OP_CCALL_i(fn, args, r, err)    if ((r=fn args) == -1 &&            \
                                             PyErr_Occurred()) goto err;
 
+#define OP_NEWARRAY(name,len,r,err)   if (!(r=alloclist_##name(len))) goto err;
+#define OP_NEWARRAY_SET(name,r,i,f,v)   ((PyList_##name*) r)->ob_item[i].f=v;
+#define OP_NEWARRAY_SET_o(name,r,i,f,o) ((PyList_##name*) r)->ob_item[i].f=o; \
+								  Py_INCREF(o);
+
 /************************************************************/
  /***  The rest is produced by genc.py                     ***/

Modified: pypy/trunk/src/pypy/translator/genc.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genc.py	(original)
+++ pypy/trunk/src/pypy/translator/genc.py	Tue Sep 21 19:59:47 2004
@@ -41,6 +41,7 @@
         self.initializationcode = []
         self.llclasses = {};   self.classeslist = []
         self.llfunctions = {}; self.functionslist = []
+        self.llarrays = {}
         # must build functions first, otherwise methods are not found
         self.build_llfunctions()
         self.build_llclasses()
@@ -308,6 +309,44 @@
 
         self.initializationcode.append('SETUP_TYPE(%s)' % llclass.name)
 
+    def declare_list(self, lltypes):
+        # called by genc_typer.py to write the type definition of a list
+        # as an array of "struct { lltypes };"
+        lltypes = tuple(lltypes)
+        if lltypes in self.llarrays:
+            return self.llarrays[lltypes]   # already seen
+
+        s = '_'.join(lltypes)
+        name = ''.join([('a'<=c<='z' or '0'<=c<='9') and c or '_' for c in s])
+        name += '_%d' % len(self.llarrays)
+        self.llarrays[lltypes] = name
+        
+        f = self.f
+        info = {
+            'name': name,
+            }
+        print >> f, self.C_LIST_HEADER % info
+        llvars1 = []
+        for i in range(len(lltypes)):
+            print >> f, '\t%s;' % cdecl(lltypes[i], 'a%d'%i)
+            llvars1.append(LLVar(lltypes[i], 'item->a%d'%i))
+        print >> f, self.C_LIST_FOOTER % info
+
+        print >> f, self.C_LIST_DEALLOC_HEADER % info
+        lldecref = self.typeset.rawoperations['xdecref']
+        line = lldecref(llvars1)
+        code = line.write()
+        if code:
+            print >> f, self.C_LIST_DEALLOC_LOOP_HEADER % info
+            for codeline in code.split('\n'):
+                print >> f, '\t\t' + codeline
+            print >> f, self.C_LIST_DEALLOC_LOOP_FOOTER % info
+        print >> f, self.C_LIST_DEALLOC_FOOTER % info
+
+        print >> f, self.C_LIST_TYPEOBJECT % info
+        return name
+
+
 # ____________________________________________________________
 
     C_HEADER = open(os.path.join(autopath.this_dir, 'genc.h')).read()
@@ -416,4 +455,88 @@
 };
 '''
 
+    C_LIST_HEADER = '''/* the type "list of %(name)s" */
+typedef struct {'''
+
+    C_LIST_FOOTER = '''} ListItem_%(name)s;
+
+typedef struct {
+	PyObject_VAR_HEAD
+	ListItem_%(name)s* ob_item;
+} PyList_%(name)s;
+'''
+
+    C_LIST_DEALLOC_HEADER = (
+'''static void dealloclist_%(name)s(PyList_%(name)s* op)
+{''')
+
+    C_LIST_DEALLOC_LOOP_HEADER = (
+'''	int i = op->ob_size;
+	ListItem_%(name)s item = op->ob_item + i;
+	while (--i >= 0) {''')
+
+    C_LIST_DEALLOC_LOOP_FOOTER = (
+'''		--item;
+	}''')
+
+    C_LIST_DEALLOC_FOOTER = (
+'''	PyMem_Free(op->ob_item);
+	PyObject_Del((PyObject*) op);
+}
+''')
+
+    C_LIST_TYPEOBJECT = '''static PyTypeObject g_ListType_%(name)s = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"list of %(name)s",
+	sizeof(PyList_%(name)s),
+	0,
+	(destructor)dealloclist_%(name)s,	/* tp_dealloc */
+	0,					/* tp_print */
+	0,					/* tp_getattr */
+	0,					/* tp_setattr */
+	0,					/* tp_compare */
+	0,					/* tp_repr */
+	0,					/* tp_as_number */
+	0,					/* tp_as_sequence */
+	0,					/* tp_as_mapping */
+	0,					/* tp_hash */
+	0,					/* tp_call */
+	0,					/* tp_str */
+	PyObject_GenericGetAttr,		/* tp_getattro */
+	0,					/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT,			/* tp_flags */
+ 	0,					/* tp_doc */
+ 	0,	/* XXX need GC */		/* tp_traverse */
+ 	0,					/* tp_clear */
+};
+
+static PyObject* alloclist_%(name)s(int len)
+{
+	void* buffer;
+	PyList_%(name)s* o;
+
+	if (len > 0) {
+		buffer = PyMem_Malloc(len * sizeof(ListItem_%(name)s));
+		if (buffer == NULL) {
+			PyErr_NoMemory();
+			return NULL;
+		}
+	}
+	else
+		buffer = NULL;
+
+	o = PyObject_New(PyList_%(name)s, &g_ListType_%(name)s);
+	if (o != NULL) {
+		o->ob_size = len;
+		o->ob_item = (ListItem_%(name)s*) buffer;
+	}
+	else {
+		PyMem_Free(buffer);
+	}
+	return o;
+}
+'''
+
 # ____________________________________________________________

Modified: pypy/trunk/src/pypy/translator/genc_op.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genc_op.py	(original)
+++ pypy/trunk/src/pypy/translator/genc_op.py	Tue Sep 21 19:59:47 2004
@@ -156,6 +156,29 @@
     macro    = 'OP_NEWLIST'
     # self.args: [input PyObjects.., output PyObject]
 
+class LoNewArray(LoC):
+    can_fail = True
+    typename = PARAMETER   # the name of the PyList_Xxx type in the C source
+    lltypes  = PARAMETER   # the C types needed to represent each array item
+    # self.args: [item0.., item1.., item2.., ..., output PyObject]
+    def writestr(self, *stuff):
+        args   = stuff[:-2]
+        result = stuff[-2]
+        err    = stuff[-1]
+        ls = ['OP_NEWARRAY(%s, %d, %s, %s)' % (self.typename,
+                                               len(args) / len(self.lltypes),
+                                               result,
+                                               err)]
+        for i in range(0, len(args), len(self.lltypes)):
+            for j in range(len(self.lltypes)):
+                if self.lltypes[j] == 'PyObject*':
+                    typecode = '_o'
+                else:
+                    typecode = ''
+                ls.append('OP_NEWARRAY_SET%s(%s, %s, %d, a%d, %s)' % (
+                    typecode, self.typename, result, i, j, args[i+j]))
+        return '\n'.join(ls)
+
 class LoGetAttr(LoC):
     cost = 1
     fld  = PARAMETER

Modified: pypy/trunk/src/pypy/translator/genc_repr.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genc_repr.py	(original)
+++ pypy/trunk/src/pypy/translator/genc_repr.py	Tue Sep 21 19:59:47 2004
@@ -250,6 +250,16 @@
             cost     = cost,
             )
 
+class CList(CRepr):
+    "A list as an array whose items are represented as r_item."
+
+    def __init__(self, r_item):
+        self.r_item = r_item
+        self.impl = ['PyObject*']
+
+    def __repr__(self):
+        return 'CList(%r)' % (self.r_item,)
+
 # ____________________________________________________________
 #
 # Predefined CReprs and caches for building more
@@ -265,6 +275,7 @@
 R_INSTANCE_CACHE = {}
 R_FUNCTION_CACHE = {}
 R_METHOD_CACHE   = {}
+R_LIST_CACHE     = {}
 
 def tuple_representation(items_r):
     items_r = tuple(items_r)
@@ -327,6 +338,13 @@
         r = R_METHOD_CACHE[key] = CMethod(r_func)
         return r
 
+def list_representation(r_item):
+    try:
+        return R_LIST_CACHE[r_item]
+    except KeyError:
+        r = R_LIST_CACHE[r_item] = CList(r_item)
+        return r
+
 
 def c_str(s):
     "Return the C expression for the string 's'."

Modified: pypy/trunk/src/pypy/translator/genc_typeset.py
==============================================================================
--- pypy/trunk/src/pypy/translator/genc_typeset.py	(original)
+++ pypy/trunk/src/pypy/translator/genc_typeset.py	Tue Sep 21 19:59:47 2004
@@ -12,6 +12,7 @@
 from pypy.translator.genc_repr import function_representation, CFunction
 from pypy.translator.genc_repr import CConstantFunction
 from pypy.translator.genc_repr import method_representation, CMethod
+from pypy.translator.genc_repr import list_representation, CList
 
 
 class CTypeSet:
@@ -72,6 +73,12 @@
                     return r_func
                 else:
                     return method_representation(r_func)
+            if 0: # still working on it -- isinstance(var, annmodel.SomeList):
+                r_item = self.gethltype(var.s_item)
+                typename = self.genc.declare_list(r_item.impl)
+                r = list_representation(r_item)
+                r.typename = typename
+                return r
             # fall-back
             return R_OBJECT
         if isinstance(var, UndefinedConstant):
@@ -149,10 +156,21 @@
     # ____________________________________________________________
 
     def extend_OP_NEWLIST(self, hltypes):
+        if not hltypes:
+            return
         # LoNewList can build a list of any length from PyObject* args.
         sig = (R_OBJECT,) * len(hltypes)
         yield sig, genc_op.LoNewList
 
+        # LoNewArray can build an array from items of the correct type.
+        r = hltypes[-1]
+        if isinstance(r, CList):
+            sig = (r.r_item,) * (len(hltypes)-1) + (r,)
+            yield sig, genc_op.LoNewArray.With(
+                typename = r.typename,
+                lltypes  = r.r_item.impl,
+                )
+
     def extend_OP_NEWTUPLE(self, hltypes):
         # We can use LoCopy to virtually build a tuple because
         # the tuple representation 'rt' is just the collection of all the



More information about the Pypy-commit mailing list