[pypy-svn] r25346 - in pypy/dist/pypy/rpython/rctypes: . test

arigo at codespeak.net arigo at codespeak.net
Wed Apr 5 11:49:07 CEST 2006


Author: arigo
Date: Wed Apr  5 11:49:06 2006
New Revision: 25346

Modified:
   pypy/dist/pypy/rpython/rctypes/rarray.py
   pypy/dist/pypy/rpython/rctypes/rprimitive.py
   pypy/dist/pypy/rpython/rctypes/test/test_rarray.py
Log:
(arre, arigo)

Switched rarray.py to the new FixedSizeArray lltype.
Got rid of the conversion from rctypes box to primitive lltypes,
which was both special-case for primitive things only and which
may be triggered unexpectedly.


Modified: pypy/dist/pypy/rpython/rctypes/rarray.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rarray.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rarray.py	Wed Apr  5 11:49:06 2006
@@ -1,7 +1,7 @@
 from ctypes import ARRAY, c_int
 from pypy.annotation.model import SomeCTypesObject, SomeBuiltin
 from pypy.rpython import extregistry
-from pypy.rpython.rmodel import Repr
+from pypy.rpython.rmodel import Repr, inputconst
 from pypy.rpython.lltypesystem import lltype
 from pypy.annotation.pairtype import pairtype
 from pypy.rpython.rmodel import IntegerRepr
@@ -21,33 +21,54 @@
                                             SomeCTypesObject.MEMORYALIAS))
 
         # Here, self.c_data_type == self.ll_type
-        c_data_type = lltype.Array(self.r_item.ll_type,
-                                    hints={"nolength": True})
-        
-        # Array elements are of the low-level type (Signed, etc) and not 
-        # of the boxed low level type (Ptr(GcStruct(...)))
+        c_data_type = lltype.FixedSizeArray(self.r_item.c_data_type,
+                                            self.length)
 
         super(ArrayRepr, self).__init__(rtyper, s_array, c_data_type)
 
+    def get_c_data_of_item(self, llops, v_array, v_index):
+        v_c_array = self.get_c_data(llops, v_array)
+        return llops.genop('getarraysubstruct', [v_c_array, v_index],
+                           lltype.Ptr(self.r_item.c_data_type))
+
 class __extend__(pairtype(ArrayRepr, IntegerRepr)):
     def rtype_setitem((r_array, r_int), hop):
         v_array, v_index, v_item = hop.inputargs(r_array, lltype.Signed,
-                r_array.r_item.ll_type)
-        v_c_data = r_array.get_c_data(hop.llops, v_array)
-        hop.genop('setarrayitem', [v_c_data, v_index, v_item])
+                                                 r_array.r_item)
+        v_item_c_data = r_array.r_item.get_c_data(hop.llops, v_item)
+        v_c_data = r_array.get_c_data_of_item(hop.llops, v_array, v_index)
+        # copy the whole structure's content over
+        reccopy(hop.llops, v_item_c_data, v_c_data)
 
     def rtype_getitem((r_array, r_int), hop):
         v_array, v_index = hop.inputargs(r_array, lltype.Signed)
+        v_c_data = r_array.get_c_data_of_item(hop.llops, v_array, v_index)
+        return r_array.r_item.return_c_data(hop.llops, v_c_data)
+
+
+def reccopy(llops, v_source, v_dest):
+    # helper (XXX move somewhere else) to copy recursively a structure
+    # or array onto another.
+    T = v_source.concretetype.TO
+    assert T == v_dest.concretetype.TO
+    assert isinstance(T, lltype.Struct)
+    for name in T._names:
+        FIELDTYPE = getattr(T, name)
+        cname = inputconst(lltype.Void, name)
+        if isinstance(FIELDTYPE, lltype.ContainerType):
+            RESTYPE = lltype.Ptr(FIELDTYPE)
+            v_subsrc = llops.genop('getsubstruct', [v_source, cname], RESTYPE)
+            v_subdst = llops.genop('getsubstruct', [v_dest,   cname], RESTYPE)
+            reccopy(llops, v_subsrc, v_subdst)
+        else:
+            v_value = llops.genop('getfield', [v_source, cname], FIELDTYPE)
+            llops.genop('setfield', [v_dest, cname, v_value])
 
