[pypy-svn] r25809 - in pypy/dist/pypy: annotation rpython/rctypes rpython/rctypes/test

arigo at codespeak.net arigo at codespeak.net
Thu Apr 13 18:43:56 CEST 2006


Author: arigo
Date: Thu Apr 13 18:43:54 2006
New Revision: 25809

Modified:
   pypy/dist/pypy/annotation/model.py
   pypy/dist/pypy/rpython/rctypes/rchar_p.py
   pypy/dist/pypy/rpython/rctypes/rprimitive.py
   pypy/dist/pypy/rpython/rctypes/rstruct.py
   pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py
   pypy/dist/pypy/rpython/rctypes/test/test_rarray.py
   pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py
Log:
Automatic c_char_p-to-str conversion when reads fields of a struct
or getting a function's result.  Typos, tests.


Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py	(original)
+++ pypy/dist/pypy/annotation/model.py	Thu Apr 13 18:43:54 2006
@@ -451,11 +451,8 @@
         from pypy.rpython import extregistry
         assert extregistry.is_registered_type(self.knowntype)
         entry = extregistry.lookup_type(self.knowntype)
-        if hasattr(entry, 'lowleveltype'):
-            # special case for returning primitives
-            return lltype_to_annotation(entry.lowleveltype)
-        else:
-            return self
+        # special case for returning primitives or c_char_p
+        return getattr(entry, 's_return_trick', self)
 
 
 class SomeImpossibleValue(SomeObject):

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	Thu Apr 13 18:43:54 2006
@@ -12,6 +12,13 @@
 
 class CCharPRepr(CTypesValueRepr):
 
+    def return_c_data(self, llops, v_c_data):
+        """Read out the RPython string from a raw C pointer.
+        Used when the data is returned from an operation or C function call.
+        """
+        v_char_p = self.getvalue_from_c_data(llops, v_c_data)
+        return llops.gendirectcall(ll_charp2str, v_char_p)
+
     def get_content_keepalives(self):
         "Return an extra keepalive field used for the RPython string."
         return [('keepalive_str', string_repr.lowleveltype)]
@@ -83,6 +90,13 @@
 def ll_str2charp(s):
     return lltype.cast_subarray_pointer(CCHARP, s.chars, 0)
 
+def ll_charp2str(p):
+    length = ll_strlen(p)
+    newstr = lltype.malloc(string_repr.lowleveltype.TO, length)
+    for i in range(length):
+        newstr.chars[i] = p[i]
+    return newstr
+
 def ll_getstring(box):
     p = box.c_data[0]
     if p:
@@ -137,7 +151,9 @@
         compute_annotation = c_char_compute_annotation,
         get_repr           = c_char_p_get_repr,
         )
+s_value_annotation = annmodel.SomeString(can_be_None=True)
 def c_char_p_get_field_annotation(s_char_p, fieldname):
     assert fieldname == 'value'
-    return annmodel.SomeString(can_be_None=True)
+    return s_value_annotation
 entry.get_field_annotation = c_char_p_get_field_annotation
+entry.s_return_trick = s_value_annotation

Modified: pypy/dist/pypy/rpython/rctypes/rprimitive.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rprimitive.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rprimitive.py	Thu Apr 13 18:43:54 2006
@@ -95,11 +95,12 @@
             compute_annotation=compute_prebuilt_instance_annotation,
             get_repr=primitive_get_repr,
             )
+    s_value_annotation = annmodel.lltype_to_annotation(ll_type)
     def primitive_get_field_annotation(s_primitive, fieldname):
         assert fieldname == 'value'
-        return annmodel.lltype_to_annotation(ll_type)
+        return s_value_annotation
     entry.get_field_annotation = primitive_get_field_annotation
-    entry.lowleveltype = ll_type
+    entry.s_return_trick = s_value_annotation
 
 for the_type, ll_type in ctypes_annotation_list:
     do_register(the_type, ll_type)

Modified: pypy/dist/pypy/rpython/rctypes/rstruct.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rstruct.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rstruct.py	Thu Apr 13 18:43:54 2006
@@ -79,7 +79,7 @@
             # primitive case (optimization only)
             return self.get_field_value(hop.llops, v_struct, name)
         # normal case
