[pypy-svn] r28883 - in pypy/dist/pypy: annotation objspace/cpy rpython/rctypes rpython/rctypes/test

arigo at codespeak.net arigo at codespeak.net
Fri Jun 16 16:21:46 CEST 2006


Author: arigo
Date: Fri Jun 16 16:21:41 2006
New Revision: 28883

Modified:
   pypy/dist/pypy/annotation/binaryop.py
   pypy/dist/pypy/annotation/model.py
   pypy/dist/pypy/objspace/cpy/refcount.py
   pypy/dist/pypy/rpython/rctypes/afunc.py
   pypy/dist/pypy/rpython/rctypes/apointer.py
   pypy/dist/pypy/rpython/rctypes/astringbuf.py
   pypy/dist/pypy/rpython/rctypes/astruct.py
   pypy/dist/pypy/rpython/rctypes/avoid_p.py
   pypy/dist/pypy/rpython/rctypes/implementation.py
   pypy/dist/pypy/rpython/rctypes/rarray.py
   pypy/dist/pypy/rpython/rctypes/rmodel.py
   pypy/dist/pypy/rpython/rctypes/rpointer.py
   pypy/dist/pypy/rpython/rctypes/rstruct.py
   pypy/dist/pypy/rpython/rctypes/test/test_rpointer.py
Log:
A clean-up that removes a now-obscure restriction in rctypes.


Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py	(original)
+++ pypy/dist/pypy/annotation/binaryop.py	Fri Jun 16 16:21:41 2006
@@ -793,8 +793,7 @@
         # because both have a _type_ attribute that contains the type of the
         # object pointed to or in the case of an array the element type.
         result_ctype = s_cto.knowntype._type_
-        s_result = SomeCTypesObject(result_ctype,
-                                    memorystate=SomeCTypesObject.MEMORYALIAS)
+        s_result = SomeCTypesObject(result_ctype, ownsmemory=False)
         return s_result.return_annotation()
 
 class __extend__(pairtype(SomeCTypesObject, SomeSlice)):
@@ -804,8 +803,7 @@
 
     def getitem((s_cto, s_slice)):
         result_ctype = s_cto.knowntype._type_
-        s_result = SomeCTypesObject(result_ctype,
-                                    memorystate=SomeCTypesObject.MEMORYALIAS)
+        s_result = SomeCTypesObject(result_ctype, ownsmemory=False)
         list_item = s_result.return_annotation()
         if isinstance(list_item, SomeChar):
             return SomeString()
@@ -815,17 +813,9 @@
 class __extend__(pairtype(SomeCTypesObject, SomeCTypesObject)):
     def union((s_cto1, s_cto2)):
         if s_cto1.knowntype == s_cto2.knowntype:
-            states = {}
-            for s in [s_cto1, s_cto2]:
-                if s.memorystate != SomeCTypesObject.NOMEMORY:
-                    states[s.memorystate] = True
-            if len(states) == 0:
-                state = SomeCTypesObject.NOMEMORY
-            elif len(states) == 1:
-                [state] = states.keys()
-            else:
-                state = SomeCTypesObject.MIXEDMEMORYOWNERSHIP
-            return SomeCTypesObject(s_cto1.knowntype, state)
+            return SomeCTypesObject(s_cto1.knowntype,
+                                    ownsmemory = (s_cto1.ownsmemory and
+                                                  s_cto2.ownsmemory))
         else:
             return SomeObject()
 

Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py	(original)
+++ pypy/dist/pypy/annotation/model.py	Fri Jun 16 16:21:41 2006
@@ -430,16 +430,14 @@
 class SomeCTypesObject(SomeExternalObject):
     """Stands for an object of the ctypes module."""
 
-    NOMEMORY = "NOMEMORY"
-    OWNSMEMORY = "OWNSMEMORY"
-    MEMORYALIAS = "MEMORYALIAS"
-    MIXEDMEMORYOWNERSHIP = "MIXEDMEMORYOWNERSHIP"
-    
-    def __init__(self, knowntype, memorystate):
-        if memorystate is None:
-            memorystate = knowntype.default_memorystate
+    def __init__(self, knowntype, ownsmemory):
         self.knowntype = knowntype
