[pypy-svn] r28515 - in pypy/dist/pypy: rpython rpython/lltypesystem rpython/lltypesystem/test rpython/memory rpython/ootypesystem rpython/test translator/c

arigo at codespeak.net arigo at codespeak.net
Thu Jun 8 15:24:51 CEST 2006


Author: arigo
Date: Thu Jun  8 15:24:47 2006
New Revision: 28515

Added:
   pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py   (contents, props changed)
   pypy/dist/pypy/rpython/rcpy.py   (contents, props changed)
Modified:
   pypy/dist/pypy/rpython/lltypesystem/lltype.py
   pypy/dist/pypy/rpython/lltypesystem/rclass.py
   pypy/dist/pypy/rpython/memory/gctransform.py
   pypy/dist/pypy/rpython/memory/lltypelayout.py
   pypy/dist/pypy/rpython/normalizecalls.py
   pypy/dist/pypy/rpython/ootypesystem/rclass.py
   pypy/dist/pypy/rpython/rbuiltin.py
   pypy/dist/pypy/rpython/rclass.py
   pypy/dist/pypy/rpython/rmodel.py
   pypy/dist/pypy/rpython/test/test_llinterp.py
   pypy/dist/pypy/rpython/test/test_nongc.py
   pypy/dist/pypy/rpython/test/test_rtyper.py
   pypy/dist/pypy/translator/c/funcgen.py
Log:
(arre, arigo)

Added support for the 'cpy' gc flavor in rclass.py.
This is used via the rcpy module for now; see test_rcpyclass.py.
Includes a whole bunch of renaming of True/False flags into
gckind-style flags.

Note that now the check 'TYPE == Ptr(PyObject)' should mostly not
be used any more!  You need instead to check for TYPE._gckind == 'cpy'.



Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py	Thu Jun  8 15:24:47 2006
@@ -299,6 +299,10 @@
             raise TypeError("a PyStruct must have another PyStruct or "
                             "PyObject as first field")
 
+STRUCT_BY_FLAVOR = {'raw': Struct,
+                    'gc':  GcStruct,
+                    'cpy': PyStruct}
+
 class Array(ContainerType):
     _gckind = 'raw'
     __name__ = 'array'
@@ -480,6 +484,13 @@
 class GcForwardReference(ForwardReference):
     _gckind = 'gc'
 
+class PyForwardReference(ForwardReference):
+    _gckind = 'cpy'
+
+FORWARDREF_BY_FLAVOR = {'raw': ForwardReference,
+                        'gc':  GcForwardReference,
+                        'cpy': PyForwardReference}
+
 
 class Primitive(LowLevelType):
     def __init__(self, name, default):

Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/rclass.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/rclass.py	Thu Jun  8 15:24:47 2006
@@ -10,12 +10,12 @@
                                 getclassrepr, getinstancerepr,\
                                 get_type_repr, rtype_new_instance
 from pypy.rpython.lltypesystem.lltype import \
-     ForwardReference, GcForwardReference, \
      Ptr, Struct, GcStruct, malloc, \
      cast_pointer, castable, nullptr, \
      RuntimeTypeInfo, getRuntimeTypeInfo, typeOf, \
      Array, Char, Void, attachRuntimeTypeInfo, \
      FuncType, Bool, Signed, functionptr, FuncType, PyObject
+from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.robject import PyObjRepr, pyobj_repr
 from pypy.rpython.extregistry import ExtRegistryEntry
 from pypy.annotation import model as annmodel
@@ -55,7 +55,7 @@
 #
 # there's also a nongcobject 
 
-OBJECT_VTABLE = ForwardReference()
+OBJECT_VTABLE = lltype.ForwardReference()
 CLASSTYPE = Ptr(OBJECT_VTABLE)
 OBJECT = GcStruct('object', ('typeptr', CLASSTYPE))
 OBJECTPTR = Ptr(OBJECT)
@@ -71,6 +71,16 @@
 NONGCOBJECT = Struct('nongcobject', ('typeptr', CLASSTYPE))
 NONGCOBJECTPTR = Ptr(OBJECT)
 
+# cpy case (XXX try to merge the typeptr with the ob_type)
+CPYOBJECT = lltype.PyStruct('cpyobject', ('head', PyObject),
+                                         ('typeptr', CLASSTYPE))
+CPYOBJECTPTR = Ptr(CPYOBJECT)
+
+OBJECT_BY_FLAVOR = {'gc': OBJECT,
+                    'raw': NONGCOBJECT,
+                    'cpy': CPYOBJECT}
+
+
 def cast_vtable_to_typeptr(vtable):
     while typeOf(vtable).TO != OBJECT_VTABLE:
         vtable = vtable.super
@@ -84,7 +94,7 @@
             # 'object' root type
             self.vtable_type = OBJECT_VTABLE
         else:
-            self.vtable_type = ForwardReference()
+            self.vtable_type = lltype.ForwardReference()
         self.lowleveltype = Ptr(self.vtable_type)
 
     def _setup_repr(self):
@@ -173,7 +183,7 @@
                 vtable.subclassrange_max = sys.maxint
             rinstance = getinstancerepr(self.rtyper, rsubcls.classdef)
             rinstance.setup()
-            if rinstance.needsgc: # only gc-case
+            if rinstance.gcflavor == 'gc': # only gc-case
                 vtable.rtti = getRuntimeTypeInfo(rinstance.object_type)
             if rsubcls.classdef is None:
                 name = 'object'
@@ -285,22 +295,17 @@
 
 
 class InstanceRepr(AbstractInstanceRepr):
-    def __init__(self, rtyper, classdef, does_need_gc=True):
+    def __init__(self, rtyper, classdef, gcflavor='gc'):
         AbstractInstanceRepr.__init__(self, rtyper, classdef)
         if classdef is None:
-            if does_need_gc:
-                self.object_type = OBJECT
-            else:
-                self.object_type = NONGCOBJECT
+            self.object_type = OBJECT_BY_FLAVOR[gcflavor]
         else:
-            if does_need_gc:
-                self.object_type = GcForwardReference()
-            else:
-                self.object_type = ForwardReference()
+            ForwardRef = lltype.FORWARDREF_BY_FLAVOR[gcflavor]
+            self.object_type = ForwardRef()
             
         self.prebuiltinstances = {}   # { id(x): (x, _ptr) }
         self.lowleveltype = Ptr(self.object_type)
-        self.needsgc = does_need_gc
+        self.gcflavor = gcflavor
 
     def _setup_repr(self):
         # NOTE: don't store mutable objects like the dicts below on 'self'
@@ -330,7 +335,8 @@
                 fields['_hash_cache_'] = 'hash_cache', rint.signed_repr
                 llfields.append(('hash_cache', Signed))
 
-            self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef, not self.needsgc)
+            self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef,
+                                         self.gcflavor)
             self.rbase.setup()
             #
             # PyObject wrapper support
@@ -338,11 +344,7 @@
                 fields['_wrapper_'] = 'wrapper', pyobj_repr
                 llfields.append(('wrapper', Ptr(PyObject)))
 
-            if self.needsgc:
-                MkStruct = GcStruct
-            else:
-                MkStruct = Struct
-            
+            MkStruct = lltype.STRUCT_BY_FLAVOR[self.gcflavor]
             object_type = MkStruct(self.classdef.name,
                                    ('super', self.rbase.object_type),
                                    *llfields)
@@ -351,11 +353,11 @@
         allinstancefields.update(fields)
         self.fields = fields
         self.allinstancefields = allinstancefields
-        if self.needsgc: # only gc-case
+        if self.gcflavor == 'gc': # only gc-case
             attachRuntimeTypeInfo(self.object_type)
 
     def _setup_repr_final(self):
-        if self.needsgc: # only gc-case
+        if self.gcflavor == 'gc': # only gc-case
             if (self.classdef is not None and
                 self.classdef.classdesc.lookup('__del__') is not None):
                 s_func = self.classdef.classdesc.s_read_attribute('__del__')
@@ -375,10 +377,7 @@
                                                   ll_runtime_type_info,
                                                   OBJECT, destrptr)
     def common_repr(self): # -> object or nongcobject reprs
