[pypy-svn] r26572 - in pypy/dist/pypy: rpython/rctypes rpython/rctypes/test translator/c

arigo at codespeak.net arigo at codespeak.net
Sat Apr 29 12:07:22 CEST 2006


Author: arigo
Date: Sat Apr 29 12:07:21 2006
New Revision: 26572

Modified:
   pypy/dist/pypy/rpython/rctypes/rstruct.py
   pypy/dist/pypy/rpython/rctypes/test/_rctypes_test.c
   pypy/dist/pypy/rpython/rctypes/test/test_rctypes.py
   pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py
   pypy/dist/pypy/translator/c/node.py
Log:
Support for C struct field names that start with '_'.


Modified: pypy/dist/pypy/rpython/rctypes/rstruct.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rstruct.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rstruct.py	Sat Apr 29 12:07:21 2006
@@ -17,7 +17,7 @@
             r_field = rtyper.getrepr(SomeCTypesObject(field_ctype,
                                                 SomeCTypesObject.MEMORYALIAS))
             self.r_fields[name] = r_field
-            llfields.append((name, r_field.ll_type))
+            llfields.append((cmangle(name), r_field.ll_type))
 
         # Here, self.c_data_type == self.ll_type
         external = getattr(struct_ctype, '_external_', False)
@@ -30,11 +30,11 @@
     def get_content_keepalive_type(self):
         "An extra struct of keepalives, one per field."
         keepalives = []
-        for name in self.c_data_type._names:
+        for name, field_ctype in self.ctype._fields_:
             r_field = self.r_fields[name]
             field_keepalive_type = r_field.get_content_keepalive_type()
             if field_keepalive_type:
-                keepalives.append((name, field_keepalive_type))
+                keepalives.append((cmangle(name), field_keepalive_type))
         if not keepalives:
             return None
         else:
@@ -45,15 +45,15 @@
             llitem = r_field.convert_const(getattr(value, name))
             if isinstance(r_field, CTypesRefRepr):
                 # ByRef case
-                reccopy(llitem.c_data, getattr(p.c_data, name))
+                reccopy(llitem.c_data, getattr(p.c_data, cmangle(name)))
             else:
                 # ByValue case
-                setattr(p.c_data, name, llitem.c_data[0])
+                setattr(p.c_data, cmangle(name), llitem.c_data[0])
 
     def get_c_data_of_field(self, llops, v_struct, fieldname):
         v_c_struct = self.get_c_data(llops, v_struct)
         r_field = self.r_fields[fieldname]
-        c_fieldname = inputconst(lltype.Void, fieldname)
+        c_fieldname = inputconst(lltype.Void, cmangle(fieldname))
         if isinstance(r_field, CTypesRefRepr):
             # ByRef case
             return llops.genop('getsubstruct', [v_c_struct, c_fieldname],
@@ -69,7 +69,7 @@
         r_field = self.r_fields[fieldname]
         assert isinstance(r_field, CTypesValueRepr)
         v_c_struct = self.get_c_data(llops, v_struct)
-        c_fieldname = inputconst(lltype.Void, fieldname)
+        c_fieldname = inputconst(lltype.Void, cmangle(fieldname))
         return llops.genop('getfield', [v_c_struct, c_fieldname],
                            resulttype = r_field.ll_type)
 
@@ -112,10 +112,15 @@
         v_newvalue = r_field.get_c_data_or_value(llops, v_item)
         # copy the new value (which might be a whole substructure)
         v_c_struct = self.get_c_data(llops, v_struct)
-        genreccopy_structfield(llops, v_newvalue, v_c_struct, name)
+        genreccopy_structfield(llops, v_newvalue, v_c_struct, cmangle(name))
         # copy the keepalive information too
         v_newkeepalive = r_field.getkeepalive(llops, v_item)
         if v_newkeepalive is not None:
             v_keepalive_struct = self.getkeepalive(llops, v_struct)
             genreccopy_structfield(llops, v_newkeepalive,
-                                   v_keepalive_struct, name)
+                                   v_keepalive_struct, cmangle(name))
+
+def cmangle(name):
+    # obscure: names starting with '_' are not allowed in
+    # lltype.Struct, so we prefix all names with 'c_'
+    return 'c_' + name

Modified: pypy/dist/pypy/rpython/rctypes/test/_rctypes_test.c
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/_rctypes_test.c	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/_rctypes_test.c	Sat Apr 29 12:07:21 2006
@@ -17,6 +17,7 @@
 typedef struct tagpoint {
 	int x;
 	int y;
+	int _z;
 } point;
 
 EXPORT(int) _testfunc_byval(point in, point *pout)
