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

ac at codespeak.net ac at codespeak.net
Fri Apr 28 09:40:12 CEST 2006


Author: ac
Date: Fri Apr 28 09:40:06 2006
New Revision: 26497

Modified:
   pypy/dist/pypy/annotation/binaryop.py
   pypy/dist/pypy/rpython/rctypes/avoid_p.py
   pypy/dist/pypy/rpython/rctypes/rstringbuf.py
   pypy/dist/pypy/rpython/rctypes/test/test_rstringbuf.py
Log:
(aleale, arre)
Support slicing and casting to pointer on stringbuffer.



Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py	(original)
+++ pypy/dist/pypy/annotation/binaryop.py	Fri Apr 28 09:40:06 2006
@@ -785,10 +785,13 @@
         pass
 
     def getitem((s_cto, s_slice)):
-        try:
-            listdef = ListDef(None, s_cto.knowntype._type_.annotator_type)
-        except AttributeError:
-            listdef = ListDef(None, SomeCTypesObject(s_cto.knowntype._type_))
+        result_ctype = s_cto.knowntype._type_
+        s_result = SomeCTypesObject(result_ctype,
+                                    memorystate=SomeCTypesObject.MEMORYALIAS)
+        list_item = s_result.return_annotation()
+        if isinstance(list_item, SomeChar):
+            return SomeString()
+        listdef = ListDef(None, list_item)
         return SomeList(listdef)
 
 class __extend__(pairtype(SomeCTypesObject, SomeCTypesObject)):

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 Apr 28 09:40:06 2006
@@ -2,7 +2,8 @@
 from pypy.rpython.rctypes.implementation import CTypesCallEntry, CTypesObjEntry
 from pypy.annotation.model import SomeCTypesObject
 
-from ctypes import c_void_p, c_int, POINTER, cast
+from ctypes import c_void_p, c_int, POINTER, cast, c_char, c_char_p
+from pypy.rpython.rctypes.astringbuf import StringBufferType
 
 PointerType = type(POINTER(c_int))
 
@@ -39,18 +40,27 @@
         assert s_type.is_constant(), (
             "cast(p, %r): argument 2 must be constant" % (s_type,))
         type = s_type.const
-        self.checkptr(s_arg.knowntype)
         self.checkptr(type)
+        if s_arg.knowntype == StringBufferType:
+            pass
+        else:
+            self.checkptr(s_arg.knowntype)
         return SomeCTypesObject(type, SomeCTypesObject.OWNSMEMORY)
 
     def specialize_call(self, hop):
         from pypy.rpython.rctypes.rpointer import PointerRepr
         from pypy.rpython.rctypes.rvoid_p import CVoidPRepr
+        from pypy.rpython.rctypes.rstringbuf import StringBufRepr
         from pypy.rpython.lltypesystem import lltype, llmemory
-        assert isinstance(hop.args_r[0], (PointerRepr, CVoidPRepr))
+        assert isinstance(hop.args_r[0], (PointerRepr, CVoidPRepr,
+                                          StringBufRepr))
         targetctype = hop.args_s[1].const
         v_box, c_targetctype = hop.inputargs(hop.args_r[0], lltype.Void)
-        v_adr = hop.args_r[0].getvalue(hop.llops, v_box)
+        if isinstance(hop.args_r[0], StringBufRepr):
+            v_index = hop.inputconst(lltype.Signed, 0)
+            v_adr = hop.args_r[0].get_c_data_of_item(hop.llops, v_box, v_index)
+        else:
+            v_adr = hop.args_r[0].getvalue(hop.llops, v_box)
         if v_adr.concretetype != llmemory.Address:
             v_adr = hop.genop('cast_ptr_to_adr', [v_adr],
                               resulttype = llmemory.Address)

Modified: pypy/dist/pypy/rpython/rctypes/rstringbuf.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rstringbuf.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rstringbuf.py	Fri Apr 28 09:40:06 2006
@@ -3,7 +3,8 @@
 from pypy.rpython.rmodel import IntegerRepr, inputconst
 from pypy.rpython.rctypes.rmodel import CTypesRefRepr
 from pypy.objspace.flow.model import Constant
-
+from pypy.rpython.rslice import AbstractSliceRepr
+from pypy.rpython.rstr import string_repr
 
 class StringBufRepr(CTypesRefRepr):
 
@@ -32,6 +33,7 @@
                                    resulttype = ONE_CHAR_PTR)
         return v_char_p
 
+
 ONE_CHAR_PTR = lltype.Ptr(lltype.FixedSizeArray(lltype.Char, 1))
 
 
@@ -49,5 +51,44 @@
         v_array = r_stringbuf.get_c_data(hop.llops, v_stringbuf)
         hop.genop('setarrayitem', [v_array, v_index, v_item])
 
