Commits

Armin Rigo  committed 38a95a2

Functions returning structs.

  • Participants
  • Parent commits 2540f3a
  • Branches ffi-backend

Comments (0)

Files changed (3)

File pypy/module/_cffi_backend/ctypefunc.py

 from pypy.module._cffi_backend.ctypeobj import W_CType
 from pypy.module._cffi_backend.ctypeptr import W_CTypePtrBase
 from pypy.module._cffi_backend.ctypevoid import W_CTypeVoid
+from pypy.module._cffi_backend.ctypestruct import W_CTypeStructOrUnion
 from pypy.module._cffi_backend import ctypeprim, ctypestruct, ctypearray
 from pypy.module._cffi_backend import cdataobj
 
 
             if isinstance(self.ctitem, W_CTypeVoid):
                 w_res = space.w_None
+            elif isinstance(self.ctitem, W_CTypeStructOrUnion):
+                w_res = self.ctitem.copy_and_convert_to_object(resultdata)
             else:
                 w_res = self.ctitem.convert_to_object(resultdata)
         finally:

File pypy/module/_cffi_backend/ctypestruct.py

         self.check_complete()
         return cdataobj.W_CData(space, cdata, self)
 
+    def copy_and_convert_to_object(self, cdata):
+        space = self.space
+        self.check_complete()
+        ob = cdataobj.W_CDataNewOwning(space, self.size, self)
+        # push push push at the llmemory interface (with hacks that
+        # are all removed after translation)
+        zero = llmemory.itemoffsetof(rffi.CCHARP.TO, 0)
+        llmemory.raw_memcopy(
+            llmemory.cast_ptr_to_adr(cdata) + zero,
+            llmemory.cast_ptr_to_adr(ob._cdata) + zero,
+            self.size * llmemory.sizeof(lltype.Char))
+        return ob
+
     def offsetof(self, fieldname):
         self.check_complete()
         try:

File pypy/module/_cffi_backend/newtype.py

             farg = farg.ctptr
         fargs.append(farg)
     #
-    if isinstance(fresult, ctypestruct.W_CTypeStructOrUnion):
-        raise OperationError(space.w_NotImplementedError,
-                         space.wrap("functions returning a struct or a union"))
     if ((fresult.size < 0 and not isinstance(fresult, ctypevoid.W_CTypeVoid))
             or isinstance(fresult, ctypearray.W_CTypeArray)):
         raise operationerrfmt(space.w_TypeError,