[pypy-commit] pypy arm-backend-2: merge default

bivab noreply at buildbot.pypy.org
Tue Jun 12 15:54:55 CEST 2012


Author: David Schneider <david.schneider at picle.org>
Branch: arm-backend-2
Changeset: r55614:36790dfd7dae
Date: 2012-04-18 13:03 +0000
http://bitbucket.org/pypy/pypy/changeset/36790dfd7dae/

Log:	merge default

diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -320,10 +320,14 @@
                    default=False),
         BoolOption("getattributeshortcut",
                    "track types that override __getattribute__",
-                   default=False),
+                   default=False,
+                   # weakrefs needed, because of get_subclasses()
+                   requires=[("translation.rweakref", True)]),
         BoolOption("newshortcut",
                    "cache and shortcut calling __new__ from builtin types",
-                   default=False),
+                   default=False,
+                   # weakrefs needed, because of get_subclasses()
+                   requires=[("translation.rweakref", True)]),
 
         BoolOption("logspaceoptypes",
                    "a instrumentation option: before exit, print the types seen by "
@@ -337,7 +341,9 @@
                    requires=[("objspace.std.builtinshortcut", True)]),
         BoolOption("withidentitydict",
                    "track types that override __hash__, __eq__ or __cmp__ and use a special dict strategy for those which do not",
-                   default=False),
+                   default=False,
+                   # weakrefs needed, because of get_subclasses()
+                   requires=[("translation.rweakref", True)]),
      ]),
 ])
 
diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -85,6 +85,10 @@
     Collects the arguments of a function call.
 
     Instances should be considered immutable.
+
+    Some parts of this class are written in a slightly convoluted style to help
+    the JIT. It is really crucial to get this right, because Python's argument
+    semantics are complex, but calls occur everywhere.
     """
 
     ###  Construction  ###
@@ -171,7 +175,13 @@
         space = self.space
         keywords, values_w = space.view_as_kwargs(w_starstararg)
         if keywords is not None: # this path also taken for empty dicts
-            self._add_keywordargs_no_unwrapping(keywords, values_w)
+            if self.keywords is None:
+                self.keywords = keywords[:] # copy to make non-resizable
+                self.keywords_w = values_w[:]
+            else:
+                self._check_not_duplicate_kwargs(keywords, values_w)
+                self.keywords = self.keywords + keywords
+                self.keywords_w = self.keywords_w + values_w
             return not jit.isconstant(len(self.keywords))
         if space.isinstance_w(w_starstararg, space.w_dict):
             keys_w = space.unpackiterable(w_starstararg)
@@ -229,22 +239,16 @@
     @jit.look_inside_iff(lambda self, keywords, keywords_w:
             jit.isconstant(len(keywords) and
             jit.isconstant(self.keywords)))
-    def _add_keywordargs_no_unwrapping(self, keywords, keywords_w):
-        if self.keywords is None:
-            self.keywords = keywords[:] # copy to make non-resizable
-            self.keywords_w = keywords_w[:]
-        else:
-            # looks quadratic, but the JIT should remove all of it nicely.
-            # Also, all the lists should be small
-            for key in keywords:
-                for otherkey in self.keywords:
-                    if otherkey == key:
-                        raise operationerrfmt(self.space.w_TypeError,
-                                              "got multiple values "
-                                              "for keyword argument "
-                                              "'%s'", key)
-            self.keywords = self.keywords + keywords
-            self.keywords_w = self.keywords_w + keywords_w
+    def _check_not_duplicate_kwargs(self, keywords, keywords_w):
+        # looks quadratic, but the JIT should remove all of it nicely.
+        # Also, all the lists should be small
+        for key in keywords:
+            for otherkey in self.keywords:
+                if otherkey == key:
+                    raise operationerrfmt(self.space.w_TypeError,
+                                          "got multiple values "
+                                          "for keyword argument "
+                                          "'%s'", key)
 
     def fixedunpack(self, argcount):
         """The simplest argument parsing: get the 'argcount' arguments,
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -1223,7 +1223,7 @@
     def run_one_step(self):
         # Execute the frame forward.  This method contains a loop that leaves
         # whenever the 'opcode_implementations' (which is one of the 'opimpl_'
-        # methods) returns True.  This is the case when the current frame
+        # methods) raises ChangeFrame.  This is the case when the current frame
         # changes, due to a call or a return.
         try:
             staticdata = self.metainterp.staticdata
diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py
--- a/pypy/module/_io/interp_iobase.py
+++ b/pypy/module/_io/interp_iobase.py
@@ -341,9 +341,13 @@
 
     def add(self, w_iobase):
         assert w_iobase.streamholder is None
-        holder = StreamHolder(w_iobase)
-        w_iobase.streamholder = holder
-        self.streams[holder] = None
+        if rweakref.has_weakref_support():
+            holder = StreamHolder(w_iobase)
+            w_iobase.streamholder = holder
+            self.streams[holder] = None
+        #else:
+        #   no support for weakrefs, so ignore and we
+        #   will not get autoflushing
 
     def remove(self, w_iobase):
         holder = w_iobase.streamholder
diff --git a/pypy/module/cpyext/iterator.py b/pypy/module/cpyext/iterator.py
--- a/pypy/module/cpyext/iterator.py
+++ b/pypy/module/cpyext/iterator.py
@@ -22,7 +22,7 @@
     cannot be iterated."""
     return space.iter(w_obj)
 
- at cpython_api([PyObject], PyObject, error=CANNOT_FAIL)
+ at cpython_api([PyObject], PyObject)
 def PyIter_Next(space, w_obj):
     """Return the next value from the iteration o.  If the object is an
     iterator, this retrieves the next value from the iteration, and returns
diff --git a/pypy/module/cpyext/test/test_iterator.py b/pypy/module/cpyext/test/test_iterator.py
--- a/pypy/module/cpyext/test/test_iterator.py
+++ b/pypy/module/cpyext/test/test_iterator.py
@@ -15,3 +15,8 @@
         assert space.unwrap(api.PyIter_Next(w_iter)) == 3
         assert api.PyIter_Next(w_iter) is None
         assert not api.PyErr_Occurred()
+
+    def test_iternext_error(self,space, api):
+        assert api.PyIter_Next(space.w_None) is None
+        assert api.PyErr_Occurred() is space.w_TypeError
+        api.PyErr_Clear()
diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py
--- a/pypy/module/cpyext/test/test_unicodeobject.py
+++ b/pypy/module/cpyext/test/test_unicodeobject.py
@@ -453,8 +453,8 @@
 
     def test_tailmatch(self, space, api):
         w_str = space.wrap(u"abcdef")
-        assert api.PyUnicode_Tailmatch(w_str, space.wrap("cde"), 2, 10, 1) == 1
-        assert api.PyUnicode_Tailmatch(w_str, space.wrap("cde"), 1, 5, -1) == 1
+        assert api.PyUnicode_Tailmatch(w_str, space.wrap("cde"), 2, 10, -1) == 1
+        assert api.PyUnicode_Tailmatch(w_str, space.wrap("cde"), 1, 5, 1) == 1
         self.raises(space, api, TypeError,
                     api.PyUnicode_Tailmatch, w_str, space.wrap(3), 2, 10, 1)
 
diff --git a/pypy/module/cpyext/unicodeobject.py b/pypy/module/cpyext/unicodeobject.py
--- a/pypy/module/cpyext/unicodeobject.py
+++ b/pypy/module/cpyext/unicodeobject.py
@@ -593,7 +593,7 @@
     suffix match), 0 otherwise. Return -1 if an error occurred."""
     str = space.unicode_w(w_str)
     substr = space.unicode_w(w_substr)
-    if rffi.cast(lltype.Signed, direction) >= 0:
+    if rffi.cast(lltype.Signed, direction) <= 0:
         return stringtype.stringstartswith(str, substr, start, end)
     else:
         return stringtype.stringendswith(str, substr, start, end)
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -762,6 +762,8 @@
 
     def test_logaddexp(self):
         import math
+        import sys
+        float_max, float_min = sys.float_info.max, sys.float_info.min
         from _numpypy import logaddexp
 
         # From the numpy documentation
@@ -772,7 +774,8 @@
 
         assert logaddexp(0, 0) == math.log(2)
         assert logaddexp(float('-inf'), 0) == 0
-        assert logaddexp(12345678, 12345678) == float('inf')
+        assert logaddexp(float_max, float_max) == float_max
+        assert logaddexp(float_min, float_min) == math.log(2)
 
         assert math.isnan(logaddexp(float('nan'), 1))
         assert math.isnan(logaddexp(1, float('nan')))
@@ -785,6 +788,8 @@
 
     def test_logaddexp2(self):
         import math
+        import sys
+        float_max, float_min = sys.float_info.max, sys.float_info.min
         from _numpypy import logaddexp2
         log2 = math.log(2)
 
@@ -796,7 +801,8 @@
 
         assert logaddexp2(0, 0) == 1
         assert logaddexp2(float('-inf'), 0) == 0
-        assert logaddexp2(12345678, 12345678) == float('inf')
+        assert logaddexp2(float_max, float_max) == float_max
+        assert logaddexp2(float_min, float_min) == 1.0
 
         assert math.isnan(logaddexp2(float('nan'), 1))
         assert math.isnan(logaddexp2(1, float('nan')))
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -17,6 +17,7 @@
                                                 'render_as_void': True})
 degToRad = math.pi / 180.0
 log2 = math.log(2)
+log2e = 1./log2
 
 def simple_unary_op(func):
     specialize.argtype(1)(func)
@@ -841,45 +842,26 @@
 
     @simple_binary_op
     def logaddexp(self, v1, v2):
-        try:
-            v1e = math.exp(v1)
-        except OverflowError:
-            v1e = rfloat.INFINITY
-        try:
-            v2e = math.exp(v2)
-        except OverflowError:
-            v2e = rfloat.INFINITY
+        tmp = v1 - v2
+        if tmp > 0:
+            return v1 + rfloat.log1p(math.exp(-tmp))
+        elif tmp <= 0:
+            return v2 + rfloat.log1p(math.exp(tmp))
+        else:
+            return v1 + v2
 
-        v12e = v1e + v2e
-        try:
-            return math.log(v12e)
-        except ValueError:
-            if v12e == 0.0:
-                # CPython raises ValueError here, so we have to check
-                # the value to find the correct numpy return value
-                return -rfloat.INFINITY
-            return rfloat.NAN
+    def npy_log2_1p(self, v):
+        return log2e * rfloat.log1p(v)
 
     @simple_binary_op
     def logaddexp2(self, v1, v2):
-        try:
-            v1e = math.pow(2, v1)
-        except OverflowError:
-            v1e = rfloat.INFINITY
-        try:
-            v2e = math.pow(2, v2)
-        except OverflowError:
-            v2e = rfloat.INFINITY
-
-        v12e = v1e + v2e
-        try:
-            return math.log(v12e) / log2
-        except ValueError:
-            if v12e == 0.0:
-                # CPython raises ValueError here, so we have to check
-                # the value to find the correct numpy return value
-                return -rfloat.INFINITY
-            return rfloat.NAN
+        tmp = v1 - v2
+        if tmp > 0:
+            return v1 + self.npy_log2_1p(math.pow(2, -tmp))
+        if tmp <= 0:
+            return v2 + self.npy_log2_1p(math.pow(2, tmp))
+        else:
+            return v1 + v2
 
 class NonNativeFloat(NonNativePrimitive, Float):
     _mixin_ = True
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -414,7 +414,8 @@
     def contains(space, w_container, w_item):
         w_descr = space.lookup(w_container, '__contains__')
         if w_descr is not None:
-            return space.get_and_call_function(w_descr, w_container, w_item)
+            w_result = space.get_and_call_function(w_descr, w_container, w_item)
+            return space.nonzero(w_result)
         return space._contains(w_container, w_item)
 
     def _contains(space, w_container, w_item):
diff --git a/pypy/objspace/test/test_descroperation.py b/pypy/objspace/test/test_descroperation.py
--- a/pypy/objspace/test/test_descroperation.py
+++ b/pypy/objspace/test/test_descroperation.py
@@ -694,5 +694,31 @@
         l = len(X(X(2)))
         assert l == 2 and type(l) is int
 
+    def test_bool___contains__(self):
+        class X(object):
+            def __contains__(self, item):
+                if item == 'foo':
+                    return 42
+                else:
+                    return 'hello world'
+        x = X()
+        res = 'foo' in x
+        assert res is True
+        res = 'bar' in x
+        assert res is True
+        #
+        class MyError(Exception):
+            pass
+        class CannotConvertToBool(object):
+            def __nonzero__(self):
+                raise MyError
+        class X(object):
+            def __contains__(self, item):
+                return CannotConvertToBool()
+        x = X()
+        raises(MyError, "'foo' in x")
+        
+            
+
 class AppTestWithBuiltinShortcut(AppTest_Descroperation):
     OPTIONS = {'objspace.std.builtinshortcut': True}
diff --git a/pypy/rlib/parsing/test/test_ebnfparse.py b/pypy/rlib/parsing/test/test_ebnfparse.py
--- a/pypy/rlib/parsing/test/test_ebnfparse.py
+++ b/pypy/rlib/parsing/test/test_ebnfparse.py
@@ -103,6 +103,7 @@
 """)
     parse = make_parse_function(regexs, rules)
     tree = parse("prefix(\n\tlonger(and_nested(term(X))), Xya, _, X0, _).")
+    assert tree.children[0].children[0].children[2].children[0].getsourcepos().lineno == 1
     assert tree is not None
     tree = parse("""
 foo(X, Y) :- bar(Y, X), bar(Y, X) ; foobar(X, Y, 1234, atom).""")
diff --git a/pypy/rlib/parsing/tree.py b/pypy/rlib/parsing/tree.py
--- a/pypy/rlib/parsing/tree.py
+++ b/pypy/rlib/parsing/tree.py
@@ -23,6 +23,9 @@
         self.symbol = symbol
         self.additional_info = additional_info
         self.token = token
