Author: Armin Rigo <[email protected]>
Branch: ffi-backend
Changeset: r55764:e46d22d6f19f
Date: 2012-06-23 10:24 +0200
http://bitbucket.org/pypy/pypy/changeset/e46d22d6f19f/
Log: Starting arrays.
diff --git a/pypy/module/_ffi_backend/__init__.py
b/pypy/module/_ffi_backend/__init__.py
--- a/pypy/module/_ffi_backend/__init__.py
+++ b/pypy/module/_ffi_backend/__init__.py
@@ -11,6 +11,7 @@
'new_primitive_type': 'newtype.new_primitive_type',
'new_pointer_type': 'newtype.new_pointer_type',
+ 'new_array_type': 'newtype.new_array_type',
'newp': 'func.newp',
'cast': 'func.cast',
diff --git a/pypy/module/_ffi_backend/cdataobj.py
b/pypy/module/_ffi_backend/cdataobj.py
--- a/pypy/module/_ffi_backend/cdataobj.py
+++ b/pypy/module/_ffi_backend/cdataobj.py
@@ -80,8 +80,9 @@
space = self.space
i = space.getindex_w(w_index, space.w_IndexError)
self.ctype._check_subscript_index(self, i)
- citem = self.ctype.ctypeitem
- w_o = citem.convert_to_object(rffi.ptradd(self._cdata, i * citem.size))
+ ctitem = self.ctype.ctitem
+ w_o = ctitem.convert_to_object(
+ rffi.ptradd(self._cdata, i * ctitem.size))
keepalive_until_here(self)
return w_o
diff --git a/pypy/module/_ffi_backend/ctypeobj.py
b/pypy/module/_ffi_backend/ctypeobj.py
--- a/pypy/module/_ffi_backend/ctypeobj.py
+++ b/pypy/module/_ffi_backend/ctypeobj.py
@@ -64,16 +64,18 @@
class W_CTypePtrOrArray(W_CType):
- pass
+
+ def __init__(self, space, size, extra, extra_position, ctitem):
+ name, name_position = ctitem.insert_name(extra, extra_position)
+ W_CType.__init__(self, space, size, name, name_position)
+ self.ctitem = ctitem
class W_CTypePointer(W_CTypePtrOrArray):
- def __init__(self, space, ctypeitem):
- name, name_position = ctypeitem.insert_name(' *', 2)
+ def __init__(self, space, ctitem):
size = rffi.sizeof(rffi.VOIDP)
- W_CType.__init__(self, space, size, name, name_position)
- self.ctypeitem = ctypeitem
+ W_CTypePtrOrArray.__init__(self, space, size, ' *', 2, ctitem)
def cast(self, w_ob):
space = self.space
@@ -91,15 +93,15 @@
def newp(self, w_init):
space = self.space
- citem = self.ctypeitem
- datasize = citem.size
+ ctitem = self.ctitem
+ datasize = ctitem.size
if datasize < 0:
xxx
- if isinstance(citem, W_CTypePrimitiveChar):
+ if isinstance(ctitem, W_CTypePrimitiveChar):
datasize *= 2 # forcefully add a null character
cdata = cdataobj.W_CDataOwn(space, datasize, self)
if not space.is_w(w_init, space.w_None):
- citem.convert_from_object(cdata._cdata, w_init)
+ ctitem.convert_from_object(cdata._cdata, w_init)
keepalive_until_here(cdata)
return cdata
@@ -111,6 +113,14 @@
self.name)
+class W_CTypeArray(W_CTypePtrOrArray):
+
+ def __init__(self, space, ctptr, length, arraysize, extra):
+ W_CTypePtrOrArray.__init__(self, space, arraysize, extra, 0,
+ ctptr.ctitem)
+ self.ctptr = ctptr
+
+
class W_CTypePrimitive(W_CType):
def cast_single_char(self, w_ob):
diff --git a/pypy/module/_ffi_backend/newtype.py
b/pypy/module/_ffi_backend/newtype.py
--- a/pypy/module/_ffi_backend/newtype.py
+++ b/pypy/module/_ffi_backend/newtype.py
@@ -1,6 +1,7 @@
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter.gateway import unwrap_spec
from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.rlib.rarithmetic import ovfcheck
from pypy.module._ffi_backend import ctypeobj
@@ -42,3 +43,34 @@
def new_pointer_type(space, ctype):
ctypeptr = ctypeobj.W_CTypePointer(space, ctype)
return ctypeptr
+
+# ____________________________________________________________
+
+@unwrap_spec(ctptr=ctypeobj.W_CType)
+def new_array_type(space, ctptr, w_length):
+ if not isinstance(ctptr, ctypeobj.W_CTypePointer):
+ raise OperationError(space.w_TypeError,
+ space.wrap("first arg must be a pointer ctype"))
+ ctitem = ctptr.ctitem
+ if ctitem.size < 0:
+ raise operationerrfmt(space.w_ValueError,
+ "array item of unknown size: '%s'",
+ ctitem.name)
+ if space.is_w(w_length, space.w_None):
+ length = -1
+ arraysize = -1
+ extra = '[]'
+ else:
+ length = space.getindex_w(w_length, space.w_OverflowError)
+ if length < 0:
+ raise OperationError(space.w_ValueError,
+ space.wrap("negative array length"))
+ try:
+ arraysize = ovfcheck(length * ctitem.size)
+ except OverflowError:
+ raise OperationError(space.w_OverflowError,
+ space.wrap("array size would overflow a ssize_t"))
+ extra = '[%d]' % length
+ #
+ ctypeptr = ctypeobj.W_CTypeArray(space, ctptr, length, arraysize, extra)
+ return ctypeptr
diff --git a/pypy/module/_ffi_backend/test/test_c.py
b/pypy/module/_ffi_backend/test/test_c.py
--- a/pypy/module/_ffi_backend/test/test_c.py
+++ b/pypy/module/_ffi_backend/test/test_c.py
@@ -52,6 +52,7 @@
tmpname2 = tmpdir.join('_all_test_c.py')
with tmpname2.open('w') as f:
+ print >> f, 'import sys'
print >> f, 'from _ffi_backend import %s' % all_names
print >> f, 'class py:'
print >> f, ' class test:'
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit