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

arigo at codespeak.net arigo at codespeak.net
Mon Apr 10 11:37:46 CEST 2006


Author: arigo
Date: Mon Apr 10 11:37:44 2006
New Revision: 25654

Modified:
   pypy/dist/pypy/rpython/rctypes/rchar_p.py
   pypy/dist/pypy/rpython/rctypes/rmodel.py
   pypy/dist/pypy/rpython/rctypes/rpointer.py
   pypy/dist/pypy/rpython/rctypes/rprimitive.py
   pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py
   pypy/dist/pypy/rpython/rctypes/test/test_rpointer.py
Log:
Support and test for prebuilt c_char_p and pointer instances.
Renamed c_data_ref to c_data for more uniformity in the ll helpers.


Modified: pypy/dist/pypy/rpython/rctypes/rchar_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rchar_p.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rchar_p.py	Mon Apr 10 11:37:44 2006
@@ -14,12 +14,16 @@
         return [('keepalive_str', string_repr.lowleveltype)]
 
     def getstring(self, llops, v_box):
-        v_c_data = self.get_c_data(llops, v_box)
-        return llops.gendirectcall(ll_getstring, v_box, v_c_data)
+        return llops.gendirectcall(ll_getstring, v_box)
 
     def setstring(self, llops, v_box, v_str):
-        v_c_data = self.get_c_data(llops, v_box)
-        llops.gendirectcall(ll_setstring, v_box, v_c_data, v_str)
+        llops.gendirectcall(ll_setstring, v_box, v_str)
+
+    def initialize_const(self, p, string):
+        if isinstance(string, c_char_p):
+            string = string.value
+        llstring = string_repr.convert_const(string)
+        ll_setstring(p, llstring)
 
     def rtype_getattr(self, hop):
         s_attr = hop.args_s[1]
@@ -55,8 +59,8 @@
 def ll_str2charp(s):
     return llmemory.cast_ptr_to_adr(s.chars) + FIRSTITEMOFS
 
-def ll_getstring(box, c_data):
-    p = c_data.value
+def ll_getstring(box):
+    p = box.c_data.value
     if p:
         if (box.keepalive_str and ll_str2charp(box.keepalive_str) == p):
             maxlen = len(box.keepalive_str.chars)
@@ -73,11 +77,11 @@
     else:
         return lltype.nullptr(string_repr.lowleveltype.TO)
 
-def ll_setstring(box, c_data, string):
+def ll_setstring(box, string):
     if string:
-        c_data.value = ll_str2charp(string)
+        box.c_data.value = ll_str2charp(string)
     else:
-        c_data.value = llmemory.NULL
+        box.c_data.value = llmemory.NULL
     box.keepalive_str = string
 
 
@@ -98,13 +102,16 @@
     specialize_call=c_char_p_specialize_call
     )
 
+def c_char_compute_annotation(the_type, instance):
+    return annmodel.SomeCTypesObject(c_char_p,
+                                     annmodel.SomeCTypesObject.OWNSMEMORY)
+
 def c_char_p_get_repr(rtyper, s_char_p):
     return CCharPRepr(rtyper, s_char_p, CCHARP)
 
 entry = extregistry.register_type(c_char_p,
-        compute_annotation = annmodel.SomeCTypesObject(c_char_p,
-                                       annmodel.SomeCTypesObject.OWNSMEMORY),
-        get_repr = c_char_p_get_repr,
+        compute_annotation = c_char_compute_annotation,
+        get_repr           = c_char_p_get_repr,
         )
 def c_char_p_get_field_annotation(s_char_p, fieldname):
     assert fieldname == 'value'

