[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