-        return getinstancerepr(self.rtyper, None, nogc=not self.needsgc)
-
-    def getflavor(self):
-        return self.classdef.classdesc.read_attribute('_alloc_flavor_', Constant('gc')).value
+        return getinstancerepr(self.rtyper, None, self.gcflavor)
 
     def null_instance(self):
         return nullptr(self.object_type)
@@ -387,7 +386,7 @@
         return cast_pointer(self.lowleveltype, result)
 
     def create_instance(self):
-        return malloc(self.object_type, flavor=self.getflavor()) # pick flavor
+        return malloc(self.object_type, flavor=self.gcflavor)
 
     def has_wrapper(self):
         return self.classdef is not None and (
@@ -481,12 +480,16 @@
         ctype = inputconst(Void, self.object_type)
         vlist = [ctype]
         if self.classdef is not None:
-            flavor = self.getflavor()
-            if flavor != 'gc': # not defalut flavor
+            flavor = self.gcflavor
+            if flavor != 'gc': # not default flavor
                 mallocop = 'flavored_malloc'
-                vlist = [inputconst(Void, flavor)] + vlist
+                vlist.insert(0, inputconst(Void, flavor))
+                if flavor == 'cpy':
+                    cpytype = self.classdef._cpy_exported_type_
+                    c = inputconst(Ptr(PyObject), lltype.pyobjectptr(cpytype))
+                    vlist.append(c)
         vptr = llops.genop(mallocop, vlist,
-                           resulttype = Ptr(self.object_type)) # xxx flavor
+                           resulttype = Ptr(self.object_type))
         ctypeptr = inputconst(CLASSTYPE, self.rclass.getvtable())
         self.setfield(vptr, '__class__', ctypeptr, llops)
         # initialize instance attributes from their defaults from the class
@@ -575,7 +578,7 @@
             return hop.gendirectcall(ll_isinstance, v_obj, v_cls)
 
 
-def buildinstancerepr(rtyper, classdef, does_need_gc=True):
+def buildinstancerepr(rtyper, classdef, gcflavor='gc'):
     if classdef is None:
         unboxed = []
     else:
@@ -583,14 +586,14 @@
                           if subdef.classdesc.pyobj is not None and
                              issubclass(subdef.classdesc.pyobj, UnboxedValue)]
     if len(unboxed) == 0:
-        return InstanceRepr(rtyper, classdef, does_need_gc)
+        return InstanceRepr(rtyper, classdef, gcflavor)
     else:
         # the UnboxedValue class and its parent classes need a
         # special repr for their instances
         if len(unboxed) != 1:
             raise TyperError("%r has several UnboxedValue subclasses" % (
                 classdef,))
-        assert does_need_gc
+        assert gcflavor == 'gc'
         from pypy.rpython.lltypesystem import rtagged
         return rtagged.TaggedInstanceRepr(rtyper, classdef, unboxed[0])
 
@@ -618,16 +621,15 @@
             return NotImplemented
 
     def rtype_is_((r_ins1, r_ins2), hop):
-        if r_ins1.needsgc != r_ins2.needsgc:
+        if r_ins1.gcflavor != r_ins2.gcflavor:
             # obscure logic, the is can be true only if both are None
             v_ins1, v_ins2 = hop.inputargs(r_ins1.common_repr(), r_ins2.common_repr())
             return hop.gendirectcall(ll_both_none, v_ins1, v_ins2)
-        nogc = not (r_ins1.needsgc and r_ins2.needsgc)
         if r_ins1.classdef is None or r_ins2.classdef is None:
             basedef = None
         else:
             basedef = r_ins1.classdef.commonbase(r_ins2.classdef)
-        r_ins = getinstancerepr(r_ins1.rtyper, basedef, nogc=nogc)
+        r_ins = getinstancerepr(r_ins1.rtyper, basedef, r_ins1.gcflavor)
         return pairtype(Repr, Repr).rtype_is_(pair(r_ins, r_ins), hop)
 
     rtype_eq = rtype_is_

