[pypy-commit] pypy win64-stage1: Merge with default

ctismer noreply at buildbot.pypy.org
Mon Nov 21 23:53:55 CET 2011


Author: Christian Tismer <tismer at stackless.com>
Branch: win64-stage1
Changeset: r49650:b3b8a737d506
Date: 2011-11-21 23:52 +0100
http://bitbucket.org/pypy/pypy/changeset/b3b8a737d506/

Log:	Merge with default

diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -1218,6 +1218,48 @@
         """
         self.optimize_loop(ops, expected, preamble)
 
+    def test_virtual_recursive_forced(self):
+        ops = """
+        [p0]
+        p41 = getfield_gc(p0, descr=nextdescr)
+        i0 = getfield_gc(p41, descr=valuedescr)
+        p1 = new_with_vtable(ConstClass(node_vtable2))
+        p2 = new_with_vtable(ConstClass(node_vtable2))
+        setfield_gc(p2, p1, descr=nextdescr)
+        setfield_gc(p1, p2, descr=nextdescr)
+        i1 = int_add(i0, 1)
+        setfield_gc(p2, i1, descr=valuedescr)
+        setfield_gc(p0, p1, descr=nextdescr)
+        jump(p1)
+        """
+        preamble = """
+        [p0]
+        p41 = getfield_gc(p0, descr=nextdescr)
+        i0 = getfield_gc(p41, descr=valuedescr)
+        i1 = int_add(i0, 1)
+        p1 = new_with_vtable(ConstClass(node_vtable2))
+        p2 = new_with_vtable(ConstClass(node_vtable2))
+        setfield_gc(p2, i1, descr=valuedescr)
+        setfield_gc(p2, p1, descr=nextdescr)
+        setfield_gc(p1, p2, descr=nextdescr)
+        setfield_gc(p0, p1, descr=nextdescr)
+        jump(p1)
+        """
+        loop = """
+        [p0]
+        p41 = getfield_gc(p0, descr=nextdescr)
+        i0 = getfield_gc(p41, descr=valuedescr)
+        i1 = int_add(i0, 1)
+        p1 = new_with_vtable(ConstClass(node_vtable2))
+        p2 = new_with_vtable(ConstClass(node_vtable2))
+        setfield_gc(p0, p1, descr=nextdescr)
+        setfield_gc(p2, p1, descr=nextdescr)
+        setfield_gc(p1, p2, descr=nextdescr)
+        setfield_gc(p2, i1, descr=valuedescr)
+        jump(p1)
+        """
+        self.optimize_loop(ops, loop, preamble)
+
     def test_virtual_constant_isnull(self):
         ops = """
         [i0]