@@ -34,6 +35,7 @@
     int tmp = p->x;
     p->x = p->y;
     p->y = tmp;
+    p->_z++;
 }
 
 EXPORT(int) _testfunc_struct(point in)

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rctypes.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rctypes.py	Sat Apr 29 12:07:21 2006
@@ -41,7 +41,8 @@
 # struct tagpoint
 class tagpoint(Structure):
     _fields_ = [("x", c_int),
-                ("y", c_int)]
+                ("y", c_int),
+                ("_z", c_int)]
     _external_ = True       # hack to avoid redeclaration of the struct in C
 
 # _test_struct
@@ -50,7 +51,7 @@
 testfunc_struct.argtypes = [tagpoint]
 
 def ll_testfunc_struct(in_):
-    return in_.x + in_.y
+    return in_.c_x + in_.c_y
 testfunc_struct.llinterp_friendly_version = ll_testfunc_struct
 testfunc_struct.includes = includes
 
@@ -61,9 +62,9 @@
 
 def ll_testfunc_byval(in_, pout):
     if pout:
-        pout.x = in_.x
-        pout.y = in_.y
-    return in_.x + in_.y
+        pout.c_x = in_.c_x
+        pout.c_y = in_.c_y
+    return in_.c_x + in_.c_y
 testfunc_byval.llinterp_friendly_version = ll_testfunc_byval
 testfunc_byval.includes = includes
 
@@ -91,7 +92,8 @@
 testfunc_swap.argtypes = [tagpointptr]
 
 def ll_testfunc_swap(p):
-    p.x, p.y = p.y, p.x
+    p.c_x, p.c_y = p.c_y, p.c_x
+    p.c__z += 1
 testfunc_swap.llinterp_friendly_version = ll_testfunc_swap
 testfunc_swap.includes = includes
 
@@ -133,9 +135,11 @@
     pt = tagpoint()
     pt.x = 5
     pt.y = 9
+    pt._z = 99
     testfunc_swap(pointer(pt))
     assert pt.x == 9
     assert pt.y == 5
+    assert pt._z == 100
     return pt.x - pt.y                   # this test function is reused below
 
 class Test_annotation:

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py	Sat Apr 29 12:07:21 2006
@@ -100,8 +100,8 @@
 
         res = interpret(create_struct, [])
         c_data = res.c_data
-        assert c_data.x == 0
-        assert c_data.y == 0
+        assert c_data.c_x == 0
+        assert c_data.c_y == 0
 
     def test_specialize_struct_access(self):
         def access_struct(n):
@@ -198,14 +198,14 @@
             return (s0, s1, s2, s3)
 
         res = interpret(func, [4, '?'])
-        assert res.item0.c_data.x == 4
-        assert res.item0.c_data.y == '\x00'
-        assert res.item1.c_data.x == 4
-        assert res.item1.c_data.y == '?'
-        assert res.item2.c_data.x == 0
-        assert res.item2.c_data.y == '?'
-        assert res.item3.c_data.x == 4
-        assert res.item3.c_data.y == '?'
+        assert res.item0.c_data.c_x == 4
+        assert res.item0.c_data.c_y == '\x00'
+        assert res.item1.c_data.c_x == 4
+        assert res.item1.c_data.c_y == '?'
+        assert res.item2.c_data.c_x == 0
+        assert res.item2.c_data.c_y == '?'
+        assert res.item3.c_data.c_x == 4
+        assert res.item3.c_data.c_y == '?'
 
     def test_specialize_bad_constructor_args(self):
         class S(Structure):

Modified: pypy/dist/pypy/translator/c/node.py
==============================================================================
--- pypy/dist/pypy/translator/c/node.py	(original)
+++ pypy/dist/pypy/translator/c/node.py	Sat Apr 29 12:07:21 2006
@@ -46,7 +46,7 @@
             with_number = False
         if STRUCT._hints.get('c_name'):
             self.barename = self.name = STRUCT._hints['c_name']
-            self.prefix = ''
+            self.c_struct_field_name = self.verbatim_field_name
         else:
             (self.barename,
              self.name) = db.namespace.uniquename(basename,
@@ -93,8 +93,14 @@
         return 'struct %s @' % self.name
 
     def c_struct_field_name(self, name):
+        # occasionally overridden in __init__():
+        #    self.c_struct_field_name = self.verbatim_field_name
         return self.prefix + name
 
+    def verbatim_field_name(self, name):
+        assert name.startswith('c_')   # produced in this way by rctypes
+        return name[2:]
+
     def c_struct_field_type(self, name):
         return self.STRUCT._flds[name]
 



More information about the Pypy-commit mailing list