Added: pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_rcpyclass.py	Thu Jun  8 15:24:47 2006
@@ -0,0 +1,24 @@
+from pypy.translator.c.test.test_genc import compile
+from pypy.rpython.rcpy import cpy_export
+
+
+class W_MyTest(object):
+
+    def __init__(self, x):
+        self.x = x
+
+    def double(self):
+        return self.x * 2
+
+
+def test_cpy_export():
+    class mytest(object):
+        pass
+
+    def f():
+        w = W_MyTest(21)
+        return cpy_export(w, mytest)
+
+    fn = compile(f, [])
+    res = fn()
+    assert type(res).__name__.endswith('mytest')

Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py	Thu Jun  8 15:24:47 2006
@@ -23,13 +23,15 @@
 def var_ispyobj(var):
     if hasattr(var, 'concretetype'):
         if isinstance(var.concretetype, lltype.Ptr):
-            return var.concretetype.TO is lltype.PyObject
+            return var.concretetype.TO._gckind == 'cpy'
         else:
             return False
     else:
         # assume PyObjPtr
         return True
-    
+
+PyObjPtr = lltype.Ptr(lltype.PyObject)
+
 
 class GCTransformer(object):
     finished_helpers = False
@@ -154,8 +156,9 @@
             op = ops[index]
             if var_needsgc(op.result):
                 if var_ispyobj(op.result):
-                    assert op.opname != 'cast_pointer', 'casting to a PyObject*??'
-                    if op.opname in ('getfield', 'getarrayitem', 'same_as'):
+                    if op.opname in ('getfield', 'getarrayitem', 'same_as',
+                                     'cast_pointer', 'getsubstruct'):
+                        # XXX more operations?
                         lst = list(self.push_alive(op.result))
                         newops.extend(lst)
                 elif op.opname not in ('direct_call', 'indirect_call'):
@@ -211,7 +214,13 @@
 
     def push_alive_pyobj(self, var):
         result = varoftype(lltype.Void)
-        return [SpaceOperation("gc_push_alive_pyobj", [var], result)]
+        lst = []
+        if hasattr(var, 'concretetype') and var.concretetype != PyObjPtr:
+            res = varoftype(PyObjPtr)
+            lst.append(SpaceOperation("cast_pointer", [var], res))
+            var = res
+        lst.append(SpaceOperation("gc_push_alive_pyobj", [var], result))
+        return lst
 
     def pop_alive(self, var):
         if var_ispyobj(var):
@@ -225,7 +234,13 @@
 
     def pop_alive_pyobj(self, var):
         result = varoftype(lltype.Void)
