[pypy-svn] r26577 - in pypy/dist/pypy/rpython: lltypesystem rctypes rctypes/test
arigo at codespeak.net
arigo at codespeak.net
Sat Apr 29 16:11:28 CEST 2006
Author: arigo
Date: Sat Apr 29 16:11:26 2006
New Revision: 26577
Modified:
pypy/dist/pypy/rpython/lltypesystem/llmemory.py
pypy/dist/pypy/rpython/rctypes/rchar_p.py
pypy/dist/pypy/rpython/rctypes/rvoid_p.py
pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py
pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py
pypy/dist/pypy/rpython/rctypes/test/test_rvoid_p.py
Log:
Some more conversions to c_char_p and c_void_p.
Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/llmemory.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py Sat Apr 29 16:11:26 2006
@@ -267,6 +267,13 @@
class _char_fakeaccessor(_fakeaccessor):
TYPE = lltype.Char
+ def convert(self, value):
+ # hack to try to interpret the items of an array of bytes as chars
+ if lltype.typeOf(value) == lltype.Signed:
+ value = chr(value)
+ assert lltype.typeOf(value) == lltype.Char
+ return value
+
class _address_fakeaccessor(_fakeaccessor):
TYPE = Address
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 Sat Apr 29 16:11:26 2006
@@ -7,7 +7,7 @@
from pypy.rpython.rctypes.rstringbuf import StringBufRepr
from pypy.annotation.pairtype import pairtype
-from ctypes import c_char, c_char_p
+from ctypes import c_char, c_char_p, cast
class CCharPRepr(CTypesValueRepr):
@@ -34,6 +34,13 @@
def setstring(self, llops, v_box, v_str):
llops.gendirectcall(ll_setstring, v_box, v_str)
+ def convert_const(self, value):
+ if not isinstance(value, (str, c_char_p)):
+ # maybe an array of characters? cast to a c_char_p
+ assert type(value)._type_ == c_char
+ value = cast(value, c_char_p)
+ return super(CCharPRepr, self).convert_const(value)
+
def initialize_const(self, p, string):
if isinstance(string, c_char_p):
string = string.value
Modified: pypy/dist/pypy/rpython/rctypes/rvoid_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rvoid_p.py (original)
+++ pypy/dist/pypy/rpython/rctypes/rvoid_p.py Sat Apr 29 16:11:26 2006
@@ -1,27 +1,22 @@
from pypy.rpython.rctypes.rmodel import CTypesValueRepr, C_ZERO
from pypy.rpython.rctypes.rstringbuf import StringBufRepr
from pypy.annotation.pairtype import pairtype
+from pypy.rpython.rstr import AbstractStringRepr
+from pypy.rpython.lltypesystem.rstr import string_repr
from pypy.rpython.rctypes.rchar_p import CCharPRepr
-from pypy.rpython.lltypesystem import llmemory
+from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.rctypes.rpointer import PointerRepr
+from pypy.rpython.rctypes.rarray import ArrayRepr
class CVoidPRepr(CTypesValueRepr):
- pass # No operations supported on c_void_p instances so far
+ def convert_const(self, value):
+ if isinstance(value, self.ctype):
+ return super(CVoidPRepr, self).convert_const(value)
+ raise NotImplementedError("XXX constant pointer passed to void* arg")
-class __extend__(pairtype(StringBufRepr, CVoidPRepr)):
- def convert_from_to((r_from, r_to), v, llops):
- # warning: no keepalives, only for short-lived conversions like
- # in argument passing
- r_temp = r_to.r_memoryowner
- v_owned_box = r_temp.allocate_instance(llops)
- v_c_array = r_from.get_c_data_of_item(llops, v, C_ZERO)
- v_adr = llops.genop('cast_ptr_to_adr', [v_c_array],
- resulttype = llmemory.Address)
- r_temp.setvalue(llops, v_owned_box, v_adr)
- return llops.convertvar(v_owned_box, r_temp, r_to)
- # XXX some code duplication above
-class __extend__(pairtype(CCharPRepr, CVoidPRepr)):
+class __extend__(pairtype(CCharPRepr, CVoidPRepr),
+ pairtype(PointerRepr, CVoidPRepr)):
def convert_from_to((r_from, r_to), v, llops):
v_ptr = r_from.getvalue(llops, v)
v_adr = llops.genop('cast_ptr_to_adr', [v_ptr],
@@ -29,11 +24,27 @@
return r_to.return_value(llops, v_adr)
-class __extend__(pairtype(PointerRepr, CVoidPRepr)):
+class __extend__(pairtype(StringBufRepr, CVoidPRepr),
+ pairtype(ArrayRepr, CVoidPRepr)):
def convert_from_to((r_from, r_to), v, llops):
- v_ptr = r_from.getvalue(llops, v)
+ v_ptr = r_from.get_c_data_of_item(llops, v, C_ZERO)
v_adr = llops.genop('cast_ptr_to_adr', [v_ptr],
resulttype = llmemory.Address)
return r_to.return_value(llops, v_adr)
+class __extend__(pairtype(AbstractStringRepr, CVoidPRepr)):
+ def convert_from_to((r_from, r_to), v, llops):
+ # warning: no keepalives, only for short-lived conversions like
+ # in argument passing
+ # r_from could be char_repr: first convert it to string_repr
+ v = llops.convertvar(v, r_from, string_repr)
+ v_adr = llops.gendirectcall(ll_string2addr, v)
+ return r_to.return_value(llops, v_adr)
+
+def ll_string2addr(s):
+ if s:
+ ptr = lltype.direct_arrayitems(s.chars)
+ return llmemory.cast_ptr_to_adr(ptr)
+ else:
+ return llmemory.NULL
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 Sat Apr 29 16:11:26 2006
@@ -174,26 +174,59 @@
assert x.value == 42
def test_pythonapi():
- pythonapi.PyInt_AsLong.argtypes = [py_object]
- pythonapi.PyInt_AsLong.restype = c_long
- assert pythonapi.PyInt_AsLong(py_object(17L)) == 17
- py.test.raises(TypeError, "pythonapi.PyInt_AsLong(py_object('hello'))")
+ PyInt_AsLong = pythonapi.PyInt_AsLong
+ saved = PyInt_AsLong.__dict__.copy()
+ try:
+ PyInt_AsLong.argtypes = [py_object]
+ PyInt_AsLong.restype = c_long
+ assert PyInt_AsLong(py_object(17L)) == 17
+ py.test.raises(TypeError, "PyInt_AsLong(py_object('hello'))")
+ finally:
+ PyInt_AsLong.__dict__ = saved
def test_py_object_subclass():
- # automatic unwrapping of the py_object result
- pythonapi.PyInt_FromLong.argtypes = [c_long]
- pythonapi.PyInt_FromLong.restype = py_object
- assert isinstance(pythonapi.PyInt_FromLong(17), int)
-
- # but not if we subclass it...
- class W_Object(py_object):
- pass
- pythonapi.PyInt_FromLong.argtypes = [c_long]
- pythonapi.PyInt_FromLong.restype = W_Object
- assert isinstance(pythonapi.PyInt_FromLong(17), W_Object)
+ PyInt_FromLong = pythonapi.PyInt_FromLong
+ saved = PyInt_FromLong.__dict__.copy()
+ try:
+ # automatic unwrapping of the py_object result
+ PyInt_FromLong.argtypes = [c_long]
+ PyInt_FromLong.restype = py_object
+ assert isinstance(PyInt_FromLong(17), int)
+
+ # but not if we subclass it...
+ class W_Object(py_object):
+ pass
+ PyInt_FromLong.argtypes = [c_long]
+ PyInt_FromLong.restype = W_Object
+ assert isinstance(PyInt_FromLong(17), W_Object)
+ finally:
+ PyInt_FromLong.__dict__ = saved
def test_sizeof():
x = create_string_buffer(117)
assert sizeof(x) == 117 # assumes that chars are one byte each
x = (c_int * 42)()
assert sizeof(x) == 42 * sizeof(c_int)
+
+def test_convert_pointers():
+ PyString_FromString = pythonapi.PyString_FromString
+ saved = PyString_FromString.__dict__.copy()
+ try:
+ PyString_FromString.restype = py_object
+
+ # automatic conversions to c_char_p
+ PyString_FromString.argtypes = [c_char_p]
+ assert PyString_FromString("hello") == "hello"
+ assert PyString_FromString(c_char_p("hello")) == "hello"
+ assert PyString_FromString((c_char * 6)(*"hello")) == "hello"
+ assert PyString_FromString(create_string_buffer("hello")) == "hello"
+
+ # automatic conversions to c_void_p
+ PyString_FromString.argtypes = [c_void_p]
+ assert PyString_FromString("hello") == "hello"
+ assert PyString_FromString(c_char_p("hello")) == "hello"
+ assert PyString_FromString((c_char * 6)(*"hello")) == "hello"
+ assert PyString_FromString((c_byte * 6)(104,101,108,108,111)) =="hello"
+ assert PyString_FromString(create_string_buffer("hello")) == "hello"
+ finally:
+ PyString_FromString.__dict__ = saved
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 Sat Apr 29 16:11:26 2006
@@ -13,6 +13,7 @@
from pypy.rpython.test.test_llinterp import interpret
from ctypes import c_char_p, pointer, Structure
+from ctypes import c_int, c_char, create_string_buffer, CFUNCTYPE
class Test_annotation:
def test_annotate_c_char_p(self):
@@ -111,6 +112,31 @@
assert not c_char_p(None)
interpret(func, [])
+ def test_convert_pointers(self):
+ from pypy.rpython.rctypes.rchar_p import ll_strlen
+ strlen = CFUNCTYPE(c_int, c_char_p)() # not directly executable!
+ strlen.__name__ = 'strlen'
+ strlen.llinterp_friendly_version = ll_strlen
+ PTR = c_char_p("hello")
+ BUF = create_string_buffer(10)
+ BUF.value = "hello"
+
+ def func(n):
+ # constant arguments
+ assert strlen("hello") == 5
+ assert strlen(PTR) == 5
+ assert strlen(BUF) == 5
+ # variable arguments
+ s = chr(n) + 'bc'
+ assert strlen(s) == 3
+ assert strlen(c_char_p(s)) == 3
+ assert strlen((c_char * 6)('a', 'b')) == 2
+ buf = create_string_buffer(10)
+ buf.value = "hello"
+ assert strlen(buf) == 5
+
+ interpret(func, [65])
+
class Test_compilation:
def test_compile_c_char_p(self):
def func():
Modified: pypy/dist/pypy/rpython/rctypes/test/test_rvoid_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rvoid_p.py (original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rvoid_p.py Sat Apr 29 16:11:26 2006
@@ -12,6 +12,7 @@
from pypy.rpython.test.test_llinterp import interpret
from ctypes import c_void_p, c_int, cast, pointer, POINTER
+from ctypes import c_char, c_byte, c_char_p, create_string_buffer, CFUNCTYPE
class Test_annotation:
def test_annotate_c_void_p(self):
@@ -48,6 +49,38 @@
assert not c_void_p()
interpret(func, [])
+ def test_convert_pointers(self):
+ strlen = CFUNCTYPE(c_int, c_void_p)()
+ strlen.__name__ = 'strlen'
+ def ll_strlen_from_void_p(adr):
+ i = 0
+ while adr.char[i] != '\x00':
+ i += 1
+ return i
+ strlen.llinterp_friendly_version = ll_strlen_from_void_p
+ PTR = c_char_p("hello")
+ BUF = create_string_buffer(10)
+ BUF.value = "hello"
+ ARR = (c_byte * 10)(65, 66, 67)
+
+ def func(n):
+ # constant arguments XXX in-progress
+ ## assert strlen("hello") == 5
+ ## assert strlen(PTR) == 5
+ ## assert strlen(BUF) == 5
+ ## assert strlen(ARR) == 3
+ # variable arguments
+ s = chr(n) + 'bc'
+ assert strlen(s) == 3
+ assert strlen(c_char_p(s)) == 3
+ assert strlen((c_char * 6)('a', 'b')) == 2
+ assert strlen((c_byte * 6)(104,101,108,108,111)) == 5
+ buf = create_string_buffer(10)
+ buf.value = "hello"
+ assert strlen(buf) == 5
+
+ interpret(func, [65])
+
class Test_compilation:
def test_compile_c_char_p(self):
def func():
More information about the Pypy-commit
mailing list