-        self.memorystate = memorystate 
+        self.ownsmemory = ownsmemory
+        # 'ownsmemory' specifies if the object is *statically known* to own
+        # its C memory.  If it is False, it will be rtyped as an alias object.
+        # Alias objects are allowed, at run-time, to have keepalives, so
+        # that they can indirectly own their memory too (it's just less
+        # efficient).
 
     def can_be_none(self):
         # only 'py_object' can also be None

Modified: pypy/dist/pypy/objspace/cpy/refcount.py
==============================================================================
--- pypy/dist/pypy/objspace/cpy/refcount.py	(original)
+++ pypy/dist/pypy/objspace/cpy/refcount.py	Fri Jun 16 16:21:41 2006
@@ -42,8 +42,7 @@
 
     def specialize_call(self, hop):
         from pypy.rpython.lltypesystem import lltype
-        s_pyobj = annmodel.SomeCTypesObject(W_Object,
-                                   annmodel.SomeCTypesObject.MEMORYALIAS)
+        s_pyobj = annmodel.SomeCTypesObject(W_Object, ownsmemory=False)
         r_pyobj = hop.rtyper.getrepr(s_pyobj)
         [v_box] = hop.inputargs(r_pyobj)
         v_value = r_pyobj.getvalue(hop.llops, v_box)
@@ -60,8 +59,7 @@
 
     def specialize_call(self, hop):
         from pypy.rpython.lltypesystem import lltype
-        s_pyobj = annmodel.SomeCTypesObject(W_Object,
-                                   annmodel.SomeCTypesObject.MEMORYALIAS)
+        s_pyobj = annmodel.SomeCTypesObject(W_Object, ownsmemory=False)
         r_pyobj = hop.rtyper.getrepr(s_pyobj)
         [v_box] = hop.inputargs(r_pyobj)
         v_value = r_pyobj.getvalue(hop.llops, v_box)

Modified: pypy/dist/pypy/rpython/rctypes/afunc.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/afunc.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/afunc.py	Fri Jun 16 16:21:41 2006
@@ -30,7 +30,7 @@
             #... because then in ctypes you don't get automatic unwrapping.
             #    That would not be annotatable, for the same reason that
             #    reading the .value attribute of py_object is not annotatable
-        s_result = SomeCTypesObject(result_ctype, SomeCTypesObject.OWNSMEMORY)
+        s_result = SomeCTypesObject(result_ctype, ownsmemory=True)
         return s_result.return_annotation()
 
 ##    def object_seen(self, bookkeeper):
@@ -66,7 +66,7 @@
         fnname = cfuncptr.__name__
 
         def repr_for_ctype(ctype):
-            s = SomeCTypesObject(ctype, SomeCTypesObject.MEMORYALIAS)
+            s = SomeCTypesObject(ctype, ownsmemory=False)
             r = hop.rtyper.getrepr(s)
             return r
 
@@ -106,8 +106,7 @@
                 unwrapped_args_v.append(r_arg.get_c_data(hop.llops, v))
                 ARGTYPES.append(r_arg.c_data_type)
         if cfuncptr.restype is not None:
-            s_res = SomeCTypesObject(cfuncptr.restype,
-                                     SomeCTypesObject.OWNSMEMORY)
+            s_res = SomeCTypesObject(cfuncptr.restype, ownsmemory=True)
             r_res = hop.rtyper.getrepr(s_res)
             RESTYPE = r_res.ll_type
         else:

Modified: pypy/dist/pypy/rpython/rctypes/apointer.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/apointer.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/apointer.py	Fri Jun 16 16:21:41 2006
@@ -25,8 +25,7 @@
         assert fieldname == "contents"
         ptrtype = self.type
         assert s_pointer.knowntype == ptrtype
-        return SomeCTypesObject(ptrtype._type_,
-                                SomeCTypesObject.MEMORYALIAS)
+        return SomeCTypesObject(ptrtype._type_, ownsmemory=False)
 
     def get_repr(self, rtyper, s_pointer):
         from pypy.rpython.rctypes.rpointer import PointerRepr
@@ -41,7 +40,7 @@
         assert isinstance(s_arg, SomeCTypesObject)
         ctype = s_arg.knowntype
         result_ctype = POINTER(ctype)