-        v_c_data = self.get_c_data_of_item(hop.llops, v_struct, name)
+        v_c_data = self.get_c_data_of_field(hop.llops, v_struct, name)
         return r_field.return_c_data(hop.llops, v_c_data)
 
     def rtype_setattr(self, hop):
@@ -91,7 +91,7 @@
         if isinstance(r_field, CTypesRefRepr):
             # ByRef case
             v_new_c_data = r_field.get_c_data(hop.llops, v_item)
-            v_c_data = self.get_c_data_of_item(hop.llops, v_struct, name)
+            v_c_data = self.get_c_data_of_field(hop.llops, v_struct, name)
             # copy the whole structure's content over
             genreccopy(hop.llops, v_new_c_data, v_c_data)
         else:

Modified: pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py	Thu Apr 13 18:43:54 2006
@@ -64,6 +64,11 @@
     p[0] = "other"
     assert x.value == p.contents.value == p[0] == "other"
 
+    myarray = (c_char_p * 10)()
+    myarray[7] = "hello"
+    assert isinstance(myarray[7], str)
+    assert myarray[7] == "hello"
+
 def test_struct():
     class tagpoint(Structure):
         _fields_ = [('x', c_int),

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	Thu Apr 13 18:43:54 2006
@@ -16,7 +16,7 @@
 except ImportError:
     py.test.skip("this test needs ctypes installed")
 
-from ctypes import c_int, c_short, ARRAY, POINTER, pointer
+from ctypes import c_int, c_short, ARRAY, POINTER, pointer, c_char_p
 
 c_int_10 = ARRAY(c_int,10)
 
@@ -118,6 +118,30 @@
             a.translator.view()
         assert s.knowntype == int
 
+    def test_annotate_variants(self):
+        A1 = c_int * 10
+        A2 = POINTER(c_int) * 10
+        A3 = A1 * 10
+        A4 = POINTER(A1) * 10
+        A5 = c_char_p * 10
+        def func():
+            a1 = A1(); a1[4] = 1000
+            a2 = A2(); a2[5] = pointer(c_int(200))
+            a3 = A3(); a3[2][9] = 30
+            a4 = A4(); a4[3] = pointer(a1); a1[1] = 4
+            a5 = A5(); a5[7] = "hello"
+            res = a1[4] + a2[5].contents.value + a3[2][9] + a4[3].contents[1]
+            res *= ord(a5[7][1])
+            return res
+        assert func() == 1234 * ord('e')
+
+        t = TranslationContext()
+        a = t.buildannotator()
+        s = a.build_types(func, [])
+        if conftest.option.view:
+            a.translator.view()
+        assert s.knowntype == int
+
 class Test_specialization:
     def test_specialize_array(self):
         def create_array():

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	Thu Apr 13 18:43:54 2006
@@ -17,7 +17,7 @@
 except ImportError:
     py.test.skip("this test needs ctypes installed")
 
-from ctypes import c_char_p, pointer
+from ctypes import c_char_p, pointer, Structure
 
 class Test_annotation:
     def test_annotate_c_char_p(self):
@@ -44,6 +44,21 @@
         if conftest.option.view:
             t.view()
 
+    def test_annotate_return(self):
+        class S(Structure):
+            _fields_ = [('string', c_char_p)]
+        def func():
+            s = S()
+            s.string = "hello"
+            return s.string
+
+        t = TranslationContext()
+        a = t.buildannotator()
+        s = a.build_types(func, [])
+        assert s.knowntype == str
+        if conftest.option.view:
+            t.view()
+
 class Test_specialization:
     def test_specialize_c_char_p(self):
         def func():
@@ -82,6 +97,18 @@
         res = interpret(func, [])
         assert ''.join(res.chars) == 'ka'
 
+    def test_specialize_return(self):
+        class S(Structure):
+            _fields_ = [('string', c_char_p)]
+        def func():
+            s = S()
+            s.string = "hello"
+            return s.string
+
+        assert func() == "hello"
+        res = interpret(func, [])
+        assert ''.join(res.chars) == "hello"
+
 
 class Test_compilation:
     def test_compile_c_char_p(self):



More information about the Pypy-commit mailing list