+class __extend__(pairtype(StringBufRepr, AbstractSliceRepr)):
+    def rtype_getitem((r_stringbuf, r_slice), hop):
+        rs = r_stringbuf.rtyper.type_system.rslice
+        if r_slice == rs.startonly_slice_repr:
+            v_stringbuf, v_start = hop.inputargs(r_stringbuf, rs.startonly_slice_repr)
+            v_array = r_stringbuf.get_c_data(hop.llops, v_stringbuf)
+            return hop.gendirectcall(ll_slice_startonly, v_array, v_start)
+        if r_slice == rs.startstop_slice_repr:
+            v_stringbuf, v_slice = hop.inputargs(r_stringbuf, rs.startstop_slice_repr)
+            v_array = r_stringbuf.get_c_data(hop.llops, v_stringbuf)
+            return hop.gendirectcall(ll_slice, v_array, v_slice)
+        raise TyperError('getitem does not support slices with %r' % (r_slice,))
+
+def ll_slice_startonly(sbuf, start):
+    return ll_slice_start_stop(sbuf, start, len(sbuf))
+    
+def ll_slice(sbuf, slice):
+    return ll_slice_start_stop(sbuf, slice.start, slice.stop)
+
+def ll_slice_start_stop(sbuf, start, stop):
+    length = len(sbuf)
+    if start < 0:
+        start = length + start
+    if start < 0:
+        start = 0
+    if stop < 0:
+        stop = length + stop
+    if stop < 0:
+        stop = 0
+    if stop > length:
+        stop = length
+    if start > stop:
+        start = stop
+    newlength = stop - start
+    newstr = lltype.malloc(string_repr.lowleveltype.TO, newlength)
+    for i in range(newlength):
+        newstr.chars[i] = sbuf[start + i]
+    return newstr
+
 
 STRBUFTYPE = lltype.Array(lltype.Char)

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rstringbuf.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rstringbuf.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rstringbuf.py	Fri Apr 28 09:40:06 2006
@@ -12,7 +12,8 @@
 import sys
 from pypy.rpython.test.test_llinterp import interpret
 
-from ctypes import create_string_buffer, sizeof, c_int
+from ctypes import create_string_buffer, cast, POINTER, c_void_p, c_char
+from ctypes import c_char_p, c_long, pointer, sizeof, c_int
 from pypy.rpython.rctypes.astringbuf import StringBufferType
 
 
@@ -54,6 +55,33 @@
         if conftest.option.view:
             a.translator.view()
 
+    def test_annotate_slice(self):
+        def func(n):
+            buf = create_string_buffer(n)
+            buf[0] = 'x'
+            buf[1] = 'y'
+            return buf[:2]
+
+        a = RPythonAnnotator()
+        s = a.build_types(func, [int])
+        assert s == annmodel.SomeString()
+
+    def test_annotate_cast_to_ptr(self):
+        charp = POINTER(c_char)
+        def func(n):
+            buf = create_string_buffer(n)
+            buf[0] = 'x'
+            buf[1] = 'y'
+            buf[2] = 'z'
+            cp = cast(buf, charp)
+            vp = cast(buf, c_void_p)
+            return  cp[0] + cast(vp, charp)[2]
+        
+        a = RPythonAnnotator()
+        s = a.build_types(func, [int])
+        assert s == annmodel.SomeString()
+
+            
 class Test_specialization:
     def test_specialize_create(self):
         def func(n):
@@ -96,6 +124,31 @@
         res = interpret(func, [12])
         assert ''.join(res.chars) == "xy"
 
+    def test_specialize_slice(self):
+        def func(n):
+            buf = create_string_buffer(n)
+            buf[0] = 'x'
+            buf[1] = 'y'
+            buf[2] = 'z'
+            return buf[:2] + '_' + buf[1:3] + '_' + buf[9:]
+
+        res = interpret(func, [12])
+        assert ''.join(res.chars) == "xy_yz_\0\0\0"
+
+    def test_specialize_cast_to_ptr(self):
+        charp = POINTER(c_char)
+        def func(n):
+            buf = create_string_buffer(n)
+            buf[0] = 'x'
+            buf[1] = 'y'
+            buf[2] = 'z'
+            cp = cast(buf, charp)
+            vp = cast(buf, c_void_p)
+            return  cp[0] + '_' + cast(vp, charp)[2]
+        
+        res = interpret(func, [12])
+        assert ''.join(res.chars) == 'x_z'
+
     def test_specialize_sizeof(self):
         def func(n):
             buf = create_string_buffer(n)
@@ -117,3 +170,17 @@
         assert res[1] == sizeof(c_int) * 42
         assert res[2] == sizeof(c_int)
         assert res[3] == sizeof(c_int) * 42
+
+    def test_compile_cast_to_ptr(self):
+        charp = POINTER(c_char)
+        def func(n):
+            c_n = c_long(n)
+            c_n_ptr = cast(pointer(c_n), POINTER(c_char))
+            buf = create_string_buffer(sizeof(c_long))
+            for i in range(sizeof(c_long)):
+                buf[i] = c_n_ptr[i]
+            c_long_ptr = cast(buf, POINTER(c_long))
+            return c_long_ptr.contents.value
+        fn = compile(func, [int])
+        res = fn(0x12345678)
+        assert res == 0x12345678



More information about the Pypy-commit mailing list