[pypy-commit] pypy stm: setarrayitem

arigo noreply at buildbot.pypy.org
Sat Nov 5 17:25:19 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: stm
Changeset: r48789:fb549313e992
Date: 2011-11-05 16:09 +0100
http://bitbucket.org/pypy/pypy/changeset/fb549313e992/

Log:	setarrayitem

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
@@ -6,8 +6,8 @@
 
 def _stm_generic_get(funcgen, op, expr):
     T = funcgen.lltypemap(op.result)
-    fieldtypename = funcgen.db.gettype(T)
-    cfieldtypename = cdecl(fieldtypename, '')
+    resulttypename = funcgen.db.gettype(T)
+    cresulttypename = cdecl(resulttypename, '')
     newvalue = funcgen.expr(op.result, special_case_void=False)
     #
     assert T is not lltype.Void     # XXX
@@ -25,7 +25,7 @@
         else:
             raise NotImplementedError(fieldsize)
         return '%s = (%s)%s((long*)&%s);' % (
-            newvalue, cfieldtypename, funcname, expr)
+            newvalue, cresulttypename, funcname, expr)
     else:
         STRUCT = funcgen.lltypemap(op.args[0]).TO
         if isinstance(STRUCT, lltype.Struct):
@@ -36,37 +36,18 @@
             basename = funcgen.expr(op.args[0])
             fieldname = op.args[1].value
             return '%s = STM_read_partial_word(%s, %s, offsetof(%s, %s));' % (
-                newvalue, cfieldtypename, basename,
+                newvalue, cresulttypename, basename,
                 cdecl(funcgen.db.gettype(STRUCT), ''),
                 structdef.c_struct_field_name(fieldname))
         #
         else:
             return '%s = stm_read_partial_word(sizeof(%s), &%s);' % (
-                newvalue, cfieldtypename, expr)
+                newvalue, cresulttypename, expr)
 
-def stm_getfield(funcgen, op):
-    STRUCT = funcgen.lltypemap(op.args[0]).TO
-    structdef = funcgen.db.gettypedefnode(STRUCT)
-    baseexpr_is_const = isinstance(op.args[0], Constant)
-    expr = structdef.ptr_access_expr(funcgen.expr(op.args[0]),
-                                     op.args[1].value,
-                                     baseexpr_is_const)
-    return _stm_generic_get(funcgen, op, expr)
-
-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)
+def _stm_generic_set(funcgen, op, targetexpr, T):
     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)
     #
-    expr = structdef.ptr_access_expr(basename,
-                                     fieldname,
-                                     baseexpr_is_const)
-    #
     assert T is not lltype.Void     # XXX
     fieldsize = rffi.sizeof(T)
     if fieldsize >= size_of_voidp or T == lltype.SingleFloat:
@@ -86,11 +67,32 @@
         else:
             raise NotImplementedError(fieldsize)
         return '%s((long*)&%s, (%s)%s);' % (
-            funcname, expr, newtype, newvalue)
+            funcname, targetexpr, newtype, newvalue)
     else:
-        cfieldtypename = cdecl(fieldtypename, '')
+        itemtypename = funcgen.db.gettype(T)
+        citemtypename = cdecl(itemtypename, '')
         return ('stm_write_partial_word(sizeof(%s), &%s, %s);' % (
-            cfieldtypename, expr, newvalue))
+            citemtypename, targetexpr, newvalue))
+
+
+def stm_getfield(funcgen, op):
+    STRUCT = funcgen.lltypemap(op.args[0]).TO
+    structdef = funcgen.db.gettypedefnode(STRUCT)
+    baseexpr_is_const = isinstance(op.args[0], Constant)
+    expr = structdef.ptr_access_expr(funcgen.expr(op.args[0]),
+                                     op.args[1].value,
+                                     baseexpr_is_const)
+    return _stm_generic_get(funcgen, op, expr)
+
+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)
+    expr = structdef.ptr_access_expr(funcgen.expr(op.args[0]),
+                                     op.args[1].value,
+                                     baseexpr_is_const)
+    T = op.args[2].concretetype
+    return _stm_generic_set(funcgen, op, expr, T)
 
 def stm_getarrayitem(funcgen, op):
     ARRAY = funcgen.lltypemap(op.args[0]).TO
@@ -100,6 +102,15 @@
     expr = arraydef.itemindex_access_expr(ptr, index)
     return _stm_generic_get(funcgen, op, expr)
 
+def stm_setarrayitem(funcgen, op):
+    ARRAY = funcgen.lltypemap(op.args[0]).TO
+    ptr = funcgen.expr(op.args[0])
+    index = funcgen.expr(op.args[1])
+    arraydef = funcgen.db.gettypedefnode(ARRAY)
+    expr = arraydef.itemindex_access_expr(ptr, index)
+    T = op.args[2].concretetype
+    return _stm_generic_set(funcgen, op, expr, T)
+
 
 def stm_begin_transaction(funcgen, op):
     return 'STM_begin_transaction();'
diff --git a/pypy/translator/stm/test/test_funcgen.py b/pypy/translator/stm/test/test_funcgen.py
--- a/pypy/translator/stm/test/test_funcgen.py
+++ b/pypy/translator/stm/test/test_funcgen.py
@@ -101,12 +101,25 @@
         assert array[i] == expected[i]
 check._annspecialcase_ = 'specialize:ll'
 
+def change(array, newvalues):
+    assert len(newvalues) <= len(array)
+    for i in range(len(newvalues)):
+        array[i] = rffi.cast(lltype.typeOf(array).TO.OF, newvalues[i])
+change._annspecialcase_ = 'specialize:ll'
+
 def do_stm_getarrayitem(argv):
     check(prebuilt_array_signed, [1, 10, -1, -10, 42])
     check(prebuilt_array_char,   [chr(1), chr(10), chr(255),
                                   chr(246), chr(42)])
     return 0
 
+def do_stm_setarrayitem(argv):
+    change(prebuilt_array_signed, [500000, -10000000, 3])
+    check(prebuilt_array_signed,  [500000, -10000000, 3, -10, 42])
+    change(prebuilt_array_char,   ['A', 'B', 'C'])
+    check(prebuilt_array_char,    ['A', 'B', 'C', chr(246), chr(42)])
+    return 0
+
 
 class TestFuncGen(CompiledSTMTests):
 
@@ -121,3 +134,7 @@
     def test_getarrayitem_all_sizes(self):
         t, cbuilder = self.compile(do_stm_getarrayitem)
         cbuilder.cmdexec('')
+
+    def test_setarrayitem_all_sizes(self):
+        t, cbuilder = self.compile(do_stm_setarrayitem)
+        cbuilder.cmdexec('')
diff --git a/pypy/translator/stm/transform.py b/pypy/translator/stm/transform.py
--- a/pypy/translator/stm/transform.py
+++ b/pypy/translator/stm/transform.py
@@ -140,7 +140,7 @@
             op1 = SpaceOperation('stm_getarrayitem', op.args, op.result)
         newoperations.append(op1)
 
-    def FINISHME_stt_setarrayitem(self, newoperations, op):
+    def stt_setarrayitem(self, newoperations, op):
         ARRAY = op.args[0].concretetype.TO
         if ARRAY._immutable_field():
             op1 = op


More information about the pypy-commit mailing list