+
+    def getsourcepos(self):
+        return self.token.source_pos
     
     def __repr__(self):
         return "Symbol(%r, %r)" % (self.symbol, self.additional_info)
@@ -49,6 +52,9 @@
         self.children = children
         self.symbol = symbol
 
+    def getsourcepos(self):
+        return self.children[0].getsourcepos()
+
     def __str__(self):
         return "%s(%s)" % (self.symbol, ", ".join([str(c) for c in self.children]))
 
diff --git a/pypy/rlib/ropenssl.py b/pypy/rlib/ropenssl.py
--- a/pypy/rlib/ropenssl.py
+++ b/pypy/rlib/ropenssl.py
@@ -3,8 +3,9 @@
 from pypy.translator.platform import platform
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 
-import sys
+import sys, os
 
+link_files = []
 if sys.platform == 'win32' and platform.name != 'mingw32':
     libraries = ['libeay32', 'ssleay32',
                  'user32', 'advapi32', 'gdi32', 'msvcrt', 'ws2_32']
@@ -17,8 +18,17 @@
         # so that openssl/ssl.h can repair this nonsense.
         'wincrypt.h']
 else:
-    libraries = ['ssl', 'crypto']
+    libraries = ['z']
     includes = []
+    if (sys.platform.startswith('linux') and
+        os.path.exists('/usr/lib/libssl.a') and
+        os.path.exists('/usr/lib/libcrypto.a')):
+        # use static linking to avoid the infinite
+        # amount of troubles due to symbol versions
+        # and 0.9.8/1.0.0
+        link_files += ['/usr/lib/libssl.a', '/usr/lib/libcrypto.a']
+    else:
+        libraries += ['ssl', 'crypto']
 
 includes += [
     'openssl/ssl.h', 
@@ -30,6 +40,7 @@
 
 eci = ExternalCompilationInfo(
     libraries = libraries,
+    link_files = link_files,
     includes = includes,
     export_symbols = [],
     post_include_bits = [
diff --git a/pypy/rlib/rweakref.py b/pypy/rlib/rweakref.py
--- a/pypy/rlib/rweakref.py
+++ b/pypy/rlib/rweakref.py
@@ -9,6 +9,9 @@
 
 ref = weakref.ref    # basic regular weakrefs are supported in RPython
 
+def has_weakref_support():
+    return True      # returns False if --no-translation-rweakref
+
 
 class RWeakValueDictionary(object):
     """A dictionary containing weak values."""
@@ -68,6 +71,20 @@
 from pypy.annotation.bookkeeper import getbookkeeper
 from pypy.tool.pairtype import pairtype
 
+class Entry(extregistry.ExtRegistryEntry):
+    _about_ = has_weakref_support
+
+    def compute_result_annotation(self):
+        translator = self.bookkeeper.annotator.translator
+        res = translator.config.translation.rweakref
+        return self.bookkeeper.immutablevalue(res)
+
+    def specialize_call(self, hop):
+        from pypy.rpython.lltypesystem import lltype
+        hop.exception_cannot_occur()
+        return hop.inputconst(lltype.Bool, hop.s_result.const)
+
+
 class SomeWeakValueDict(annmodel.SomeObject):
     knowntype = RWeakValueDictionary
 
diff --git a/pypy/rlib/test/test_rweakref.py b/pypy/rlib/test/test_rweakref.py
new file mode 100644
--- /dev/null
+++ b/pypy/rlib/test/test_rweakref.py
@@ -0,0 +1,14 @@
+from pypy.rlib.rweakref import has_weakref_support
+from pypy.rpython.test.test_llinterp import interpret
+
+
+def test_has_weakref_support():
+    assert has_weakref_support()
+
+    res = interpret(lambda: has_weakref_support(), [],
+                    **{'translation.rweakref': True})
+    assert res == True
+
+    res = interpret(lambda: has_weakref_support(), [],
+                    **{'translation.rweakref': False})
+    assert res == False
diff --git a/pypy/rpython/module/ll_os.py b/pypy/rpython/module/ll_os.py
--- a/pypy/rpython/module/ll_os.py
+++ b/pypy/rpython/module/ll_os.py
@@ -1174,8 +1174,11 @@
             DIRENTP = lltype.Ptr(DIRENT)
             os_opendir = self.llexternal('opendir', [rffi.CCHARP], DIRP,
                                          compilation_info=compilation_info)
+            # XXX macro=True is hack to make sure we get the correct kind of
+            # dirent struct (which depends on defines)
             os_readdir = self.llexternal('readdir', [DIRP], DIRENTP,
-                                         compilation_info=compilation_info)
+                                         compilation_info=compilation_info,
+                                         macro=True)
             os_closedir = self.llexternal('closedir', [DIRP], rffi.INT,
                                           compilation_info=compilation_info)
 


More information about the pypy-commit mailing list