[pypy-svn] r52524 - in pypy/branch/jit-hotpath/pypy/objspace/flow: . test

arigo at codespeak.net arigo at codespeak.net
Fri Mar 14 18:56:32 CET 2008


Author: arigo
Date: Fri Mar 14 18:56:27 2008
New Revision: 52524

Modified:
   pypy/branch/jit-hotpath/pypy/objspace/flow/objspace.py
   pypy/branch/jit-hotpath/pypy/objspace/flow/test/test_objspace.py
Log:
Experimental: this removes the unexpected difference the flow object
space makes for constant-folding between 'i += 1' and 'i = i + 1'.


Modified: pypy/branch/jit-hotpath/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/objspace/flow/objspace.py	(original)
+++ pypy/branch/jit-hotpath/pypy/objspace/flow/objspace.py	Fri Mar 14 18:56:27 2008
@@ -592,8 +592,9 @@
     op = None
     skip = False
     arithmetic = False
+    check_immutable_args = False
 
-    if name.startswith('del') or name.startswith('set') or name.startswith('inplace_'):
+    if name.startswith('del') or name.startswith('set'):
         # skip potential mutators
         if debug: print "Skip", name
         skip = True
@@ -611,6 +612,7 @@
     else:
         op = FunctionByName[name]
         arithmetic = (name + '_ovf') in FunctionByName
+        check_immutable_args = name.startswith('inplace_')
 
     if not op:
         if not skip:
@@ -618,8 +620,7 @@
     else:
         if debug: print "Can constant-fold operation: %s" % name
 
-    def generic_operator(self, *args_w):
-        assert len(args_w) == arity, name+" got the wrong number of arguments"
+    def try_to_constant_fold(self, *args_w):
         if op:
             args = []
             for w_arg in args_w:
@@ -631,6 +632,12 @@
                     args.append(arg)
             else:
                 # All arguments are constants: call the operator now
+                if check_immutable_args:
+                    try:
+                        map(hash, args)
+                    except TypeError:
+                        raise TypeError("operation %r should not be applied on"
+                                        " constant objects %r" % (name, args))
                 #print >> sys.stderr, 'Constant operation', op
                 try:
                     result = op(*args)
@@ -655,6 +662,12 @@
                             # store operation with variable result instead
                             pass
 
+    def generic_operator(self, *args_w):
+        assert len(args_w) == arity, name+" got the wrong number of arguments"
+        result = try_to_constant_fold(self, *args_w)
+        if result is not None:
+            return result
+
         #print >> sys.stderr, 'Variable operation', name, args_w
         w_result = self.do_operation_with_implicit_exceptions(name, *args_w)
         return w_result

Modified: pypy/branch/jit-hotpath/pypy/objspace/flow/test/test_objspace.py
==============================================================================
--- pypy/branch/jit-hotpath/pypy/objspace/flow/test/test_objspace.py	(original)
+++ pypy/branch/jit-hotpath/pypy/objspace/flow/test/test_objspace.py	Fri Mar 14 18:56:27 2008
@@ -856,6 +856,24 @@
             return foolist[0]
         py.test.raises(RuntimeError, "self.codetest(f)")
 
+    def test_constant_fold_immutable_inplace_add(self):
+        def f():
+            i = 5
+            i += 1
+            return i
+        graph = self.codetest(f)
+        simplify_graph(graph)
+        assert self.all_operations(graph) == {}
+
+        l1 = []
+        l2 = []
+        def g():
+            i = l1
+            i += l2       # mutates global lists - forbidden
+            return i
+        py.test.raises(TypeError, self.codetest, g)
+
+
 class TestFlowObjSpaceDelay(Base):
     def setup_class(cls):
         cls.space = FlowObjSpace()



More information about the Pypy-commit mailing list