Modified: pypy/dist/pypy/rpython/rctypes/rmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rmodel.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rmodel.py	Mon Apr 10 11:37:44 2006
@@ -63,7 +63,7 @@
             self.r_memoryowner = rtyper.getrepr(s_memoryowner)
             self.lowleveltype = lltype.Ptr(
                 lltype.GcStruct( "CtypesBox_%s" % (ctype.__name__,),
-                 ( "c_data_ref", lltype.Ptr(self.c_data_type) ),
+                 ( "c_data", lltype.Ptr(self.c_data_type) ),
                  ( "c_data_owner_keepalive", self.r_memoryowner.lowleveltype ),
                  *content_keepalives
                 )
@@ -80,7 +80,7 @@
             return llops.genop('getsubstruct', inputargs,
                         lltype.Ptr(self.c_data_type) )
         else:
-            inputargs = [v_box, inputconst(lltype.Void, "c_data_ref")]
+            inputargs = [v_box, inputconst(lltype.Void, "c_data")]
             return llops.genop('getfield', inputargs,
                         lltype.Ptr(self.c_data_type) )
 
@@ -99,12 +99,12 @@
 
     def allocate_instance_ref(self, llops, v_c_data, v_c_data_owner=None):
         """Only if self.ownsmemory is false.  This allocates a new instance
-        and initialize its c_data_ref field."""
+        and initialize its c_data pointer."""
         if self.ownsmemory:
             raise TyperError("allocate_instance_ref: %r owns its memory" % (
                 self,))
         v_box = self.allocate_instance(llops)
-        inputargs = [v_box, inputconst(lltype.Void, "c_data_ref"), v_c_data]
+        inputargs = [v_box, inputconst(lltype.Void, "c_data"), v_c_data]
         llops.genop('setfield', inputargs)
         if v_c_data_owner is not None:
             assert (v_c_data_owner.concretetype ==
@@ -172,3 +172,34 @@
         """Writes to the 'value' field of the raw data."""
         v_c_data = self.get_c_data(llops, v_box)
         self.setvalue_inside_c_data(llops, v_c_data, v_value)
+
+    def convert_const(self, value):
+        if isinstance(value, self.ctype):
+            key = "by_id", id(value)
+            keepalive = value
+        else:
+            if self.ownsmemory:
+                raise TyperError("convert_const(%r) but repr owns memory" % (
+                    value,))
+            key = "by_value", value
+            keepalive = None
+        try:
+            return self.const_cache[key][0]
+        except KeyError:
+            p = lltype.malloc(self.r_memoryowner.lowleveltype.TO)
+            self.initialize_const(p, 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 = p.c_data    # initialize c_data pointer
+                result.c_data_owner_keepalive = p
+            self.const_cache[key] = result, keepalive
+            return result
+
+    def initialize_const(self, p, value):
+        if isinstance(value, self.ctype):
+            value = value.value
+        p.c_data.value = value

Modified: pypy/dist/pypy/rpython/rctypes/rpointer.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rpointer.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rpointer.py	Mon Apr 10 11:37:44 2006
@@ -30,6 +30,13 @@
                      v_owner]
         llops.genop('setfield', inputargs)
 
+    def initialize_const(self, p, ptr):
+        llcontents = self.r_contents.convert_const(ptr.contents)
+        p.c_data.value = llcontents.c_data
+        # the following line is probably pointless, as 'llcontents' will be
+        # an immortal global constant just like 'p', but better safe than sorry
+        p.keepalive_contents = llcontents.c_data_owner_keepalive
+
     def rtype_getattr(self, hop):
         s_attr = hop.args_s[1]
         assert s_attr.is_constant()

Modified: pypy/dist/pypy/rpython/rctypes/rprimitive.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rprimitive.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rprimitive.py	Mon Apr 10 11:37:44 2006
@@ -34,34 +34,6 @@
         """
         return self.getvalue_from_c_data(llops, v_c_data)
 
-    def convert_const(self, 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.r_memoryowner.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]
         assert s_attr.is_constant()

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py	Mon Apr 10 11:37:44 2006
@@ -27,9 +27,19 @@
         t = TranslationContext()
         a = t.buildannotator()
         s = a.build_types(func, [])
-
         assert s.knowntype == str
+        if conftest.option.view:
+            t.view()
+
+    def test_annotate_prebuilt(self):
+        p = c_char_p("hello")
+        def func():
+            return p.value
 
+        t = TranslationContext()
+        a = t.buildannotator()
+        s = a.build_types(func, [])
+        assert s.knowntype == str
         if conftest.option.view:
             t.view()
 
@@ -42,5 +52,29 @@
         res = interpret(func, [])
         assert ''.join(res.chars) == "hello"
 
+    def test_specialize_prebuilt(self):
+        p = c_char_p("hello")
+        def func():
+            return p.value
+
+        res = interpret(func, [])
+        assert ''.join(res.chars) == "hello"
+
 class Test_compilation:
-    pass
+    def test_compile_c_char_p(self):
+        def func():
+            p = c_char_p("hello")
+            return p.value
+
+        fn = compile(func, [])
+        res = fn()
+        assert res == "hello"
+
+    def test_compile_prebuilt(self):
+        p = c_char_p("hello")
+        def func():
+            return p.value
+
+        fn = compile(func, [])
+        res = fn()
+        assert res == "hello"

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	Mon Apr 10 11:37:44 2006
@@ -83,6 +83,21 @@
         if conftest.option.view:
             t.view()
 
+    def test_annotate_prebuilt(self):
+        c = c_int(10)
+        p = pointer(c)
+        def access_prebuilt():
+            p.contents.value += 1
+            return p[0]
+
+        t = TranslationContext()
+        a = t.buildannotator()
+        s = a.build_types(access_prebuilt, [])
+        assert s.knowntype == int
+
+        if conftest.option.view:
+            t.view()
+
 
 class Test_specialization:
     def test_specialize_c_int_ptr(self):
@@ -172,3 +187,13 @@
         assert access_array() == 5 * 7 * 11
         res = interpret(access_array, [])
         assert res == 5 * 7 * 11
+
+    def test_specialize_prebuilt(self):
+        c = c_int(10)
+        p = pointer(c)
+        def access_prebuilt():
+            p.contents.value += 1
+            return p[0]
+
+        res = interpret(access_prebuilt, [])
+        assert res == 11



More information about the Pypy-commit mailing list