Author: Alex Gaynor <alex.gay...@gmail.com> 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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit