Author: Philip Jenvey <[email protected]>
Branch: py3k
Changeset: r64804:54af5b1ed1de
Date: 2013-06-05 11:49 -0700
http://bitbucket.org/pypy/pypy/changeset/54af5b1ed1de/

Log:    merge default

diff --git a/lib-python/2.7/opcode.py b/lib-python/2.7/opcode.py
--- a/lib-python/2.7/opcode.py
+++ b/lib-python/2.7/opcode.py
@@ -193,5 +193,6 @@
 hasname.append(201)
 def_op('CALL_METHOD', 202)            # #args not including 'self'
 def_op('BUILD_LIST_FROM_ARG', 203)
+jrel_op('JUMP_IF_NOT_DEBUG', 204)     # jump over assert statements
 
 del def_op, name_op, jrel_op, jabs_op
diff --git a/lib-python/2.7/test/test_code.py b/lib-python/2.7/test/test_code.py
--- a/lib-python/2.7/test/test_code.py
+++ b/lib-python/2.7/test/test_code.py
@@ -75,7 +75,7 @@
 cellvars: ()
 freevars: ()
 nlocals: 0
-flags: 67
+flags: 1048643
 consts: ("'doc string'", 'None')
 
 """
diff --git a/lib-python/2.7/test/test_dis.py b/lib-python/2.7/test/test_dis.py
--- a/lib-python/2.7/test/test_dis.py
+++ b/lib-python/2.7/test/test_dis.py
@@ -53,25 +53,26 @@
     pass
 
 dis_bug1333982 = """\
- %-4d         0 LOAD_CONST               1 (0)
-              3 POP_JUMP_IF_TRUE        41
-              6 LOAD_GLOBAL              0 (AssertionError)
-              9 LOAD_FAST                0 (x)
-             12 BUILD_LIST_FROM_ARG      0
-             15 GET_ITER
-        >>   16 FOR_ITER                12 (to 31)
-             19 STORE_FAST               1 (s)
-             22 LOAD_FAST                1 (s)
-             25 LIST_APPEND              2
-             28 JUMP_ABSOLUTE           16
+ %-4d         0 JUMP_IF_NOT_DEBUG       41 (to 44)
+              3 LOAD_CONST               1 (0)
+              6 POP_JUMP_IF_TRUE        44
+              9 LOAD_GLOBAL              0 (AssertionError)
+             12 LOAD_FAST                0 (x)
+             15 BUILD_LIST_FROM_ARG      0
+             18 GET_ITER
+        >>   19 FOR_ITER                12 (to 34)
+             22 STORE_FAST               1 (s)
+             25 LOAD_FAST                1 (s)
+             28 LIST_APPEND              2
+             31 JUMP_ABSOLUTE           19
 
- %-4d   >>   31 LOAD_CONST               2 (1)
-             34 BINARY_ADD
-             35 CALL_FUNCTION            1
-             38 RAISE_VARARGS            1
+ %-4d   >>   34 LOAD_CONST               2 (1)
+             37 BINARY_ADD
+             38 CALL_FUNCTION            1
+             41 RAISE_VARARGS            1
 
