[pypy-svn] r6295 - pypy/branch/pypy-genc/translator

arigo at codespeak.net arigo at codespeak.net
Mon Sep 6 14:47:07 CEST 2004


Author: arigo
Date: Mon Sep  6 14:47:06 2004
New Revision: 6295

Added:
   pypy/branch/pypy-genc/translator/classtyper.py
Removed:
   pypy/branch/pypy-genc/translator/formatter.py
   pypy/branch/pypy-genc/translator/genc_class.h
Modified:
   pypy/branch/pypy-genc/translator/genc.h
   pypy/branch/pypy-genc/translator/genc.py
   pypy/branch/pypy-genc/translator/genc_typeset.py
   pypy/branch/pypy-genc/translator/typer.py
Log:
Replaced the combination genc_class.h/formatter.py with classtyper.py which 
preprocesses class definitions into simple structures and support functions.  
The support functions are generated by producing a control flow graph, which 
is then translated into a C function by genc.py like all user-defined 
functions.

 --This line, and those below, will be ignored--

A    translator/classtyper.py
M    translator/genc_typeset.py
D    translator/genc_class.h
M    translator/typer.py
D    translator/formatter.py
M    translator/genc.h
M    translator/genc.py


Added: pypy/branch/pypy-genc/translator/classtyper.py
==============================================================================
--- (empty file)
+++ pypy/branch/pypy-genc/translator/classtyper.py	Mon Sep  6 14:47:06 2004
@@ -0,0 +1,93 @@
+"""
+Extension to typer.py to preprocess class definitions and usage into
+lower-level field and function definitions.
+"""
+from __future__ import generators
+import re
+from pypy.objspace.flow.model import Variable, Constant, SpaceOperation
+from pypy.objspace.flow.model import FunctionGraph, Block, Link
+from pypy.annotation import model as annmodel
+from pypy.translator.typer import LLTyper, LLFunction
+
+r_ends_in_underscore_digit = re.compile(r'_\d+$')
+
+# ____________________________________________________________
+
+class ClassField:
+    "An attribute of a class, mapped to some field(s) of a low-level struct."
+    
+    def __init__(self, hltype, name, llclass):
+        self.hltype  = hltype
+        self.name    = name
+        self.llclass = llclass
+        varname = '%s_%s' % (llclass.field_prefix, name)
+        # to avoid name collisions between the 2nd lltype of a field called xyz
+        # and another field whose name is exactly xyz_1, forbid field names
+        # ending in '_\d+'
+        if r_ends_in_underscore_digit.search(name):
+            varname += '_'
+        # self.var is a Variable that can stand for this field
+        self.var = Variable(varname)
+        llclass.makevar(self.var, hltype=hltype)
+        # this (high-level) field is implemented as a list of LLVars
+        # that are real fields for the C struct
+        self.llvars = llclass.llreprs[self.var]
+
+# ____________________________________________________________
+
+class LLClass(LLTyper):
+    """Low-level representation of a class as a structure and
+    global functions that operate on it."""
+    
+    def __init__(self, typeset, name, cdef):
+        LLTyper.__init__(self, typeset)
+        self.typeset = typeset
+        self.name = name
+        self.cdef = cdef    # instance of pypy.annotator.factory.ClassDef
+        self.bindings = typeset.bindings
+
+        # collect the fields that the annotator deduced for this class
+        cls = cdef.cls
+        mainletters = [c.lower() for c in cls.__name__ if 'A' <= c <= 'Z']
+        self.field_prefix = ''.join(mainletters[:3] or ['f'])
+        self.fields = [ClassField(typeset.gethltype(s_value), attr, self)
+                       for attr, s_value in cdef.attrs.items()]
+
+        self.pyobj_fields = [  # XXX this should not be necessary
+            fld.name for fld in self.fields if fld.hltype is typeset.R_OBJECT]
+        self.s_instance = annmodel.SomeInstance(self.cdef)
+
+    def get_management_functions(self):
+        "Generate LLFunctions that operate on this class' structure."
+        yield self.make_fn_new()
+
+    def build_llfunc(self, graph):
+        return LLFunction(self.typeset, graph.name, graph)
+
+    def put_op(self, b):
+        def op(opname, *args, **kw):
+            assert kw.keys() == ['s_result']
+            result = Variable()
+            self.bindings[result] = kw['s_result']
+            b.operations.append(SpaceOperation(opname, args, result))
+            return result
+        return op
+
+    def make_fn_new(self):
+        # generate the flow graph of the xxx_new() function
+        b = Block([])
+        op = self.put_op(b)
+        cls = self.cdef.cls
+        v1 = op('alloc_instance', Constant(cls),
+                s_result = self.s_instance)
+        # class attributes are used as defaults to initialize fields
+        for fld in self.fields:
+            if hasattr(cls, fld.name):
+                value = getattr(cls, fld.name)
+                op('setattr', v1, Constant(fld.name), Constant(value),
+                   s_result = annmodel.SomeImpossibleValue())
+        # finally, return v1
+        graph = FunctionGraph('%s_new' % self.name, b)
+        self.bindings[graph.getreturnvar()] = self.bindings[v1]
+        b.closeblock(Link([v1], graph.returnblock))
+        return self.build_llfunc(graph)