-        v_c_data = r_array.get_c_data(hop.llops, v_array)
-        return hop.genop('getarrayitem', [v_c_data, v_index],
-                r_array.r_item.ll_type)
 
 def arraytype_specialize_call(hop):
     r_array = hop.r_result
-    return hop.genop("malloc_varsize", [
+    return hop.genop("malloc", [
         hop.inputconst(lltype.Void, r_array.lowleveltype.TO), 
-        hop.inputconst(lltype.Signed, r_array.length),
         ], resulttype=r_array.lowleveltype,
     )
 

Modified: pypy/dist/pypy/rpython/rctypes/rprimitive.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rprimitive.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rprimitive.py	Wed Apr  5 11:49:06 2006
@@ -7,6 +7,7 @@
 from pypy.rpython.lltypesystem import lltype
 from pypy.annotation.pairtype import pairtype
 from pypy.rpython.rmodel import IntegerRepr
+from pypy.rpython.error import TyperError
 from pypy.rpython.rctypes.rmodel import CTypesValueRepr
 
 ctypes_annotation_list = [
@@ -34,16 +35,32 @@
         return self.getvalue_from_c_data(llops, v_c_data)
 
     def convert_const(self, ctype_value):
-        assert isinstance(ctype_value, self.ctype)
-        key = id(ctype_value)
+        if isinstance(ctype_value, self.ctype):
+            key = "by_id", id(ctype_value)
+            value = ctype_value.value
+            keepalive = ctype_value
+        else:
+            if self.ownsmemory:
+                raise TyperError("convert_const(%r) but repr owns memory" % (
+                    ctype_value,))
+            key = "by_value", ctype_value
+            value = ctype_value
+            keepalive = None
         try:
             return self.const_cache[key][0]
         except KeyError:
-            p = lltype.malloc(self.lowleveltype.TO)
-            
-            self.const_cache[key] = p, ctype_value
-            p.c_data.value = ctype_value.value
-            return p
+            p = lltype.malloc(self.owner_lowleveltype.TO)
+            p.c_data.value = value
+            if self.ownsmemory:
+                result = p
+            else:
+                # we must return a non-memory-owning box that keeps the
+                # memory-owning box alive
+                result = lltype.malloc(self.lowleveltype.TO)
+                result.c_data_ref = p.c_data
+                result.c_data_owner_keepalive = p
+            self.const_cache[key] = result, keepalive
+            return result
         
     def rtype_getattr(self, hop):
         s_attr = hop.args_s[1]
@@ -60,14 +77,6 @@
                                                         self.ll_type)
         self.setvalue(hop.llops, v_primitive, v_value)
 
-# need to extend primitive repr to implement convert_from_to() for various
-# conversions, firstly the conversion from c_long() to Signed
-
-class __extend__(pairtype(PrimitiveRepr, IntegerRepr)):
-    def convert_from_to((r_from, r_to), v, llops):
-        assert r_from.ll_type == r_to.lowleveltype
-
-        return r_from.getvalue(llops, v)
 
 def primitive_specialize_call(hop):
     r_primitive = hop.r_result

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rarray.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rarray.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rarray.py	Wed Apr  5 11:49:06 2006
@@ -108,10 +108,10 @@
 
         res = interpret(create_array, [])
         c_data = res.c_data
-        assert c_data[0] == 0
-        assert c_data[9] == 0
+        assert c_data[0].value == 0
+        assert c_data[9].value == 0
         py.test.raises(IndexError, "c_data[10]")
-        py.test.raises(TypeError, "len(c_data)")
+        assert len(c_data) == 10
 
     def test_specialize_array_access(self):
         def access_array():
@@ -126,6 +126,7 @@
 
 class Test_compilation:
     def test_compile_array_access(self):
+        py.test.skip("in-progress")
         def access_array():
             my_array = c_int_10()
             my_array[0] = 1



More information about the Pypy-commit mailing list