-        return [SpaceOperation("gc_pop_alive_pyobj", [var], result)]
+        lst = []
+        if hasattr(var, 'concretetype') and var.concretetype != PyObjPtr:
+            res = varoftype(PyObjPtr)
+            lst.append(SpaceOperation("cast_pointer", [var], res))
+            var = res
+        lst.append(SpaceOperation("gc_pop_alive_pyobj", [var], result))
+        return lst
 
     def replace_gc_protect(self, op, livevars, block):
         """ protect this object from gc (make it immortal). the specific
@@ -653,7 +668,7 @@
             if type_contains_pyobjs(TYPE._flds[name]):
                 return True
         return False
-    elif isinstance(TYPE, lltype.Ptr) and TYPE.TO == lltype.PyObject:
+    elif isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'cpy':
         return True
     else:
         return False
@@ -722,7 +737,7 @@
     t = lltype.typeOf(v)
     if isinstance(t, lltype.Struct):
         for n, t2 in t._flds.iteritems():
-            if isinstance(t2, lltype.Ptr) and t2._needsgc() and t2.TO != lltype.PyObject:
+            if isinstance(t2, lltype.Ptr) and t2.TO._gckind == 'gc':
                 yield adr + llmemory.offsetof(t, n)
             elif isinstance(t2, (lltype.Array, lltype.Struct)):
                 for a in gc_pointers_inside(getattr(v, n), adr + llmemory.offsetof(t, n)):
@@ -1068,7 +1083,7 @@
                 adr = llmemory.cast_ptr_to_adr(hdr)
                 self.gcdata.gc.init_gc_object(adr, typeid)
 
-        if TYPE != lltype.PyObject and find_gc_ptrs_in_type(TYPE):
+        if find_gc_ptrs_in_type(TYPE):
             adr = llmemory.cast_ptr_to_adr(value._as_ptr())
             if isinstance(TYPE, (lltype.GcStruct, lltype.GcArray)):
                 self.static_gc_roots.append(adr)
@@ -1292,8 +1307,7 @@
         #adr = llmemory.cast_ptr_to_adr(ex)
         #for off in offsets:
         #    (adr + off)
-    elif (isinstance(TYPE, lltype.Ptr) and TYPE._needsgc() and
-          TYPE.TO is not lltype.PyObject):
+    elif isinstance(TYPE, lltype.Ptr) and TYPE.TO._gckind == 'gc':
         offsets.append(0)
     return offsets
 

Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/lltypelayout.py	(original)
+++ pypy/dist/pypy/rpython/memory/lltypelayout.py	Thu Jun  8 15:24:47 2006
@@ -115,8 +115,7 @@
         offsets = []
         for name in TYPE._names:
             FIELD = getattr(TYPE, name)
-            if (isinstance(FIELD, lltype.Ptr) and FIELD._needsgc() and
-                FIELD.TO is not lltype.PyObject):
+            if isinstance(FIELD, lltype.Ptr) and FIELD.TO._gckind == 'gc':
                 offsets.append(llmemory.offsetof(TYPE, name))
             elif isinstance(FIELD, lltype.Struct):
                 suboffsets = offsets_to_gc_pointers(FIELD)

Modified: pypy/dist/pypy/rpython/normalizecalls.py
==============================================================================
--- pypy/dist/pypy/rpython/normalizecalls.py	(original)
+++ pypy/dist/pypy/rpython/normalizecalls.py	Thu Jun  8 15:24:47 2006
@@ -8,7 +8,7 @@
 from pypy.tool.sourcetools import has_varargs, valid_identifier
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.rpython.error import TyperError
-from pypy.rpython.rmodel import needsgc
+from pypy.rpython.rmodel import getgcflavor
 from pypy.rpython.objectmodel import instantiate, ComputedIntSymbolic
 
 def normalize_call_familes(annotator):
@@ -246,7 +246,7 @@
     needs_generic_instantiate = annotator.bookkeeper.needs_generic_instantiate
     
     for classdef in needs_generic_instantiate:
-        assert needsgc(classdef) # only gc-case
+        assert getgcflavor(classdef) == 'gc'   # only gc-case
         create_instantiate_function(annotator, classdef)
 
 def create_instantiate_function(annotator, classdef):

Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/rclass.py	(original)
+++ pypy/dist/pypy/rpython/ootypesystem/rclass.py	Thu Jun  8 15:24:47 2006
@@ -148,7 +148,7 @@
     return mangled[1:]
 
 class InstanceRepr(AbstractInstanceRepr):
-    def __init__(self, rtyper, classdef, does_need_gc=True):
+    def __init__(self, rtyper, classdef, gcflavor='ignored'):
         AbstractInstanceRepr.__init__(self, rtyper, classdef)
 
         self.baserepr = None
@@ -237,7 +237,7 @@
 
         ootype.addFields(self.lowleveltype, fields)
 
-        self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef, True)
+        self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef)
         self.rbase.setup()
 
         methods = {}

Modified: pypy/dist/pypy/rpython/rbuiltin.py
==============================================================================
--- pypy/dist/pypy/rpython/rbuiltin.py	(original)
+++ pypy/dist/pypy/rpython/rbuiltin.py	Thu Jun  8 15:24:47 2006
@@ -539,7 +539,7 @@
 
 def rtype_free_non_gc_object(hop):
     vinst, = hop.inputargs(hop.args_r[0])
-    flavor = hop.args_r[0].getflavor()
+    flavor = hop.args_r[0].gcflavor
     assert not flavor.startswith('gc')
     cflavor = hop.inputconst(lltype.Void, flavor)
     return hop.genop('flavored_free', [cflavor, vinst])

Modified: pypy/dist/pypy/rpython/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/rclass.py	(original)
+++ pypy/dist/pypy/rpython/rclass.py	Thu Jun  8 15:24:47 2006
@@ -3,7 +3,7 @@
 #from pypy.annotation.classdef import isclassdef
 from pypy.annotation import description
 from pypy.rpython.error import TyperError
-from pypy.rpython.rmodel import Repr, needsgc
+from pypy.rpython.rmodel import Repr, getgcflavor
 
 def getclassrepr(rtyper, classdef):
     try:
@@ -24,19 +24,18 @@
         rtyper.add_pendingsetup(result)
     return result
 
-def getinstancerepr(rtyper, classdef, nogc=False):
-    does_need_gc = needsgc(classdef, nogc)
+def getinstancerepr(rtyper, classdef, default_flavor='gc'):
+    if classdef is None:
+        flavor = default_flavor
+    else:
+        flavor = getgcflavor(classdef)
     try:
-        result = rtyper.instance_reprs[classdef, does_need_gc]
+        result = rtyper.instance_reprs[classdef, flavor]
     except KeyError:
-        #if classdef and classdef.cls is Exception:
-        #    # see getclassrepr()
-        #    result = getinstancerepr(rtyper, None, nogc=False)
-        #else:
         result = rtyper.type_system.rclass.buildinstancerepr(
-                        rtyper, classdef, does_need_gc=does_need_gc)
+                        rtyper, classdef, gcflavor=flavor)
 
-        rtyper.instance_reprs[classdef, does_need_gc] = result
+        rtyper.instance_reprs[classdef, flavor] = result
         rtyper.add_pendingsetup(result)
     return result
 

Added: pypy/dist/pypy/rpython/rcpy.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/rcpy.py	Thu Jun  8 15:24:47 2006
@@ -0,0 +1,30 @@
+from pypy.rpython.extregistry import ExtRegistryEntry
+
+
+def cpy_export(obj, cpytype):
+    raise NotImplementedError("only works in translated versions")
+
+
+class Entry(ExtRegistryEntry):
+    _about_ = cpy_export
+
+    def compute_result_annotation(self, s_obj, s_cpytype):
+        from pypy.annotation.model import SomeObject
+        from pypy.annotation.model import SomeInstance
+        assert isinstance(s_obj, SomeInstance)
+        assert s_cpytype.is_constant()
+        cpytype = s_cpytype.const
+        if hasattr(s_obj.classdef, '_cpy_exported_type_'):
+            assert s_obj.classdef._cpy_exported_type_ == cpytype
+        else:
+            s_obj.classdef._cpy_exported_type_ = cpytype
+        s = SomeObject()
+        s.knowntype = cpytype
+        return s
+
+    def specialize_call(self, hop):
+        from pypy.rpython.lltypesystem import lltype
+        r_inst = hop.args_r[0]
+        v_inst = hop.inputarg(r_inst, arg=0)
+        return hop.genop('cast_pointer', [v_inst],
+                         resulttype = lltype.Ptr(lltype.PyObject))

Modified: pypy/dist/pypy/rpython/rmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/rmodel.py	(original)
+++ pypy/dist/pypy/rpython/rmodel.py	Thu Jun  8 15:24:47 2006
@@ -421,14 +421,14 @@
 # __________ utilities __________
 PyObjPtr = Ptr(PyObject)
 
-def needsgc(classdef, nogc=False):
-    if classdef is None:
-        return not nogc
+def getgcflavor(classdef):
+    if hasattr(classdef, '_cpy_exported_type_'):
+        return 'cpy'
     else:
         classdesc = classdef.classdesc
         alloc_flavor = classdesc.read_attribute('_alloc_flavor_',
                                                 Constant('gc')).value     
-        return alloc_flavor.startswith('gc')
+        return alloc_flavor
 
 def externalvsinternal(rtyper, item_repr): # -> external_item_repr, (internal_)item_repr
     from pypy.rpython import rclass

Modified: pypy/dist/pypy/rpython/test/test_llinterp.py
==============================================================================

Modified: pypy/dist/pypy/rpython/test/test_nongc.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_nongc.py	(original)
+++ pypy/dist/pypy/rpython/test/test_nongc.py	Thu Jun  8 15:24:47 2006
@@ -39,8 +39,8 @@
     assert s.knowntype == Adef
     rtyper = RPythonTyper(a)
     rtyper.specialize()
-    assert (Adef, False) in rtyper.instance_reprs
-    assert (Adef, True) not in rtyper.instance_reprs    
+    assert (Adef, 'raw') in rtyper.instance_reprs
+    assert (Adef, 'gc') not in rtyper.instance_reprs    
     
 def test_alloc_flavor_subclassing():
     class A:
@@ -58,10 +58,10 @@
     assert s.knowntype == Bdef
     rtyper = RPythonTyper(a)
     rtyper.specialize()
-    assert (Adef, False) in rtyper.instance_reprs
-    assert (Adef, True) not in rtyper.instance_reprs
-    assert (Bdef, False) in rtyper.instance_reprs
-    assert (Bdef, True) not in rtyper.instance_reprs        
+    assert (Adef, 'raw') in rtyper.instance_reprs
+    assert (Adef, 'gc') not in rtyper.instance_reprs
+    assert (Bdef, 'raw') in rtyper.instance_reprs
+    assert (Bdef, 'gc') not in rtyper.instance_reprs        
 
 def test_unsupported():
     class A:

Modified: pypy/dist/pypy/rpython/test/test_rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rtyper.py	(original)
+++ pypy/dist/pypy/rpython/test/test_rtyper.py	Thu Jun  8 15:24:47 2006
@@ -113,13 +113,13 @@
     assert [vT.concretetype for vT in vTs] == [Void] * 3
     
 
-def test_needsgc():
+def test_getgcflavor():
     class A:
         pass
     class B:
         _alloc_flavor_ = "gc"
     class R:
-        _alloc_flavor_ = "nongc"
+        _alloc_flavor_ = "raw"
 
     NDF = object()
 
@@ -137,16 +137,9 @@
                 else:
                     return default
             
-    assert rmodel.needsgc(DummyClsDescDef(A))
-    assert rmodel.needsgc(DummyClsDescDef(A), nogc=True)
-    assert rmodel.needsgc(DummyClsDescDef(B))
-    assert rmodel.needsgc(DummyClsDescDef(B), nogc=True)
-    assert not rmodel.needsgc(DummyClsDescDef(R))
-    assert not rmodel.needsgc(DummyClsDescDef(R), nogc=False)
-    assert rmodel.needsgc(None)
-    assert rmodel.needsgc(None, nogc=False)
-    assert not rmodel.needsgc(None, nogc=True)            
-
-    
-
-        
+    assert rmodel.getgcflavor(DummyClsDescDef(A)) == 'gc'
+    assert rmodel.getgcflavor(DummyClsDescDef(B)) == 'gc'
+    assert rmodel.getgcflavor(DummyClsDescDef(R)) == 'raw'
+    cdef = DummyClsDescDef(A)
+    cdef._cpy_exported_type_ = type(Ellipsis)
+    assert rmodel.getgcflavor(cdef) == 'cpy'

Modified: pypy/dist/pypy/translator/c/funcgen.py
==============================================================================
--- pypy/dist/pypy/translator/c/funcgen.py	(original)
+++ pypy/dist/pypy/translator/c/funcgen.py	Thu Jun  8 15:24:47 2006
@@ -559,7 +559,11 @@
         if flavor == "raw": 
             return "OP_RAW_MALLOC(%s, %s);" % (esize, eresult) 
         elif flavor == "stack": 
-            return "OP_STACK_MALLOC(%s, %s);" % (esize, eresult) 
+            return "OP_STACK_MALLOC(%s, %s);" % (esize, eresult)
+        elif flavor == "cpy":
+            cpytype = self.expr(op.args[2])
+            return "%s = PyObject_New(%s, (PyTypeObject *)%s);" % (
+                eresult, cdecl(typename, ''), cpytype)
         else:
             raise NotImplementedError
 
@@ -593,7 +597,6 @@
         result.append('%s = (%s)%s;' % (self.expr(op.result),
                                         cdecl(typename, ''),
                                         self.expr(op.args[0])))
-        assert TYPE != PyObjPtr
         return '\t'.join(result)
 
     OP_CAST_PTR_TO_ADR = OP_CAST_POINTER



More information about the Pypy-commit mailing list