-        return SomeCTypesObject(result_ctype, SomeCTypesObject.OWNSMEMORY)
+        return SomeCTypesObject(result_ctype, ownsmemory=True)
 
     def specialize_call(hop):
         r_ptr = hop.r_result

Modified: pypy/dist/pypy/rpython/rctypes/astringbuf.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/astringbuf.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/astringbuf.py	Fri Jun 16 16:21:41 2006
@@ -21,7 +21,7 @@
     def compute_result_annotation(self, s_length):
         if s_length.knowntype != int:
             raise Exception("only supports create_string_buffer(length)")
-        return SomeCTypesObject(StringBufferType, SomeCTypesObject.OWNSMEMORY)
+        return SomeCTypesObject(StringBufferType, ownsmemory=True)
 
     def specialize_call(self, hop):
         from pypy.rpython.lltypesystem import lltype
@@ -71,6 +71,6 @@
                 raise TyperError("ctypes.sizeof(non_ctypes_object)")
             # XXX check that s_arg.const is really a ctypes type
             ctype = s_arg.const
-            s_arg = SomeCTypesObject(ctype, SomeCTypesObject.OWNSMEMORY)
+            s_arg = SomeCTypesObject(ctype, ownsmemory=True)
             r_arg = hop.rtyper.getrepr(s_arg)
         return hop.inputconst(lltype.Signed, llmemory.sizeof(r_arg.ll_type))

Modified: pypy/dist/pypy/rpython/rctypes/astruct.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/astruct.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/astruct.py	Fri Jun 16 16:21:41 2006
@@ -53,8 +53,7 @@
     def get_field_annotation(self, s_struct, fieldname):
         for name, ctype in self.type._fields_:
             if name == fieldname:
-                s_result = SomeCTypesObject(ctype,
-                                            SomeCTypesObject.MEMORYALIAS)
+                s_result = SomeCTypesObject(ctype, ownsmemory=False)
                 return s_result.return_annotation()
         raise AttributeError('%r has no field %r' % (self.type, fieldname))
 

Modified: pypy/dist/pypy/rpython/rctypes/avoid_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/avoid_p.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/avoid_p.py	Fri Jun 16 16:21:41 2006
@@ -46,7 +46,7 @@
             pass
         else:
             self.checkptr(s_arg.knowntype)
-        return SomeCTypesObject(type, SomeCTypesObject.OWNSMEMORY)
+        return SomeCTypesObject(type, ownsmemory=True)
 
     def specialize_call(self, hop):
         from pypy.rpython.rctypes.rpointer import PointerRepr

Modified: pypy/dist/pypy/rpython/rctypes/implementation.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/implementation.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/implementation.py	Fri Jun 16 16:21:41 2006
@@ -96,7 +96,7 @@
 
     def compute_result_annotation(self, *args_s, **kwds_s):
         ctype = self.instance    # the ctype is the called object
-        return SomeCTypesObject(ctype, SomeCTypesObject.OWNSMEMORY)
+        return SomeCTypesObject(ctype, ownsmemory=True)
 
 class CTypesObjEntry(CTypesEntry):
     "Annotation and rtyping of ctypes instances."
@@ -104,7 +104,7 @@
     def compute_annotation(self):
         #self.ctype_object_discovered()
         ctype = self.type
-        return SomeCTypesObject(ctype, SomeCTypesObject.OWNSMEMORY)
+        return SomeCTypesObject(ctype, ownsmemory=True)
 
 
 # Importing for side effect of registering types with extregistry

