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

Reply via email to