- %-4d   >>   41 LOAD_CONST               0 (None)
-             44 RETURN_VALUE
+ %-4d   >>   44 LOAD_CONST               0 (None)
+             47 RETURN_VALUE
 """%(bug1333982.func_code.co_firstlineno + 1,
      bug1333982.func_code.co_firstlineno + 2,
      bug1333982.func_code.co_firstlineno + 3)
diff --git a/lib_pypy/_ctypes/pointer.py b/lib_pypy/_ctypes/pointer.py
--- a/lib_pypy/_ctypes/pointer.py
+++ b/lib_pypy/_ctypes/pointer.py
@@ -119,6 +119,7 @@
         return self._buffer[0] != 0
 
     contents = property(getcontents, setcontents)
+    _obj = property(getcontents) # byref interface
 
     def _as_ffi_pointer_(self, ffitype):
         return as_ffi_pointer(self, ffitype)
diff --git a/lib_pypy/_pypy_irc_topic.py b/lib_pypy/_pypy_irc_topic.py
--- a/lib_pypy/_pypy_irc_topic.py
+++ b/lib_pypy/_pypy_irc_topic.py
@@ -1,4 +1,4 @@
-"""eclguba: flagnk naq frznagvpf bs clguba, fcrrq bs p, erfgevpgvbaf bs wnin 
naq pbzcvyre reebe zrffntrf nf crargenoyr nf ZHZCF
+__doc__ = """eclguba: flagnk naq frznagvpf bs clguba, fcrrq bs p, erfgevpgvbaf 
bs wnin naq pbzcvyre reebe zrffntrf nf crargenoyr nf ZHZCF
 pglcrf unf n fcva bs 1/3
 ' ' vf n fcnpr gbb
 Clguba 2.k rfg cerfdhr zbeg, ivir Clguba!
diff --git a/pypy/bin/pyinteractive.py b/pypy/bin/pyinteractive.py
--- a/pypy/bin/pyinteractive.py
+++ b/pypy/bin/pyinteractive.py
@@ -27,7 +27,8 @@
     BoolOption("completer", "use readline commandline completer",
                default=False, cmdline="-C"),
     BoolOption("optimize",
-               "dummy optimization flag for compatibility with CPython",
+               "skip assert statements and remove docstrings when importing 
modules"
+               " (this is -OO in regular CPython)",
                default=False, cmdline="-O"),
     BoolOption("no_site_import", "do not 'import site' on initialization",
                default=False, cmdline="-S"),
@@ -94,6 +95,17 @@
     space.setitem(space.sys.w_dict, space.wrap('executable'),
                   space.wrap(argv[0]))
 
+    if interactiveconfig.optimize:
+        #change the optimize flag's value and set __debug__ to False
+        space.appexec([], """():
+            import sys
+            flags = list(sys.flags)
+            flags[6] = 2
+            sys.flags = type(sys.flags)(flags)
+            import __pypy__
+            __pypy__.set_debug(False)
+        """)
+
     # call pypy_find_stdlib: the side-effect is that it sets sys.prefix and
     # sys.exec_prefix
     executable = argv[0]
diff --git a/pypy/doc/man/pypy.1.rst b/pypy/doc/man/pypy.1.rst
--- a/pypy/doc/man/pypy.1.rst
+++ b/pypy/doc/man/pypy.1.rst
@@ -16,7 +16,10 @@
     Inspect interactively after running script.
 
 -O
-    Dummy optimization flag for compatibility with C Python.
+    Skip assert statements.
+
+-OO
+    Remove docstrings when importing modules in addition to -O.
 
 -c *cmd*
     Program passed in as CMD (terminates option list).
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -50,3 +50,5 @@
 .. branch: win32-fixes3
 Skip and fix some non-translated (own) tests for win32 builds
 
+.. branch: ctypes-byref
+Add the '_obj' attribute on ctypes pointer() and byref() objects
diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py
--- a/pypy/interpreter/app_main.py
+++ b/pypy/interpreter/app_main.py
@@ -2,8 +2,9 @@
 # App-level version of py.py.
 # See test/test_app_main.
 
-# Missing vs CPython: -b, -d, -OO, -v, -x, -3
-"""\
+# Missing vs CPython: -b, -d, -v, -x, -3
+from __future__ import print_function, unicode_literals
+USAGE1 = __doc__ = """\
 Options and arguments (and corresponding environment variables):
 -B     : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x
 -c cmd : program passed in as string (terminates option list)
@@ -12,7 +13,8 @@
 -i     : inspect interactively after running script; forces a prompt even
          if stdin does not appear to be a terminal; also PYTHONINSPECT=x
 -m mod : run library module as a script (terminates option list)
--O     : dummy optimization flag for compatibility with CPython
+-O     : skip assert statements
+-OO    : remove docstrings when importing modules in addition to -O
 -q     : don't print version and copyright messages on interactive startup
 -R     : ignored (see http://bugs.python.org/issue14621)
 -s     : don't add user site directory to sys.path; also PYTHONNOUSERSITE
@@ -28,8 +30,6 @@
 PyPy options and arguments:
 --info : print translation information about this PyPy executable
 """
-from __future__ import print_function, unicode_literals
-USAGE1 = __doc__
 # Missing vs CPython: PYTHONHOME, PYTHONCASEOK
 USAGE2 = """
 Other environment variables:
@@ -465,6 +465,10 @@
     sys._xoptions = dict(x.split('=', 1) if '=' in x else (x, True)
                          for x in options['_xoptions'])
 
+        if sys.flags.optimize >= 1:
+            import __pypy__
+            __pypy__.set_debug(False)
+
 ##    if not we_are_translated():
 ##        for key in sorted(options):
 ##            print '%40s: %s' % (key, options[key])
diff --git a/pypy/interpreter/astcompiler/assemble.py 
b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -246,6 +246,8 @@
         if w_len is None:
             w_len = space.len(self.w_consts)
             space.setitem(self.w_consts, w_key, w_len)
+        if space.int_w(w_len) == 0:
+            self.scope.doc_removable = False
         return space.int_w(w_len)
 
     def _make_key(self, obj):
@@ -618,6 +620,7 @@
     ops.JUMP_IF_FALSE_OR_POP : 0,
     ops.POP_JUMP_IF_TRUE : -1,
     ops.POP_JUMP_IF_FALSE : -1,
+    ops.JUMP_IF_NOT_DEBUG : 0,
 
     ops.BUILD_LIST_FROM_ARG: 1,
 }
diff --git a/pypy/interpreter/astcompiler/codegen.py 
b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -263,6 +263,7 @@
                 start = 1
                 doc_expr.walkabout(self)
                 self.name_op("__doc__", ast.Store)
+                self.scope.doc_removable = True
             for i in range(start, len(body)):
                 body[i].walkabout(self)
             return True
@@ -435,6 +436,7 @@
     def visit_Assert(self, asrt):
         self.update_position(asrt.lineno)
         end = self.new_block()
+        self.emit_jump(ops.JUMP_IF_NOT_DEBUG, end)
         asrt.test.accept_jump_if(self, True, end)
         self.emit_op_name(ops.LOAD_GLOBAL, self.names, "AssertionError")
         if asrt.msg:
@@ -1225,6 +1227,8 @@
         flags = 0
         if not self.cell_vars and not self.free_vars:
             flags |= consts.CO_NOFREE
+        if self.scope.doc_removable:
+            flags |= consts.CO_KILL_DOCSTRING
         return flags
 
 
@@ -1244,6 +1248,8 @@
             flags |= consts.CO_VARARGS
         if scope.has_keywords_arg:
             flags |= consts.CO_VARKEYWORDS
+        if scope.doc_removable:
+            flags |= consts.CO_KILL_DOCSTRING
         if not self.cell_vars and not self.free_vars:
             flags |= consts.CO_NOFREE
         return PythonCodeGenerator._get_code_flags(self) | flags
@@ -1260,6 +1266,7 @@
             doc_expr = None
         if doc_expr is not None:
             self.add_const(doc_expr.s)
+            self.scope.doc_removable = True
             start = 1
         else:
             self.add_const(self.space.w_None)
@@ -1339,3 +1346,9 @@
             # This happens when nobody references the cell
             self.load_const(self.space.w_None)
         self.emit_op(ops.RETURN_VALUE)
+
+    def _get_code_flags(self):
+        flags = 0
+        if self.scope.doc_removable:
+            flags |= consts.CO_KILL_DOCSTRING
+        return PythonCodeGenerator._get_code_flags(self) | flags
diff --git a/pypy/interpreter/astcompiler/consts.py 
b/pypy/interpreter/astcompiler/consts.py
--- a/pypy/interpreter/astcompiler/consts.py
+++ b/pypy/interpreter/astcompiler/consts.py
@@ -16,6 +16,8 @@
 CO_FUTURE_PRINT_FUNCTION = 0x10000
 CO_FUTURE_UNICODE_LITERALS = 0x20000
 CO_FUTURE_BARRY_AS_BDFL = 0x40000
+#pypy specific:
+CO_KILL_DOCSTRING = 0x100000
 
 PyCF_MASK = (CO_FUTURE_DIVISION | CO_FUTURE_ABSOLUTE_IMPORT |
              CO_FUTURE_WITH_STATEMENT | CO_FUTURE_PRINT_FUNCTION |
diff --git a/pypy/interpreter/astcompiler/symtable.py 
b/pypy/interpreter/astcompiler/symtable.py
--- a/pypy/interpreter/astcompiler/symtable.py
+++ b/pypy/interpreter/astcompiler/symtable.py
@@ -42,6 +42,7 @@
         self.has_free = False
         self.child_has_free = False
         self.nested = False
+        self.doc_removable = False
 
     def lookup(self, name):
         """Find the scope of identifier 'name'."""
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py 
b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -842,6 +842,58 @@
         """
         self.simple_test(source, 'ok', 1)
 