Modified: pypy/dist/pypy/rpython/rctypes/rarray.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rarray.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rarray.py	Fri Jun 16 16:21:41 2006
@@ -22,7 +22,7 @@
         
         # Find the repr and low-level type of items from their ctype
         self.r_item = rtyper.getrepr(SomeCTypesObject(item_ctype,
-                                            SomeCTypesObject.MEMORYALIAS))
+                                                      ownsmemory=False))
 
         # Here, self.c_data_type == self.ll_type
         c_data_type = lltype.FixedSizeArray(self.r_item.ll_type,

Modified: pypy/dist/pypy/rpython/rctypes/rmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rmodel.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rmodel.py	Fri Jun 16 16:21:41 2006
@@ -34,17 +34,11 @@
         # ll_type: the low-level type representing the raw
         #          data, which is then embedded in a box.
         ctype = s_ctypesobject.knowntype
-        memorystate = s_ctypesobject.memorystate
 
         self.rtyper = rtyper
         self.ctype = ctype
         self.ll_type = ll_type
-        if memorystate == SomeCTypesObject.OWNSMEMORY:
-            self.ownsmemory = True
-        elif memorystate == SomeCTypesObject.MEMORYALIAS:
-            self.ownsmemory = False
-        else:
-            raise TyperError("unsupported ctypes memorystate %r" % memorystate)
+        self.ownsmemory = s_ctypesobject.ownsmemory
 
         self.c_data_type = self.get_c_data_type(ll_type)
 
@@ -57,8 +51,7 @@
             self.r_memoryowner = self
             fields.append(( "c_data", self.c_data_type ))
         else:
-            s_memoryowner = SomeCTypesObject(ctype,
-                                             SomeCTypesObject.OWNSMEMORY)
+            s_memoryowner = SomeCTypesObject(ctype, ownsmemory=True)
             self.r_memoryowner = rtyper.getrepr(s_memoryowner)
             fields += [
                 ( "c_data_owner_keepalive", self.r_memoryowner.lowleveltype ),

Modified: pypy/dist/pypy/rpython/rctypes/rpointer.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rpointer.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rpointer.py	Fri Jun 16 16:21:41 2006
@@ -20,7 +20,7 @@
         rtyper = self.rtyper
         ref_ctype = self.ctype._type_
         self.r_contents = rtyper.getrepr(SomeCTypesObject(ref_ctype,
-                                               SomeCTypesObject.MEMORYALIAS))
+                                                          ownsmemory=False))
         if isinstance(self.ll_type.TO, lltype.ForwardReference):
             self.ll_type.TO.become(self.r_contents.c_data_type)
         if isinstance(self.keepalive_box_type, lltype.GcForwardReference):

Modified: pypy/dist/pypy/rpython/rctypes/rstruct.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rstruct.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rstruct.py	Fri Jun 16 16:21:41 2006
@@ -15,7 +15,7 @@
         llfields = []
         for name, field_ctype in struct_ctype._fields_:
             r_field = rtyper.getrepr(SomeCTypesObject(field_ctype,
-                                                SomeCTypesObject.MEMORYALIAS))
+                                                      ownsmemory=False))
             self.r_fields[name] = r_field
             llfields.append((cmangle(name), r_field.ll_type))
 

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rpointer.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rpointer.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rpointer.py	Fri Jun 16 16:21:41 2006
@@ -8,6 +8,7 @@
 from pypy import conftest
 from pypy.rpython.test.test_llinterp import interpret
 from pypy.translator.c.test.test_genc import compile
+from pypy.annotation.model import SomeCTypesObject
 
 from ctypes import c_int, c_float, POINTER, pointer, Structure
 
@@ -129,6 +130,21 @@
         if conftest.option.view:
             t.view()
 
+    def test_annotate_mixed_ownership(self):
+        def fn(n):
+            if n > 0:
+                p = pointer(c_int())
+                q = p.contents
+            else:
+                q = c_int()
+            return q
+
+        t = TranslationContext()
+        a = t.buildannotator()
+        s = a.build_types(fn, [int])
+        assert isinstance(s, SomeCTypesObject)
+        assert not s.ownsmemory
+
 
 class Test_specialization:
     def test_specialize_c_int_ptr(self):
@@ -275,6 +291,21 @@
             assert p
         interpret(fn, [])
 
+    def test_specialize_mixed_ownership(self):
+        def fn(n):
+            a = c_int(55)
+            if n > 0:
+                p = pointer(a)
+                q = p.contents
+            else:
+                q = c_int()
+            q.value = n
+            return a.value
+        res = interpret(fn, [12])
+        assert res == 12
+        res = interpret(fn, [-12])
+        assert res == 55
+
 class Test_compilation:
     def test_compile_getitem_nonzero_index(self):
         A = c_int * 10



More information about the Pypy-commit mailing list