[pypy-svn] r29308 - in pypy/dist/pypy/rpython/lltypesystem: . test

arigo at codespeak.net arigo at codespeak.net
Sun Jun 25 12:50:36 CEST 2006


Author: arigo
Date: Sun Jun 25 12:50:33 2006
New Revision: 29308

Modified:
   pypy/dist/pypy/rpython/lltypesystem/lloperation.py
   pypy/dist/pypy/rpython/lltypesystem/opimpl.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_lloperation.py
Log:
Allow constant-folding getfield and getarrayitem when 'immutable'.


Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py	Sun Jun 25 12:50:33 2006
@@ -52,12 +52,16 @@
             return fold(*args)
 
     def fold(self, RESULTTYPE, *args):
-        if not self.canfold:
-            raise TypeError, "cannot constant-fold operation %r" % (
-                self.opname,)
-        from pypy.rpython.lltypesystem.opimpl import get_op_impl
+        if self.canfold or self.opname in ('getfield', 'getarrayitem'):
+            from pypy.rpython.lltypesystem.opimpl import get_op_impl
+            op_impl = get_op_impl(self.opname)
+        else:
+            error = TypeError("cannot constant-fold operation %r" % (
+                self.opname,))
+            def op_impl(*args):
+                raise error
         # cache the implementation function into 'self'
-        self.fold = get_op_impl(self.opname)
+        self.fold = op_impl
         return self(RESULTTYPE, *args)
     fold.need_result_type = True
 

Modified: pypy/dist/pypy/rpython/lltypesystem/opimpl.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/opimpl.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/opimpl.py	Sun Jun 25 12:50:33 2006
@@ -322,6 +322,18 @@
     checkadr(addr2)
     return addr1 - addr2
 
+def op_getfield(p, name):
+    checkptr(p)
+    if not lltype.typeOf(p).TO._hints.get('immutable'):
+        raise TypeError("cannot fold getfield on mutable struct")
+    return getattr(p, name)
+
+def op_getarrayitem(p, index):
+    checkptr(p)
+    if not lltype.typeOf(p).TO._hints.get('immutable'):
+        raise TypeError("cannot fold getfield on mutable array")
+    return p[index]
+
 # ____________________________________________________________
 
 def get_op_impl(opname):

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_lloperation.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_lloperation.py	Sun Jun 25 12:50:33 2006
@@ -1,3 +1,4 @@
+import py
 from pypy.rpython.lltypesystem.lloperation import LL_OPERATIONS, llop
 from pypy.rpython.lltypesystem import lltype, opimpl
 from pypy.rpython.llinterp import LLFrame
@@ -25,6 +26,14 @@
 def test_llop_fold():
     assert llop.int_add(lltype.Signed, 10, 2) == 12
     assert llop.int_add(lltype.Signed, -6, -7) == -13
+    S1 = lltype.GcStruct('S1', ('x', lltype.Signed), hints={'immutable': True})
+    s1 = lltype.malloc(S1)
+    s1.x = 123
+    assert llop.getfield(lltype.Signed, s1, 'x') == 123
+    S2 = lltype.GcStruct('S2', ('x', lltype.Signed))
+    s2 = lltype.malloc(S2)
+    s2.x = 123
+    py.test.raises(TypeError, "llop.getfield(lltype.Signed, s2, 'x')")
 
 def test_llop_interp():
     from pypy.rpython.annlowlevel import LowLevelAnnotatorPolicy



More information about the Pypy-commit mailing list