Author: Alex Gaynor <[email protected]>
Branch:
Changeset: r49654:bdb51cc58e95
Date: 2011-11-22 00:01 -0500
http://bitbucket.org/pypy/pypy/changeset/bdb51cc58e95/
Log: merged upstream
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
@@ -5507,8 +5507,43 @@
jump()
"""
self.optimize_loop(ops, expected)
-
- def test_immutable_dont_constantfold_recursive(self):
+ # ----------
+ 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))
@@ -5516,7 +5551,23 @@
escape(p0)
jump()
"""
- self.optimize_loop(ops, ops)
+ 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()
diff --git a/pypy/translator/platform/windows.py
b/pypy/translator/platform/windows.py
--- a/pypy/translator/platform/windows.py
+++ b/pypy/translator/platform/windows.py
@@ -71,6 +71,8 @@
so_ext = 'dll'
exe_ext = 'exe'
+ relevant_environ = ('PATH', 'INCLUDE', 'LIB')
+
cc = 'cl.exe'
link = 'link.exe'
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit