[pypy-svn] r10641 - pypy/dist/pypy/translator/genc

arigo at codespeak.net arigo at codespeak.net
Thu Apr 14 21:01:58 CEST 2005


Author: arigo
Date: Thu Apr 14 21:01:57 2005
New Revision: 10641

Added:
   pypy/dist/pypy/translator/genc/classtype.py   (contents, props changed)
   pypy/dist/pypy/translator/genc/heapobject_include.h   (contents, props changed)
   pypy/dist/pypy/translator/genc/heapobject_template.h   (contents, props changed)
   pypy/dist/pypy/translator/genc/heapobjecttype.py   (contents, props changed)
   pypy/dist/pypy/translator/genc/instancetype.py   (contents, props changed)
Modified:
   pypy/dist/pypy/translator/genc/basetype.py
   pypy/dist/pypy/translator/genc/ctyper.py
   pypy/dist/pypy/translator/genc/funcdef.py
   pypy/dist/pypy/translator/genc/g_include.h
Log:
Some preliminary support for user-defined instances.  Disabled for now.



Modified: pypy/dist/pypy/translator/genc/basetype.py
==============================================================================
--- pypy/dist/pypy/translator/genc/basetype.py	(original)
+++ pypy/dist/pypy/translator/genc/basetype.py	Thu Apr 14 21:01:57 2005
@@ -8,7 +8,7 @@
         self.translator = translator
 
     def debugname(self):
-        return self.__class__.__name__
+        return self.typename
 
     def genc():
         """A hack to get at the currently running GenC instance."""

Added: pypy/dist/pypy/translator/genc/classtype.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/genc/classtype.py	Thu Apr 14 21:01:57 2005
@@ -0,0 +1,38 @@
+from __future__ import generators
+from pypy.translator.genc.basetype import CType
+from pypy.objspace.flow.model import SpaceOperation, Constant, Variable
+
+
+class CClassPtrType(CType):
+    error_return  = 'NULL'
+
+    # For now, this is the singleton type "pointer to the class C"
+    # It's supposed to become "pointer to class C or any subclass of C"
+
+    def __init__(self, translator, classdef, instancetype):
+        super(CClassPtrType, self).__init__(translator)
+        self.classdef = classdef
+        self.instancetype = instancetype
+        self.typename = 'Kls' + instancetype.typename
+
+    def nameof(self, cls, debug=None):
+        assert cls is self.classdef.cls    # for now
+        return '((%s)1)' % self.typename   # no class data at all
+
+    def init_globals(self, genc):
+        yield 'typedef void *%s;' % self.typename
+        yield '#define OP_INCREF_%s(x)  /* nothing */' % self.typename
+        yield '#define OP_DECREF_%s(x)  /* nothing */' % self.typename
+
+    # ____________________________________________________________
+
+    def spec_simple_call(self, typer, op):
+        cinst = self.instancetype
+        yield typer.typed_op(SpaceOperation('new_%s' % (cinst.typename,),
+                                            [], op.result),   # args, ret
+                                            [], cinst     )   # args_t, ret_t
+
+        cls = self.classdef.cls
+        init = getattr(cls, '__init__', None)
+        if init is not None and init != object.__init__:
+            raise Exception, "XXX not implemented"

Modified: pypy/dist/pypy/translator/genc/ctyper.py
==============================================================================
--- pypy/dist/pypy/translator/genc/ctyper.py	(original)
+++ pypy/dist/pypy/translator/genc/ctyper.py	Thu Apr 14 21:01:57 2005
@@ -12,6 +12,8 @@
 from pypy.translator.genc.functype import CFuncPtrType
 from pypy.translator.genc.tupletype import CTupleType
 from pypy.translator.genc.listtype import CListType
+from pypy.translator.genc.classtype import CClassPtrType
+from pypy.translator.genc.instancetype import CInstanceType
 import types
 from pypy.interpreter.pycode import CO_VARARGS
 
@@ -60,6 +62,13 @@
                     besttype = self.annotator.translator.getconcretetype(
                         CFuncPtrType, tuple(args_ct), res_ct)
 
+## -- DISABLED while it's under development
+##                elif (s_value.is_constant() and
+##                      isinstance(s_value.const, (type, types.ClassType))):
+##                    classdef = self.annotator.getuserclasses()[s_value.const]
+##                    besttype = self.annotator.translator.getconcretetype(
+##                        CClassPtrType, classdef, self.getinstancetype(classdef))
+
             elif isinstance(s_value, SomeTuple):
                 items_ct = [self.annotation2concretetype(s_item)
                             for s_item in s_value.items]
@@ -105,3 +114,15 @@
         vnone = Variable()
         vnone.concretetype = self.TNone
         return SpaceOperation('decref', [v], vnone)