@@ -5465,6 +5507,67 @@
         jump()
         """
         self.optimize_loop(ops, expected)
+        # ----------
+        ops = """
+        [p1]
+        p0 = new_with_vtable(ConstClass(ptrobj_immut_vtable))
+        setfield_gc(p0, p1, descr=immut_ptrval)
+        escape(p0)
+        jump(p1)
+        """
+        self.optimize_loop(ops, ops)
+        # ----------
+        ops = """
+        []
+        p0 = new_with_vtable(ConstClass(ptrobj_immut_vtable))
+        p1 = new_with_vtable(ConstClass(intobj_immut_vtable))
+        setfield_gc(p1, 1242, descr=immut_intval)
+        setfield_gc(p0, p1, descr=immut_ptrval)
+        escape(p0)
+        jump()
+        """
+        class PtrObj1242(object):
+            _TYPE = llmemory.GCREF.TO
+            def __eq__(slf, other):
+                if slf is other:
+                    return 1
+                p1 = other.container.ptrval
+                p1cast = lltype.cast_pointer(lltype.Ptr(self.INTOBJ_IMMUT), p1)
+                return p1cast.intval == 1242
+        self.namespace['ptrobj1242'] = lltype._ptr(llmemory.GCREF,
+                                                   PtrObj1242())
+        expected = """
+        []
+        escape(ConstPtr(ptrobj1242))
+        jump()
+        """
+        self.optimize_loop(ops, expected)
+
+    def test_immutable_constantfold_recursive(self):
+        ops = """
+        []
+        p0 = new_with_vtable(ConstClass(ptrobj_immut_vtable))
+        setfield_gc(p0, p0, descr=immut_ptrval)
+        escape(p0)
+        jump()
+        """
+        from pypy.rpython.lltypesystem import lltype, llmemory
+        class PtrObjSelf(object):
+            _TYPE = llmemory.GCREF.TO
+            def __eq__(slf, other):
+                if slf is other:
+                    return 1
+                p1 = other.container.ptrval
+                p1cast = lltype.cast_pointer(lltype.Ptr(self.PTROBJ_IMMUT), p1)
+                return p1cast.ptrval == p1
+        self.namespace['ptrobjself'] = lltype._ptr(llmemory.GCREF,
+                                                   PtrObjSelf())
+        expected = """
+        []
+        escape(ConstPtr(ptrobjself))
+        jump()
+        """
+        self.optimize_loop(ops, expected)
 
     # ----------
     def optimize_strunicode_loop(self, ops, optops, preamble):
diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py
--- a/pypy/jit/metainterp/optimizeopt/virtualize.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualize.py
@@ -87,14 +87,36 @@
     def _get_descr(self):
         raise NotImplementedError
 
-    def _is_immutable_and_filled_with_constants(self, optforce):
+    def _is_immutable_and_filled_with_constants(self, memo=None):
+        # check if it is possible to force the given structure into a
+        # compile-time constant: this is allowed only if it is declared
+        # immutable, if all fields are already filled, and if each field
+        # is either a compile-time constant or (recursively) a structure
+        # which also answers True to the same question.
+        #
+        # check that all fields are filled.  The following equality check
+        # also fails if count == -1, meaning "not an immutable at all".
         count = self._get_descr().count_fields_if_immutable()
-        if count != len(self._fields):    # always the case if count == -1
+        if count != len(self._fields):
             return False
+        #
+        # initialize 'memo'
+        if memo is None:
+            memo = {}
+        elif self in memo:
+            return True   # recursive case: assume yes
+        memo[self] = None
+        #
         for value in self._fields.itervalues():
-            subbox = value.force_box(optforce)
-            if not isinstance(subbox, Const):
-                return False
+            if value.is_constant():
+                pass            # it is a constant value: ok
+            elif (isinstance(value, AbstractVirtualStructValue)
+                  and value.box is None):
+                # recursive check
+                if not value._is_immutable_and_filled_with_constants(memo):
+                    return False
+            else:
+                return False    # not a constant at all
         return True
 
     def force_at_end_of_preamble(self, already_forced, optforce):
@@ -114,7 +136,7 @@
         if not we_are_translated():
             op.name = 'FORCE ' + self.source_op.name
 
-        if self._is_immutable_and_filled_with_constants(optforce):
+        if self._is_immutable_and_filled_with_constants():
             box = optforce.optimizer.constant_fold(op)
             self.make_constant(box)
             for ofs, value in self._fields.iteritems():
diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py
--- a/pypy/module/pyexpat/interp_pyexpat.py
+++ b/pypy/module/pyexpat/interp_pyexpat.py
@@ -3,9 +3,7 @@
 from pypy.interpreter.gateway import NoneNotWrapped
 from pypy.interpreter.gateway import interp2app, unwrap_spec
 from pypy.interpreter.error import OperationError
-from pypy.objspace.descroperation import object_setattr
 from pypy.rlib import rgc
-from pypy.rlib.unroll import unrolling_iterable
 from pypy.rpython.lltypesystem import rffi, lltype
 from pypy.rpython.tool import rffi_platform
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
@@ -339,8 +337,6 @@
     'XML_SetUnknownEncodingHandler',
     [XML_Parser, callback_type, rffi.VOIDP], lltype.Void)
 
-ENUMERATE_SETTERS = unrolling_iterable(SETTERS.items())
-
 # Declarations of external functions
 
 XML_ParserCreate = expat_external(
@@ -545,15 +541,19 @@
                 self.buffer_used = 0
         return False
 
+    def gethandler(self, space, name, index):
+        if name == 'CharacterDataHandler':
+            return self.w_character_data_handler or space.w_None
+        return self.handlers[index]
+
     def sethandler(self, space, name, w_handler, index, setter, handler):
-
         if name == 'CharacterDataHandler':
             self.flush_character_buffer(space)
             if space.is_w(w_handler, space.w_None):
                 self.w_character_data_handler = None
             else:
                 self.w_character_data_handler = w_handler
-
+        #
         self.handlers[index] = w_handler
         setter(self.itself, handler)
 
@@ -580,21 +580,29 @@
         return True
 
 
-    @unwrap_spec(name=str)
-    def setattr(self, space, name, w_value):
-        if name == "namespace_prefixes":
-            XML_SetReturnNSTriplet(self.itself, space.int_w(w_value))
-            return
+    @staticmethod
+    def _make_property(name):
+        index, setter, handler = SETTERS[name]
+        #
+        def descr_get_property(self, space):
+            return self.gethandler(space, name, index)
+        #
+        def descr_set_property(self, space, w_value):
+            return self.sethandler(space, name, w_value,
+                                   index, setter, handler)
+        #
+        return GetSetProperty(descr_get_property,
+                              descr_set_property,
+                              cls=W_XMLParserType)
 
-        for handler_name, (index, setter, handler) in ENUMERATE_SETTERS:
-            if name == handler_name:
-                return self.sethandler(space, handler_name, w_value,
-                                       index, setter, handler)
 
-        # fallback to object.__setattr__()
-        return space.call_function(
-            object_setattr(space),
-            space.wrap(self), space.wrap(name), w_value)
+    def get_namespace_prefixes(self, space):
+        raise OperationError(space.w_AttributeError,
+            space.wrap("not implemented: reading namespace_prefixes"))
+
+    @unwrap_spec(value=int)
+    def set_namespace_prefixes(self, space, value):
+        XML_SetReturnNSTriplet(self.itself, bool(value))
 
     # Parse methods
 
@@ -732,10 +740,18 @@
 if XML_COMBINED_VERSION >= 19505:
     XMLParser_methods.append('UseForeignDTD')
 
+_XMLParser_extras = {}
+for name in XMLParser_methods:
+    _XMLParser_extras[name] = interp2app(getattr(W_XMLParserType, name))
+for name in SETTERS:
+    _XMLParser_extras[name] = W_XMLParserType._make_property(name)
+
 W_XMLParserType.typedef = TypeDef(
     "pyexpat.XMLParserType",
     __doc__ = "XML parser",
-    __setattr__ = interp2app(W_XMLParserType.setattr),
+    namespace_prefixes = GetSetProperty(W_XMLParserType.get_namespace_prefixes,
+                                        W_XMLParserType.set_namespace_prefixes,
+                                        cls=W_XMLParserType),
     returns_unicode = bool_property('returns_unicode', W_XMLParserType),
     ordered_attributes = bool_property('ordered_attributes', W_XMLParserType),
     specified_attributes = bool_property('specified_attributes', W_XMLParserType),
@@ -754,8 +770,7 @@
     CurrentColumnNumber = GetSetProperty(W_XMLParserType.descr_ErrorColumnNumber, cls=W_XMLParserType),
     CurrentByteIndex = GetSetProperty(W_XMLParserType.descr_ErrorByteIndex, cls=W_XMLParserType),
 
-    **dict((name, interp2app(getattr(W_XMLParserType, name)))
-           for name in XMLParser_methods)
+    **_XMLParser_extras
     )
 
 def ParserCreate(space, w_encoding=None, w_namespace_separator=None,
diff --git a/pypy/module/pyexpat/test/test_parser.py b/pypy/module/pyexpat/test/test_parser.py
--- a/pypy/module/pyexpat/test/test_parser.py
+++ b/pypy/module/pyexpat/test/test_parser.py
@@ -52,6 +52,19 @@
                 assert res == 1
                 assert data == [u"\u00f6"]
 
+    def test_get_handler(self):
+        import pyexpat
+        p = pyexpat.ParserCreate()
+        assert p.StartElementHandler is None
+        assert p.EndElementHandler is None
+        def f(*args): pass
+        p.StartElementHandler = f
+        assert p.StartElementHandler is f
+        def g(*args): pass
+        p.EndElementHandler = g
+        assert p.StartElementHandler is f
+        assert p.EndElementHandler is g
+
     def test_intern(self):
         import pyexpat
         p = pyexpat.ParserCreate()


More information about the pypy-commit mailing list