Author: Laurence Tratt <lau...@tratt.net> Branch: recursion_and_inlining Changeset: r74867:fd5a11ac1b71 Date: 2014-12-09 15:48 +0000 http://bitbucket.org/pypy/pypy/changeset/fd5a11ac1b71/
Log: Merge default. diff too long, truncating to 2000 out of 18633 lines diff --git a/lib-python/2.7/subprocess.py b/lib-python/2.7/subprocess.py --- a/lib-python/2.7/subprocess.py +++ b/lib-python/2.7/subprocess.py @@ -655,6 +655,21 @@ """Create new Popen instance.""" _cleanup() + # --- PyPy hack, see _pypy_install_libs_after_virtualenv() --- + # match arguments passed by different versions of virtualenv + if args[1:] in ( + ['-c', 'import sys; print(sys.prefix)'], # 1.6 10ba3f3c + ['-c', "\nimport sys\nprefix = sys.prefix\n" # 1.7 0e9342ce + "if sys.version_info[0] == 3:\n" + " prefix = prefix.encode('utf8')\n" + "if hasattr(sys.stdout, 'detach'):\n" + " sys.stdout = sys.stdout.detach()\n" + "elif hasattr(sys.stdout, 'buffer'):\n" + " sys.stdout = sys.stdout.buffer\nsys.stdout.write(prefix)\n"], + ['-c', 'import sys;out=sys.stdout;getattr(out, "buffer"' + ', out).write(sys.prefix.encode("utf-8"))']): # 1.7.2 a9454bce + _pypy_install_libs_after_virtualenv(args[0]) + if not isinstance(bufsize, (int, long)): raise TypeError("bufsize must be an integer") @@ -1560,6 +1575,27 @@ self.send_signal(signal.SIGKILL) +def _pypy_install_libs_after_virtualenv(target_executable): + # https://bitbucket.org/pypy/pypy/issue/1922/future-proofing-virtualenv + # + # PyPy 2.4.1 turned --shared on by default. This means the pypy binary + # depends on the 'libpypy-c.so' shared library to be able to run. + # The virtualenv code existing at the time did not account for this + # and would break. Try to detect that we're running under such a + # virtualenv in the "Testing executable with" phase and copy the + # library ourselves. + caller = sys._getframe(2) + if ('virtualenv_version' in caller.f_globals and + 'copyfile' in caller.f_globals): + dest_dir = sys.pypy_resolvedirof(target_executable) + src_dir = sys.pypy_resolvedirof(sys.executable) + for libname in ['libpypy-c.so']: + dest_library = os.path.join(dest_dir, libname) + src_library = os.path.join(src_dir, libname) + if os.path.exists(src_library): + caller.f_globals['copyfile'](src_library, dest_library) + + def _demo_posix(): # # Example 1: Simple redirection: Get process list diff --git a/lib-python/conftest.py b/lib-python/conftest.py --- a/lib-python/conftest.py +++ b/lib-python/conftest.py @@ -59,7 +59,7 @@ def __init__(self, basename, core=False, compiler=None, usemodules='', skip=None): self.basename = basename - self._usemodules = usemodules.split() + ['signal', 'rctime', 'itertools', '_socket'] + self._usemodules = usemodules.split() + ['signal', 'time', 'itertools', '_socket'] self._compiler = compiler self.core = core self.skip = skip diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py --- a/pypy/config/pypyoption.py +++ b/pypy/config/pypyoption.py @@ -29,7 +29,7 @@ # --allworkingmodules working_modules = default_modules.copy() working_modules.update([ - "_socket", "unicodedata", "mmap", "fcntl", "_locale", "pwd", "rctime" , + "_socket", "unicodedata", "mmap", "fcntl", "_locale", "pwd", "time" , "select", "zipimport", "_lsprof", "crypt", "signal", "_rawffi", "termios", "zlib", "bz2", "struct", "_hashlib", "_md5", "_sha", "_minimal_curses", "cStringIO", "thread", "itertools", "pyexpat", "_ssl", "cpyext", "array", @@ -40,7 +40,7 @@ translation_modules = default_modules.copy() translation_modules.update([ - "fcntl", "rctime", "select", "signal", "_rawffi", "zlib", "struct", "_md5", + "fcntl", "time", "select", "signal", "_rawffi", "zlib", "struct", "_md5", "cStringIO", "array", "binascii", # the following are needed for pyrepl (and hence for the # interactive prompt/pdb) @@ -64,19 +64,15 @@ default_modules.add("_locale") if sys.platform == "sunos5": - working_modules.remove('mmap') # depend on ctypes, can't get at c-level 'errono' - working_modules.remove('rctime') # depend on ctypes, missing tm_zone/tm_gmtoff - working_modules.remove('signal') # depend on ctypes, can't get at c-level 'errono' working_modules.remove('fcntl') # LOCK_NB not defined working_modules.remove("_minimal_curses") working_modules.remove("termios") - working_modules.remove("_multiprocessing") # depends on rctime if "cppyy" in working_modules: working_modules.remove("cppyy") # depends on ctypes module_dependencies = { - '_multiprocessing': [('objspace.usemodules.rctime', True), + '_multiprocessing': [('objspace.usemodules.time', True), ('objspace.usemodules.thread', True)], 'cpyext': [('objspace.usemodules.array', True)], 'cppyy': [('objspace.usemodules.cpyext', True)], diff --git a/pypy/doc/config/objspace.usemodules.rctime.txt b/pypy/doc/config/objspace.usemodules.rctime.txt deleted file mode 100644 --- a/pypy/doc/config/objspace.usemodules.rctime.txt +++ /dev/null @@ -1,7 +0,0 @@ -Use the 'rctime' module. - -'rctime' is our `rffi`_ based implementation of the builtin 'time' module. -It supersedes the less complete :config:`objspace.usemodules.time`, -at least for C-like targets (the C and LLVM backends). - -.. _`rffi`: ../rffi.html diff --git a/pypy/doc/config/objspace.usemodules.time.txt b/pypy/doc/config/objspace.usemodules.time.txt --- a/pypy/doc/config/objspace.usemodules.time.txt +++ b/pypy/doc/config/objspace.usemodules.time.txt @@ -1,5 +1,1 @@ Use the 'time' module. - -Obsolete; use :config:`objspace.usemodules.rctime` for our up-to-date version -of the application-level 'time' module, at least for C-like targets (the C -and LLVM backends). diff --git a/pypy/doc/cpython_differences.rst b/pypy/doc/cpython_differences.rst --- a/pypy/doc/cpython_differences.rst +++ b/pypy/doc/cpython_differences.rst @@ -205,23 +205,28 @@ The above is true both in CPython and in PyPy. Differences can occur about whether a built-in function or method will call an overridden method of *another* object than ``self``. -In PyPy, they are generally always called, whereas not in -CPython. For example, in PyPy, ``dict1.update(dict2)`` -considers that ``dict2`` is just a general mapping object, and -will thus call overridden ``keys()`` and ``__getitem__()`` -methods on it. So the following code prints ``42`` on PyPy -but ``foo`` on CPython:: +In PyPy, they are often called in cases where CPython would not. +Two examples:: - >>>> class D(dict): - .... def __getitem__(self, key): - .... return 42 - .... - >>>> - >>>> d1 = {} - >>>> d2 = D(a='foo') - >>>> d1.update(d2) - >>>> print d1['a'] - 42 + class D(dict): + def __getitem__(self, key): + return "%r from D" % (key,) + + class A(object): + pass + + a = A() + a.__dict__ = D() + a.foo = "a's own foo" + print a.foo + # CPython => a's own foo + # PyPy => 'foo' from D + + glob = D(foo="base item") + loc = {} + exec "print foo" in glob, loc + # CPython => base item + # PyPy => 'foo' from D Mutating classes of objects which are already used as dictionary keys @@ -292,6 +297,9 @@ above types will return a value that is computed from the argument, and can thus be larger than ``sys.maxint`` (i.e. it can be an arbitrary long). +Notably missing from the list above are ``str`` and ``unicode``. If your +code relies on comparing strings with ``is``, then it might break in PyPy. + Miscellaneous ------------- diff --git a/pypy/doc/embedding.rst b/pypy/doc/embedding.rst --- a/pypy/doc/embedding.rst +++ b/pypy/doc/embedding.rst @@ -6,6 +6,10 @@ C. It was developed in collaboration with Roberto De Ioris from the `uwsgi`_ project. The `PyPy uwsgi plugin`_ is a good example of using the embedding API. +**NOTE**: As of 1st of December, PyPy comes with ``--shared`` by default +on linux, linux64 and windows. We will make it the default on all platforms +by the time of the next release. + The first thing that you need is to compile PyPy yourself with the option ``--shared``. We plan to make ``--shared`` the default in the future. Consult the `how to compile PyPy`_ doc for details. This will result in ``libpypy.so`` diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst --- a/pypy/doc/project-ideas.rst +++ b/pypy/doc/project-ideas.rst @@ -35,6 +35,13 @@ PyPy's bytearray type is very inefficient. It would be an interesting task to look into possible optimizations on this. +Implement AF_XXX packet types for PyPy +-------------------------------------- + +PyPy is missing AF_XXX types of sockets. Implementing it is easy-to-medium +task. `bug report`_ + +.. _`bug report`: https://bitbucket.org/pypy/pypy/issue/1942/support-for-af_xxx-sockets#more Implement copy-on-write list slicing ------------------------------------ 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 @@ -43,3 +43,11 @@ .. branch nditer-external_loop Implement `external_loop` arguement to numpy's nditer + +.. branch kill-rctime + +Rename pypy/module/rctime to pypy/module/time, since it contains the implementation of the 'time' module. + +.. branch: ssa-flow + +Use SSA form for flow graphs inside build_flow() and part of simplify_graph() 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 @@ -1,15 +1,13 @@ -""" -Python control flow graph generation and bytecode assembly. -""" +"""Python control flow graph generation and bytecode assembly.""" -from pypy.interpreter.astcompiler import ast, symtable -from pypy.interpreter import pycode +from rpython.rlib import rfloat +from rpython.rlib.objectmodel import we_are_translated + +from pypy.interpreter.astcompiler import ast, misc, symtable +from pypy.interpreter.error import OperationError +from pypy.interpreter.pycode import PyCode from pypy.tool import stdlib_opcode as ops -from pypy.interpreter.error import OperationError -from rpython.rlib.objectmodel import we_are_translated -from rpython.rlib import rfloat - class Instruction(object): """Represents a single opcode.""" @@ -21,14 +19,12 @@ self.has_jump = False def size(self): - """Return the size of bytes of this instruction when it is encoded.""" + """Return the size of bytes of this instruction when it is + encoded. + """ if self.opcode >= ops.HAVE_ARGUMENT: - if self.arg > 0xFFFF: - return 6 - else: - return 3 - else: - return 1 + return (6 if self.arg > 0xFFFF else 3) + return 1 def jump_to(self, target, absolute=False): """Indicate the target this jump instruction. @@ -54,9 +50,9 @@ class Block(object): """A basic control flow block. - It has one entry point and several possible exit points. Its instructions - may be jumps to other blocks, or if control flow reaches the end of the - block, it continues to next_block. + It has one entry point and several possible exit points. Its + instructions may be jumps to other blocks, or if control flow + reaches the end of the block, it continues to next_block. """ def __init__(self): @@ -71,10 +67,10 @@ stack.append(nextblock) def post_order(self): - """Return this block and its children in post order. - This means that the graph of blocks is first cleaned up to - ignore back-edges, thus turning it into a DAG. Then the DAG - is linearized. For example: + """Return this block and its children in post order. This means + that the graph of blocks is first cleaned up to ignore + back-edges, thus turning it into a DAG. Then the DAG is + linearized. For example: A --> B -\ => [A, D, B, C] \-> D ---> C @@ -105,7 +101,9 @@ return resultblocks def code_size(self): - """Return the encoded size of all the instructions in this block.""" + """Return the encoded size of all the instructions in this + block. + """ i = 0 for instr in self.instructions: i += instr.size() @@ -141,6 +139,7 @@ i += 1 return result + def _list_to_dict(l, offset=0): result = {} index = offset @@ -300,11 +299,11 @@ def _resolve_block_targets(self, blocks): """Compute the arguments of jump instructions.""" last_extended_arg_count = 0 - # The reason for this loop is extended jumps. EXTENDED_ARG extends the - # bytecode size, so it might invalidate the offsets we've already given. - # Thus we have to loop until the number of extended args is stable. Any - # extended jump at all is extremely rare, so performance is not too - # concerning. + # The reason for this loop is extended jumps. EXTENDED_ARG + # extends the bytecode size, so it might invalidate the offsets + # we've already given. Thus we have to loop until the number of + # extended args is stable. Any extended jump at all is + # extremely rare, so performance is not too concerning. while True: extended_arg_count = 0 offset = 0 @@ -330,7 +329,8 @@ instr.opcode = ops.JUMP_ABSOLUTE absolute = True elif target_op == ops.RETURN_VALUE: - # Replace JUMP_* to a RETURN into just a RETURN + # Replace JUMP_* to a RETURN into + # just a RETURN instr.opcode = ops.RETURN_VALUE instr.arg = 0 instr.has_jump = False @@ -345,7 +345,8 @@ instr.arg = jump_arg if jump_arg > 0xFFFF: extended_arg_count += 1 - if extended_arg_count == last_extended_arg_count and not force_redo: + if (extended_arg_count == last_extended_arg_count and + not force_redo): break else: last_extended_arg_count = extended_arg_count @@ -360,12 +361,14 @@ while True: try: w_key = space.next(w_iter) - except OperationError, e: + except OperationError as e: if not e.match(space, space.w_StopIteration): raise break w_index = space.getitem(w_consts, w_key) - consts_w[space.int_w(w_index)] = space.getitem(w_key, first) + w_constant = space.getitem(w_key, first) + w_constant = misc.intern_if_common_string(space, w_constant) + consts_w[space.int_w(w_index)] = w_constant return consts_w def _get_code_flags(self): @@ -433,15 +436,16 @@ continue addr = offset - current_off # Python assumes that lineno always increases with - # increasing bytecode address (lnotab is unsigned char). - # Depending on when SET_LINENO instructions are emitted this - # is not always true. Consider the code: + # increasing bytecode address (lnotab is unsigned + # char). Depending on when SET_LINENO instructions + # are emitted this is not always true. Consider the + # code: # a = (1, # b) - # In the bytecode stream, the assignment to "a" occurs after - # the loading of "b". This works with the C Python compiler - # because it only generates a SET_LINENO instruction for the - # assignment. + # In the bytecode stream, the assignment to "a" + # occurs after the loading of "b". This works with + # the C Python compiler because it only generates a + # SET_LINENO instruction for the assignment. if line or addr: while addr > 255: push(chr(255)) @@ -484,22 +488,22 @@ free_names = _list_from_dict(self.free_vars, len(cell_names)) flags = self._get_code_flags() | self.compile_info.flags bytecode = ''.join([block.get_code() for block in blocks]) - return pycode.PyCode(self.space, - self.argcount, - len(self.var_names), - stack_depth, - flags, - bytecode, - list(consts_w), - names, - var_names, - self.compile_info.filename, - self.name, - self.first_lineno, - lnotab, - free_names, - cell_names, - self.compile_info.hidden_applevel) + return PyCode(self.space, + self.argcount, + len(self.var_names), + stack_depth, + flags, + bytecode, + list(consts_w), + names, + var_names, + self.compile_info.filename, + self.name, + self.first_lineno, + lnotab, + free_names, + cell_names, + self.compile_info.hidden_applevel) def _list_from_dict(d, offset=0): @@ -510,134 +514,134 @@ _static_opcode_stack_effects = { - ops.NOP : 0, - ops.STOP_CODE : 0, + ops.NOP: 0, + ops.STOP_CODE: 0, - ops.POP_TOP : -1, - ops.ROT_TWO : 0, - ops.ROT_THREE : 0, - ops.ROT_FOUR : 0, - ops.DUP_TOP : 1, + ops.POP_TOP: -1, + ops.ROT_TWO: 0, + ops.ROT_THREE: 0, + ops.ROT_FOUR: 0, + ops.DUP_TOP: 1, - ops.UNARY_POSITIVE : 0, - ops.UNARY_NEGATIVE : 0, - ops.UNARY_NOT : 0, - ops.UNARY_CONVERT : 0, - ops.UNARY_INVERT : 0, + ops.UNARY_POSITIVE: 0, + ops.UNARY_NEGATIVE: 0, + ops.UNARY_NOT: 0, + ops.UNARY_CONVERT: 0, + ops.UNARY_INVERT: 0, - ops.LIST_APPEND : -1, - ops.SET_ADD : -1, - ops.MAP_ADD : -2, - ops.STORE_MAP : -2, + ops.LIST_APPEND: -1, + ops.SET_ADD: -1, + ops.MAP_ADD: -2, + ops.STORE_MAP: -2, - ops.BINARY_POWER : -1, - ops.BINARY_MULTIPLY : -1, - ops.BINARY_DIVIDE : -1, - ops.BINARY_MODULO : -1, - ops.BINARY_ADD : -1, - ops.BINARY_SUBTRACT : -1, - ops.BINARY_SUBSCR : -1, - ops.BINARY_FLOOR_DIVIDE : -1, - ops.BINARY_TRUE_DIVIDE : -1, - ops.BINARY_LSHIFT : -1, - ops.BINARY_RSHIFT : -1, - ops.BINARY_AND : -1, - ops.BINARY_OR : -1, - ops.BINARY_XOR : -1, + ops.BINARY_POWER: -1, + ops.BINARY_MULTIPLY: -1, + ops.BINARY_DIVIDE: -1, + ops.BINARY_MODULO: -1, + ops.BINARY_ADD: -1, + ops.BINARY_SUBTRACT: -1, + ops.BINARY_SUBSCR: -1, + ops.BINARY_FLOOR_DIVIDE: -1, + ops.BINARY_TRUE_DIVIDE: -1, + ops.BINARY_LSHIFT: -1, + ops.BINARY_RSHIFT: -1, + ops.BINARY_AND: -1, + ops.BINARY_OR: -1, + ops.BINARY_XOR: -1, - ops.INPLACE_FLOOR_DIVIDE : -1, - ops.INPLACE_TRUE_DIVIDE : -1, - ops.INPLACE_ADD : -1, - ops.INPLACE_SUBTRACT : -1, - ops.INPLACE_MULTIPLY : -1, - ops.INPLACE_DIVIDE : -1, - ops.INPLACE_MODULO : -1, - ops.INPLACE_POWER : -1, - ops.INPLACE_LSHIFT : -1, - ops.INPLACE_RSHIFT : -1, - ops.INPLACE_AND : -1, - ops.INPLACE_OR : -1, - ops.INPLACE_XOR : -1, + ops.INPLACE_FLOOR_DIVIDE: -1, + ops.INPLACE_TRUE_DIVIDE: -1, + ops.INPLACE_ADD: -1, + ops.INPLACE_SUBTRACT: -1, + ops.INPLACE_MULTIPLY: -1, + ops.INPLACE_DIVIDE: -1, + ops.INPLACE_MODULO: -1, + ops.INPLACE_POWER: -1, + ops.INPLACE_LSHIFT: -1, + ops.INPLACE_RSHIFT: -1, + ops.INPLACE_AND: -1, + ops.INPLACE_OR: -1, + ops.INPLACE_XOR: -1, - ops.SLICE+0 : 1, - ops.SLICE+1 : 0, - ops.SLICE+2 : 0, - ops.SLICE+3 : -1, - ops.STORE_SLICE+0 : -2, - ops.STORE_SLICE+1 : -3, - ops.STORE_SLICE+2 : -3, - ops.STORE_SLICE+3 : -4, - ops.DELETE_SLICE+0 : -1, - ops.DELETE_SLICE+1 : -2, - ops.DELETE_SLICE+2 : -2, - ops.DELETE_SLICE+3 : -3, + ops.SLICE+0: 1, + ops.SLICE+1: 0, + ops.SLICE+2: 0, + ops.SLICE+3: -1, + ops.STORE_SLICE+0: -2, + ops.STORE_SLICE+1: -3, + ops.STORE_SLICE+2: -3, + ops.STORE_SLICE+3: -4, + ops.DELETE_SLICE+0: -1, + ops.DELETE_SLICE+1: -2, + ops.DELETE_SLICE+2: -2, + ops.DELETE_SLICE+3: -3, - ops.STORE_SUBSCR : -2, - ops.DELETE_SUBSCR : -2, + ops.STORE_SUBSCR: -2, + ops.DELETE_SUBSCR: -2, - ops.GET_ITER : 0, - ops.FOR_ITER : 1, - ops.BREAK_LOOP : 0, - ops.CONTINUE_LOOP : 0, - ops.SETUP_LOOP : 0, + ops.GET_ITER: 0, + ops.FOR_ITER: 1, + ops.BREAK_LOOP: 0, + ops.CONTINUE_LOOP: 0, + ops.SETUP_LOOP: 0, - ops.PRINT_EXPR : -1, - ops.PRINT_ITEM : -1, - ops.PRINT_NEWLINE : 0, - ops.PRINT_ITEM_TO : -2, - ops.PRINT_NEWLINE_TO : -1, + ops.PRINT_EXPR: -1, + ops.PRINT_ITEM: -1, + ops.PRINT_NEWLINE: 0, + ops.PRINT_ITEM_TO: -2, + ops.PRINT_NEWLINE_TO: -1, - ops.WITH_CLEANUP : -1, - ops.POP_BLOCK : 0, - ops.END_FINALLY : -1, - ops.SETUP_WITH : 1, - ops.SETUP_FINALLY : 0, - ops.SETUP_EXCEPT : 0, + ops.WITH_CLEANUP: -1, + ops.POP_BLOCK: 0, + ops.END_FINALLY: -1, + ops.SETUP_WITH: 1, + ops.SETUP_FINALLY: 0, + ops.SETUP_EXCEPT: 0, - ops.LOAD_LOCALS : 1, - ops.RETURN_VALUE : -1, - ops.EXEC_STMT : -3, - ops.YIELD_VALUE : 0, - ops.BUILD_CLASS : -2, - ops.BUILD_MAP : 1, - ops.BUILD_SET : 1, - ops.COMPARE_OP : -1, + ops.LOAD_LOCALS: 1, + ops.RETURN_VALUE: -1, + ops.EXEC_STMT: -3, + ops.YIELD_VALUE: 0, + ops.BUILD_CLASS: -2, + ops.BUILD_MAP: 1, + ops.BUILD_SET: 1, + ops.COMPARE_OP: -1, - ops.LOOKUP_METHOD : 1, + ops.LOOKUP_METHOD: 1, - ops.LOAD_NAME : 1, - ops.STORE_NAME : -1, - ops.DELETE_NAME : 0, + ops.LOAD_NAME: 1, + ops.STORE_NAME: -1, + ops.DELETE_NAME: 0, - ops.LOAD_FAST : 1, - ops.STORE_FAST : -1, - ops.DELETE_FAST : 0, + ops.LOAD_FAST: 1, + ops.STORE_FAST: -1, + ops.DELETE_FAST: 0, - ops.LOAD_ATTR : 0, - ops.STORE_ATTR : -2, - ops.DELETE_ATTR : -1, + ops.LOAD_ATTR: 0, + ops.STORE_ATTR: -2, + ops.DELETE_ATTR: -1, - ops.LOAD_GLOBAL : 1, - ops.STORE_GLOBAL : -1, - ops.DELETE_GLOBAL : 0, + ops.LOAD_GLOBAL: 1, + ops.STORE_GLOBAL: -1, + ops.DELETE_GLOBAL: 0, - ops.LOAD_CLOSURE : 1, - ops.LOAD_DEREF : 1, - ops.STORE_DEREF : -1, + ops.LOAD_CLOSURE: 1, + ops.LOAD_DEREF: 1, + ops.STORE_DEREF: -1, - ops.LOAD_CONST : 1, + ops.LOAD_CONST: 1, - ops.IMPORT_STAR : -1, - ops.IMPORT_NAME : -1, - ops.IMPORT_FROM : 1, + ops.IMPORT_STAR: -1, + ops.IMPORT_NAME: -1, + ops.IMPORT_FROM: 1, - ops.JUMP_FORWARD : 0, - ops.JUMP_ABSOLUTE : 0, - ops.JUMP_IF_TRUE_OR_POP : 0, - 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.JUMP_FORWARD: 0, + ops.JUMP_ABSOLUTE: 0, + ops.JUMP_IF_TRUE_OR_POP: 0, + 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/misc.py b/pypy/interpreter/astcompiler/misc.py --- a/pypy/interpreter/astcompiler/misc.py +++ b/pypy/interpreter/astcompiler/misc.py @@ -106,3 +106,13 @@ except IndexError: return name return "_%s%s" % (klass[i:], name) + + +def intern_if_common_string(space, w_const): + # only intern identifier-like strings + if not space.is_w(space.type(w_const), space.w_str): + return w_const + for c in space.str_w(w_const): + if not (c.isalnum() or c == '_'): + return w_const + return space.new_interned_w_str(w_const) diff --git a/pypy/interpreter/astcompiler/optimize.py b/pypy/interpreter/astcompiler/optimize.py --- a/pypy/interpreter/astcompiler/optimize.py +++ b/pypy/interpreter/astcompiler/optimize.py @@ -272,6 +272,11 @@ if w_const is None: return tup consts_w[i] = w_const + # intern the string constants packed into the tuple here, + # because assemble.py will see the result as just a tuple constant + for i in range(len(consts_w)): + consts_w[i] = misc.intern_if_common_string( + self.space, consts_w[i]) else: consts_w = [] w_consts = self.space.newtuple(consts_w) diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py --- a/pypy/interpreter/baseobjspace.py +++ b/pypy/interpreter/baseobjspace.py @@ -14,7 +14,7 @@ UserDelAction) from pypy.interpreter.error import OperationError, new_exception_class, oefmt from pypy.interpreter.argument import Arguments -from pypy.interpreter.miscutils import ThreadLocals +from pypy.interpreter.miscutils import ThreadLocals, make_weak_value_dictionary __all__ = ['ObjSpace', 'OperationError', 'W_Root'] @@ -384,7 +384,7 @@ self.builtin_modules = {} self.reloading_modules = {} - self.interned_strings = {} + self.interned_strings = make_weak_value_dictionary(self, str, W_Root) self.actionflag = ActionFlag() # changed by the signal module self.check_signal_action = None # changed by the signal module self.user_del_action = UserDelAction(self) @@ -522,11 +522,6 @@ if name not in modules: modules.append(name) - # a bit of custom logic: rctime take precedence over time - # XXX this could probably be done as a "requires" in the config - if 'rctime' in modules and 'time' in modules: - modules.remove('time') - self._builtinmodule_list = modules return self._builtinmodule_list @@ -782,25 +777,30 @@ return self.w_False def new_interned_w_str(self, w_s): + assert isinstance(w_s, W_Root) # and is not None s = self.str_w(w_s) if not we_are_translated(): assert type(s) is str - try: - return self.interned_strings[s] - except KeyError: - pass - self.interned_strings[s] = w_s - return w_s + w_s1 = self.interned_strings.get(s) + if w_s1 is None: + w_s1 = w_s + self.interned_strings.set(s, w_s1) + return w_s1 def new_interned_str(self, s): if not we_are_translated(): assert type(s) is str - try: - return self.interned_strings[s] - except KeyError: - pass - w_s = self.interned_strings[s] = self.wrap(s) - return w_s + w_s1 = self.interned_strings.get(s) + if w_s1 is None: + w_s1 = self.wrap(s) + self.interned_strings.set(s, w_s1) + return w_s1 + + def is_interned_str(self, s): + # interface for marshal_impl + if not we_are_translated(): + assert type(s) is str + return self.interned_strings.get(s) is not None def descr_self_interp_w(self, RequiredClass, w_obj): if not isinstance(w_obj, RequiredClass): diff --git a/pypy/interpreter/miscutils.py b/pypy/interpreter/miscutils.py --- a/pypy/interpreter/miscutils.py +++ b/pypy/interpreter/miscutils.py @@ -31,3 +31,19 @@ def getallvalues(self): return {0: self._value} + + +def make_weak_value_dictionary(space, keytype, valuetype): + "NOT_RPYTHON" + if space.config.translation.rweakref: + from rpython.rlib.rweakref import RWeakValueDictionary + return RWeakValueDictionary(keytype, valuetype) + else: + class FakeWeakValueDict(object): + def __init__(self): + self._dict = {} + def get(self, key): + return self._dict.get(key, None) + def set(self, key, value): + self._dict[key] = value + return FakeWeakValueDict() diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py --- a/pypy/interpreter/pyframe.py +++ b/pypy/interpreter/pyframe.py @@ -131,7 +131,6 @@ # class bodies only have CO_NEWLOCALS. # CO_NEWLOCALS: make a locals dict unless optimized is also set # CO_OPTIMIZED: no locals dict needed at all - # NB: this method is overridden in nestedscope.py flags = code.co_flags if not (flags & pycode.CO_OPTIMIZED): if flags & pycode.CO_NEWLOCALS: diff --git a/pypy/interpreter/test/test_compiler.py b/pypy/interpreter/test/test_compiler.py --- a/pypy/interpreter/test/test_compiler.py +++ b/pypy/interpreter/test/test_compiler.py @@ -970,7 +970,12 @@ sys.stdout = out output = s.getvalue() assert "CALL_METHOD" in output - + + def test_interned_strings(self): + source = """x = ('foo_bar42', 5); y = 'foo_bar42'; z = x[0]""" + exec source + assert y is z + class AppTestExceptions: def test_indentation_error(self): diff --git a/pypy/interpreter/test/test_objspace.py b/pypy/interpreter/test/test_objspace.py --- a/pypy/interpreter/test/test_objspace.py +++ b/pypy/interpreter/test/test_objspace.py @@ -378,3 +378,41 @@ assert space.str_w(space.getattr(space.sys, w_executable)) == 'foobar' space.startup() assert space.str_w(space.getattr(space.sys, w_executable)) == 'foobar' + + def test_interned_strings_are_weak(self): + import weakref, gc, random + space = self.space + assert space.config.translation.rweakref + w1 = space.new_interned_str("abcdef") + w2 = space.new_interned_str("abcdef") + assert w2 is w1 + # + # check that 'w1' goes away if we don't hold a reference to it + rw1 = weakref.ref(w1) + del w1, w2 + i = 10 + while rw1() is not None: + i -= 1 + assert i >= 0 + gc.collect() + # + s = "foobar%r" % random.random() + w0 = space.wrap(s) + w1 = space.new_interned_w_str(w0) + assert w1 is w0 + w2 = space.new_interned_w_str(w0) + assert w2 is w0 + w3 = space.wrap(s) + assert w3 is not w0 + w4 = space.new_interned_w_str(w3) + assert w4 is w0 + # + # check that 'w0' goes away if we don't hold a reference to it + # (even if we hold a reference to 'w3') + rw0 = weakref.ref(w0) + del w0, w1, w2, w4 + i = 10 + while rw0() is not None: + i -= 1 + assert i >= 0 + gc.collect() diff --git a/pypy/module/_cffi_backend/ctypeprim.py b/pypy/module/_cffi_backend/ctypeprim.py --- a/pypy/module/_cffi_backend/ctypeprim.py +++ b/pypy/module/_cffi_backend/ctypeprim.py @@ -158,21 +158,14 @@ class W_CTypePrimitiveSigned(W_CTypePrimitive): - _attrs_ = ['value_fits_long', 'vmin', 'vrangemax'] - _immutable_fields_ = ['value_fits_long', 'vmin', 'vrangemax'] + _attrs_ = ['value_fits_long', 'value_smaller_than_long'] + _immutable_fields_ = ['value_fits_long', 'value_smaller_than_long'] is_primitive_integer = True def __init__(self, *args): W_CTypePrimitive.__init__(self, *args) self.value_fits_long = self.size <= rffi.sizeof(lltype.Signed) - if self.size < rffi.sizeof(lltype.Signed): - assert self.value_fits_long - sh = self.size * 8 - self.vmin = r_uint(-1) << (sh - 1) - self.vrangemax = (r_uint(1) << sh) - 1 - else: - self.vmin = r_uint(0) - self.vrangemax = r_uint(-1) + self.value_smaller_than_long = self.size < rffi.sizeof(lltype.Signed) def cast_to_int(self, cdata): return self.convert_to_object(cdata) @@ -192,8 +185,17 @@ def convert_from_object(self, cdata, w_ob): if self.value_fits_long: value = misc.as_long(self.space, w_ob) - if self.size < rffi.sizeof(lltype.Signed): - if r_uint(value) - self.vmin > self.vrangemax: + if self.value_smaller_than_long: + size = self.size + if size == 1: + signextended = misc.signext(value, 1) + elif size == 2: + signextended = misc.signext(value, 2) + elif size == 4: + signextended = misc.signext(value, 4) + else: + raise AssertionError("unsupported size") + if value != signextended: self._overflow(w_ob) misc.write_raw_signed_data(cdata, value, self.size) else: @@ -221,7 +223,7 @@ length = w_cdata.get_array_length() populate_list_from_raw_array(res, buf, length) return res - elif self.value_fits_long: + elif self.value_smaller_than_long: res = [0] * w_cdata.get_array_length() misc.unpack_list_from_raw_array(res, w_cdata._cdata, self.size) return res @@ -235,8 +237,8 @@ cdata = rffi.cast(rffi.LONGP, cdata) copy_list_to_raw_array(int_list, cdata) else: - overflowed = misc.pack_list_to_raw_array_bounds( - int_list, cdata, self.size, self.vmin, self.vrangemax) + overflowed = misc.pack_list_to_raw_array_bounds_signed( + int_list, cdata, self.size) if overflowed != 0: self._overflow(self.space.wrap(overflowed)) return True @@ -314,8 +316,8 @@ def pack_list_of_items(self, cdata, w_ob): int_list = self.space.listview_int(w_ob) if int_list is not None: - overflowed = misc.pack_list_to_raw_array_bounds( - int_list, cdata, self.size, r_uint(0), self.vrangemax) + overflowed = misc.pack_list_to_raw_array_bounds_unsigned( + int_list, cdata, self.size, self.vrangemax) if overflowed != 0: self._overflow(self.space.wrap(overflowed)) return True diff --git a/pypy/module/_cffi_backend/misc.py b/pypy/module/_cffi_backend/misc.py --- a/pypy/module/_cffi_backend/misc.py +++ b/pypy/module/_cffi_backend/misc.py @@ -216,6 +216,19 @@ neg_msg = "can't convert negative number to unsigned" ovf_msg = "long too big to convert" +@specialize.arg(1) +def signext(value, size): + # 'value' is sign-extended from 'size' bytes to a full integer. + # 'size' should be a constant smaller than a full integer size. + if size == rffi.sizeof(rffi.SIGNEDCHAR): + return rffi.cast(lltype.Signed, rffi.cast(rffi.SIGNEDCHAR, value)) + elif size == rffi.sizeof(rffi.SHORT): + return rffi.cast(lltype.Signed, rffi.cast(rffi.SHORT, value)) + elif size == rffi.sizeof(rffi.INT): + return rffi.cast(lltype.Signed, rffi.cast(rffi.INT, value)) + else: + raise AssertionError("unsupported size") + # ____________________________________________________________ class _NotStandardObject(Exception): @@ -334,13 +347,26 @@ # ____________________________________________________________ -def pack_list_to_raw_array_bounds(int_list, target, size, vmin, vrangemax): +def pack_list_to_raw_array_bounds_signed(int_list, target, size): for TP, TPP in _prim_signed_types: if size == rffi.sizeof(TP): ptr = rffi.cast(TPP, target) for i in range(len(int_list)): x = int_list[i] - if r_uint(x) - vmin > vrangemax: + y = rffi.cast(TP, x) + if x != rffi.cast(lltype.Signed, y): + return x # overflow + ptr[i] = y + return 0 + raise NotImplementedError("bad integer size") + +def pack_list_to_raw_array_bounds_unsigned(int_list, target, size, vrangemax): + for TP, TPP in _prim_signed_types: + if size == rffi.sizeof(TP): + ptr = rffi.cast(TPP, target) + for i in range(len(int_list)): + x = int_list[i] + if r_uint(x) > vrangemax: return x # overflow ptr[i] = rffi.cast(TP, x) return 0 diff --git a/pypy/module/_file/test/test_file.py b/pypy/module/_file/test/test_file.py --- a/pypy/module/_file/test/test_file.py +++ b/pypy/module/_file/test/test_file.py @@ -304,7 +304,7 @@ py.test.skip("works with internals of _file impl on py.py") state = [0] def read(fd, n=None): - if fd != 42: + if fd != 424242: return cls.old_read(fd, n) if state[0] == 0: state[0] += 1 @@ -315,7 +315,7 @@ return '' os.read = read stdin = W_File(cls.space) - stdin.file_fdopen(42, 'rb', 1) + stdin.file_fdopen(424242, 'rb', 1) stdin.name = '<stdin>' cls.w_stream = stdin diff --git a/pypy/module/_file/test/test_file_extra.py b/pypy/module/_file/test/test_file_extra.py --- a/pypy/module/_file/test/test_file_extra.py +++ b/pypy/module/_file/test/test_file_extra.py @@ -221,7 +221,7 @@ expected_filename = str(udir.join('sample')) expected_mode = 'rb' extra_args = () - spaceconfig = {'usemodules': ['binascii', 'rctime', 'struct']} + spaceconfig = {'usemodules': ['binascii', 'time', 'struct']} def setup_method(self, method): space = self.space @@ -281,7 +281,7 @@ expected_filename = '<fdopen>' expected_mode = 'rb' extra_args = () - spaceconfig = {'usemodules': ['binascii', 'rctime', 'struct']} + spaceconfig = {'usemodules': ['binascii', 'time', 'struct']} def setup_method(self, method): space = self.space @@ -359,7 +359,7 @@ # A few extra tests class AppTestAFewExtra: - spaceconfig = {'usemodules': ['_socket', 'array', 'binascii', 'rctime', + spaceconfig = {'usemodules': ['_socket', 'array', 'binascii', 'time', 'struct']} def setup_method(self, method): diff --git a/pypy/module/_lsprof/test/test_cprofile.py b/pypy/module/_lsprof/test/test_cprofile.py --- a/pypy/module/_lsprof/test/test_cprofile.py +++ b/pypy/module/_lsprof/test/test_cprofile.py @@ -1,6 +1,6 @@ class AppTestCProfile(object): spaceconfig = { - "usemodules": ['_lsprof', 'rctime'], + "usemodules": ['_lsprof', 'time'], } def setup_class(cls): diff --git a/pypy/module/_md5/test/test_md5.py b/pypy/module/_md5/test/test_md5.py --- a/pypy/module/_md5/test/test_md5.py +++ b/pypy/module/_md5/test/test_md5.py @@ -5,7 +5,7 @@ class AppTestMD5(object): spaceconfig = { - 'usemodules': ['_md5', 'binascii', 'rctime', 'struct'], + 'usemodules': ['_md5', 'binascii', 'time', 'struct'], } def setup_class(cls): diff --git a/pypy/module/_multiprocessing/interp_semaphore.py b/pypy/module/_multiprocessing/interp_semaphore.py --- a/pypy/module/_multiprocessing/interp_semaphore.py +++ b/pypy/module/_multiprocessing/interp_semaphore.py @@ -254,7 +254,7 @@ start = _GetTickCount() while True: - from pypy.module.rctime.interp_time import State + from pypy.module.time.interp_time import State interrupt_event = space.fromcache(State).get_interrupt_event() handles = [self.handle, interrupt_event] diff --git a/pypy/module/_random/test/test_random.py b/pypy/module/_random/test/test_random.py --- a/pypy/module/_random/test/test_random.py +++ b/pypy/module/_random/test/test_random.py @@ -1,6 +1,6 @@ class AppTestRandom: spaceconfig = { - "usemodules": ['_random', 'rctime'], + "usemodules": ['_random', 'time'], } def test_dict(self): diff --git a/pypy/module/_sha/test/test_sha.py b/pypy/module/_sha/test/test_sha.py --- a/pypy/module/_sha/test/test_sha.py +++ b/pypy/module/_sha/test/test_sha.py @@ -5,7 +5,7 @@ class AppTestSHA(object): spaceconfig = { - 'usemodules': ['_sha', 'binascii', 'rctime', 'struct'], + 'usemodules': ['_sha', 'binascii', 'time', 'struct'], } def setup_class(cls): diff --git a/pypy/module/_ssl/interp_ssl.py b/pypy/module/_ssl/interp_ssl.py --- a/pypy/module/_ssl/interp_ssl.py +++ b/pypy/module/_ssl/interp_ssl.py @@ -52,7 +52,8 @@ if not OPENSSL_NO_SSL2: constants["PROTOCOL_SSLv2"] = PY_SSL_VERSION_SSL2 -constants["PROTOCOL_SSLv3"] = PY_SSL_VERSION_SSL3 +if not OPENSSL_NO_SSL3: + constants["PROTOCOL_SSLv3"] = PY_SSL_VERSION_SSL3 constants["PROTOCOL_SSLv23"] = PY_SSL_VERSION_SSL23 constants["PROTOCOL_TLSv1"] = PY_SSL_VERSION_TLS1 @@ -656,7 +657,7 @@ # set up context if protocol == PY_SSL_VERSION_TLS1: method = libssl_TLSv1_method() - elif protocol == PY_SSL_VERSION_SSL3: + elif protocol == PY_SSL_VERSION_SSL3 and not OPENSSL_NO_SSL3: method = libssl_SSLv3_method() elif protocol == PY_SSL_VERSION_SSL2 and not OPENSSL_NO_SSL2: method = libssl_SSLv2_method() diff --git a/pypy/module/_ssl/thread_lock.py b/pypy/module/_ssl/thread_lock.py --- a/pypy/module/_ssl/thread_lock.py +++ b/pypy/module/_ssl/thread_lock.py @@ -24,12 +24,19 @@ separate_module_source = """ #include <openssl/crypto.h> +#ifndef _WIN32 +# include <pthread.h> +#endif static unsigned int _ssl_locks_count = 0; static struct RPyOpaque_ThreadLock *_ssl_locks; static unsigned long _ssl_thread_id_function(void) { - return RPyThreadGetIdent(); +#ifdef _WIN32 + return (unsigned long)GetCurrentThreadId(); +#else + return (unsigned long)pthread_self(); +#endif } static void _ssl_thread_locking_function(int mode, int n, const char *file, diff --git a/pypy/module/bz2/test/test_bz2_file.py b/pypy/module/bz2/test/test_bz2_file.py --- a/pypy/module/bz2/test/test_bz2_file.py +++ b/pypy/module/bz2/test/test_bz2_file.py @@ -53,7 +53,7 @@ class AppTestBZ2File(CheckAllocation): spaceconfig = { - 'usemodules': ['bz2', 'binascii', 'rctime', 'struct'] + 'usemodules': ['bz2', 'binascii', 'time', 'struct'] } def setup_class(cls): diff --git a/pypy/module/cppyy/include/capi.h b/pypy/module/cppyy/include/capi.h --- a/pypy/module/cppyy/include/capi.h +++ b/pypy/module/cppyy/include/capi.h @@ -2,6 +2,7 @@ #define CPPYY_CAPI #include <stddef.h> +#include "src/precommondefs.h" #ifdef __cplusplus extern "C" { @@ -15,102 +16,167 @@ typedef void* (*cppyy_methptrgetter_t)(cppyy_object_t); /* name to opaque C++ scope representation -------------------------------- */ + RPY_EXTERN int cppyy_num_scopes(cppyy_scope_t parent); + RPY_EXTERN char* cppyy_scope_name(cppyy_scope_t parent, int iscope); + RPY_EXTERN char* cppyy_resolve_name(const char* cppitem_name); + RPY_EXTERN cppyy_scope_t cppyy_get_scope(const char* scope_name); + RPY_EXTERN cppyy_type_t cppyy_get_template(const char* template_name); + RPY_EXTERN cppyy_type_t cppyy_actual_class(cppyy_type_t klass, cppyy_object_t obj); /* memory management ------------------------------------------------------ */ + RPY_EXTERN cppyy_object_t cppyy_allocate(cppyy_type_t type); + RPY_EXTERN void cppyy_deallocate(cppyy_type_t type, cppyy_object_t self); + RPY_EXTERN void cppyy_destruct(cppyy_type_t type, cppyy_object_t self); /* method/function dispatching -------------------------------------------- */ + RPY_EXTERN void cppyy_call_v(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + RPY_EXTERN unsigned char cppyy_call_b(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + RPY_EXTERN char cppyy_call_c(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + RPY_EXTERN short cppyy_call_h(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + RPY_EXTERN int cppyy_call_i(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + RPY_EXTERN long cppyy_call_l(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + RPY_EXTERN long long cppyy_call_ll(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + RPY_EXTERN float cppyy_call_f(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + RPY_EXTERN double cppyy_call_d(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + RPY_EXTERN void* cppyy_call_r(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + RPY_EXTERN char* cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs, void* args); + RPY_EXTERN cppyy_object_t cppyy_constructor(cppyy_method_t method, cppyy_type_t klass, int nargs, void* args); + RPY_EXTERN cppyy_object_t cppyy_call_o(cppyy_method_t method, cppyy_object_t self, int nargs, void* args, cppyy_type_t result_type); + RPY_EXTERN cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_scope_t scope, cppyy_index_t idx); /* handling of function argument buffer ----------------------------------- */ + RPY_EXTERN void* cppyy_allocate_function_args(int nargs); + RPY_EXTERN void cppyy_deallocate_function_args(void* args); + RPY_EXTERN size_t cppyy_function_arg_sizeof(); + RPY_EXTERN size_t cppyy_function_arg_typeoffset(); /* scope reflection information ------------------------------------------- */ + RPY_EXTERN int cppyy_is_namespace(cppyy_scope_t scope); + RPY_EXTERN int cppyy_is_enum(const char* type_name); /* class reflection information ------------------------------------------- */ + RPY_EXTERN char* cppyy_final_name(cppyy_type_t type); + RPY_EXTERN char* cppyy_scoped_final_name(cppyy_type_t type); + RPY_EXTERN int cppyy_has_complex_hierarchy(cppyy_type_t type); + RPY_EXTERN int cppyy_num_bases(cppyy_type_t type); + RPY_EXTERN char* cppyy_base_name(cppyy_type_t type, int base_index); + RPY_EXTERN int cppyy_is_subtype(cppyy_type_t derived, cppyy_type_t base); /* calculate offsets between declared and actual type, up-cast: direction > 0; down-cast: direction < 0 */ + RPY_EXTERN ptrdiff_t cppyy_base_offset(cppyy_type_t derived, cppyy_type_t base, cppyy_object_t address, int direction); /* method/function reflection information --------------------------------- */ + RPY_EXTERN int cppyy_num_methods(cppyy_scope_t scope); + RPY_EXTERN cppyy_index_t cppyy_method_index_at(cppyy_scope_t scope, int imeth); + RPY_EXTERN cppyy_index_t* cppyy_method_indices_from_name(cppyy_scope_t scope, const char* name); + RPY_EXTERN char* cppyy_method_name(cppyy_scope_t scope, cppyy_index_t idx); + RPY_EXTERN char* cppyy_method_result_type(cppyy_scope_t scope, cppyy_index_t idx); + RPY_EXTERN int cppyy_method_num_args(cppyy_scope_t scope, cppyy_index_t idx); + RPY_EXTERN int cppyy_method_req_args(cppyy_scope_t scope, cppyy_index_t idx); + RPY_EXTERN char* cppyy_method_arg_type(cppyy_scope_t scope, cppyy_index_t idx, int arg_index); + RPY_EXTERN char* cppyy_method_arg_default(cppyy_scope_t scope, cppyy_index_t idx, int arg_index); + RPY_EXTERN char* cppyy_method_signature(cppyy_scope_t scope, cppyy_index_t idx); + RPY_EXTERN int cppyy_method_is_template(cppyy_scope_t scope, cppyy_index_t idx); + RPY_EXTERN int cppyy_method_num_template_args(cppyy_scope_t scope, cppyy_index_t idx); + RPY_EXTERN char* cppyy_method_template_arg_name(cppyy_scope_t scope, cppyy_index_t idx, cppyy_index_t iarg); + RPY_EXTERN cppyy_method_t cppyy_get_method(cppyy_scope_t scope, cppyy_index_t idx); + RPY_EXTERN cppyy_index_t cppyy_get_global_operator( cppyy_scope_t scope, cppyy_scope_t lc, cppyy_scope_t rc, const char* op); /* method properties ------------------------------------------------------ */ + RPY_EXTERN int cppyy_is_constructor(cppyy_type_t type, cppyy_index_t idx); + RPY_EXTERN int cppyy_is_staticmethod(cppyy_type_t type, cppyy_index_t idx); /* data member reflection information ------------------------------------- */ + RPY_EXTERN int cppyy_num_datamembers(cppyy_scope_t scope); + RPY_EXTERN char* cppyy_datamember_name(cppyy_scope_t scope, int datamember_index); + RPY_EXTERN char* cppyy_datamember_type(cppyy_scope_t scope, int datamember_index); + RPY_EXTERN ptrdiff_t cppyy_datamember_offset(cppyy_scope_t scope, int datamember_index); + RPY_EXTERN int cppyy_datamember_index(cppyy_scope_t scope, const char* name); /* data member properties ------------------------------------------------- */ + RPY_EXTERN int cppyy_is_publicdata(cppyy_type_t type, int datamember_index); + RPY_EXTERN int cppyy_is_staticdata(cppyy_type_t type, int datamember_index); /* misc helpers ----------------------------------------------------------- */ + RPY_EXTERN long long cppyy_strtoll(const char* str); + RPY_EXTERN unsigned long long cppyy_strtoull(const char* str); + RPY_EXTERN void cppyy_free(void* ptr); + RPY_EXTERN cppyy_object_t cppyy_charp2stdstring(const char* str); + RPY_EXTERN cppyy_object_t cppyy_stdstring2stdstring(cppyy_object_t ptr); #ifdef __cplusplus diff --git a/pypy/module/cppyy/src/dummy_backend.cxx b/pypy/module/cppyy/src/dummy_backend.cxx --- a/pypy/module/cppyy/src/dummy_backend.cxx +++ b/pypy/module/cppyy/src/dummy_backend.cxx @@ -1,4 +1,3 @@ -#include "src/precommondefs.h" #include "cppyy.h" #include "capi.h" @@ -349,29 +348,24 @@ /* name to opaque C++ scope representation -------------------------------- */ -RPY_EXTERN int cppyy_num_scopes(cppyy_scope_t handle) { return 0; } -RPY_EXTERN char* cppyy_resolve_name(const char* cppitem_name) { return cppstring_to_cstring(cppitem_name); } -RPY_EXTERN cppyy_scope_t cppyy_get_scope(const char* scope_name) { return s_handles[scope_name]; // lookup failure will return 0 (== error) } -RPY_EXTERN cppyy_type_t cppyy_actual_class(cppyy_type_t klass, cppyy_object_t /* obj */) { return klass; } /* memory management ------------------------------------------------------ */ -RPY_EXTERN void cppyy_destruct(cppyy_type_t handle, cppyy_object_t self) { if (handle == s_handles["example01"]) delete (dummy::example01*)self; @@ -379,7 +373,6 @@ /* method/function dispatching -------------------------------------------- */ -RPY_EXTERN void cppyy_call_v(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { long idx = (long)method; if (idx == s_methods["static_example01::staticSetPayload_payload*_double"]) { @@ -469,7 +462,6 @@ } } -RPY_EXTERN unsigned char cppyy_call_b(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { unsigned char result = 0; const long idx = (long)method; @@ -482,7 +474,6 @@ return result; } -RPY_EXTERN char cppyy_call_c(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { char result = 0; const long idx = (long)method; @@ -498,7 +489,6 @@ return result; } -RPY_EXTERN short cppyy_call_h(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { short result = 0; const long idx = (long)method; @@ -514,7 +504,6 @@ return result; } -RPY_EXTERN int cppyy_call_i(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { int result = 0; const long idx = (long)method; @@ -547,7 +536,6 @@ return result; } -RPY_EXTERN long cppyy_call_l(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { long result = 0; const long idx = (long)method; @@ -689,7 +677,6 @@ return result; } -RPY_EXTERN long long cppyy_call_ll(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { long long result = 0; const long idx = (long)method; @@ -705,7 +692,6 @@ return result; } -RPY_EXTERN float cppyy_call_f(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { float result = 0; const long idx = (long)method; @@ -718,7 +704,6 @@ return result; } -RPY_EXTERN double cppyy_call_d(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { double result = 0.; const long idx = (long)method; @@ -740,7 +725,6 @@ return result; } -RPY_EXTERN char* cppyy_call_s(cppyy_method_t method, cppyy_object_t self, int nargs, void* args) { char* result = 0; const long idx = (long)method; @@ -753,7 +737,6 @@ return result; } -RPY_EXTERN cppyy_object_t cppyy_constructor(cppyy_method_t method, cppyy_type_t handle, int nargs, void* args) { void* result = 0; const long idx = (long)method; @@ -776,14 +759,12 @@ return (cppyy_object_t)result; } -RPY_EXTERN cppyy_methptrgetter_t cppyy_get_methptr_getter(cppyy_type_t /* handle */, cppyy_index_t /* method_index */) { return (cppyy_methptrgetter_t)0; } /* handling of function argument buffer ----------------------------------- */ -RPY_EXTERN void* cppyy_allocate_function_args(int nargs) { CPPYY_G__value* args = (CPPYY_G__value*)malloc(nargs*sizeof(CPPYY_G__value)); for (int i = 0; i < nargs; ++i) @@ -793,36 +774,30 @@ /* handling of function argument buffer ----------------------------------- */ -RPY_EXTERN void cppyy_deallocate_function_args(void* args) { free(args); } -RPY_EXTERN size_t cppyy_function_arg_sizeof() { return sizeof(CPPYY_G__value); } -RPY_EXTERN size_t cppyy_function_arg_typeoffset() { return offsetof(CPPYY_G__value, type); } /* scope reflection information ------------------------------------------- */ -RPY_EXTERN int cppyy_is_namespace(cppyy_scope_t /* handle */) { return 0; } -RPY_EXTERN int cppyy_is_enum(const char* /* type_name */) { return 0; } /* class reflection information ------------------------------------------- */ -RPY_EXTERN char* cppyy_final_name(cppyy_type_t handle) { for (Handles_t::iterator isp = s_handles.begin(); isp != s_handles.end(); ++isp) { if (isp->second == handle) @@ -831,75 +806,61 @@ return cppstring_to_cstring("<unknown>"); } -RPY_EXTERN char* cppyy_scoped_final_name(cppyy_type_t handle) { return cppyy_final_name(handle); } -RPY_EXTERN int cppyy_has_complex_hierarchy(cppyy_type_t /* handle */) { return 0; } -RPY_EXTERN int cppyy_num_bases(cppyy_type_t /*handle*/) { return 0; } /* method/function reflection information --------------------------------- */ -RPY_EXTERN int cppyy_num_methods(cppyy_scope_t handle) { return s_scopes[handle].m_methods.size(); } -RPY_EXTERN cppyy_index_t cppyy_method_index_at(cppyy_scope_t /* scope */, int imeth) { return (cppyy_index_t)imeth; } -RPY_EXTERN char* cppyy_method_name(cppyy_scope_t handle, cppyy_index_t method_index) { return cppstring_to_cstring(s_scopes[handle].m_methods[(int)method_index].m_name); } -RPY_EXTERN char* cppyy_method_result_type(cppyy_scope_t handle, cppyy_index_t method_index) { return cppstring_to_cstring(s_scopes[handle].m_methods[method_index].m_returntype); } -RPY_EXTERN int cppyy_method_num_args(cppyy_scope_t handle, cppyy_index_t method_index) { return s_scopes[handle].m_methods[method_index].m_argtypes.size(); } -RPY_EXTERN int cppyy_method_req_args(cppyy_scope_t handle, cppyy_index_t method_index) { return cppyy_method_num_args(handle, method_index); } -RPY_EXTERN char* cppyy_method_arg_type(cppyy_scope_t handle, cppyy_index_t method_index, int arg_index) { return cppstring_to_cstring(s_scopes[handle].m_methods[method_index].m_argtypes[arg_index]); } -RPY_EXTERN char* cppyy_method_arg_default( cppyy_scope_t /* handle */, cppyy_index_t /* method_index */, int /* arg_index */) { return cppstring_to_cstring(""); } -RPY_EXTERN char* cppyy_method_signature(cppyy_scope_t /* handle */, cppyy_index_t /* method_index */) { return cppstring_to_cstring(""); } -RPY_EXTERN int cppyy_method_is_template(cppyy_scope_t /* handle */, cppyy_index_t /* method_index */) { return 0; } -RPY_EXTERN cppyy_method_t cppyy_get_method(cppyy_scope_t handle, cppyy_index_t method_index) { if (s_scopes.find(handle) != s_scopes.end()) { long id = s_scopes[handle].m_method_offset + (long)method_index; @@ -911,7 +872,6 @@ /* method properties ----------------------------------------------------- */ -RPY_EXTERN int cppyy_is_constructor(cppyy_type_t handle, cppyy_index_t method_index) { if (s_scopes.find(handle) != s_scopes.end()) return s_scopes[handle].m_methods[method_index].m_type == kConstructor; @@ -919,7 +879,6 @@ return 0; } -RPY_EXTERN int cppyy_is_staticmethod(cppyy_type_t handle, cppyy_index_t method_index) { if (s_scopes.find(handle) != s_scopes.end()) return s_scopes[handle].m_methods[method_index].m_type == kStatic; @@ -929,34 +888,28 @@ /* data member reflection information ------------------------------------- */ -RPY_EXTERN int cppyy_num_datamembers(cppyy_scope_t handle) { return s_scopes[handle].m_datambrs.size(); } -RPY_EXTERN char* cppyy_datamember_name(cppyy_scope_t handle, int idatambr) { return cppstring_to_cstring(s_scopes[handle].m_datambrs[idatambr].m_name); } -RPY_EXTERN char* cppyy_datamember_type(cppyy_scope_t handle, int idatambr) { return cppstring_to_cstring(s_scopes[handle].m_datambrs[idatambr].m_type); } -RPY_EXTERN ptrdiff_t cppyy_datamember_offset(cppyy_scope_t handle, int idatambr) { return s_scopes[handle].m_datambrs[idatambr].m_offset; } /* data member properties ------------------------------------------------ */ -RPY_EXTERN int cppyy_is_publicdata(cppyy_scope_t handle, int idatambr) { return 1; } -RPY_EXTERN int cppyy_is_staticdata(cppyy_scope_t handle, int idatambr) { return s_scopes[handle].m_datambrs[idatambr].m_isstatic; } @@ -964,44 +917,37 @@ /* misc helpers ----------------------------------------------------------- */ #if defined(_MSC_VER) -RPY_EXTERN long long cppyy_strtoll(const char* str) { return _strtoi64(str, NULL, 0); } extern "C" { -RPY_EXTERN unsigned long long cppyy_strtoull(const char* str) { return _strtoui64(str, NULL, 0); } } #else -RPY_EXTERN long long cppyy_strtoll(const char* str) { return strtoll(str, NULL, 0); } extern "C" { -RPY_EXTERN unsigned long long cppyy_strtoull(const char* str) { return strtoull(str, NULL, 0); } } #endif -RPY_EXTERN void cppyy_free(void* ptr) { free(ptr); } -RPY_EXTERN cppyy_object_t cppyy_charp2stdstring(const char* str) { void* arena = new char[sizeof(std::string)]; new (arena) std::string(str); return (cppyy_object_t)arena; } -RPY_EXTERN cppyy_object_t cppyy_stdstring2stdstring(cppyy_object_t ptr) { void* arena = new char[sizeof(std::string)]; new (arena) std::string(*(std::string*)ptr); diff --git a/pypy/module/cpyext/src/pythread.c b/pypy/module/cpyext/src/pythread.c --- a/pypy/module/cpyext/src/pythread.c +++ b/pypy/module/cpyext/src/pythread.c @@ -1,11 +1,18 @@ #include <Python.h> +#ifndef _WIN32 +# include <pthread.h> +#endif #include "pythread.h" #include "src/thread.h" long PyThread_get_thread_ident(void) { - return RPyThreadGetIdent(); +#ifdef _WIN32 + return (long)GetCurrentThreadId(); +#else + return (long)pthread_self(); +#endif } PyThread_type_lock diff --git a/pypy/module/cpyext/test/conftest.py b/pypy/module/cpyext/test/conftest.py --- a/pypy/module/cpyext/test/conftest.py +++ b/pypy/module/cpyext/test/conftest.py @@ -7,7 +7,7 @@ # it's necessary to run "import time" at least once before any # other cpyext test, otherwise the same statement will fail in # test_datetime.py. - space = gettestobjspace(usemodules=['rctime']) + space = gettestobjspace(usemodules=['time']) space.getbuiltinmodule("time") def pytest_ignore_collect(path, config): diff --git a/pypy/module/cpyext/test/test_cpyext.py b/pypy/module/cpyext/test/test_cpyext.py --- a/pypy/module/cpyext/test/test_cpyext.py +++ b/pypy/module/cpyext/test/test_cpyext.py @@ -102,7 +102,7 @@ class LeakCheckingTest(object): """Base class for all cpyext tests.""" spaceconfig = dict(usemodules=['cpyext', 'thread', '_rawffi', 'array', - 'itertools', 'rctime', 'binascii', 'micronumpy']) + 'itertools', 'time', 'binascii', 'micronumpy']) spaceconfig['std.withmethodcache'] = True enable_leak_checking = True diff --git a/pypy/module/fcntl/test/test_fcntl.py b/pypy/module/fcntl/test/test_fcntl.py --- a/pypy/module/fcntl/test/test_fcntl.py +++ b/pypy/module/fcntl/test/test_fcntl.py @@ -12,7 +12,7 @@ class AppTestFcntl: spaceconfig = dict(usemodules=('fcntl', 'array', 'struct', 'termios', - 'select', 'rctime')) + 'select', 'time')) def setup_class(cls): tmpprefix = str(udir.ensure('test_fcntl', dir=1).join('tmp_')) diff --git a/pypy/module/imp/test/test_app.py b/pypy/module/imp/test/test_app.py --- a/pypy/module/imp/test/test_app.py +++ b/pypy/module/imp/test/test_app.py @@ -4,7 +4,7 @@ class AppTestImpModule: spaceconfig = { - 'usemodules': ['binascii', 'imp', 'itertools', 'rctime', 'struct'], + 'usemodules': ['binascii', 'imp', 'itertools', 'time', 'struct'], } def setup_class(cls): diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py --- a/pypy/module/imp/test/test_import.py +++ b/pypy/module/imp/test/test_import.py @@ -149,7 +149,7 @@ class AppTestImport: spaceconfig = { - "usemodules": ['_md5', 'rctime'], + "usemodules": ['_md5', 'time'], } def setup_class(cls): @@ -1044,7 +1044,7 @@ class AppTestImportHooks(object): spaceconfig = { - "usemodules": ['struct', 'itertools', 'rctime'], + "usemodules": ['struct', 'itertools', 'time'], } def setup_class(cls): @@ -1304,7 +1304,7 @@ class AppTestMultithreadedImp(object): - spaceconfig = dict(usemodules=['thread', 'rctime']) + spaceconfig = dict(usemodules=['thread', 'time']) def setup_class(cls): #if not conftest.option.runappdirect: diff --git a/pypy/module/marshal/interp_marshal.py b/pypy/module/marshal/interp_marshal.py --- a/pypy/module/marshal/interp_marshal.py +++ b/pypy/module/marshal/interp_marshal.py @@ -144,7 +144,6 @@ atom_int(tc, int) puts code and int atom_int64(tc, int64) puts code and int64 atom_str(tc, str) puts code, len and string - atom_strlist(tc, strlist) puts code, len and list of strings building blocks for compound types: @@ -198,15 +197,6 @@ self.atom_int(typecode, len(x)) self.put(x) - def atom_strlist(self, typecode, tc2, x): - self.atom_int(typecode, len(x)) - atom_str = self.atom_str - for item in x: - # type(str) seems to be forbidden - #if type(item) is not str: - # self.raise_exc('object with wrong type in strlist') - atom_str(tc2, item) - def start(self, typecode): # type(char) not supported self.put(typecode) @@ -379,16 +369,6 @@ self.start(typecode) return self.get_lng() - def atom_strlist(self, typecode, tc2): - self.start(typecode) - lng = self.get_lng() - res = [None] * lng - idx = 0 - while idx < lng: - res[idx] = self.atom_str(tc2) - idx += 1 - return res - def start(self, typecode): tc = self.get1() if tc != typecode: @@ -436,7 +416,6 @@ def get_w_obj(self, allow_null=False): space = self.space - w_ret = space.w_None # something not None tc = self.get1() w_ret = self._dispatch[ord(tc)](space, self, tc) if w_ret is None and not allow_null: diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py --- a/pypy/module/math/test/test_math.py +++ b/pypy/module/math/test/test_math.py @@ -7,7 +7,7 @@ class AppTestMath: spaceconfig = { - "usemodules": ['math', 'struct', 'itertools', 'rctime', 'binascii'], + "usemodules": ['math', 'struct', 'itertools', 'time', 'binascii'], } def setup_class(cls): diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py --- a/pypy/module/micronumpy/base.py +++ b/pypy/module/micronumpy/base.py @@ -1,7 +1,7 @@ from pypy.interpreter.baseobjspace import W_Root -from pypy.interpreter.error import OperationError +from pypy.interpreter.error import OperationError, oefmt from rpython.tool.pairtype import extendabletype - +from pypy.module.micronumpy import support def wrap_impl(space, w_cls, w_instance, impl): if w_cls is None or space.is_w(w_cls, space.gettypefor(W_NDimArray)): @@ -44,11 +44,32 @@ return W_NDimArray(impl) @staticmethod - def from_shape_and_storage(space, shape, storage, dtype, order='C', owning=False, - w_subtype=None, w_base=None, writable=True): + def from_shape_and_storage(space, shape, storage, dtype, storage_bytes=-1, + order='C', owning=False, w_subtype=None, + w_base=None, writable=True, strides=None): from pypy.module.micronumpy import concrete - from pypy.module.micronumpy.strides import calc_strides - strides, backstrides = calc_strides(shape, dtype, order) + from pypy.module.micronumpy.strides import (calc_strides, + calc_backstrides) + isize = dtype.elsize + if storage_bytes > 0 : + totalsize = support.product(shape) * isize + if totalsize > storage_bytes: + raise OperationError(space.w_TypeError, space.wrap( + "buffer is too small for requested array")) + else: + storage_bytes = support.product(shape) * isize + if strides is None: + strides, backstrides = calc_strides(shape, dtype, order) + else: + if len(strides) != len(shape): + raise oefmt(space.w_ValueError, + 'strides, if given, must be the same length as shape') + for i in range(len(strides)): + if strides[i] < 0 or strides[i]*shape[i] > storage_bytes: + raise oefmt(space.w_ValueError, + 'strides is incompatible with shape of requested ' + 'array and size of buffer') + backstrides = calc_backstrides(strides, shape) if w_base is not None: if owning: raise OperationError(space.w_ValueError, diff --git a/pypy/module/micronumpy/boxes.py b/pypy/module/micronumpy/boxes.py --- a/pypy/module/micronumpy/boxes.py +++ b/pypy/module/micronumpy/boxes.py @@ -59,9 +59,9 @@ _mixin_ = True def reduce(self, space): - numpypy = space.getbuiltinmodule("_numpypy") - assert isinstance(numpypy, MixedModule) - multiarray = numpypy.get("multiarray") + _numpypy = space.getbuiltinmodule("_numpypy") + assert isinstance(_numpypy, MixedModule) + multiarray = _numpypy.get("multiarray") assert isinstance(multiarray, MixedModule) scalar = multiarray.get("scalar") @@ -167,7 +167,7 @@ if len(args_w) >= 1: for w_arg in args_w: try: - idx = support.index_w(space, w_arg) + support.index_w(space, w_arg) except OperationError: raise oefmt(space.w_TypeError, "an integer is required") raise oefmt(space.w_ValueError, "axes don't match array") diff --git a/pypy/module/micronumpy/compile.py b/pypy/module/micronumpy/compile.py --- a/pypy/module/micronumpy/compile.py +++ b/pypy/module/micronumpy/compile.py @@ -34,8 +34,8 @@ SINGLE_ARG_FUNCTIONS = ["sum", "prod", "max", "min", "all", "any", - "unegative", "flat", "tostring","count_nonzero", - "argsort"] + "unegative", "flat", "tostring", "count_nonzero", + "argsort", "cumsum", "logical_xor_reduce"] TWO_ARG_FUNCTIONS = ["dot", 'take', 'searchsorted'] TWO_ARG_FUNCTIONS_OR_NONE = ['view', 'astype'] THREE_ARG_FUNCTIONS = ['where'] @@ -559,6 +559,11 @@ w_res = arr.descr_any(interp.space) elif self.name == "all": w_res = arr.descr_all(interp.space) + elif self.name == "cumsum": + w_res = arr.descr_cumsum(interp.space) + elif self.name == "logical_xor_reduce": + logical_xor = ufuncs.get(interp.space).logical_xor + w_res = logical_xor.reduce(interp.space, arr, None) elif self.name == "unegative": neg = ufuncs.get(interp.space).negative w_res = neg.call(interp.space, [arr]) diff --git a/pypy/module/micronumpy/concrete.py b/pypy/module/micronumpy/concrete.py --- a/pypy/module/micronumpy/concrete.py +++ b/pypy/module/micronumpy/concrete.py @@ -11,7 +11,7 @@ from pypy.module.micronumpy.iterators import ArrayIter from pypy.module.micronumpy.strides import (Chunk, Chunks, NewAxisChunk, RecordChunk, calc_strides, calc_new_strides, shape_agreement, - calculate_broadcast_strides) + calculate_broadcast_strides, calc_backstrides) class BaseConcreteArray(object): @@ -47,6 +47,7 @@ def setitem(self, index, value): self.dtype.itemtype.store(self, index, 0, value) + @jit.unroll_safe def setslice(self, space, arr): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit