[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