+    def test_remove_docstring(self):
+        source = '"module_docstring"\n' + """if 1:
+        def f1():
+            'docstring'
+        def f2():
+            'docstring'
+            return 'docstring'
+        def f3():
+            'foo'
+            return 'bar'
+        class C1():
+            'docstring'
+        class C2():
+            __doc__ = 'docstring'
+        class C3():
+            field = 'not docstring'
+        class C4():
+            'docstring'
+            field = 'docstring'
+        """
+        code_w = compile_with_astcompiler(source, 'exec', self.space)
+        code_w.remove_docstrings(self.space)
+        dict_w = self.space.newdict();
+        code_w.exec_code(self.space, dict_w, dict_w)
+
+        yield self.check, dict_w, "f1.__doc__", None
+        yield self.check, dict_w, "f2.__doc__", 'docstring'
+        yield self.check, dict_w, "f2()", 'docstring'
+        yield self.check, dict_w, "f3.__doc__", None
+        yield self.check, dict_w, "f3()", 'bar'
+        yield self.check, dict_w, "C1.__doc__", None
+        yield self.check, dict_w, "C2.__doc__", 'docstring'
+        yield self.check, dict_w, "C3.field", 'not docstring'
+        yield self.check, dict_w, "C4.field", 'docstring'
+        yield self.check, dict_w, "C4.__doc__", 'docstring'
+        yield self.check, dict_w, "C4.__doc__", 'docstring'
+        yield self.check, dict_w, "__doc__", None
+
+    def test_assert_skipping(self):
+        space = self.space
+        mod = space.getbuiltinmodule('__pypy__')
+        w_set_debug = space.getattr(mod, space.wrap('set_debug'))
+        space.call_function(w_set_debug, space.w_False)
+
+        source = """if 1:
+        assert False
+        """
+        try:
+            self.run(source)
+        finally:
+            space.call_function(w_set_debug, space.w_True)
+
     def test_raise_from(self):
         test = """if 1:
         def f():
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -12,7 +12,7 @@
 from pypy.interpreter.gateway import unwrap_spec
 from pypy.interpreter.astcompiler.consts import (
     CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED,
-    CO_GENERATOR)
+    CO_GENERATOR, CO_KILL_DOCSTRING)
 from pypy.tool.stdlib_opcode import opcodedesc, HAVE_ARGUMENT
 from rpython.rlib.rarithmetic import intmask
 from rpython.rlib.objectmodel import compute_hash, we_are_translated
@@ -240,6 +240,13 @@
                 return w_first
         return space.w_None
 
+    def remove_docstrings(self, space):
+        if self.co_flags & CO_KILL_DOCSTRING:
+            self.co_consts_w[0] = space.w_None
+        for w_co in self.co_consts_w:
+            if isinstance(w_co, PyCode):
+                w_co.remove_docstrings(space)
+
     def _to_code(self):
         """For debugging only."""
         consts = [None] * len(self.co_consts_w)
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -855,6 +855,11 @@
         self.popvalue()
         return next_instr
 
+    def JUMP_IF_NOT_DEBUG(self, jumpby, next_instr):
+        if not self.space.sys.debug:
+            next_instr += jumpby
+        return next_instr
+
     def GET_ITER(self, oparg, next_instr):
         w_iterable = self.popvalue()
         w_iterator = self.space.iter(w_iterable)
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -59,6 +59,7 @@
         'add_memory_pressure'       : 'interp_magic.add_memory_pressure',
         'newdict'                   : 'interp_dict.newdict',
         'dictstrategy'              : 'interp_dict.dictstrategy',
+        'set_debug'                 : 'interp_magic.set_debug',
     }
 
     submodules = {
diff --git a/pypy/module/__pypy__/interp_magic.py 
b/pypy/module/__pypy__/interp_magic.py
--- a/pypy/module/__pypy__/interp_magic.py
+++ b/pypy/module/__pypy__/interp_magic.py
@@ -98,6 +98,13 @@
 def newlist_hint(space, sizehint):
     return space.newlist_hint(sizehint)
 
+@unwrap_spec(debug=bool)
+def set_debug(space, debug):
+    space.sys.debug = debug
+    space.setitem(space.builtin.w_dict,
+                  space.wrap('__debug__'),
+                  space.wrap(debug))
+
 @unwrap_spec(estimate=int)
 def add_memory_pressure(estimate):
     rgc.add_memory_pressure(estimate)
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -992,6 +992,13 @@
             if not space.is_true(space.sys.get('dont_write_bytecode')):
                 write_compiled_module(space, code_w, cpathname, mode, mtime)
 
+    try:
+        optimize = space.sys.get_flag('optimize')
+    except Exception:
+        optimize = 0
+    if optimize >= 2:
+        code_w.remove_docstrings(space)
+
     update_code_filenames(space, code_w, pathname)
     exec_code_module(space, w_mod, code_w, pathname, cpathname)
 
@@ -1086,6 +1093,13 @@
                               "Bad magic number in %s", cpathname)
     #print "loading pyc file:", cpathname
     code_w = read_compiled_module(space, cpathname, source)
+    try:
+        optimize = space.sys.get_flag('optimize')
+    except Exception:
+        optimize = 0
+    if optimize >= 2:
+        code_w.remove_docstrings(space)
+
     exec_code_module(space, w_mod, code_w, cpathname, cpathname, write_paths)
 
     return w_mod
diff --git a/pypy/module/micronumpy/interp_boxes.py 
b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -13,6 +13,9 @@
 from pypy.module.micronumpy.arrayimpl.voidbox import VoidBoxStorage
 from rpython.rlib.objectmodel import specialize
 from pypy.interpreter.mixedmodule import MixedModule
+from rpython.rtyper.lltypesystem import lltype
+from rpython.rlib.rstring import StringBuilder
+
 
 MIXIN_32 = (long_typedef,) if LONG_BIT == 32 else ()
 MIXIN_64 = (long_typedef,) if LONG_BIT == 64 else ()
@@ -42,7 +45,23 @@
     return func_with_new_name(new, name + "_box_new"), 
staticmethod(_get_dtype), func_with_new_name(descr_reduce, "descr_reduce")
 
 
-class PrimitiveBox(object):
+class Box(object):
+    _mixin_ = True
+
+    def reduce(self, space):
+        from rpython.rlib.rstring import StringBuilder
+        from rpython.rtyper.lltypesystem import rffi, lltype
+
+        numpypy = space.getbuiltinmodule("_numpypy")
+        assert isinstance(numpypy, MixedModule)
+        multiarray = numpypy.get("multiarray")
+        assert isinstance(multiarray, MixedModule)
+        scalar = multiarray.get("scalar")
+
+        ret = space.newtuple([scalar, 
space.newtuple([space.wrap(self._get_dtype(space)), 
space.wrap(self.raw_str())])])
+        return ret
+
+class PrimitiveBox(Box):
     _mixin_ = True
 
     def __init__(self, value):
@@ -54,27 +73,19 @@
     def __repr__(self):
         return '%s(%s)' % (self.__class__.__name__, self.value)
 
-    def reduce(self, space):
-        from rpython.rlib.rstring import StringBuilder
-        from rpython.rtyper.lltypesystem import rffi, lltype
-
-        numpypy = space.getbuiltinmodule("_numpypy")
-        assert isinstance(numpypy, MixedModule)
-        multiarray = numpypy.get("multiarray")
-        assert isinstance(multiarray, MixedModule)
-        scalar = multiarray.get("scalar")
-
+    def raw_str(self):
         value = lltype.malloc(rffi.CArray(lltype.typeOf(self.value)), 1, 
flavor="raw")
         value[0] = self.value
 
         builder = StringBuilder()
         builder.append_charpsize(rffi.cast(rffi.CCHARP, value), 
rffi.sizeof(lltype.typeOf(self.value)))
+        ret = builder.build()
 
-        ret = space.newtuple([scalar, 
space.newtuple([space.wrap(self._get_dtype(space)), 
space.wrap(builder.build())])])
         lltype.free(value, flavor="raw")
+
         return ret
 
-class ComplexBox(object):
+class ComplexBox(Box):
     _mixin_ = True
 
     def __init__(self, real, imag=0.):
@@ -90,25 +101,17 @@
     def convert_imag_to(self, dtype):
         return dtype.box(self.imag)
 
-    def reduce(self, space):
-        from rpython.rlib.rstring import StringBuilder
-        from rpython.rtyper.lltypesystem import rffi, lltype
-
-        numpypy = space.getbuiltinmodule("_numpypy")
-        assert isinstance(numpypy, MixedModule)
-        multiarray = numpypy.get("multiarray")
-        assert isinstance(multiarray, MixedModule)
-        scalar = multiarray.get("scalar")
-
+    def raw_str(self):
         value = lltype.malloc(rffi.CArray(lltype.typeOf(self.real)), 2, 
flavor="raw")
         value[0] = self.real
         value[1] = self.imag
 
         builder = StringBuilder()
         builder.append_charpsize(rffi.cast(rffi.CCHARP, value), 
rffi.sizeof(lltype.typeOf(self.real)) * 2)
+        ret = builder.build()
 
-        ret = space.newtuple([scalar, 
space.newtuple([space.wrap(self._get_dtype(space)), 
space.wrap(builder.build())])])
         lltype.free(value, flavor="raw")
+
         return ret
 
 class W_GenericBox(W_Root):
diff --git a/pypy/module/micronumpy/interp_numarray.py 
b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -786,6 +786,7 @@
         from rpython.rtyper.lltypesystem import rffi
         from rpython.rlib.rstring import StringBuilder
         from pypy.interpreter.mixedmodule import MixedModule
+        from pypy.module.micronumpy.arrayimpl.concrete import SliceArray
 
         numpypy = space.getbuiltinmodule("_numpypy")
         assert isinstance(numpypy, MixedModule)
@@ -796,7 +797,14 @@
         parameters = space.newtuple([space.gettypefor(W_NDimArray), 
space.newtuple([space.wrap(0)]), space.wrap("b")])
 
         builder = StringBuilder()
-        builder.append_charpsize(self.implementation.get_storage(), 
self.implementation.get_storage_size())
+        if isinstance(self.implementation, SliceArray):
+            iter = self.implementation.create_iter()
+            while not iter.done():
+                box = iter.getitem()
+                builder.append(box.raw_str())
+                iter.next()
+        else:
+            builder.append_charpsize(self.implementation.get_storage(), 
self.implementation.get_storage_size())
 
         state = space.newtuple([
                 space.wrap(1),      # version
diff --git a/pypy/module/micronumpy/test/test_numarray.py 
b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -1801,6 +1801,13 @@
         pickled_data = dumps(a)
         assert (loads(pickled_data) == a).all()
 
+    def test_pickle_slice(self):
+        from cPickle import loads, dumps
+        import numpypy as numpy
+
+        a = numpy.arange(10.).reshape((5, 2))[::2]
+        assert (loads(dumps(a)) == a).all()
+
 class AppTestMultiDim(BaseNumpyAppTest):
     def test_init(self):
         import numpypy
diff --git a/pypy/module/pypyjit/test/test_policy.py 
b/pypy/module/pypyjit/test/test_policy.py
--- a/pypy/module/pypyjit/test/test_policy.py
+++ b/pypy/module/pypyjit/test/test_policy.py
@@ -8,7 +8,12 @@
 
 def test_bigint():
     from rpython.rlib.rbigint import rbigint
+    assert not pypypolicy.look_inside_function(rbigint.eq.im_func)
+    assert not pypypolicy.look_inside_function(rbigint.ne.im_func)
     assert not pypypolicy.look_inside_function(rbigint.lt.im_func)
+    assert not pypypolicy.look_inside_function(rbigint.le.im_func)
+    assert not pypypolicy.look_inside_function(rbigint.gt.im_func)
+    assert not pypypolicy.look_inside_function(rbigint.ge.im_func)
 
 def test_rlocale():
     from rpython.rlib.rlocale import setlocale
diff --git a/pypy/module/pypyjit/test_pypy_c/test_intbound.py 
b/pypy/module/pypyjit/test_pypy_c/test_intbound.py
--- a/pypy/module/pypyjit/test_pypy_c/test_intbound.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_intbound.py
@@ -231,6 +231,7 @@
         assert loop.match("""
             i8 = int_lt(i6, 300)
             guard_true(i8, descr=...)
+            guard_not_invalidated?
             i10 = int_lshift(i6, 1)
             i12 = int_add_ovf(i5, 1)
             guard_no_overflow(descr=...)
@@ -253,6 +254,7 @@
         assert loop.match("""
             i8 = int_lt(i6, 300)
             guard_true(i8, descr=...)
+            guard_not_invalidated?
             i10 = int_add_ovf(i5, 8)
             guard_no_overflow(descr=...)
             i12 = int_add(i6, 1)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_misc.py 
b/pypy/module/pypyjit/test_pypy_c/test_misc.py
--- a/pypy/module/pypyjit/test_pypy_c/test_misc.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_misc.py
@@ -74,7 +74,6 @@
             jump(..., descr=...)
         """)
 
-
     def test_mixed_type_loop(self):
         def main(n):
             i = 0.0
@@ -94,7 +93,6 @@
             jump(..., descr=...)
         """)
 
-
     def test_cached_pure_func_of_equal_fields(self):
         def main(n):
             class A(object):
@@ -196,7 +194,6 @@
             jump(..., descr=...)
         """)
 
-
     def test_chain_of_guards(self):
         src = """
         class A(object):
@@ -220,7 +217,6 @@
         loops = log.loops_by_filename(self.filepath)
         assert len(loops) == 1
 
-
     def test_unpack_iterable_non_list_tuple(self):
         def main(n):
             import array
@@ -258,7 +254,6 @@
             jump(..., descr=...)
         """)
 
-
     def test_dont_trace_every_iteration(self):
         def main(a, b):
             i = sa = 0
@@ -289,7 +284,6 @@
         assert log.result == 300 * (-10 % -20)
         assert log.jit_summary.tracing_no == 1
 
-
     def test_overflow_checking(self):
         """
         This test only checks that we get the expected result, not that any
@@ -298,7 +292,8 @@
         def main():
             import sys
             def f(a,b):
-                if a < 0: return -1
+                if a < 0:
+                    return -1
                 return a-b
             #
             total = sys.maxint - 2147483647
@@ -309,7 +304,6 @@
         #
         self.run_and_check(main, [])
 
-
     def test_global(self):
         log = self.run("""
         i = 0
@@ -404,3 +398,13 @@
         # the following assertion fails if the loop was cancelled due
         # to "abort: vable escape"
         assert len(log.loops_by_id("exc_info")) == 1
+
+    def test_long_comparison(self):
+        def main(n):
+            while n:
+                12345L > 123L  # ID: long_op
+                n -= 1
+
+        log = self.run(main, [300])
+        loop, = log.loops_by_id("long_op")
+        assert len(loop.ops_by_id("long_op")) == 0
diff --git a/pypy/module/sys/__init__.py b/pypy/module/sys/__init__.py
--- a/pypy/module/sys/__init__.py
+++ b/pypy/module/sys/__init__.py
@@ -7,6 +7,7 @@
 
 class Module(MixedModule):
     """Sys Builtin Module. """
+    _immutable_fields_ = ["defaultencoding?", "debug?"]
 
     def __init__(self, space, w_name):
         """NOT_RPYTHON""" # because parent __init__ isn't
@@ -17,6 +18,7 @@
         self.w_default_encoder = None
         self.defaultencoding = "utf-8"
         self.filesystemencoding = None
+        self.debug = True
 
     interpleveldefs = {
         '__name__'              : '(space.wrap("sys"))', 
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_pointers.py 
b/pypy/module/test_lib_pypy/ctypes_tests/test_pointers.py
--- a/pypy/module/test_lib_pypy/ctypes_tests/test_pointers.py
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_pointers.py
@@ -108,6 +108,13 @@
 
             py.test.raises(TypeError, delitem, p, 0)
 
+    def test_byref(self):
+        for ct, pt in zip(ctype_types, python_types):
+            i = ct(42)
+            p = byref(i)
+            assert type(p._obj) is ct
+            assert p._obj.value == 42
+
     def test_pointer_to_pointer(self):
         x = c_int(32)
         y = c_int(42)
diff --git a/rpython/flowspace/flowcontext.py b/rpython/flowspace/flowcontext.py
--- a/rpython/flowspace/flowcontext.py
+++ b/rpython/flowspace/flowcontext.py
@@ -800,6 +800,9 @@
         self.popvalue()
         return next_instr
 
+    def JUMP_IF_NOT_DEBUG(self, target, next_instr):
+        return next_instr
+
     def GET_ITER(self, oparg, next_instr):
         w_iterable = self.popvalue()
         w_iterator = self.space.iter(w_iterable)
diff --git a/rpython/jit/backend/test/runner_test.py 
b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -1911,6 +1911,29 @@
                                      [BoxPtr(x)], 'int').value
         assert res == -19
 
+    def test_cast_int_to_float(self):
+        if not self.cpu.supports_floats:
+            py.test.skip("requires floats")
+        for x in [-10, -1, 0, 3, 42, sys.maxint-1]:
+            res = self.execute_operation(rop.CAST_INT_TO_FLOAT,
+                                         [BoxInt(x)],  'float').value
+            assert longlong.getrealfloat(res) == float(x)
+            res = self.execute_operation(rop.CAST_INT_TO_FLOAT,
+                                         [ConstInt(x)],  'float').value
+            assert longlong.getrealfloat(res) == float(x)
+
+    def test_cast_float_to_int(self):
+        if not self.cpu.supports_floats:
+            py.test.skip("requires floats")
+        for x in [-24.23, -5.3, 0.0, 3.1234, 11.1, 0.1]:
+            v = longlong.getfloatstorage(x)
+            res = self.execute_operation(rop.CAST_FLOAT_TO_INT,
+                                         [BoxFloat(v)],  'int').value
+            assert res == int(x)
+            res = self.execute_operation(rop.CAST_FLOAT_TO_INT,
+                                         [ConstFloat(v)],  'int').value
+            assert res == int(x)
+
     def test_convert_float_bytes(self):
         if not self.cpu.supports_floats:
             py.test.skip("requires floats")
diff --git a/rpython/jit/codewriter/policy.py b/rpython/jit/codewriter/policy.py
--- a/rpython/jit/codewriter/policy.py
+++ b/rpython/jit/codewriter/policy.py
@@ -39,8 +39,6 @@
         return True # look into everything by default
 
     def _reject_function(self, func):
-        if hasattr(func, '_jit_look_inside_'):
-            return not func._jit_look_inside_
         # explicitly elidable functions are always opaque
         if getattr(func, '_elidable_function_', False):
             return True
@@ -58,8 +56,11 @@
         except AttributeError:
             see_function = True
         else:
-            see_function = (self.look_inside_function(func) and not
-                            self._reject_function(func))
+            if hasattr(func, '_jit_look_inside_'):
+                see_function = func._jit_look_inside_   # override guessing
+            else:
+                see_function = (self.look_inside_function(func) and not
+                                self._reject_function(func))
             contains_loop = contains_loop and not getattr(
                     func, '_jit_unroll_safe_', False)
 
diff --git a/rpython/jit/codewriter/test/test_policy.py 
b/rpython/jit/codewriter/test/test_policy.py
--- a/rpython/jit/codewriter/test/test_policy.py
+++ b/rpython/jit/codewriter/test/test_policy.py
@@ -65,6 +65,20 @@
     graph = support.getgraph(h, [5])
     assert not JitPolicy().look_inside_graph(graph)
 
+def test_look_inside():
+    def h1(x):
+        return x + 1
+    @jit.look_inside    # force True, even if look_inside_function() thinks not
+    def h2(x):
+        return x + 2
+    class MyPolicy(JitPolicy):
+        def look_inside_function(self, func):
+            return False
+    graph1 = support.getgraph(h1, [5])
+    graph2 = support.getgraph(h2, [5])
+    assert not MyPolicy().look_inside_graph(graph1)
+    assert MyPolicy().look_inside_graph(graph2)
+
 def test_loops():
     def g(x):
         i = 0
diff --git a/rpython/jit/metainterp/optimizeopt/intutils.py 
b/rpython/jit/metainterp/optimizeopt/intutils.py
--- a/rpython/jit/metainterp/optimizeopt/intutils.py
+++ b/rpython/jit/metainterp/optimizeopt/intutils.py
@@ -2,12 +2,14 @@
 from rpython.rlib.objectmodel import we_are_translated
 from rpython.jit.metainterp.resoperation import rop, ResOperation
 from rpython.jit.metainterp.history import BoxInt, ConstInt
+
 MAXINT = maxint
 MININT = -maxint - 1
 
+
 class IntBound(object):
     _attrs_ = ('has_upper', 'has_lower', 'upper', 'lower')
-    
+
     def __init__(self, lower, upper):
         self.has_upper = True
         self.has_lower = True
@@ -29,7 +31,7 @@
 
     def make_lt(self, other):
         return self.make_le(other.add(-1))
- 
+
     def make_ge(self, other):
         if other.has_lower:
             if not self.has_lower or other.lower > self.lower:
@@ -86,7 +88,7 @@
                 r = True
 
         return r
-    
+
     def add(self, offset):
         res = self.clone()
         try:
@@ -101,7 +103,7 @@
 
     def mul(self, value):
         return self.mul_bound(IntBound(value, value))
-    
+
     def add_bound(self, other):
         res = self.clone()
         if other.has_upper:
@@ -115,7 +117,7 @@
             try:
                 res.lower = ovfcheck(res.lower + other.lower)
             except OverflowError:
-                res.has_lower = False            
+                res.has_lower = False
         else:
             res.has_lower = False
         return res