+
+    # ____________________________________________________________
+
+    def getinstancetype(self, classdef):
+        attritems = classdef.attrs.items()
+        attritems.sort()
+        fieldnames = [name for name, attrdef in attritems]
+        fieldtypes = [self.annotation2concretetype(attrdef.getvalue())
+                      for name, attrdef in attritems]
+        return self.annotator.translator.getconcretetype(
+            CInstanceType, tuple(fieldnames), tuple(fieldtypes),
+            classdef.cls.__name__)

Modified: pypy/dist/pypy/translator/genc/funcdef.py
==============================================================================
--- pypy/dist/pypy/translator/genc/funcdef.py	(original)
+++ pypy/dist/pypy/translator/genc/funcdef.py	Thu Apr 14 21:01:57 2005
@@ -569,6 +569,20 @@
         return '%s = %s(%s); if (PyErr_Occurred()) FAIL(%s)' % (
             r, args[0], ', '.join(args[1:]), err)
 
+    def OP_INST_GETATTR(self, op, err):
+        return '%s = INST_ATTR_%s__%s(%s);' % (
+            self.expr(op.result),
+            op.args[0].concretetype.typename,
+            op.args[1].value,
+            self.expr(op.args[0]))
+
+    def OP_INST_SETATTR(self, op, err):
+        return 'INST_ATTR_%s__%s(%s) = %s;' % (
+            op.args[0].concretetype.typename,
+            op.args[1].value,
+            self.expr(op.args[0]),
+            self.expr(op.args[2]))
+
     def OP_CONV_TO_OBJ(self, op, err):
         v = op.args[0]
         return '%s = CONV_TO_OBJ_%s(%s); if (PyErr_Occurred()) FAIL(%s)' % (

Modified: pypy/dist/pypy/translator/genc/g_include.h
==============================================================================
--- pypy/dist/pypy/translator/genc/g_include.h	(original)
+++ pypy/dist/pypy/translator/genc/g_include.h	Thu Apr 14 21:01:57 2005
@@ -14,6 +14,7 @@
 #include "g_support.h"
 #include "g_module.h"
 
+#include "heapobject_include.h"
 #include "int_include.h"
 #include "list_include.h"
 #include "none_include.h"

Added: pypy/dist/pypy/translator/genc/heapobject_include.h
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/genc/heapobject_include.h	Thu Apr 14 21:01:57 2005
@@ -0,0 +1,32 @@
+
+/************************************************************/
+ /***  C header subsection: the base (empty) heap object   ***/
+
+
+typedef struct s_baseobject {
+	int refcount;
+} *baseobject;
+
+#define OP_NEW_BASEOBJECT(r,err)  if (!(r=allocate_baseobject())) FAIL(err)
+#define INIT_HEAPOBJ_baseobject(obj)  (obj).refcount = 1;
+#define FINI_HEAPOBJ_baseobject(obj)  ;
+#define REFCNT_baseobject(obj)        (obj).refcount
+
+#define OP_INCREF_baseobject(x)   x->refcount++;
+#define OP_DECREF_baseobject(x)   if (!--x->refcount) dealloc_baseobject(x);
+
+static baseobject allocate_baseobject(void)
+{
+	baseobject result = (baseobject)
+		PyObject_Malloc(sizeof(struct s_baseobject));
+	if (result == NULL)
+		PyErr_NoMemory();
+	INIT_HEAPOBJ_baseobject(*result)
+	return result;
+}
+
+static void dealloc_baseobject(baseobject obj)
+{
+	FINI_HEAPOBJ_baseobject(*obj)
+	PyObject_Free(obj);
+}

Added: pypy/dist/pypy/translator/genc/heapobject_template.h
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/genc/heapobject_template.h	Thu Apr 14 21:01:57 2005
@@ -0,0 +1,38 @@
+
+/************************************************************/
+ /***  C header template: heap object %(typename)s         ***/
+
+/* NB. %(typename)s is the type "pointer to struct s_%(typename)s" */
+
+typedef struct s_%(typename)s {
+	%(basestructname)s base;
+	%(extensiontypename)s ext;
+} *%(typename)s;
+
+#define OP_NEW_%(TYPENAME)s(r,err)  if (!(r=allocate_%(typename)s())) FAIL(err)
+#define INIT_HEAPOBJ_%(typename)s(obj) \
+		INIT_HEAPOBJ_%(basetypename)s((obj).base)
+#define FINI_HEAPOBJ_%(typename)s(obj) \
+		FINI_HEAPOBJ_%(basetypename)s((obj).base)
+#define REFCNT_%(typename)s(obj) \
+		REFCNT_%(basetypename)s((obj).base)
+
+#define OP_INCREF_%(typename)s(x)   REFCNT_%(typename)s(*x)++;
+#define OP_DECREF_%(typename)s(x)   if (!--REFCNT_%(typename)s(*x)) \
+						dealloc_%(typename)s(x);
+
+static %(typename)s allocate_%(typename)s(void)
+{
+	%(typename)s result = (%(typename)s)
+		PyObject_Malloc(sizeof(struct s_%(typename)s));
+	if (result == NULL)
+		PyErr_NoMemory();
+	INIT_HEAPOBJ_%(typename)s(*result)
+	return result;
+}
+
+static void dealloc_%(typename)s(%(typename)s obj)
+{
+	FINI_HEAPOBJ_%(typename)s(*obj)
+	PyObject_Free(obj);
+}

Added: pypy/dist/pypy/translator/genc/heapobjecttype.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/genc/heapobjecttype.py	Thu Apr 14 21:01:57 2005
@@ -0,0 +1,47 @@
+from __future__ import generators
+from pypy.translator.genc.basetype import CType
+
+
+class CHeapObjectType(CType):
+    """The type 'pointer to an object in the heap'.  The object's layout must
+    be an extension of another existing object layout (there is an empty
+    base object, which in this version contains just a ref counter).
+    The extension is by adding a single field to the parent.  This field can
+    be a tuple (i.e. a struct), so you can add a bunch of data at once in this
+    way.
+    """
+    error_return  = 'NULL'
+
+    Counter = {}
+
+    def __init__(self, translator, basetype, extensiontype, namehint):
+        super(CHeapObjectType, self).__init__(translator)
+        self.basetype = basetype
+        if basetype is None:
+            self.basetypename = 'baseobject'     # from object_include.h
+            self.basestructname = 'struct s_baseobject'
+        else:
+            assert isinstance(basetype, CHeapObjectType)
+            self.basetypename = self.basetype.typename
+            self.basestructname = self.basetype.structname
+        self.extensiontype = extensiontype
+
+        while namehint.find('__') >= 0:
+            namehint = namehint.replace('__', '_')
+        key = namehint.upper()
+        self.typename = 'P%d_%s' % (
+            CHeapObjectType.Counter.setdefault(key, 0), namehint)
+        self.structname = 'struct s_' + self.typename
+        CHeapObjectType.Counter[key] += 1
+
+    def nameof(self, cls, debug=None):
+        XXX(Later)
+
+    def init_globals(self, genc):
+        yield genc.loadincludefile('heapobject_template.h') % {
+            'typename'          : self.typename,
+            'TYPENAME'          : self.typename.upper(),
+            'basetypename'      : self.basetypename,
+            'basestructname'    : self.basestructname,
+            'extensiontypename' : self.extensiontype.typename,
+            }

Added: pypy/dist/pypy/translator/genc/instancetype.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/genc/instancetype.py	Thu Apr 14 21:01:57 2005
@@ -0,0 +1,57 @@
+from __future__ import generators
+from pypy.objspace.flow.model import Constant, SpaceOperation
+from pypy.translator.genc.heapobjecttype import CHeapObjectType
+from pypy.translator.genc.tupletype import CTupleType
+
+
+class CInstanceType(CHeapObjectType):
+    """The type 'pointer to a class instance in the heap."""
+
+    def __init__(self, translator, fieldnames, fieldtypes, classname):
+        self.fieldnames = fieldnames
+        self.fieldtypes = fieldtypes
+        contenttype = translator.getconcretetype(CTupleType, fieldtypes)
+        super(CInstanceType, self).__init__(translator, None, contenttype,
+                                            classname)
+        self.fields = {}  # XXX parent
+        for name, ct in zip(fieldnames, fieldtypes):
+            self.fields[name] = ct
+
+    def init_globals(self, genc):
+        for line in super(CInstanceType, self).init_globals(genc):
+            yield line
+        for i, name in zip(range(len(self.fieldnames)), self.fieldnames):
+            yield '#define INST_ATTR_%s__%s(x)    (x)->ext.f%d' % (
+                self.typename, name, i)
+
+    # ____________________________________________________________
+
+    def spec_getattr(self, typer, op):
+        if not isinstance(op.args[1], Constant):
+            raise NotImplementedError
+        attrname = op.args[1].value
+        try:
+            ct = self.fields[attrname]
+        except KeyError:
+            print "* warning, no field %s in %s" % (attrname, self.typename)
+            raise NotImplementedError
+        TPyObject = typer.TPyObject
+        yield typer.typed_op(op, [self, TPyObject], ct,   # args_t, ret_t
+                             newopname='inst_getattr')
+        yield typer.incref_op(op.result)
+
+    def spec_setattr(self, typer, op):
+        if not isinstance(op.args[1], Constant):
+            raise NotImplementedError
+        attrname = op.args[1].value
+        try:
+            ct = self.fields[attrname]
+        except KeyError:
+            print "* warning, no field %s in %s" % (attrname, self.typename)
+            raise NotImplementedError
+        TNone = typer.TNone
+        TPyObject = typer.TPyObject
+        # XXX decref existing value first
+        yield typer.typed_op(op, [self, TPyObject, ct], TNone,  # args_t, ret_t
+                             newopname='inst_setattr')
+        yield typer.incref_op(op.args[2])



More information about the Pypy-commit mailing list