[pypy-svn] r78094 - in pypy/trunk/pypy/module/_rawffi: . test

arigo at codespeak.net arigo at codespeak.net
Tue Oct 19 18:18:28 CEST 2010


Author: arigo
Date: Tue Oct 19 18:18:27 2010
New Revision: 78094

Modified:
   pypy/trunk/pypy/module/_rawffi/structure.py
   pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py
Log:
Support unions with explicit fields, like we support structs
with explicit fields.


Modified: pypy/trunk/pypy/module/_rawffi/structure.py
==============================================================================
--- pypy/trunk/pypy/module/_rawffi/structure.py	(original)
+++ pypy/trunk/pypy/module/_rawffi/structure.py	Tue Oct 19 18:18:27 2010
@@ -34,7 +34,7 @@
 def round_up(size, alignment):
     return (size + alignment - 1) & -alignment
 
-def size_alignment_pos(fields):
+def size_alignment_pos(fields, is_union=False):
     size = 0
     alignment = 1
     pos = []
@@ -42,16 +42,20 @@
         # fieldtype is a W_Array
         fieldsize = fieldtype.size
         fieldalignment = fieldtype.alignment
-        size = round_up(size, fieldalignment)
         alignment = max(alignment, fieldalignment)
-        pos.append(size)
-        size += intmask(fieldsize)
+        if is_union:
+            pos.append(0)
+            size = max(size, fieldsize)
+        else:
+            size = round_up(size, fieldalignment)
+            pos.append(size)
+            size += intmask(fieldsize)
     size = round_up(size, alignment)
     return size, alignment, pos
 
 
 class W_Structure(W_DataShape):
-    def __init__(self, space, fields, size, alignment):
+    def __init__(self, space, fields, size, alignment, is_union=False):
         name_to_index = {}
         if fields is not None:
             for i in range(len(fields)):
@@ -60,7 +64,7 @@
                     raise operationerrfmt(space.w_ValueError,
                         "duplicate field name %s", name)
                 name_to_index[name] = i
-            size, alignment, pos = size_alignment_pos(fields)
+            size, alignment, pos = size_alignment_pos(fields, is_union)
         else: # opaque case
             fields = []
             pos = []
@@ -69,6 +73,7 @@
         self.alignment = alignment                
         self.ll_positions = pos
         self.name_to_index = name_to_index
+        self.is_union = is_union
 
     def allocate(self, space, length, autofree=False):
         # length is ignored!
@@ -133,15 +138,17 @@
     
 
 
-def descr_new_structure(space, w_type, w_shapeinfo):
+def descr_new_structure(space, w_type, w_shapeinfo, union=0):
+    is_union = bool(union)
     if space.is_true(space.isinstance(w_shapeinfo, space.w_tuple)):
         w_size, w_alignment = space.fixedview(w_shapeinfo, expected_length=2)
         S = W_Structure(space, None, space.int_w(w_size),
-                                     space.int_w(w_alignment))
+                                     space.int_w(w_alignment), is_union)
     else:
         fields = unpack_fields(space, w_shapeinfo)
-        S = W_Structure(space, fields, 0, 0)
+        S = W_Structure(space, fields, 0, 0, is_union)
     return space.wrap(S)
+descr_new_structure.unwrap_spec = [ObjSpace, W_Root, W_Root, int]
 
 W_Structure.typedef = TypeDef(
     'Structure',

Modified: pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py
==============================================================================
--- pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py	(original)
+++ pypy/trunk/pypy/module/_rawffi/test/test__rawffi.py	Tue Oct 19 18:18:27 2010
@@ -945,14 +945,15 @@
         assert a[4] == 't'
 
     def test_union(self):
-        skip("segfaulting")
         import _rawffi
         longsize = _rawffi.sizeof('l')
-        S = _rawffi.Structure((longsize, longsize))
+        S = _rawffi.Structure([('x', 'h'), ('y', 'l')], union=True)
         s = S(autofree=False)
+        s.x = 12345
         lib = _rawffi.CDLL(self.lib_name)
         f = lib.ptr('ret_un_func', [(S, 1)], (S, 1))
         ret = f(s)
+        assert ret.y == 1234500, "ret.y == %d" % (ret.y,)
         s.free()
 
 class AppTestAutoFree:



More information about the Pypy-commit mailing list