Deleted: /pypy/branch/pypy-genc/translator/formatter.py
==============================================================================
--- /pypy/branch/pypy-genc/translator/formatter.py	Mon Sep  6 14:47:06 2004
+++ (empty file)
@@ -1,33 +0,0 @@
-from __future__ import generators
-import sys
-from StringIO import StringIO
-
-class TemplateFormatter:
-    """For use with format strings.
-    
-    'formatstring % formatter' will evaluate all %(xxx)s expressions
-    found in the format string in the given globals/locals.
-
-    Multiline expressions are assumed to be one or several complete
-    statements; they are executed and whatever they print is inserted back
-    into the format string."""
-    
-    def __init__(self, globals, locals=None):
-        if locals is None:
-            locals = globals
-        self.globals = globals
-        self.locals = locals
-    
-    def __getitem__(self, expr):
-        if '\n' in expr:
-            if not expr.endswith('\n'):
-                expr += '\n'
-            prevstdout = sys.stdout
-            try:
-                sys.stdout = f = StringIO()
-                exec expr in self.globals, self.locals
-            finally:
-                sys.stdout = prevstdout
-            return f.getvalue()
-        else:
-            return eval(expr, self.globals, self.locals)

Modified: pypy/branch/pypy-genc/translator/genc.h
==============================================================================
--- pypy/branch/pypy-genc/translator/genc.h	(original)
+++ pypy/branch/pypy-genc/translator/genc.h	Mon Sep  6 14:47:06 2004
@@ -48,6 +48,7 @@
 #define OP_SETITEM_ooov(x,y,z,err)  if ((PyObject_SetItem(x,y,z))<0)   goto err;
 #define OP_GETATTR_ooo(x,y,r,err)   if (!(r=PyObject_GetAttr(x,y)))    goto err;
 #define OP_SETATTR_ooov(x,y,z,err)  if ((PyObject_SetAttr(x,y,z))<0)   goto err;
+#define OP_DELATTR_oov(x,y,err)     if ((PyObject_SetAttr(x,y,NULL))<0)goto err;
 #define OP_NEWSLICE_oooo(x,y,z,r,err)  if (!(r=PySlice_New(x,y,z)))    goto err;
 
 
@@ -82,6 +83,7 @@
 #define returnerr_o()           return NULL;
 #define incref_o(o)             Py_INCREF(o);
 #define decref_o(o)             Py_DECREF(o);
+#define xdecref_o(o)            Py_XDECREF(o);
 
 #define OP_EXCEPTION_ov(x)    /* XXX exceptions not implemented */
 
@@ -95,6 +97,8 @@
 	}
 
 #define INSTANTIATE(cls, r, err)    if (!(r=cls##_new())) goto err;
