[pypy-svn] r79479 - in pypy/branch/rlist-jit/pypy: annotation annotation/test interpreter module/_sre objspace/std rlib rlib/rsre

arigo at codespeak.net arigo at codespeak.net
Wed Nov 24 17:31:11 CET 2010


Author: arigo
Date: Wed Nov 24 17:31:09 2010
New Revision: 79479

Modified:
   pypy/branch/rlist-jit/pypy/annotation/description.py
   pypy/branch/rlist-jit/pypy/annotation/listdef.py
   pypy/branch/rlist-jit/pypy/annotation/test/test_annrpython.py
   pypy/branch/rlist-jit/pypy/interpreter/pycode.py
   pypy/branch/rlist-jit/pypy/module/_sre/interp_sre.py
   pypy/branch/rlist-jit/pypy/objspace/std/objspace.py
   pypy/branch/rlist-jit/pypy/objspace/std/tupleobject.py
   pypy/branch/rlist-jit/pypy/rlib/debug.py
   pypy/branch/rlist-jit/pypy/rlib/rsre/rsre_core.py
Log:
Simplify yet another time the approach.


Modified: pypy/branch/rlist-jit/pypy/annotation/description.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/annotation/description.py	(original)
+++ pypy/branch/rlist-jit/pypy/annotation/description.py	Wed Nov 24 17:31:09 2010
@@ -649,7 +649,7 @@
                 if search in cdesc.classdict['_immutable_fields_'].value:
                     s_result.listdef.never_resize()
                     s_copy = s_result.listdef.offspring()
-                    s_copy.listdef.never_mutate()
+                    s_copy.listdef.mark_as_immutable()
                     return s_copy
             cdesc = cdesc.basedesc
         return s_result     # common case

Modified: pypy/branch/rlist-jit/pypy/annotation/listdef.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/annotation/listdef.py	(original)
+++ pypy/branch/rlist-jit/pypy/annotation/listdef.py	Wed Nov 24 17:31:09 2010
@@ -14,7 +14,7 @@
     resized = False    # True for lists resized after creation
     range_step = None  # the step -- only for lists only created by a range()
     dont_change_any_more = False   # set to True when too late for changes
-    must_not_mutate = False   # list_not_modified_any_more()
+    immutable = False  # for getattr out of _immutable_fields_ = ['attr[*]']
     must_not_resize = False   # make_sure_not_resized()
 
     # what to do if range_step is different in merge.
@@ -38,8 +38,7 @@
         if not self.mutated:
             if self.dont_change_any_more:
                 raise TooLateForChange
-            if self.must_not_mutate:
-                raise ListChangeUnallowed("mutating list")
+            self.immutable = False
             self.mutated = True
 
     def resize(self):
@@ -71,10 +70,7 @@
                     # things more general
                     self, other = other, self
 
-            if other.must_not_mutate:
-                if self.mutated:
-                    raise ListChangeUnallowed("list merge with a mutated")
-                self.must_not_mutate = True
+            self.immutable &= other.immutable
             if other.must_not_resize:
                 if self.resized:
                     raise ListChangeUnallowed("list merge with a resized")
@@ -192,7 +188,7 @@
         return '<[%r]%s%s%s%s>' % (self.listitem.s_value,
                                self.listitem.mutated and 'm' or '',
                                self.listitem.resized and 'r' or '',
-                               self.listitem.must_not_mutate and '!M' or '',
+                               self.listitem.immutable and 'I' or '',
                                self.listitem.must_not_resize and '!R' or '')
 
     def mutate(self):
@@ -207,11 +203,16 @@
             raise ListChangeUnallowed("list already resized")
         self.listitem.must_not_resize = True
 
-    def never_mutate(self):
+    def mark_as_immutable(self):
+        # Sets the 'immutable' flag.  Note that unlike "never resized",
+        # the immutable flag is only a hint.  It is cleared again e.g.
+        # when we merge with a "normal" list that doesn't have it.  It
+        # is thus expected to live only shortly, mostly for the case
+        # of writing 'x.list[n]'.
         self.never_resize()
         if self.listitem.mutated:
             raise ListChangeUnallowed("list already mutated")
-        self.listitem.must_not_mutate = True
+        self.listitem.immutable = True
 
 MOST_GENERAL_LISTDEF = ListDef(None, SomeObject())
 