@@ -133,7 +135,7 @@
             try:
                 res.lower = ovfcheck(res.lower - other.upper)
             except OverflowError:
-                res.has_lower = False            
+                res.has_lower = False
         else:
             res.has_lower = False
         return res
@@ -196,7 +198,6 @@
         else:
             return IntUnbounded()
 
-
     def contains(self, val):
         if self.has_lower and val < self.lower:
             return False
@@ -216,7 +217,7 @@
         elif self.has_upper:
             return False
         return True
-        
+
     def __repr__(self):
         if self.has_lower:
             l = '%d' % self.lower
@@ -249,7 +250,7 @@
             guards.append(op)
             op = ResOperation(rop.GUARD_TRUE, [res], None)
             guards.append(op)
-    
+
 
 class IntUpperBound(IntBound):
     def __init__(self, upper):
@@ -285,7 +286,7 @@
         self._raise()
     def make_constant(self, value):
         self._raise()
-    def intersect(self, other):        
+    def intersect(self, other):
         self._raise()
 
 def min4(t):
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -83,6 +83,13 @@
     func._jit_look_inside_ = False
     return func
 
+def look_inside(func):
+    """ Make sure the JIT traces inside decorated function, even
+    if the rest of the module is not visible to the JIT
+    """
+    func._jit_look_inside_ = True
+    return func
+
 def unroll_safe(func):
     """ JIT can safely unroll loops in this function and this will
     not lead to code explosion
diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -190,9 +190,9 @@
             
         
     @staticmethod
+    @jit.elidable
     def frombool(b):
-        # This function is marked as pure, so you must not call it and
-        # then modify the result.
+        # You must not call this function and then modify the result.
         if b:
             return ONERBIGINT
         return NULLRBIGINT
@@ -251,6 +251,7 @@
         return _decimalstr_to_bigint(s)
 
     @staticmethod
+    @jit.elidable
     def frombytes(s, byteorder, signed):
         if byteorder not in ('big', 'little'):
             raise InvalidEndiannessError()
@@ -383,9 +384,11 @@
     def tolonglong(self):
         return _AsLongLong(self)
 
+    @jit.look_inside
     def tobool(self):
         return self.sign != 0
 
+    @jit.elidable
     def touint(self):
         if self.sign == -1:
             raise ValueError("cannot convert negative integer to unsigned int")
@@ -410,13 +413,16 @@
             raise ValueError("cannot convert negative integer to unsigned int")
         return _AsULonglong_ignore_sign(self)
 
+    @jit.elidable
     def uintmask(self):
         return _AsUInt_mask(self)
 
+    @jit.elidable
     def ulonglongmask(self):
         """Return r_ulonglong(self), truncating."""
         return _AsULonglong_mask(self)
 
+    @jit.elidable
     def tofloat(self):
         return _AsDouble(self)
 
@@ -448,6 +454,7 @@
             i += 1
         return True
 
+    @jit.look_inside
     def ne(self, other):
         return not self.eq(other)
 
@@ -486,12 +493,15 @@
             i -= 1
         return False
 
+    @jit.look_inside
     def le(self, other):
         return not other.lt(self)
 
+    @jit.look_inside
     def gt(self, other):
         return other.lt(self)
 
+    @jit.look_inside
     def ge(self, other):
         return not self.lt(other)
 
@@ -592,6 +602,7 @@
             
         return div
 
+    @jit.look_inside
     def div(self, other):
         return self.floordiv(other)
 
@@ -792,14 +803,17 @@
             z = z.sub(c)
         return z
 
+    @jit.elidable
     def neg(self):
         return rbigint(self._digits, -self.sign, self.size)
 
+    @jit.elidable
     def abs(self):
         if self.sign != -1:
             return self
         return rbigint(self._digits, 1, self.size)
 
+    @jit.elidable
     def invert(self): #Implement ~x as -(x + 1)
         if self.sign == 0:
             return ONENEGATIVERBIGINT
@@ -909,12 +923,14 @@
     def or_(self, other):
         return _bitwise(self, '|', other)
 
+    @jit.elidable
     def oct(self):
         if self.sign == 0:
             return '0L'
         else:
             return _format(self, BASE8, '0', 'L')
 
+    @jit.elidable
     def hex(self):
         return _format(self, BASE16, '0x', 'L')
 
diff --git a/rpython/rtyper/lltypesystem/rstr.py 
b/rpython/rtyper/lltypesystem/rstr.py
--- a/rpython/rtyper/lltypesystem/rstr.py
+++ b/rpython/rtyper/lltypesystem/rstr.py
@@ -332,7 +332,7 @@
             newstr = s2.malloc(len1 + len2)
             newstr.copy_contents_from_str(s1, newstr, 0, 0, len1)
         else:
-            newstr = s1.malloc(len1 + len2)            
+            newstr = s1.malloc(len1 + len2)
             newstr.copy_contents(s1, newstr, 0, 0, len1)
         if typeOf(s2) == Ptr(STR):
             newstr.copy_contents_from_str(s2, newstr, 0, len1, len2)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to