[pypy-commit] pypy stm: stm_setfield.

arigo noreply at buildbot.pypy.org
Tue Sep 27 21:53:21 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: stm
Changeset: r47637:6baab137c312
Date: 2011-09-27 21:53 +0200
http://bitbucket.org/pypy/pypy/changeset/6baab137c312/

Log:	stm_setfield.

diff --git a/pypy/translator/stm/funcgen.py b/pypy/translator/stm/funcgen.py
--- a/pypy/translator/stm/funcgen.py
+++ b/pypy/translator/stm/funcgen.py
@@ -34,6 +34,34 @@
             cdecl(funcgen.db.gettype(STRUCT), ''),
             structdef.c_struct_field_name(fieldname))
 
+def stm_setfield(funcgen, op):
+    STRUCT = funcgen.lltypemap(op.args[0]).TO
+    structdef = funcgen.db.gettypedefnode(STRUCT)
+    baseexpr_is_const = isinstance(op.args[0], Constant)
+    basename = funcgen.expr(op.args[0])
+    fieldname = op.args[1].value
+    T = funcgen.lltypemap(op.args[2])
+    fieldtypename = funcgen.db.gettype(T)
+    newvalue = funcgen.expr(op.args[2], special_case_void=False)
+    #
+    assert T is not lltype.Void     # XXX
+    fieldsize = rffi.sizeof(T)
+    if fieldsize >= size_of_voidp:
+        assert 1      # xxx assert somehow that the field is aligned
+        assert fieldsize == size_of_voidp     # XXX
+        expr = structdef.ptr_access_expr(basename,
+                                         fieldname,
+                                         baseexpr_is_const)
+        return 'stm_write_word((long*)&%s, (long)%s);' % (
+            expr, newvalue)
+    else:
+        cfieldtypename = cdecl(fieldtypename, '')
+        return ('stm_write_partial_word(sizeof(%s), (char*)%s, '
+                'offsetof(%s, %s), (long)%s);' % (
+            cfieldtypename, basename,
+            cdecl(funcgen.db.gettype(STRUCT), ''),
+            structdef.c_struct_field_name(fieldname), newvalue))
+
 
 def op_stm(funcgen, op):
     func = globals()[op.opname]
diff --git a/pypy/translator/stm/rstm.py b/pypy/translator/stm/rstm.py
--- a/pypy/translator/stm/rstm.py
+++ b/pypy/translator/stm/rstm.py
@@ -12,6 +12,7 @@
 
 
 def stm_getfield(structptr, fieldname):
+    "NOT_RPYTHON"
     STRUCT = lltype.typeOf(structptr).TO
     FIELD = getattr(STRUCT, fieldname)
     p = lltype.direct_fieldptr(structptr, fieldname)
@@ -30,6 +31,7 @@
     return rffi.cast(FIELD, res)
 
 def stm_setfield(structptr, fieldname, newvalue):
+    "NOT_RPYTHON"
     STRUCT = lltype.typeOf(structptr).TO
     FIELD = getattr(STRUCT, fieldname)
     p = lltype.direct_fieldptr(structptr, fieldname)
@@ -49,7 +51,7 @@
         val = rffi.cast(lltype.Signed, newvalue)
         val = val << (misalignment * 8)
         word = _rffi_stm.stm_read_word(p)
-        mask = (1 << (misalignment * 8)) * ((1 << (fieldsize * 8)) - 1)
+        mask = ((1 << (fieldsize * 8)) - 1) << (misalignment * 8)
         val = (val & mask) | (word & ~mask)
         #print 'getting %x, mask=%x, replacing with %x' % (word, mask, val)
         _rffi_stm.stm_write_word(p, val)
diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c
--- a/pypy/translator/stm/src_stm/et.c
+++ b/pypy/translator/stm/src_stm/et.c
@@ -750,3 +750,15 @@
 {
   tx_abort(7);     /* manual abort */
 }
+
+// XXX little-endian only!
+void stm_write_partial_word(int fieldsize, char *base, long offset, long nval)
+{
+  long *p = (long*)(base + (offset & ~(sizeof(void*)-1)));
+  int misalignment = offset & (sizeof(void*)-1);
+  long val = nval << (misalignment * 8);
+  long word = stm_read_word(p);
+  long mask = ((1 << (fieldsize * 8)) - 1) << (misalignment * 8);
+  val = (val & mask) | (word & ~mask);
+  stm_write_word(p, val);
+}
diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h
--- a/pypy/translator/stm/src_stm/et.h
+++ b/pypy/translator/stm/src_stm/et.h
@@ -33,5 +33,7 @@
            (long*)(((char*)(base)) + ((offset) & ~(sizeof(void*)-1))))  \
         >> (8 * ((offset) & (sizeof(void*)-1))))
 
+void stm_write_partial_word(int fieldsize, char *base, long offset, long nval);
+
 
 #endif  /* _ET_H */


More information about the pypy-commit mailing list