Modified: pypy/branch/rlist-jit/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/annotation/test/test_annrpython.py	(original)
+++ pypy/branch/rlist-jit/pypy/annotation/test/test_annrpython.py	Wed Nov 24 17:31:09 2010
@@ -3375,24 +3375,6 @@
         a.build_types(fn, [])
         # assert did not raise ListChangeUnallowed
 
-    def test_list_not_modified_any_more(self):
-        from pypy.rlib.debug import list_not_modified_any_more
-
-        def pycode(consts):
-            return list_not_modified_any_more(consts)
-        def build1():
-            return pycode(consts=[1])
-        def build2():
-            return pycode(consts=[0])
-        def fn():
-            build1()
-            build2()
-
-        a = self.RPythonAnnotator()
-        a.translator.config.translation.list_comprehension_operations = True
-        a.build_types(fn, [])
-        # assert did not raise ListChangeUnallowed
-
     def test_return_immutable_list(self):
         class A:
             _immutable_fields_ = 'lst[*]'
@@ -3405,7 +3387,7 @@
 
         a = self.RPythonAnnotator()
         s = a.build_types(f, [int])
-        assert s.listdef.listitem.must_not_mutate
+        assert s.listdef.listitem.immutable
 
     def test_immutable_list_is_actually_resized(self):
         class A:
@@ -3420,6 +3402,39 @@
         a = self.RPythonAnnotator()
         py.test.raises(ListChangeUnallowed, a.build_types, f, [int])
 
+    def test_can_merge_immutable_list_with_regular_list(self):
+        class A:
+            _immutable_fields_ = 'lst[*]'
+        def f(n):
+            a = A()
+            l1 = [n, 0]
+            l1[1] = n+1
+            a.lst = l1
+            if n > 0:
+                lst = a.lst
+            else:
+                lst = []
+            return lst
+
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [int])
+        assert not s.listdef.listitem.immutable
+
+        def f(n):
+            a = A()
+            l1 = [n, 0]
+            l1[1] = n+1
+            a.lst = l1
+            if n > 0:
+                lst = []
+            else:
+                lst = a.lst
+            return lst
+
+        a = self.RPythonAnnotator()
+        s = a.build_types(f, [int])
+        assert not s.listdef.listitem.immutable
+
 
 def g(n):
     return [0,1,2,n]

Modified: pypy/branch/rlist-jit/pypy/interpreter/pycode.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/interpreter/pycode.py	(original)
+++ pypy/branch/rlist-jit/pypy/interpreter/pycode.py	Wed Nov 24 17:31:09 2010
@@ -15,7 +15,7 @@
     CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED,
     CO_GENERATOR, CO_CONTAINSGLOBALS)
 from pypy.rlib.rarithmetic import intmask
-from pypy.rlib.debug import make_sure_not_resized, list_not_modified_any_more
+from pypy.rlib.debug import make_sure_not_resized
 from pypy.rlib import jit
 from pypy.rlib.objectmodel import compute_hash
 from pypy.tool.stdlib_opcode import opcodedesc, HAVE_ARGUMENT
@@ -69,7 +69,7 @@
         self.co_stacksize = stacksize
         self.co_flags = flags
         self.co_code = code
-        self.co_consts_w = list_not_modified_any_more(consts)
+        self.co_consts_w = consts
         self.co_names_w = [space.new_interned_str(aname) for aname in names]
         self.co_varnames = varnames
         self.co_freevars = freevars

Modified: pypy/branch/rlist-jit/pypy/module/_sre/interp_sre.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/module/_sre/interp_sre.py	(original)
+++ pypy/branch/rlist-jit/pypy/module/_sre/interp_sre.py	Wed Nov 24 17:31:09 2010
@@ -6,7 +6,6 @@
 from pypy.interpreter.gateway import interp2app, ObjSpace, W_Root
 from pypy.interpreter.error import OperationError
 from pypy.rlib.rarithmetic import intmask
-from pypy.rlib.debug import list_not_modified_any_more
 from pypy.tool.pairtype import extendabletype
 
 
@@ -112,18 +111,17 @@
         space = self.space
         if pos < 0: pos = 0
         if endpos < pos: endpos = pos
-        pattern = list_not_modified_any_more(self.code)
         if space.is_true(space.isinstance(w_string, space.w_unicode)):
             unicodestr = space.unicode_w(w_string)
             if pos > len(unicodestr): pos = len(unicodestr)
             if endpos > len(unicodestr): endpos = len(unicodestr)