+#define ALLOC_INSTANCE(cls, r, err)                             \
+		if (!(r=PyType_GenericAlloc(&cls##_Type, 0))) goto err;
 
 
 /* a few built-in functions */

Modified: pypy/branch/pypy-genc/translator/genc.py
==============================================================================
--- pypy/branch/pypy-genc/translator/genc.py	(original)
+++ pypy/branch/pypy-genc/translator/genc.py	Mon Sep  6 14:47:06 2004
@@ -5,12 +5,8 @@
 from __future__ import generators
 import autopath, os
 from pypy.translator.typer import LLFunction, LLOp, LLConst
-from pypy.translator import genc_typeset, formatter
-
-class CClass:
-    def __init__(self, name, cdef):
-        self.name = name
-        self.cdef = cdef    # instance of pypy.annotator.factory.ClassDef
+from pypy.translator.classtyper import LLClass
+from pypy.translator import genc_typeset
 
 # ____________________________________________________________
 
@@ -33,9 +29,9 @@
             bindings = {}
         self.typeset = genc_typeset.CTypeSet(self, bindings)
         self.initializationcode = []
-        self.cclasses = {}
-        self.llfunctions = {}
-        self.build_cclasses()
+        self.llclasses = {};   self.classeslist = []
+        self.llfunctions = {}; self.functionslist = []
+        self.build_llclasses()
         self.build_llfunctions()
         self.gen_source()
 
@@ -50,21 +46,19 @@
 
         # forward declarations
         print >> f, '/* forward declarations */'
-        for func in self.translator.functions:
-            print >> f, '%s;' % self.cfunction_header(func)
+        for llfunc in self.functionslist:
+            print >> f, '%s;' % self.cfunction_header(llfunc)
         print >> f
 
-        # class declarations
-        if self.cclasses:
-            # keep original order, so don't iterate over the dict self.cclasses
-            for cdef in self.translator.annotator.getuserclassdefinitions():
-                self.gen_cclass(self.cclasses[cdef.cls])
+        # declaration of class structures
+        for llclass in self.classeslist:
+            self.gen_cclass(llclass)
 
         # function implementation
         print >> f, self.C_SEP
         print >> f
-        for func in self.translator.functions:
-            self.gen_cfunction(func)
+        for llfunc in self.functionslist:
+            self.gen_cfunction(llfunc)
             print >> f
 
         # entry point
@@ -81,30 +75,36 @@
         print >> f, self.C_INIT_FOOTER % info
 
 
-    def build_cclasses(self):
+    def build_llclasses(self):
         if not self.translator.annotator:
             return
         n = 0
         for cdef in self.translator.annotator.getuserclassdefinitions():
             cls = cdef.cls
-            self.cclasses[cls] = CClass(
+            assert cls not in self.llclasses, '%r duplicate' % (cls,)
+            llclass = LLClass(
+                typeset = self.typeset,
                 name = '%s__%d' % (cls.__name__, n),
                 cdef = cdef,
                 )
+            self.llclasses[cls] = llclass
+            self.classeslist.append(llclass)
+            self.functionslist += llclass.get_management_functions()
             n += 1
 
     def build_llfunctions(self):
         n = 0
         for func in self.translator.functions:
             assert func not in self.llfunctions, '%r duplicate' % (func,)
-            self.llfunctions[func] = LLFunction(
+            llfunc = LLFunction(
                 typeset = self.typeset,
                 name    = '%s__%d' % (func.func_name, n),
                 graph   = self.translator.flowgraphs[func])
+            self.llfunctions[func] = llfunc
+            self.functionslist.append(llfunc)
             n += 1
 
-    def cfunction_header(self, func):
-        llfunc = self.llfunctions[func]
+    def cfunction_header(self, llfunc):
         llargs, rettype = llfunc.ll_header()
         l = ['%s %s' % (a.type, a.name) for a in llargs]
         l = l or ['void']
@@ -134,9 +134,8 @@
         print >> f, '\t\treturn NULL;'
         print >> f, '\treturn %s(%s);' % (llfunc.name, ', '.join(l2))
 
-    def gen_cfunction(self, func):
+    def gen_cfunction(self, llfunc):
         f = self.f
-        llfunc = self.llfunctions[func]
 
         # generate the body of the function
         body = list(llfunc.ll_body())
@@ -160,7 +159,7 @@
             print >> f
 
         # print header
-        print >> f, self.cfunction_header(func)
+        print >> f, self.cfunction_header(llfunc)
         print >> f, '{'
 
         # collect and print all the local variables from the body
@@ -201,49 +200,61 @@
                 print >> f
         print >> f, '}'
 
-    LL_ONLY_OPERATIONS = {
-        'move': lambda x,y: '%s = %s;' % (y,x),
-        'goto': lambda err: 'goto %s;' % err,
-        }
-
-    def gen_cclass(self, cclass):
+    def gen_cclass(self, llclass):
         f = self.f
-        loc = {
-            'name': cclass.name,
-            'cdef': cclass.cdef,
-            'cls': cclass.cdef.cls,
-            'genc': self,
-            'typeset': self.typeset,
+        cls = llclass.cdef.cls
+        info = {
+            'module': cls.__module__,
+            'basename': cls.__name__,
+            'name': llclass.name,
             }
-        print >> f, self.C_CLASS % formatter.TemplateFormatter(loc)
 
-    def copy(self, srcrepr, srcvars, dstrepr, dstvars, errlabel):
-        # write the code to copy a value from src to dst.
-        if srcrepr == dstrepr:
-            for s, d in zip(srcvars, dstvars):
-                yield '%s = %s;' % (d, s)
+        # print the C struct declaration
+        print >> f, self.C_STRUCT_HEADER % info
+        for fld in llclass.fields:
+            for llvar in fld.llvars:
+                print >> f, '\t%s %s;' % (llvar.type, llvar.name)
+        print >> f, self.C_STRUCT_FOOTER % info
+
+        # generate the deallocator function -- must special-case it;
+        # other functions are generated by LLClass.get_management_functions()
+        print >> f, self.C_DEALLOC_HEADER % info
+        for fld in llclass.fields:
             try:
-                sig = (dstrepr,)
-                llname, can_fail = self.typeset.lloperations['incref'][sig]
+                sig = (fld.hltype,)
+                llname, can_fail = self.typeset.lloperations['xdecref'][sig]
             except KeyError:
-                pass   # no incref
+                continue    # ignore fields with no xdecref operation
+            assert not can_fail
+            args = ['op->%s' % llvar.name for llvar in fld.llvars]
+            print >> f, '\t' + llname(*args)
+        print >> f, self.C_DEALLOC_FOOTER % info
+
+        # generate the member list for the type object
+        print >> f, self.C_MEMBERLIST_HEADER % info
+        # XXX write member definitions for member with well-known types only
+        for fld in llclass.fields:
+            if fld.hltype is self.typeset.R_OBJECT:
+                t = 'T_OBJECT_EX'
+            elif fld.hltype is self.typeset.R_INT:
+                t = 'T_INT'
             else:
-                assert not can_fail
-                for codeline in llname(*dstvars).split('\n'):
-                    yield codeline
-        else:
-            sig = (srcrepr, dstrepr)
-            llname, can_fail = self.typeset.lloperations['convert'][sig]
-            args = srcvars + dstvars
-            if can_fail:
-                args.append(errlabel)
-            for codeline in llname(*args).split('\n'):
-                yield codeline
+                continue   # ignored
+            print >> f, '\t{"%s",\t%s,\toffsetof(%s_Object, %s)},' % (
+                fld.name, t, llclass.name, fld.llvars[0].name)
+        print >> f, self.C_MEMBERLIST_FOOTER % info
+
+        # declare and initialize the static PyTypeObject
+        print >> f, self.C_TYPEOBJECT % info
 
 # ____________________________________________________________
 
+    LL_ONLY_OPERATIONS = {
+        'move': lambda x,y: '%s = %s;' % (y,x),
+        'goto': lambda err: 'goto %s;' % err,
+        }
+
     C_HEADER = open(os.path.join(autopath.this_dir, 'genc.h')).read()
-    C_CLASS = open(os.path.join(autopath.this_dir, 'genc_class.h')).read()
 
     C_SEP = "/************************************************************/"
 
@@ -266,4 +277,70 @@
 
     C_INIT_FOOTER = '''}'''
 
+    C_STRUCT_HEADER = C_SEP + '''
+/*** Definition of class %(module)s.%(basename)s ***/
+
+typedef struct {
+	PyObject_HEAD'''
+
+    C_STRUCT_FOOTER = '''} %(name)s_Object;
+'''
+
+    C_DEALLOC_HEADER = '''static void %(name)s_dealloc(%(name)s_Object* op)
+{'''
+
+    C_DEALLOC_FOOTER = '''	op->ob_type->tp_free((PyObject*) op);
+}
+'''
+
+    C_MEMBERLIST_HEADER = '''static PyMemberDef %(name)s_memberlist[] = {'''
+
+    C_MEMBERLIST_FOOTER = '''	{NULL}	/* Sentinel */
+};
+'''
+
+    C_TYPEOBJECT = '''static PyTypeObject %(name)s_Type = {
+	PyObject_HEAD_INIT(&PyType_Type)
+	0,
+	"%(name)s",
+	sizeof(%(name)s_Object),
+	0,
+	(destructor)%(name)s_dealloc,		/* 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 */
+	PyObject_GenericSetAttr,		/* tp_setattro */
+	0,					/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,/* tp_flags */
+ 	0,					/* tp_doc */
+ 	0,	/* XXX need GC */		/* tp_traverse */
+ 	0,					/* tp_clear */
+	0,					/* tp_richcompare */
+	0,					/* tp_weaklistoffset */
+	0,					/* tp_iter */
+	0,					/* tp_iternext */
+	0,					/* tp_methods */
+	%(name)s_memberlist,			/* tp_members */
+	0,					/* tp_getset */
+	0,					/* tp_base */
+	0,					/* tp_dict */
+	0,					/* tp_descr_get */
+	0,					/* tp_descr_set */
+	0,					/* tp_dictoffset */
+	0,  /* XXX call %(name)s_new() */	/* tp_init */
+	PyType_GenericAlloc,			/* tp_alloc */
+	PyType_GenericNew,			/* tp_new */
+	PyObject_Del,				/* tp_free */
+};
+'''
+
 # ____________________________________________________________

Deleted: /pypy/branch/pypy-genc/translator/genc_class.h
==============================================================================
--- /pypy/branch/pypy-genc/translator/genc_class.h	Mon Sep  6 14:47:06 2004
+++ (empty file)
@@ -1,166 +0,0 @@
-/************************************************************/
-/* Definition of class %(cls.__module__)s.%(cls.__name__)s */
-
-typedef struct {
-	PyObject_HEAD
-%(
-# write here the definition of all fields
-# (see formatter.py for the definition of this small templating language)
-import re
-
-mainletters = [c.lower() for c in cls.__name__ if 'A' <= c <= 'Z']
-field_prefix = ''.join(mainletters or ['f'])
-pyobj_fields = []
-fields = []
-
-def llfield(field, hltype):
-    lltypes = typeset.represent(hltype)
-    for i in range(len(lltypes)):
-        if i:
-            suffix = '_%d' % i
-        else:
-            suffix = ''
-        yield field + suffix
-
-for attr, s_value in cdef.attrs.items():
-    hltype = typeset.gethltype(s_value)
-    lltypes = typeset.represent(hltype)
-    # to avoid name collisions between the 2nd lltype of a field called xyz
-    # and another field whose name is exactly xyz_1, forbid field names ending
-    # in '_\d+'.
-    field = '%s_%s' % (field_prefix, attr)
-    if re.search(r'_\d+$', attr):
-        field += '_'
-    fields.append((attr, field, hltype))
-    if hltype is typeset.R_OBJECT:
-        pyobj_fields.append(field)
-    for lltype, llname in zip(lltypes, llfield(field, hltype)):
-        print '\t%s %s;' % (lltype, llname)
-# ----
-)s} %(name)s_Object;
-
-staticforward PyTypeObject %(name)s_Type;
-
-static PyObject* %(name)s_new(void)
-{
-	%(name)s_Object* op = PyObject_GC_New(%(name)s_Object, &%(name)s_Type);
-	if (op == NULL) goto err;
-%(
-# initialize fields from the  PyObject* fields to NULL
-for field in pyobj_fields:
-    print '\top->%s = NULL;' % field
-# initialize fields using the class attributes as a default
-for attr, field, hltype in fields:
-    if hasattr(cls, attr):
-        r = typeset.constant_representation(getattr(cls, attr))
-        for codeline in genc.copy(r, [],
-                  hltype, ['op->%s' % f for f in llfield(field, hltype)],
-                  'err'):
-            print '\t' + codeline
-# ----
-)s	PyObject_GC_Track(op);
-	/* XXX call __init__ */
-	return (PyObject*) op;
-
-    err:
-        Py_XDECREF(op);
-        return NULL;
-}
-
-static void %(name)s_dealloc(%(name)s_Object* op)
-{
-	PyObject_GC_UnTrack(op);
-%(
-# release PyObject* fields   XXX should be more general
-for field in pyobj_fields:
-    print '\tPy_XDECREF(op->%s);' % field
-# ----
-)s	op->ob_type->tp_free((PyObject *)op);
-}
-
-static int %(name)s_traverse(%(name)s_Object* op, visitproc visit, void* arg)
-{
-%(
-# traverse PyObject* fields
-for field in pyobj_fields:
-    print '\tif (op->%s != NULL) {' % field
-    print '\t\tint err = visit(op->%s, arg);' % field
-    print '\t\tif (err) return err;'
-    print '\t}'
-# ----
-)s	return 0;
-}
-
-static int %(name)s_clear(%(name)s_Object* op)
-{
-%(
-# clear PyObject* fields
-for field in pyobj_fields:
-    print '\tif (op->%s != NULL) {' % field
-    print '\t\tPyObject* tmp = op->%s;' % field
-    print '\t\top->%s = NULL;' % field
-    print '\t\tPy_DECREF(tmp);'
-    print '\t}'
-# ----
-)s	return 0;
-}
-
-static PyMemberDef %(name)s_memberlist[] = {
-%(
-# write member definitions for member with well-known types  XXX generalize
-for attr, field, hltype in fields:
-    if hltype is typeset.R_OBJECT:
-        t = 'T_OBJECT_EX'
-    elif hltype is typeset.R_INT:
-        t = 'T_INT'
-    else:
-        continue   # ignored
-    print '\t{"%s",\t%s,\toffsetof(%s_Object, %s)},' % (
-        attr, t, name, field)
-# ----
-)s	{NULL}	/* Sentinel */
-};
-
-statichere PyTypeObject %(name)s_Type = {
-	PyObject_HEAD_INIT(&PyType_Type)
-	0,
-	"%(name)s",
-	sizeof(%(name)s_Object),
-	0,
-	(destructor)%(name)s_dealloc,		/* 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 */
-	PyObject_GenericSetAttr,		/* tp_setattro */
-	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
-		Py_TPFLAGS_BASETYPE,		/* tp_flags */
- 	0,					/* tp_doc */
- 	(traverseproc)%(name)s_traverse,	/* tp_traverse */
- 	(inquiry)%(name)s_clear,		/* tp_clear */
-	0,					/* tp_richcompare */
-	0,					/* tp_weaklistoffset */
-	0,					/* tp_iter */
-	0,					/* tp_iternext */
-	0,					/* tp_methods */
-	%(name)s_memberlist,			/* tp_members */
-	0,					/* tp_getset */
-	0,					/* tp_base */
-	0,					/* tp_dict */
-	0,					/* tp_descr_get */
-	0,					/* tp_descr_set */
-	0,					/* tp_dictoffset */
-	0,					/* tp_init */
-	PyType_GenericAlloc,			/* tp_alloc */
-	PyType_GenericNew,			/* tp_new */
-	PyObject_GC_Del,			/* tp_free */
-};

Modified: pypy/branch/pypy-genc/translator/genc_typeset.py
==============================================================================
--- pypy/branch/pypy-genc/translator/genc_typeset.py	(original)
+++ pypy/branch/pypy-genc/translator/genc_typeset.py	Mon Sep  6 14:47:06 2004
@@ -189,14 +189,21 @@
                         sig = (r,) + sig
                         ops[sig] = ll
             elif (isinstance(value, (type, types.ClassType)) and
-                  value in self.genc.cclasses):
+                  value in self.genc.llclasses):
                 # a user-defined class
                 ops = self.lloperations.setdefault('OP_SIMPLE_CALL', {})
                 # XXX do __init__
                 sig = (r, self.R_OBJECT)
                 def writer(res, err):
                     return 'INSTANTIATE(%s, %s, %s)' % (
-                        self.genc.cclasses[value].name, res, err)
+                        self.genc.llclasses[value].name, res, err)
+                ops[sig] = writer, True
+                # OP_ALLOC_INSTANCE used by the constructor function xxx_new()
+                ops = self.lloperations.setdefault('OP_ALLOC_INSTANCE', {})
+                sig = (r, self.R_OBJECT)
+                def writer(res, err):
+                    return 'ALLOC_INSTANCE(%s, %s, %s)' % (
+                        self.genc.llclasses[value].name, res, err)
                 ops[sig] = writer, True
             else:
                 print "// XXX not implemented: constant", key

Modified: pypy/branch/pypy-genc/translator/typer.py
==============================================================================
--- pypy/branch/pypy-genc/translator/typer.py	(original)
+++ pypy/branch/pypy-genc/translator/typer.py	Mon Sep  6 14:47:06 2004
@@ -70,13 +70,10 @@
 # ____________________________________________________________
 
 
-class LLFunction:
-    "A low-level version of a function from a control flow graph."
+class LLTyper:
+    "Base class for type-oriented low-level generators."
 
-    def __init__(self, typeset, name, graph):
-        remove_direct_loops(graph)
-        self.name = name
-        self.graph = graph
+    def __init__(self, typeset):
         self.gethltype    = typeset.gethltype
         self.represent    = typeset.represent
         self.lloperations = typeset.lloperations
@@ -85,6 +82,34 @@
         self.hltypes = {}
         self.llreprs = {}
 
+    def makevar(self, v, hltype=None):
+        "Record v in self.hltypes and self.llreprs."
+        if v in self.llreprs:
+            return
+        if hltype is None:
+            hltype = self.gethltype(v)
+        llrepr = []
+        lltypes = self.represent(hltype)
+        for i, lltype in zip(range(len(lltypes)), lltypes):
+            if i:
+                suffix = '_%d' % i
+            else:
+                suffix = ''
+            llrepr.append(LLVar(lltype, v.name + suffix))
+        self.hltypes[v] = hltype
+        self.llreprs[v] = llrepr
+
+# ____________________________________________________________
+
+class LLFunction(LLTyper):
+    "A low-level version of a function from a control flow graph."
+
+    def __init__(self, typeset, name, graph):
+        LLTyper.__init__(self, typeset)
+        remove_direct_loops(graph)
+        self.name = name
+        self.graph = graph
+
     def ll_header(self):
         """
         Get the low-level representation of the header.
@@ -182,23 +207,6 @@
 
     # __________ Type checking and conversion routines __________
 
-    def makevar(self, v, hltype=None):
-        "Record v in self.hltypes and self.llreprs."
-        if v in self.llreprs:
-            return
-        if hltype is None:
-            hltype = self.gethltype(v)
-        llrepr = []
-        lltypes = self.represent(hltype)
-        for i, lltype in zip(range(len(lltypes)), lltypes):
-            if i:
-                suffix = '_%d' % i
-            else:
-                suffix = ''
-            llrepr.append(LLVar(lltype, v.name + suffix))
-        self.hltypes[v] = hltype
-        self.llreprs[v] = llrepr
-
     def mark_release(self, v):
         sig = (self.hltypes[v],)
         try:



More information about the Pypy-commit mailing list