[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