-            return rsre_core.UnicodeMatchContext(pattern, unicodestr,
+            return rsre_core.UnicodeMatchContext(self.code, unicodestr,
                                                  pos, endpos, self.flags)
         else:
             str = space.bufferstr_w(w_string)
             if pos > len(str): pos = len(str)
             if endpos > len(str): endpos = len(str)
-            return rsre_core.StrMatchContext(pattern, str,
+            return rsre_core.StrMatchContext(self.code, str,
                                              pos, endpos, self.flags)
 
     def getmatch(self, ctx, found):

Modified: pypy/branch/rlist-jit/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/objspace/std/objspace.py	(original)
+++ pypy/branch/rlist-jit/pypy/objspace/std/objspace.py	Wed Nov 24 17:31:09 2010
@@ -8,8 +8,7 @@
                                transparent, callmethod, proxyobject)
 from pypy.objspace.descroperation import DescrOperation, raiseattrerror
 from pypy.rlib.objectmodel import instantiate, r_dict, specialize
-from pypy.rlib.debug import make_sure_not_resized, list_not_modified_any_more
-from pypy.rlib.debug import _list_annotated_as_modifiable_again
+from pypy.rlib.debug import make_sure_not_resized
 from pypy.rlib.rarithmetic import base_int
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rlib.jit import hint
@@ -266,7 +265,8 @@
 
     def newtuple(self, list_w):
         assert isinstance(list_w, list)
-        return W_TupleObject(list_not_modified_any_more(list_w))
+        make_sure_not_resized(list_w)
+        return W_TupleObject(list_w)
 
     def newlist(self, list_w):
         return W_ListObject(list_w)
@@ -360,7 +360,7 @@
         """ Fast paths
         """
         if isinstance(w_obj, W_TupleObject):
-            t = _list_annotated_as_modifiable_again(w_obj.wrappeditems)
+            t = w_obj.wrappeditems
         elif isinstance(w_obj, W_ListObject):
             t = w_obj.wrappeditems[:]
         else:

Modified: pypy/branch/rlist-jit/pypy/objspace/std/tupleobject.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/objspace/std/tupleobject.py	(original)
+++ pypy/branch/rlist-jit/pypy/objspace/std/tupleobject.py	Wed Nov 24 17:31:09 2010
@@ -6,17 +6,15 @@
 from pypy.rlib.rarithmetic import intmask
 from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
 from pypy.interpreter import gateway
+from pypy.rlib.debug import make_sure_not_resized
 
 class W_TupleObject(W_Object):
     from pypy.objspace.std.tupletype import tuple_typedef as typedef
     _immutable_fields_ = ['wrappeditems[*]']
 
     def __init__(w_self, wrappeditems):
+        make_sure_not_resized(wrappeditems)
         w_self.wrappeditems = wrappeditems   # a list of wrapped values
-        # Note that to make annotation happy with respect to
-        # _immutable_fields_, wrappeditems must be a list known to
-        # be never mutated.  Use space.newtuple() instead of directly
-        # calling this constructor.
 
     def __repr__(w_self):
         """ representation for debugging purposes """
@@ -57,12 +55,12 @@
     for i in range(slicelength):
         subitems[i] = items[start]
         start += step
-    return space.newtuple(subitems)
+    return W_TupleObject(subitems)
 
 def getslice__Tuple_ANY_ANY(space, w_tuple, w_start, w_stop):
     length = len(w_tuple.wrappeditems)
     start, stop = normalize_simple_slice(space, length, w_start, w_stop)
-    return space.newtuple(w_tuple.wrappeditems[start:stop])
+    return W_TupleObject(w_tuple.wrappeditems[start:stop])
 
 def contains__Tuple_ANY(space, w_tuple, w_obj):
     for w_item in w_tuple.wrappeditems:
@@ -77,7 +75,7 @@
 def add__Tuple_Tuple(space, w_tuple1, w_tuple2):
     items1 = w_tuple1.wrappeditems
     items2 = w_tuple2.wrappeditems
-    return space.newtuple(items1 + items2)
+    return W_TupleObject(items1 + items2)
 
 def mul_tuple_times(space, w_tuple, w_times):
     try:
@@ -89,7 +87,7 @@
     if times == 1 and space.type(w_tuple) == space.w_tuple:
         return w_tuple
     items = w_tuple.wrappeditems
-    return space.newtuple(items * times)    
+    return W_TupleObject(items * times)    
 
 def mul__Tuple_ANY(space, w_tuple, w_times):
     return mul_tuple_times(space, w_tuple, w_times)

Modified: pypy/branch/rlist-jit/pypy/rlib/debug.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/rlib/debug.py	(original)
+++ pypy/branch/rlist-jit/pypy/rlib/debug.py	Wed Nov 24 17:31:09 2010
@@ -226,62 +226,6 @@
         hop.exception_cannot_occur()
         return hop.inputarg(hop.args_r[0], arg=0)
 
-def list_not_modified_any_more(arg):
-    """ Returns an annotator-time copy of the list 'arg' which is
-    flagged as 'don't mutate me'.  Actually implemented as just
-    returning 'arg'.  This is useful for debugging only.
-    """
-    return arg
-
-class Entry(ExtRegistryEntry):
-    _about_ = list_not_modified_any_more
-
-    def compute_result_annotation(self, s_arg):
-        from pypy.annotation.model import SomeList
-        assert isinstance(s_arg, SomeList)
-        # the logic behind it is that we try not to propagate
-        # make_sure_not_resized, when list comprehension is not on
-        if self.bookkeeper.annotator.translator.config.translation.list_comprehension_operations:
-            s_arg = s_arg.listdef.offspring()
-            s_arg.listdef.never_mutate()
-        else:
-            from pypy.annotation.annrpython import log
-            log.WARNING('list_not_modified_any_more called, but has no effect since list_comprehension is off')
-        return s_arg
-    
-    def specialize_call(self, hop):
-        hop.exception_cannot_occur()
-        return hop.inputarg(hop.args_r[0], arg=0)
-
-
-def _list_annotated_as_modifiable_again(arg):
-    """ Returns an annotator-time copy of the list 'arg' which is
-    *not* flagged as 'don't mutate me'.  Actually implemented as just
-    returning 'arg'.  This is useful for cases like space.fixedview()
-    where the returned list can escape to a lot of places that don't
-    expect a list flagged 'don't mutate me'.  Of course it relies on
-    the assumption that the code will not actually go ahead and mutate
-    the returned list, in practice.
-    """
-    return arg
-
-class Entry(ExtRegistryEntry):
-    _about_ = _list_annotated_as_modifiable_again
-
-    def compute_result_annotation(self, s_arg):
-        from pypy.annotation.model import SomeList
-        assert isinstance(s_arg, SomeList)
-        if self.bookkeeper.annotator.translator.config.translation.list_comprehension_operations:
-            s_arg = s_arg.listdef.offspring()
-        else:
-            from pypy.annotation.annrpython import log
-            log.WARNING('_list_annotated_as_modified_again called, but has no effect since list_comprehension is off')
-        return s_arg
-    
-    def specialize_call(self, hop):
-        hop.exception_cannot_occur()
-        return hop.inputarg(hop.args_r[0], arg=0)
-
 
 class IntegerCanBeNegative(Exception):
     pass

Modified: pypy/branch/rlist-jit/pypy/rlib/rsre/rsre_core.py
==============================================================================
--- pypy/branch/rlist-jit/pypy/rlib/rsre/rsre_core.py	(original)
+++ pypy/branch/rlist-jit/pypy/rlib/rsre/rsre_core.py	Wed Nov 24 17:31:09 2010
@@ -1,5 +1,5 @@
 import sys
-from pypy.rlib.debug import check_nonneg, list_not_modified_any_more
+from pypy.rlib.debug import check_nonneg, make_sure_not_modified
 from pypy.rlib.unroll import unrolling_iterable
 from pypy.rlib.rsre import rsre_char
 from pypy.tool.sourcetools import func_with_new_name
@@ -471,6 +471,7 @@
     while True:
         op = ctx.pat(ppos)
         ppos += 1
+        make_sure_not_modified(ctx.pattern)
 
         #jit.jit_debug("sre_match", op, ppos, ptr)
         #
@@ -946,7 +947,6 @@
 
 def match(pattern, string, start=0, end=sys.maxint, flags=0):
     start, end = _adjust(start, end, len(string))
-    pattern = list_not_modified_any_more(pattern)
     ctx = StrMatchContext(pattern, string, start, end, flags)
     if match_context(ctx):
         return ctx
@@ -955,7 +955,6 @@
 
 def search(pattern, string, start=0, end=sys.maxint, flags=0):
     start, end = _adjust(start, end, len(string))
-    pattern = list_not_modified_any_more(pattern)
     ctx = StrMatchContext(pattern, string, start, end, flags)
     if search_context(ctx):
         return ctx



More information about the Pypy-commit mailing list