[pypy-commit] pypy numpy-record-dtypes: merge default
fijal
noreply at buildbot.pypy.org
Thu Mar 15 20:33:54 CET 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: numpy-record-dtypes
Changeset: r53704:f1f9927010ac
Date: 2012-03-15 20:33 +0100
http://bitbucket.org/pypy/pypy/changeset/f1f9927010ac/
Log: merge default
diff --git a/lib-python/2.7/SimpleXMLRPCServer.py b/lib-python/2.7/SimpleXMLRPCServer.py
--- a/lib-python/2.7/SimpleXMLRPCServer.py
+++ b/lib-python/2.7/SimpleXMLRPCServer.py
@@ -486,7 +486,10 @@
L = []
while size_remaining:
chunk_size = min(size_remaining, max_chunk_size)
- L.append(self.rfile.read(chunk_size))
+ chunk = self.rfile.read(chunk_size)
+ if not chunk:
+ break
+ L.append(chunk)
size_remaining -= len(L[-1])
data = ''.join(L)
diff --git a/lib-python/2.7/test/test_xmlrpc.py b/lib-python/2.7/test/test_xmlrpc.py
--- a/lib-python/2.7/test/test_xmlrpc.py
+++ b/lib-python/2.7/test/test_xmlrpc.py
@@ -308,7 +308,7 @@
global ADDR, PORT, URL
ADDR, PORT = serv.socket.getsockname()
#connect to IP address directly. This avoids socket.create_connection()
- #trying to connect to to "localhost" using all address families, which
+ #trying to connect to "localhost" using all address families, which
#causes slowdown e.g. on vista which supports AF_INET6. The server listens
#on AF_INET only.
URL = "http://%s:%d"%(ADDR, PORT)
@@ -367,7 +367,7 @@
global ADDR, PORT, URL
ADDR, PORT = serv.socket.getsockname()
#connect to IP address directly. This avoids socket.create_connection()
- #trying to connect to to "localhost" using all address families, which
+ #trying to connect to "localhost" using all address families, which
#causes slowdown e.g. on vista which supports AF_INET6. The server listens
#on AF_INET only.
URL = "http://%s:%d"%(ADDR, PORT)
@@ -472,6 +472,9 @@
# protocol error; provide additional information in test output
self.fail("%s\n%s" % (e, getattr(e, "headers", "")))
+ def test_unicode_host(self):
+ server = xmlrpclib.ServerProxy(u"http://%s:%d/RPC2"%(ADDR, PORT))
+ self.assertEqual(server.add("a", u"\xe9"), u"a\xe9")
# [ch] The test 404 is causing lots of false alarms.
def XXXtest_404(self):
@@ -586,6 +589,12 @@
# This avoids waiting for the socket timeout.
self.test_simple1()
+ def test_partial_post(self):
+ # Check that a partial POST doesn't make the server loop: issue #14001.
+ conn = httplib.HTTPConnection(ADDR, PORT)
+ conn.request('POST', '/RPC2 HTTP/1.0\r\nContent-Length: 100\r\n\r\nbye')
+ conn.close()
+
class MultiPathServerTestCase(BaseServerTestCase):
threadFunc = staticmethod(http_multi_server)
request_count = 2
diff --git a/lib-python/conftest.py b/lib-python/conftest.py
--- a/lib-python/conftest.py
+++ b/lib-python/conftest.py
@@ -311,7 +311,7 @@
RegrTest('test_mimetypes.py'),
RegrTest('test_MimeWriter.py', core=False),
RegrTest('test_minidom.py'),
- RegrTest('test_mmap.py'),
+ RegrTest('test_mmap.py', usemodules="mmap"),
RegrTest('test_module.py', core=True),
RegrTest('test_modulefinder.py'),
RegrTest('test_msilib.py', skip=only_win32),
diff --git a/lib-python/modified-2.7/distutils/command/bdist_wininst.py b/lib-python/modified-2.7/distutils/command/bdist_wininst.py
--- a/lib-python/modified-2.7/distutils/command/bdist_wininst.py
+++ b/lib-python/modified-2.7/distutils/command/bdist_wininst.py
@@ -298,7 +298,8 @@
bitmaplen, # number of bytes in bitmap
)
file.write(header)
- file.write(open(arcname, "rb").read())
+ with open(arcname, "rb") as arcfile:
+ file.write(arcfile.read())
# create_exe()
diff --git a/lib-python/modified-2.7/distutils/sysconfig_pypy.py b/lib-python/modified-2.7/distutils/sysconfig_pypy.py
--- a/lib-python/modified-2.7/distutils/sysconfig_pypy.py
+++ b/lib-python/modified-2.7/distutils/sysconfig_pypy.py
@@ -60,6 +60,7 @@
g['EXE'] = ""
g['SO'] = _get_so_extension() or ".so"
g['SOABI'] = g['SO'].rsplit('.')[0]
+ g['LIBDIR'] = os.path.join(sys.prefix, 'lib')
global _config_vars
_config_vars = g
diff --git a/lib-python/modified-2.7/opcode.py b/lib-python/modified-2.7/opcode.py
--- a/lib-python/modified-2.7/opcode.py
+++ b/lib-python/modified-2.7/opcode.py
@@ -192,5 +192,6 @@
def_op('LOOKUP_METHOD', 201) # Index in name list
hasname.append(201)
def_op('CALL_METHOD', 202) # #args not including 'self'
+def_op('BUILD_LIST_FROM_ARG', 203)
del def_op, name_op, jrel_op, jabs_op
diff --git a/lib-python/modified-2.7/test/test_dis.py b/lib-python/modified-2.7/test/test_dis.py
new file mode 100644
--- /dev/null
+++ b/lib-python/modified-2.7/test/test_dis.py
@@ -0,0 +1,150 @@
+# Minimal tests for dis module
+
+from test.test_support import run_unittest
+import unittest
+import sys
+import dis
+import StringIO
+
+
+def _f(a):
+ print a
+ return 1
+
+dis_f = """\
+ %-4d 0 LOAD_FAST 0 (a)
+ 3 PRINT_ITEM
+ 4 PRINT_NEWLINE
+
+ %-4d 5 LOAD_CONST 1 (1)
+ 8 RETURN_VALUE
+"""%(_f.func_code.co_firstlineno + 1,
+ _f.func_code.co_firstlineno + 2)
+
+
+def bug708901():
+ for res in range(1,
+ 10):
+ pass
+
+dis_bug708901 = """\
+ %-4d 0 SETUP_LOOP 23 (to 26)
+ 3 LOAD_GLOBAL 0 (range)
+ 6 LOAD_CONST 1 (1)
+
+ %-4d 9 LOAD_CONST 2 (10)
+ 12 CALL_FUNCTION 2
+ 15 GET_ITER
+ >> 16 FOR_ITER 6 (to 25)
+ 19 STORE_FAST 0 (res)
+
+ %-4d 22 JUMP_ABSOLUTE 16
+ >> 25 POP_BLOCK
+ >> 26 LOAD_CONST 0 (None)
+ 29 RETURN_VALUE
+"""%(bug708901.func_code.co_firstlineno + 1,
+ bug708901.func_code.co_firstlineno + 2,
+ bug708901.func_code.co_firstlineno + 3)
+
+
+def bug1333982(x=[]):
+ assert 0, ([s for s in x] +
+ 1)
+ pass
+
+dis_bug1333982 = """\
+ %-4d 0 LOAD_CONST 1 (0)
+ 3 POP_JUMP_IF_TRUE 38
+ 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 >> 31 LOAD_CONST 2 (1)
+ 34 BINARY_ADD
+ 35 RAISE_VARARGS 2
+
+ %-4d >> 38 LOAD_CONST 0 (None)
+ 41 RETURN_VALUE
+"""%(bug1333982.func_code.co_firstlineno + 1,
+ bug1333982.func_code.co_firstlineno + 2,
+ bug1333982.func_code.co_firstlineno + 3)
+
+_BIG_LINENO_FORMAT = """\
+%3d 0 LOAD_GLOBAL 0 (spam)
+ 3 POP_TOP
+ 4 LOAD_CONST 0 (None)
+ 7 RETURN_VALUE
+"""
+
+class DisTests(unittest.TestCase):
+ def do_disassembly_test(self, func, expected):
+ s = StringIO.StringIO()
+ save_stdout = sys.stdout
+ sys.stdout = s
+ dis.dis(func)
+ sys.stdout = save_stdout
+ got = s.getvalue()
+ # Trim trailing blanks (if any).
+ lines = got.split('\n')
+ lines = [line.rstrip() for line in lines]
+ expected = expected.split("\n")
+ import difflib
+ if expected != lines:
+ self.fail(
+ "events did not match expectation:\n" +
+ "\n".join(difflib.ndiff(expected,
+ lines)))
+
+ def test_opmap(self):
+ self.assertEqual(dis.opmap["STOP_CODE"], 0)
+ self.assertIn(dis.opmap["LOAD_CONST"], dis.hasconst)
+ self.assertIn(dis.opmap["STORE_NAME"], dis.hasname)
+
+ def test_opname(self):
+ self.assertEqual(dis.opname[dis.opmap["LOAD_FAST"]], "LOAD_FAST")
+
+ def test_boundaries(self):
+ self.assertEqual(dis.opmap["EXTENDED_ARG"], dis.EXTENDED_ARG)
+ self.assertEqual(dis.opmap["STORE_NAME"], dis.HAVE_ARGUMENT)
+
+ def test_dis(self):
+ self.do_disassembly_test(_f, dis_f)
+
+ def test_bug_708901(self):
+ self.do_disassembly_test(bug708901, dis_bug708901)
+
+ def test_bug_1333982(self):
+ # This one is checking bytecodes generated for an `assert` statement,
+ # so fails if the tests are run with -O. Skip this test then.
+ if __debug__:
+ self.do_disassembly_test(bug1333982, dis_bug1333982)
+
+ def test_big_linenos(self):
+ def func(count):
+ namespace = {}
+ func = "def foo():\n " + "".join(["\n "] * count + ["spam\n"])
+ exec func in namespace
+ return namespace['foo']
+
+ # Test all small ranges
+ for i in xrange(1, 300):
+ expected = _BIG_LINENO_FORMAT % (i + 2)
+ self.do_disassembly_test(func(i), expected)
+
+ # Test some larger ranges too
+ for i in xrange(300, 5000, 10):
+ expected = _BIG_LINENO_FORMAT % (i + 2)
+ self.do_disassembly_test(func(i), expected)
+
+def test_main():
+ run_unittest(DisTests)
+
+
+if __name__ == "__main__":
+ test_main()
diff --git a/lib_pypy/_csv.py b/lib_pypy/_csv.py
--- a/lib_pypy/_csv.py
+++ b/lib_pypy/_csv.py
@@ -414,7 +414,7 @@
def _parse_add_char(self, c):
if len(self.field) + len(c) > _field_limit:
- raise Error("field larget than field limit (%d)" % (_field_limit))
+ raise Error("field larger than field limit (%d)" % (_field_limit))
self.field += c
diff --git a/lib_pypy/_ctypes/builtin.py b/lib_pypy/_ctypes/builtin.py
--- a/lib_pypy/_ctypes/builtin.py
+++ b/lib_pypy/_ctypes/builtin.py
@@ -31,24 +31,20 @@
arg = cobj._get_buffer_value()
return _rawffi.wcharp2rawunicode(arg, lgt)
-class ErrorObject(local):
- def __init__(self):
- self.errno = 0
- self.winerror = 0
-_error_object = ErrorObject()
+_err = local()
def get_errno():
- return _error_object.errno
+ return getattr(_err, "errno", 0)
def set_errno(errno):
- old_errno = _error_object.errno
- _error_object.errno = errno
+ old_errno = get_errno()
+ _err.errno = errno
return old_errno
def get_last_error():
- return _error_object.winerror
+ return getattr(_err, "winerror", 0)
def set_last_error(winerror):
- old_winerror = _error_object.winerror
- _error_object.winerror = winerror
+ old_winerror = get_last_error()
+ _err.winerror = winerror
return old_winerror
diff --git a/lib_pypy/_ctypes/function.py b/lib_pypy/_ctypes/function.py
--- a/lib_pypy/_ctypes/function.py
+++ b/lib_pypy/_ctypes/function.py
@@ -3,7 +3,7 @@
from _ctypes.primitive import SimpleType, _SimpleCData
from _ctypes.basics import ArgumentError, keepalive_key
from _ctypes.basics import is_struct_shape
-from _ctypes.builtin import set_errno, set_last_error
+from _ctypes.builtin import get_errno, set_errno, get_last_error, set_last_error
import _rawffi
import _ffi
import sys
@@ -350,16 +350,24 @@
def _call_funcptr(self, funcptr, *newargs):
if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
- set_errno(_rawffi.get_errno())
+ tmp = _rawffi.get_errno()
+ _rawffi.set_errno(get_errno())
+ set_errno(tmp)
if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
- set_last_error(_rawffi.get_last_error())
+ tmp = _rawffi.get_last_error()
+ _rawffi.set_last_error(get_last_error())
+ set_last_error(tmp)
try:
result = funcptr(*newargs)
finally:
if self._flags_ & _rawffi.FUNCFLAG_USE_ERRNO:
- set_errno(_rawffi.get_errno())
+ tmp = _rawffi.get_errno()
+ _rawffi.set_errno(get_errno())
+ set_errno(tmp)
if self._flags_ & _rawffi.FUNCFLAG_USE_LASTERROR:
- set_last_error(_rawffi.get_last_error())
+ tmp = _rawffi.get_last_error()
+ _rawffi.set_last_error(get_last_error())
+ set_last_error(tmp)
#
try:
return self._build_result(self._restype_, result, newargs)
diff --git a/pypy/annotation/builtin.py b/pypy/annotation/builtin.py
--- a/pypy/annotation/builtin.py
+++ b/pypy/annotation/builtin.py
@@ -37,7 +37,11 @@
try:
realresult = func(*args)
except (ValueError, OverflowError):
- return s_ImpossibleValue # no possible answer for this precise input
+ # no possible answer for this precise input. Be conservative
+ # and keep the computation non-constant. Example:
+ # unichr(constant-that-doesn't-fit-16-bits) on platforms where
+ # the underlying Python has sys.maxunicode == 0xffff.
+ return s_result
s_realresult = immutablevalue(realresult)
if not s_result.contains(s_realresult):
raise Exception("%s%r returned %r, which is not contained in %s" % (
@@ -163,7 +167,7 @@
r.const = False
return r
- assert not issubclass(typ, (int,long)) or typ in (bool, int), (
+ assert not issubclass(typ, (int, long)) or typ in (bool, int, long), (
"for integers only isinstance(.,int|r_uint) are supported")
if s_obj.is_constant():
@@ -297,7 +301,7 @@
def robjmodel_instantiate(s_clspbc):
assert isinstance(s_clspbc, SomePBC)
clsdef = None
- more_than_one = len(s_clspbc.descriptions)
+ more_than_one = len(s_clspbc.descriptions) > 1
for desc in s_clspbc.descriptions:
cdef = desc.getuniqueclassdef()
if more_than_one:
diff --git a/pypy/annotation/classdef.py b/pypy/annotation/classdef.py
--- a/pypy/annotation/classdef.py
+++ b/pypy/annotation/classdef.py
@@ -134,12 +134,19 @@
if self.name not in homedef.classdesc.all_enforced_attrs:
self.attr_allowed = False
if not self.readonly:
- raise NoSuchAttrError(homedef, self.name)
+ raise NoSuchAttrError(
+ "setting forbidden attribute %r on %r" % (
+ self.name, homedef))
def modified(self, classdef='?'):
self.readonly = False
if not self.attr_allowed:
- raise NoSuchAttrError(classdef, self.name)
+ raise NoSuchAttrError(
+ "Attribute %r on %r should be read-only.\n" % (self.name,
+ classdef) +
+ "This error can be caused by another 'getattr' that promoted\n"
+ "the attribute here; the list of read locations is:\n" +
+ '\n'.join([str(loc[0]) for loc in self.read_locations]))
class ClassDef(object):
diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py
--- a/pypy/annotation/description.py
+++ b/pypy/annotation/description.py
@@ -398,7 +398,6 @@
cls = pyobj
base = object
baselist = list(cls.__bases__)
- baselist.reverse()
# special case: skip BaseException in Python 2.5, and pretend
# that all exceptions ultimately inherit from Exception instead
@@ -408,17 +407,27 @@
elif baselist == [py.builtin.BaseException]:
baselist = [Exception]
+ mixins_before = []
+ mixins_after = []
for b1 in baselist:
if b1 is object:
continue
if b1.__dict__.get('_mixin_', False):
- self.add_mixin(b1)
+ if base is object:
+ mixins_before.append(b1)
+ else:
+ mixins_after.append(b1)
else:
assert base is object, ("multiple inheritance only supported "
"with _mixin_: %r" % (cls,))
base = b1
+ if mixins_before and mixins_after:
+ raise Exception("unsupported: class %r has mixin bases both"
+ " before and after the regular base" % (self,))
+ self.add_mixins(mixins_after, check_not_in=base)
+ self.add_mixins(mixins_before)
+ self.add_sources_for_class(cls)
- self.add_sources_for_class(cls)
if base is not object:
self.basedesc = bookkeeper.getdesc(base)
@@ -480,14 +489,30 @@
return
self.classdict[name] = Constant(value)
- def add_mixin(self, base):
- for subbase in base.__bases__:
- if subbase is object:
- continue
- assert subbase.__dict__.get("_mixin_", False), ("Mixin class %r has non"
- "mixin base class %r" % (base, subbase))
- self.add_mixin(subbase)
- self.add_sources_for_class(base, mixin=True)
+ def add_mixins(self, mixins, check_not_in=object):
+ if not mixins:
+ return
+ A = type('tmp', tuple(mixins) + (object,), {})
+ mro = A.__mro__
+ assert mro[0] is A and mro[-1] is object
+ mro = mro[1:-1]
+ #
+ skip = set()
+ def add(cls):
+ if cls is not object:
+ for base in cls.__bases__:
+ add(base)
+ for name in cls.__dict__:
+ skip.add(name)
+ add(check_not_in)
+ #
+ for base in reversed(mro):
+ assert base.__dict__.get("_mixin_", False), ("Mixin class %r has non"
+ "mixin base class %r" % (mixins, base))
+ for name, value in base.__dict__.items():
+ if name in skip:
+ continue
+ self.add_source_attribute(name, value, mixin=True)
def add_sources_for_class(self, cls, mixin=False):
for name, value in cls.__dict__.items():
diff --git a/pypy/annotation/model.py b/pypy/annotation/model.py
--- a/pypy/annotation/model.py
+++ b/pypy/annotation/model.py
@@ -786,12 +786,15 @@
#
# safety check that no-one is trying to make annotation and translation
# faster by providing the -O option to Python.
-try:
- assert False
-except AssertionError:
- pass # fine
-else:
- raise RuntimeError("The annotator relies on 'assert' statements from the\n"
+import os
+if "WINGDB_PYTHON" not in os.environ:
+ # ...but avoiding this boring check in the IDE
+ try:
+ assert False
+ except AssertionError:
+ pass # fine
+ else:
+ raise RuntimeError("The annotator relies on 'assert' statements from the\n"
"\tannotated program: you cannot run it with 'python -O'.")
# this has the side-effect of registering the unary and binary operations
diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py
--- a/pypy/annotation/test/test_annrpython.py
+++ b/pypy/annotation/test/test_annrpython.py
@@ -1,15 +1,12 @@
from __future__ import with_statement
-import autopath
import py.test
import sys
from pypy import conftest
-from pypy.tool.udir import udir
from pypy.annotation import model as annmodel
from pypy.annotation.annrpython import RPythonAnnotator as _RPythonAnnotator
from pypy.translator.translator import graphof as tgraphof
from pypy.annotation import policy
-from pypy.annotation import specialize
from pypy.annotation.listdef import ListDef, ListChangeUnallowed
from pypy.annotation.dictdef import DictDef
from pypy.objspace.flow.model import *
@@ -2431,6 +2428,52 @@
assert isinstance(s.items[1], annmodel.SomeChar)
assert isinstance(s.items[2], annmodel.SomeChar)
+ def test_mixin_first(self):
+ class Mixin(object):
+ _mixin_ = True
+ def foo(self): return 4
+ class Base(object):
+ def foo(self): return 5
+ class Concrete(Mixin, Base):
+ pass
+ def f():
+ return Concrete().foo()
+
+ assert f() == 4
+ a = self.RPythonAnnotator()
+ s = a.build_types(f, [])
+ assert s.const == 4
+
+ def test_mixin_last(self):
+ class Mixin(object):
+ _mixin_ = True
+ def foo(self): return 4
+ class Base(object):
+ def foo(self): return 5
+ class Concrete(Base, Mixin):
+ pass
+ def f():
+ return Concrete().foo()
+
+ assert f() == 5
+ a = self.RPythonAnnotator()
+ s = a.build_types(f, [])
+ assert s.const == 5
+
+ def test_mixin_concrete(self):
+ class Mixin(object):
+ _mixin_ = True
+ def foo(self): return 4
+ class Concrete(Mixin):
+ def foo(self): return 5
+ def f():
+ return Concrete().foo()
+
+ assert f() == 5
+ a = self.RPythonAnnotator()
+ s = a.build_types(f, [])
+ assert s.const == 5
+
def test_multiple_mixins_mro(self):
# an obscure situation, but it occurred in module/micronumpy/types.py
class A(object):
@@ -2510,6 +2553,26 @@
s = a.build_types(f, [int])
assert s.knowntype == int
+ def test_slots_reads(self):
+ class A(object):
+ __slots__ = ()
+ class B(A):
+ def __init__(self, x):
+ self.x = x
+ def f(x):
+ if x:
+ a = A()
+ else:
+ a = B(x)
+ return a.x # should explode here
+
+ a = self.RPythonAnnotator()
+ e = py.test.raises(Exception, a.build_types, f, [int])
+ # this should explode on reading the attribute 'a.x', but it can
+ # sometimes explode on 'self.x = x', which does not make much sense.
+ # But it looks hard to fix in general: we don't know yet during 'a.x'
+ # if the attribute x will be read-only or read-write.
+
def test_unboxed_value(self):
class A(object):
__slots__ = ()
diff --git a/pypy/bin/rpython b/pypy/bin/rpython
new file mode 100755
--- /dev/null
+++ b/pypy/bin/rpython
@@ -0,0 +1,18 @@
+#!/usr/bin/env pypy
+
+"""RPython translation usage:
+
+rpython <translation options> target <targetoptions>
+
+run with --help for more information
+"""
+
+import sys
+from pypy.translator.goal.translate import main
+
+# no implicit targets
+if len(sys.argv) == 1:
+ print __doc__
+ sys.exit(1)
+
+main()
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -176,9 +176,6 @@
cmdline="--translationmodules",
suggests=[("objspace.allworkingmodules", False)]),
- BoolOption("geninterp", "specify whether geninterp should be used",
- default=False),
-
BoolOption("logbytecodes",
"keep track of bytecode usage",
default=False),
@@ -392,10 +389,6 @@
config.objspace.std.suggest(withsmalllong=True)
# xxx other options? ropes maybe?
- # completely disable geninterp in a level 0 translation
- if level == '0':
- config.objspace.suggest(geninterp=False)
-
# some optimizations have different effects depending on the typesystem
if type_system == 'ootype':
config.objspace.std.suggest(multimethods="doubledispatch")
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -182,11 +182,6 @@
# Flags of the TranslationContext:
BoolOption("simplifying", "Simplify flow graphs", default=True),
- BoolOption("builtins_can_raise_exceptions",
- "When true, assume any call to a 'simple' builtin such as "
- "'hex' can raise an arbitrary exception",
- default=False,
- cmdline=None),
BoolOption("list_comprehension_operations",
"When true, look for and special-case the sequence of "
"operations that results from a list comprehension and "
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
@@ -610,6 +610,8 @@
ops.JUMP_IF_FALSE_OR_POP : 0,
ops.POP_JUMP_IF_TRUE : -1,
ops.POP_JUMP_IF_FALSE : -1,
+
+ 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
@@ -965,7 +965,7 @@
self.emit_op_arg(ops.CALL_METHOD, (kwarg_count << 8) | arg_count)
return True
- def _listcomp_generator(self, gens, gen_index, elt):
+ def _listcomp_generator(self, gens, gen_index, elt, single=False):
start = self.new_block()
skip = self.new_block()
if_cleanup = self.new_block()
@@ -973,6 +973,8 @@
gen = gens[gen_index]
assert isinstance(gen, ast.comprehension)
gen.iter.walkabout(self)
+ if single:
+ self.emit_op_arg(ops.BUILD_LIST_FROM_ARG, 0)
self.emit_op(ops.GET_ITER)
self.use_next_block(start)
self.emit_jump(ops.FOR_ITER, anchor)
@@ -998,8 +1000,12 @@
def visit_ListComp(self, lc):
self.update_position(lc.lineno)
- self.emit_op_arg(ops.BUILD_LIST, 0)
- self._listcomp_generator(lc.generators, 0, lc.elt)
+ if len(lc.generators) != 1 or lc.generators[0].ifs:
+ single = False
+ self.emit_op_arg(ops.BUILD_LIST, 0)
+ else:
+ single = True
+ self._listcomp_generator(lc.generators, 0, lc.elt, single=single)
def _comp_generator(self, node, generators, gen_index):
start = self.new_block()
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
@@ -58,7 +58,8 @@
w_res = pyco_expr.exec_host_bytecode(w_dict, w_dict)
res = space.str_w(space.repr(w_res))
if not isinstance(expected, float):
- assert res == repr(expected)
+ noL = lambda expr: expr.replace('L', '')
+ assert noL(res) == noL(repr(expected))
else:
# Float representation can vary a bit between interpreter
# versions, compare the numbers instead.
@@ -908,3 +909,17 @@
return d['f'](5)
""")
assert 'generator' in space.str_w(space.repr(w_generator))
+
+ def test_list_comprehension(self):
+ source = "def f(): [i for i in l]"
+ source2 = "def f(): [i for i in l for j in l]"
+ source3 = "def f(): [i for i in l if i]"
+ counts = self.count_instructions(source)
+ assert ops.BUILD_LIST not in counts
+ assert counts[ops.BUILD_LIST_FROM_ARG] == 1
+ counts = self.count_instructions(source2)
+ assert counts[ops.BUILD_LIST] == 1
+ assert ops.BUILD_LIST_FROM_ARG not in counts
+ counts = self.count_instructions(source3)
+ assert counts[ops.BUILD_LIST] == 1
+ assert ops.BUILD_LIST_FROM_ARG not in counts
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -7,7 +7,8 @@
from pypy.interpreter.miscutils import ThreadLocals
from pypy.tool.cache import Cache
from pypy.tool.uid import HUGEVAL_BYTES
-from pypy.rlib.objectmodel import we_are_translated, newlist, compute_unique_id
+from pypy.rlib.objectmodel import we_are_translated, newlist_hint,\
+ compute_unique_id
from pypy.rlib.debug import make_sure_not_resized
from pypy.rlib.timer import DummyTimer, Timer
from pypy.rlib.rarithmetic import r_uint
@@ -833,7 +834,7 @@
items = []
else:
try:
- items = newlist(lgt_estimate)
+ items = newlist_hint(lgt_estimate)
except MemoryError:
items = [] # it might have lied
#
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -47,6 +47,11 @@
def async(self, space):
"Check if this is an exception that should better not be caught."
+ if not space.full_exceptions:
+ # flow objspace does not support such exceptions and more
+ # importantly, raises KeyboardInterrupt if you try to access
+ # space.w_KeyboardInterrupt
+ return False
return (self.match(space, space.w_SystemExit) or
self.match(space, space.w_KeyboardInterrupt))
diff --git a/pypy/interpreter/gateway.py b/pypy/interpreter/gateway.py
--- a/pypy/interpreter/gateway.py
+++ b/pypy/interpreter/gateway.py
@@ -907,18 +907,12 @@
self.filename = filename
self.source = str(py.code.Source(source).deindent())
self.modname = modname
- # look at the first three lines for a NOT_RPYTHON tag
- first = "\n".join(source.split("\n", 3)[:3])
- if "NOT_RPYTHON" in first:
- self.can_use_geninterp = False
- else:
- self.can_use_geninterp = True
# make source code available for tracebacks
lines = [x + "\n" for x in source.split("\n")]
py.std.linecache.cache[filename] = (1, None, lines, filename)
def __repr__(self):
- return "<ApplevelClass filename=%r can_use_geninterp=%r>" % (self.filename, self.can_use_geninterp)
+ return "<ApplevelClass filename=%r>" % (self.filename,)
def getwdict(self, space):
return space.fromcache(ApplevelCache).getorbuild(self)
@@ -979,10 +973,7 @@
def build(self, app):
"NOT_RPYTHON. Called indirectly by Applevel.getwdict()."
- if self.space.config.objspace.geninterp and app.can_use_geninterp:
- return PyPyCacheDir.build_applevelinterp_dict(app, self.space)
- else:
- return build_applevel_dict(app, self.space)
+ return build_applevel_dict(app, self.space)
# __________ pure applevel version __________
@@ -996,157 +987,6 @@
filename=self.filename)
return w_glob
-# __________ geninterplevel version __________
-
-class PyPyCacheDir:
- "NOT_RPYTHON"
- # similar to applevel, but using translation to interp-level.
- # This version maintains a cache folder with single files.
-
- def build_applevelinterp_dict(cls, self, space):
- "NOT_RPYTHON"
- # N.B. 'self' is the ApplevelInterp; this is a class method,
- # just so that we have a convenient place to store the global state.
- if not cls._setup_done:
- cls._setup()
-
- from pypy.translator.geninterplevel import translate_as_module
- import marshal
- scramble = md5(cls.seed)
- scramble.update(marshal.dumps(self.source))
- key = scramble.hexdigest()
- initfunc = cls.known_code.get(key)
- if not initfunc:
- # try to get it from file
- name = key
- if self.filename:
- prename = os.path.splitext(os.path.basename(self.filename))[0]
- else:
- prename = 'zznoname'
- name = "%s_%s" % (prename, name)
- try:
- __import__("pypy._cache."+name)
- except ImportError, x:
- # print x
- pass
- else:
- initfunc = cls.known_code[key]
- if not initfunc:
- # build it and put it into a file
- initfunc, newsrc = translate_as_module(
- self.source, self.filename, self.modname)
- fname = cls.cache_path.join(name+".py").strpath
- f = file(get_tmp_file_name(fname), "w")
- print >> f, """\
-# self-destruct on double-click:
-if __name__ == "__main__":
- from pypy import _cache
- import os
- namestart = os.path.join(os.path.split(_cache.__file__)[0], '%s')
- for ending in ('.py', '.pyc', '.pyo'):
- try:
- os.unlink(namestart+ending)
- except os.error:
- pass""" % name
- print >> f
- print >> f, newsrc
- print >> f, "from pypy._cache import known_code"
- print >> f, "known_code[%r] = %s" % (key, initfunc.__name__)
- f.close()
- rename_tmp_to_eventual_file_name(fname)
- w_glob = initfunc(space)
- return w_glob
- build_applevelinterp_dict = classmethod(build_applevelinterp_dict)
-
- _setup_done = False
-
- def _setup(cls):
- """NOT_RPYTHON"""
- lp = py.path.local
- import pypy, os
- p = lp(pypy.__file__).new(basename='_cache').ensure(dir=1)
- cls.cache_path = p
- ini = p.join('__init__.py')
- try:
- if not ini.check():
- raise ImportError # don't import if only a .pyc file left!!!
- from pypy._cache import known_code, \
- GI_VERSION_RENDERED
- except ImportError:
- GI_VERSION_RENDERED = 0
- from pypy.translator.geninterplevel import GI_VERSION
- cls.seed = md5(str(GI_VERSION)).digest()
- if GI_VERSION != GI_VERSION_RENDERED or GI_VERSION is None:
- for pth in p.listdir():
- if pth.check(file=1):
- try:
- pth.remove()
- except: pass
- f = file(get_tmp_file_name(str(ini)), "w")
- f.write("""\
-# This folder acts as a cache for code snippets which have been
-# compiled by compile_as_module().
-# It will get a new entry for every piece of code that has
-# not been seen, yet.
-#
-# Caution! Only the code snippet is checked. If something
-# is imported, changes are not detected. Also, changes
-# to geninterplevel or gateway are also not checked.
-# Exception: There is a checked version number in geninterplevel.py
-#
-# If in doubt, remove this file from time to time.
-
-GI_VERSION_RENDERED = %r
-
-known_code = {}
-
-# self-destruct on double-click:
-def harakiri():
- import pypy._cache as _c
- import py
- lp = py.path.local
- for pth in lp(_c.__file__).dirpath().listdir():
- try:
- pth.remove()
- except: pass
-
-if __name__ == "__main__":
- harakiri()
-
-del harakiri
-""" % GI_VERSION)
- f.close()
- rename_tmp_to_eventual_file_name(str(ini))
- import pypy._cache
- cls.known_code = pypy._cache.known_code
- cls._setup_done = True
- _setup = classmethod(_setup)
-
-
-def gethostname(_cache=[]):
- if not _cache:
- try:
- import socket
- hostname = socket.gethostname()
- except:
- hostname = ''
- _cache.append(hostname)
- return _cache[0]
-
-def get_tmp_file_name(fname):
- return '%s~%s~%d' % (fname, gethostname(), os.getpid())
-
-def rename_tmp_to_eventual_file_name(fname):
- # generated files are first written to the host- and process-specific
- # file 'tmpname', and then atomically moved to their final 'fname'
- # to avoid problems if py.py is started several times in parallel
- tmpname = get_tmp_file_name(fname)
- try:
- os.rename(tmpname, fname)
- except (OSError, IOError):
- os.unlink(fname) # necessary on Windows
- os.rename(tmpname, fname)
-
# ____________________________________________________________
def appdef(source, applevel=ApplevelClass, filename=None):
@@ -1184,11 +1024,6 @@
return build_applevel_dict(self, space)
-class applevelinterp_temp(ApplevelClass):
- hidden_applevel = False
- def getwdict(self, space): # no cache
- return PyPyCacheDir.build_applevelinterp_dict(self, space)
-
# app2interp_temp is used for testing mainly
def app2interp_temp(func, applevel_temp=applevel_temp, filename=None):
""" NOT_RPYTHON """
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -15,9 +15,8 @@
from pypy.rlib.rarithmetic import r_uint, intmask
from pypy.rlib.unroll import unrolling_iterable
from pypy.rlib.debug import check_nonneg
-from pypy.tool.stdlib_opcode import (bytecode_spec, host_bytecode_spec,
- unrolling_all_opcode_descs, opmap,
- host_opmap)
+from pypy.tool.stdlib_opcode import (bytecode_spec,
+ unrolling_all_opcode_descs)
def unaryoperation(operationname):
"""NOT_RPYTHON"""
@@ -713,6 +712,19 @@
w_list = self.space.newlist(items)
self.pushvalue(w_list)
+ def BUILD_LIST_FROM_ARG(self, _, next_instr):
+ # this is a little dance, because list has to be before the
+ # value
+ last_val = self.popvalue()
+ try:
+ lgt = self.space.len_w(last_val)
+ except OperationError, e:
+ if e.async(self.space):
+ raise
+ lgt = 0 # oh well
+ self.pushvalue(self.space.newlist([], sizehint=lgt))
+ self.pushvalue(last_val)
+
def LOAD_ATTR(self, nameindex, next_instr):
"obj.attributename"
w_obj = self.popvalue()
@@ -1419,11 +1431,9 @@
if lastchar.isspace() and lastchar != ' ':
return
file_softspace(stream, True)
- print_item_to._annspecialcase_ = "specialize:argtype(0)"
def print_item(x):
print_item_to(x, sys_stdout())
- print_item._annspecialcase_ = "flowspace:print_item"
def print_newline_to(stream):
stream.write("\n")
@@ -1431,7 +1441,6 @@
def print_newline():
print_newline_to(sys_stdout())
- print_newline._annspecialcase_ = "flowspace:print_newline"
def file_softspace(file, newflag):
try:
diff --git a/pypy/interpreter/test/test_appinterp.py b/pypy/interpreter/test/test_appinterp.py
--- a/pypy/interpreter/test/test_appinterp.py
+++ b/pypy/interpreter/test/test_appinterp.py
@@ -1,6 +1,6 @@
import py
-from pypy.interpreter.gateway import appdef, ApplevelClass, applevel_temp, applevelinterp_temp
+from pypy.interpreter.gateway import appdef, ApplevelClass, applevel_temp
from pypy.interpreter.error import OperationError
def test_execwith_novars(space):
@@ -82,9 +82,6 @@
w_res = g(space, space.wrap(10), space.wrap(1))
assert space.eq_w(w_res, space.wrap(-9))
-def test_applevelinterp_functions(space):
- test_applevel_functions(space, applevel_temp = applevelinterp_temp)
-
def test_applevel_class(space, applevel_temp = applevel_temp):
app = applevel_temp('''
class C(object):
@@ -99,9 +96,6 @@
w_clsattr = space.getattr(c, space.wrap('attr'))
assert space.eq_w(w_clsattr, space.wrap(17))
-def test_applevelinterp_class(space):
- test_applevel_class(space, applevel_temp = applevelinterp_temp)
-
def app_test_something_at_app_level():
x = 2
assert x/2 == 1
@@ -161,7 +155,7 @@
w_str = space1.getattr(w_mymod1, space1.wrap("hi"))
assert space1.str_w(w_str) == "hello"
- def test_geninterp_can_unfreeze(self):
+ def test_random_stuff_can_unfreeze(self):
# When a module contains an "import" statement in applevel code, the
# imported module is initialized, possibly after it has been already
# frozen.
diff --git a/pypy/interpreter/test/test_gateway.py b/pypy/interpreter/test/test_gateway.py
--- a/pypy/interpreter/test/test_gateway.py
+++ b/pypy/interpreter/test/test_gateway.py
@@ -101,14 +101,6 @@
g3 = gateway.app2interp_temp(noapp_g3, gateway.applevel_temp)
assert self.space.eq_w(g3(self.space, w('foo'), w('bar')), w('foobar'))
- def test_app2interp2(self):
- """same but using transformed code"""
- w = self.space.wrap
- def noapp_g3(a, b):
- return a+b
- g3 = gateway.app2interp_temp(noapp_g3, gateway.applevelinterp_temp)
- assert self.space.eq_w(g3(self.space, w('foo'), w('bar')), w('foobar'))
-
def test_app2interp_general_args(self):
w = self.space.wrap
def app_general(x, *args, **kwds):
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -599,7 +599,7 @@
# if convenient for the backend, we compute the info about
# the flag as (byte-offset, single-byte-flag).
import struct
- value = struct.pack("l", flag_word)
+ value = struct.pack(lltype.SignedFmt, flag_word)
assert value.count('\x00') == len(value) - 1 # only one byte is != 0
i = 0
while value[i] == '\x00': i += 1
diff --git a/pypy/jit/backend/llsupport/regalloc.py b/pypy/jit/backend/llsupport/regalloc.py
--- a/pypy/jit/backend/llsupport/regalloc.py
+++ b/pypy/jit/backend/llsupport/regalloc.py
@@ -321,7 +321,7 @@
except KeyError:
pass # 'var' is already not in a register
- def loc(self, box):
+ def loc(self, box, must_exist=False):
""" Return the location of 'box'.
"""
self._check_type(box)
@@ -332,6 +332,8 @@
except KeyError:
if box in self.bindings_to_frame_reg:
return self.frame_reg
+ if must_exist:
+ return self.frame_manager.bindings[box]
return self.frame_manager.loc(box)
def return_constant(self, v, forbidden_vars=[], selected_reg=None):
@@ -360,7 +362,7 @@
self._check_type(v)
if isinstance(v, Const):
return self.return_constant(v, forbidden_vars, selected_reg)
- prev_loc = self.loc(v)
+ prev_loc = self.loc(v, must_exist=True)
if prev_loc is self.frame_reg and selected_reg is None:
return prev_loc
loc = self.force_allocate_reg(v, forbidden_vars, selected_reg,
diff --git a/pypy/jit/backend/llsupport/test/test_descr.py b/pypy/jit/backend/llsupport/test/test_descr.py
--- a/pypy/jit/backend/llsupport/test/test_descr.py
+++ b/pypy/jit/backend/llsupport/test/test_descr.py
@@ -148,7 +148,7 @@
#
def get_alignment(code):
# Retrieve default alignment for the compiler/platform
- return struct.calcsize('l' + code) - struct.calcsize(code)
+ return struct.calcsize(lltype.SignedFmt + code) - struct.calcsize(code)
assert descr1.basesize == get_alignment('c')
assert descr2.basesize == get_alignment('p')
assert descr3.basesize == get_alignment('p')
diff --git a/pypy/jit/backend/llsupport/test/test_ffisupport.py b/pypy/jit/backend/llsupport/test/test_ffisupport.py
--- a/pypy/jit/backend/llsupport/test/test_ffisupport.py
+++ b/pypy/jit/backend/llsupport/test/test_ffisupport.py
@@ -2,6 +2,7 @@
from pypy.jit.codewriter.longlong import is_64_bit
from pypy.jit.backend.llsupport.descr import *
from pypy.jit.backend.llsupport.ffisupport import *
+from pypy.rlib.rarithmetic import is_emulated_long
class FakeCPU:
@@ -43,7 +44,7 @@
assert descr.result_flag == FLAG_UNSIGNED
assert descr.is_result_signed() == False
- if not is_64_bit:
+ if not is_64_bit or is_emulated_long:
descr = get_call_descr_dynamic(FakeCPU(), [], types.slonglong,
None, 42)
assert descr is None # missing longlongs
diff --git a/pypy/jit/backend/llsupport/test/test_gc.py b/pypy/jit/backend/llsupport/test/test_gc.py
--- a/pypy/jit/backend/llsupport/test/test_gc.py
+++ b/pypy/jit/backend/llsupport/test/test_gc.py
@@ -11,6 +11,7 @@
from pypy.jit.tool.oparser import parse
from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
from pypy.jit.metainterp.optimizeopt.util import equaloplists
+from pypy.rlib.rarithmetic import is_valid_int
def test_boehm():
gc_ll_descr = GcLLDescr_boehm(None, None, None)
@@ -103,7 +104,7 @@
gcrootmap.put(retaddr, shapeaddr)
assert gcrootmap._gcmap[0] == retaddr
assert gcrootmap._gcmap[1] == shapeaddr
- p = rffi.cast(rffi.LONGP, gcrootmap.gcmapstart())
+ p = rffi.cast(rffi.SIGNEDP, gcrootmap.gcmapstart())
assert p[0] == retaddr
assert (gcrootmap.gcmapend() ==
gcrootmap.gcmapstart() + rffi.sizeof(lltype.Signed) * 2)
@@ -419,9 +420,9 @@
assert newops[0].getarg(1) == v_value
assert newops[0].result is None
wbdescr = newops[0].getdescr()
- assert isinstance(wbdescr.jit_wb_if_flag, int)
- assert isinstance(wbdescr.jit_wb_if_flag_byteofs, int)
- assert isinstance(wbdescr.jit_wb_if_flag_singlebyte, int)
+ assert is_valid_int(wbdescr.jit_wb_if_flag)
+ assert is_valid_int(wbdescr.jit_wb_if_flag_byteofs)
+ assert is_valid_int(wbdescr.jit_wb_if_flag_singlebyte)
def test_get_rid_of_debug_merge_point(self):
operations = [
diff --git a/pypy/jit/backend/llsupport/test/test_regalloc.py b/pypy/jit/backend/llsupport/test/test_regalloc.py
--- a/pypy/jit/backend/llsupport/test/test_regalloc.py
+++ b/pypy/jit/backend/llsupport/test/test_regalloc.py
@@ -1,4 +1,4 @@
-
+import py
from pypy.jit.metainterp.history import BoxInt, ConstInt, BoxFloat, INT, FLOAT
from pypy.jit.backend.llsupport.regalloc import FrameManager
from pypy.jit.backend.llsupport.regalloc import RegisterManager as BaseRegMan
@@ -236,6 +236,16 @@
assert isinstance(loc, FakeFramePos)
assert len(asm.moves) == 1
+ def test_bogus_make_sure_var_in_reg(self):
+ b0, = newboxes(0)
+ longevity = {b0: (0, 1)}
+ fm = TFrameManager()
+ asm = MockAsm()
+ rm = RegisterManager(longevity, frame_manager=fm, assembler=asm)
+ rm.next_instruction()
+ # invalid call to make_sure_var_in_reg(): box unknown so far
+ py.test.raises(KeyError, rm.make_sure_var_in_reg, b0)
+
def test_return_constant(self):
asm = MockAsm()
boxes, longevity = boxes_and_longevity(5)
diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -16,7 +16,7 @@
from pypy.rpython.annlowlevel import llhelper
from pypy.rpython.llinterp import LLException
from pypy.jit.codewriter import heaptracker, longlong
-from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.rarithmetic import intmask, is_valid_int
from pypy.jit.backend.detect_cpu import autodetect_main_model_and_size
def boxfloat(x):
@@ -493,7 +493,7 @@
if cpu.supports_floats:
def func(f, i):
assert isinstance(f, float)
- assert isinstance(i, int)
+ assert is_valid_int(i)
return f - float(i)
FPTR = self.Ptr(self.FuncType([lltype.Float, lltype.Signed],
lltype.Float))
diff --git a/pypy/jit/backend/test/support.py b/pypy/jit/backend/test/support.py
--- a/pypy/jit/backend/test/support.py
+++ b/pypy/jit/backend/test/support.py
@@ -3,6 +3,7 @@
from pypy.rlib.debug import debug_print
from pypy.translator.translator import TranslationContext, graphof
from pypy.jit.metainterp.optimizeopt import ALL_OPTS_NAMES
+from pypy.rlib.rarithmetic import is_valid_int
class BaseCompiledMixin(object):
@@ -24,7 +25,7 @@
from pypy.annotation import model as annmodel
for arg in args:
- assert isinstance(arg, int)
+ assert is_valid_int(arg)
self.pre_translation_hook()
t = self._get_TranslationContext()
diff --git a/pypy/jit/backend/x86/codebuf.py b/pypy/jit/backend/x86/codebuf.py
--- a/pypy/jit/backend/x86/codebuf.py
+++ b/pypy/jit/backend/x86/codebuf.py
@@ -19,8 +19,8 @@
class MachineCodeBlockWrapper(BlockBuilderMixin,
- codebuilder_cls,
- LocationCodeBuilder):
+ LocationCodeBuilder,
+ codebuilder_cls):
def __init__(self):
self.init_block_builder()
# a list of relative positions; for each position p, the bytes
diff --git a/pypy/jit/backend/x86/support.py b/pypy/jit/backend/x86/support.py
--- a/pypy/jit/backend/x86/support.py
+++ b/pypy/jit/backend/x86/support.py
@@ -36,15 +36,15 @@
# ____________________________________________________________
-if sys.platform == 'win32':
- ensure_sse2_floats = lambda : None
- # XXX check for SSE2 on win32 too
+if WORD == 4:
+ extra = ['-DPYPY_X86_CHECK_SSE2']
else:
- if WORD == 4:
- extra = ['-DPYPY_X86_CHECK_SSE2']
- else:
- extra = []
- ensure_sse2_floats = rffi.llexternal_use_eci(ExternalCompilationInfo(
- compile_extra = ['-msse2', '-mfpmath=sse',
- '-DPYPY_CPU_HAS_STANDARD_PRECISION'] + extra,
- ))
+ extra = []
+
+if sys.platform != 'win32':
+ extra = ['-msse2', '-mfpmath=sse',
+ '-DPYPY_CPU_HAS_STANDARD_PRECISION'] + extra
+
+ensure_sse2_floats = rffi.llexternal_use_eci(ExternalCompilationInfo(
+ compile_extra = extra,
+))
diff --git a/pypy/jit/backend/x86/test/conftest.py b/pypy/jit/backend/x86/test/conftest.py
--- a/pypy/jit/backend/x86/test/conftest.py
+++ b/pypy/jit/backend/x86/test/conftest.py
@@ -1,4 +1,4 @@
-import py
+import py, os
from pypy.jit.backend import detect_cpu
cpu = detect_cpu.autodetect()
@@ -6,5 +6,7 @@
if cpu not in ('x86', 'x86_64'):
py.test.skip("x86/x86_64 tests skipped: cpu is %r" % (cpu,))
if cpu == 'x86_64':
+ if os.name == "nt":
+ py.test.skip("Windows cannot allocate non-reserved memory")
from pypy.rpython.lltypesystem import ll2ctypes
ll2ctypes.do_allocation_in_far_regions()
diff --git a/pypy/jit/backend/x86/tool/viewcode.py b/pypy/jit/backend/x86/tool/viewcode.py
--- a/pypy/jit/backend/x86/tool/viewcode.py
+++ b/pypy/jit/backend/x86/tool/viewcode.py
@@ -34,7 +34,7 @@
# I am porting it in a lazy fashion... See py-utils/xam.py
if sys.platform == "win32":
- XXX # lots more in Psyco
+ pass # lots more in Psyco
def machine_code_dump(data, originaddr, backend_name, label_list=None):
objdump_backend_option = {
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -365,7 +365,7 @@
def handle_builtin_call(self, op):
oopspec_name, args = support.decode_builtin_call(op)
# dispatch to various implementations depending on the oopspec_name
- if oopspec_name.startswith('list.') or oopspec_name == 'newlist':
+ if oopspec_name.startswith('list.') or oopspec_name.startswith('newlist'):
prepare = self._handle_list_call
elif oopspec_name.startswith('stroruni.'):
prepare = self._handle_stroruni_call
@@ -1494,6 +1494,14 @@
arraydescr, v_length],
op.result)
+ def do_resizable_newlist_hint(self, op, args, arraydescr, lengthdescr,
+ itemsdescr, structdescr):
+ v_hint = self._get_initial_newlist_length(op, args)
+ return SpaceOperation('newlist_hint',
+ [structdescr, lengthdescr, itemsdescr,
+ arraydescr, v_hint],
+ op.result)
+
def do_resizable_list_getitem(self, op, args, arraydescr, lengthdescr,
itemsdescr, structdescr):
v_index, extraop = self._prepare_list_getset(op, lengthdescr, args,
diff --git a/pypy/jit/codewriter/support.py b/pypy/jit/codewriter/support.py
--- a/pypy/jit/codewriter/support.py
+++ b/pypy/jit/codewriter/support.py
@@ -144,6 +144,10 @@
_ll_1_newlist.need_result_type = True
_ll_2_newlist.need_result_type = True
+def _ll_1_newlist_hint(LIST, hint):
+ return LIST.ll_newlist_hint(hint)
+_ll_1_newlist_hint.need_result_type = True
+
def _ll_1_list_len(l):
return l.ll_length()
def _ll_2_list_getitem(l, index):
diff --git a/pypy/jit/codewriter/test/test_longlong.py b/pypy/jit/codewriter/test/test_longlong.py
--- a/pypy/jit/codewriter/test/test_longlong.py
+++ b/pypy/jit/codewriter/test/test_longlong.py
@@ -1,6 +1,6 @@
import py, sys
-from pypy.rlib.rarithmetic import r_longlong, intmask
+from pypy.rlib.rarithmetic import r_longlong, intmask, is_valid_int
from pypy.objspace.flow.model import SpaceOperation, Variable, Constant
from pypy.objspace.flow.model import Block, Link
from pypy.translator.unsimplify import varoftype
@@ -32,7 +32,7 @@
def test_functions():
xll = longlong.getfloatstorage(3.5)
assert longlong.getrealfloat(xll) == 3.5
- assert isinstance(longlong.gethash(xll), int)
+ assert is_valid_int(longlong.gethash(xll))
class TestLongLong:
diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py
--- a/pypy/jit/metainterp/blackhole.py
+++ b/pypy/jit/metainterp/blackhole.py
@@ -982,6 +982,15 @@
cpu.bh_setfield_gc_r(result, itemsdescr, items)
return result
+ @arguments("cpu", "d", "d", "d", "d", "i", returns="r")
+ def bhimpl_newlist_hint(cpu, structdescr, lengthdescr, itemsdescr,
+ arraydescr, lengthhint):
+ result = cpu.bh_new(structdescr)
+ cpu.bh_setfield_gc_i(result, lengthdescr, 0)
+ items = cpu.bh_new_array(arraydescr, lengthhint)
+ cpu.bh_setfield_gc_r(result, itemsdescr, items)
+ return result
+
@arguments("cpu", "r", "d", "d", "i", returns="i")
def bhimpl_getlistitem_gc_i(cpu, lst, itemsdescr, arraydescr, index):
items = cpu.bh_getfield_gc_r(lst, itemsdescr)
@@ -1176,14 +1185,14 @@
def bhimpl_getinteriorfield_gc_f(cpu, array, index, descr):
return cpu.bh_getinteriorfield_gc_f(array, index, descr)
- @arguments("cpu", "r", "i", "d", "i")
- def bhimpl_setinteriorfield_gc_i(cpu, array, index, descr, value):
+ @arguments("cpu", "r", "i", "i", "d")
+ def bhimpl_setinteriorfield_gc_i(cpu, array, index, value, descr):
cpu.bh_setinteriorfield_gc_i(array, index, descr, value)
- @arguments("cpu", "r", "i", "d", "r")
- def bhimpl_setinteriorfield_gc_r(cpu, array, index, descr, value):
+ @arguments("cpu", "r", "i", "r", "d")
+ def bhimpl_setinteriorfield_gc_r(cpu, array, index, value, descr):
cpu.bh_setinteriorfield_gc_r(array, index, descr, value)
- @arguments("cpu", "r", "i", "d", "f")
- def bhimpl_setinteriorfield_gc_f(cpu, array, index, descr, value):
+ @arguments("cpu", "r", "i", "f", "d")
+ def bhimpl_setinteriorfield_gc_f(cpu, array, index, value, descr):
cpu.bh_setinteriorfield_gc_f(array, index, descr, value)
@arguments("cpu", "r", "d", returns="i")
diff --git a/pypy/jit/metainterp/executor.py b/pypy/jit/metainterp/executor.py
--- a/pypy/jit/metainterp/executor.py
+++ b/pypy/jit/metainterp/executor.py
@@ -2,7 +2,7 @@
"""
from pypy.rpython.lltypesystem import lltype, rstr
-from pypy.rlib.rarithmetic import ovfcheck, r_longlong
+from pypy.rlib.rarithmetic import ovfcheck, r_longlong, is_valid_int
from pypy.rlib.rtimer import read_timestamp
from pypy.rlib.unroll import unrolling_iterable
from pypy.jit.metainterp.history import BoxInt, BoxPtr, BoxFloat, check_descr
@@ -248,7 +248,7 @@
def do_read_timestamp(cpu, _):
x = read_timestamp()
if longlong.is_64_bit:
- assert isinstance(x, int) # 64-bit
+ assert is_valid_int(x) # 64-bit
return BoxInt(x)
else:
assert isinstance(x, r_longlong) # 32-bit
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -4,7 +4,8 @@
from pypy.rpython.ootypesystem import ootype
from pypy.rlib.objectmodel import we_are_translated, Symbolic
from pypy.rlib.objectmodel import compute_unique_id
-from pypy.rlib.rarithmetic import r_int64
+from pypy.rlib.rarithmetic import r_int64, is_valid_int
+
from pypy.conftest import option
from pypy.jit.metainterp.resoperation import ResOperation, rop
@@ -213,7 +214,7 @@
def __init__(self, value):
if not we_are_translated():
- if isinstance(value, int):
+ if is_valid_int(value):
value = int(value) # bool -> int
else:
assert isinstance(value, Symbolic)
@@ -448,7 +449,7 @@
def __init__(self, value=0):
if not we_are_translated():
- if isinstance(value, int):
+ if is_valid_int(value):
value = int(value) # bool -> int
else:
assert isinstance(value, Symbolic)
diff --git a/pypy/jit/metainterp/optimizeopt/intutils.py b/pypy/jit/metainterp/optimizeopt/intutils.py
--- a/pypy/jit/metainterp/optimizeopt/intutils.py
+++ b/pypy/jit/metainterp/optimizeopt/intutils.py
@@ -1,10 +1,9 @@
-from pypy.rlib.rarithmetic import ovfcheck, LONG_BIT
+from pypy.rlib.rarithmetic import ovfcheck, LONG_BIT, maxint, is_valid_int
from pypy.rlib.objectmodel import we_are_translated
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.jit.metainterp.history import BoxInt, ConstInt
-import sys
-MAXINT = sys.maxint
-MININT = -sys.maxint - 1
+MAXINT = maxint
+MININT = -maxint - 1
class IntBound(object):
_attrs_ = ('has_upper', 'has_lower', 'upper', 'lower')
@@ -16,8 +15,8 @@
self.lower = lower
# check for unexpected overflows:
if not we_are_translated():
- assert type(upper) is not long
- assert type(lower) is not long
+ assert type(upper) is not long or is_valid_int(upper)
+ assert type(lower) is not long or is_valid_int(lower)
# Returns True if the bound was updated
def make_le(self, other):
diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py b/pypy/jit/metainterp/optimizeopt/vstring.py
--- a/pypy/jit/metainterp/optimizeopt/vstring.py
+++ b/pypy/jit/metainterp/optimizeopt/vstring.py
@@ -10,6 +10,8 @@
from pypy.rlib.unroll import unrolling_iterable
from pypy.rpython import annlowlevel
from pypy.rpython.lltypesystem import lltype, rstr
+from pypy.rlib.rarithmetic import is_valid_int
+
class StrOrUnicode(object):
@@ -730,7 +732,7 @@
for name in dir(OptString):
if name.startswith(prefix):
value = getattr(EffectInfo, 'OS_' + name[len(prefix):])
- assert isinstance(value, int) and value != 0
+ assert is_valid_int(value) and value != 0
result.append((value, getattr(OptString, name)))
return unrolling_iterable(result)
opt_call_oopspec_ops = _findall_call_oopspec()
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -509,6 +509,15 @@
self._opimpl_setfield_gc_any(sbox, itemsdescr, abox)
return sbox
+ @arguments("descr", "descr", "descr", "descr", "box")
+ def opimpl_newlist_hint(self, structdescr, lengthdescr, itemsdescr,
+ arraydescr, sizehintbox):
+ sbox = self.opimpl_new(structdescr)
+ self._opimpl_setfield_gc_any(sbox, lengthdescr, history.CONST_FALSE)
+ abox = self.opimpl_new_array(arraydescr, sizehintbox)
+ self._opimpl_setfield_gc_any(sbox, itemsdescr, abox)
+ return sbox
+
@arguments("box", "descr", "descr", "box")
def _opimpl_getlistitem_gc_any(self, listbox, itemsdescr, arraydescr,
indexbox):
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -14,7 +14,7 @@
loop_invariant, elidable, promote, jit_debug, assert_green,
AssertGreenFailed, unroll_safe, current_trace_length, look_inside_iff,
isconstant, isvirtual, promote_string, set_param, record_known_class)
-from pypy.rlib.rarithmetic import ovfcheck
+from pypy.rlib.rarithmetic import ovfcheck, is_valid_int
from pypy.rpython.lltypesystem import lltype, llmemory, rffi
from pypy.rpython.ootypesystem import ootype
@@ -2296,7 +2296,7 @@
self.check_resops(int_rshift=3)
bigval = 1
- while (bigval << 3).__class__ is int:
+ while is_valid_int(bigval << 3):
bigval = bigval << 1
assert self.meta_interp(f, [bigval, 5]) == 0
@@ -2341,7 +2341,7 @@
self.check_resops(int_rshift=3)
bigval = 1
- while (bigval << 3).__class__ is int:
+ while is_valid_int(bigval << 3):
bigval = bigval << 1
assert self.meta_interp(f, [bigval, 5]) == 0
@@ -3784,6 +3784,15 @@
assert res == 11 * 12 * 13
self.check_operations_history(int_add=3, int_mul=2)
+ def test_setinteriorfield(self):
+ A = lltype.GcArray(lltype.Struct('S', ('x', lltype.Signed)))
+ a = lltype.malloc(A, 5, immortal=True)
+ def g(n):
+ a[n].x = n + 2
+ return a[n].x
+ res = self.interp_operations(g, [1])
+ assert res == 3
+
class TestLLtype(BaseLLtypeTests, LLJitMixin):
def test_tagged(self):
diff --git a/pypy/jit/metainterp/test/test_list.py b/pypy/jit/metainterp/test/test_list.py
--- a/pypy/jit/metainterp/test/test_list.py
+++ b/pypy/jit/metainterp/test/test_list.py
@@ -1,4 +1,5 @@
import py
+from pypy.rlib.objectmodel import newlist_hint
from pypy.rlib.jit import JitDriver
from pypy.jit.metainterp.test.support import LLJitMixin, OOJitMixin
@@ -228,6 +229,28 @@
self.check_resops({'jump': 1, 'int_gt': 2, 'int_add': 2,
'guard_true': 2, 'int_sub': 2})
+ def test_newlist_hint(self):
+ def f(i):
+ l = newlist_hint(i)
+ l[0] = 55
+ return len(l)
+
+ r = self.interp_operations(f, [3])
+ assert r == 0
+
+ def test_newlist_hint_optimized(self):
+ driver = JitDriver(greens = [], reds = ['i'])
+
+ def f(i):
+ while i > 0:
+ driver.jit_merge_point(i=i)
+ l = newlist_hint(5)
+ l.append(1)
+ i -= l[0]
+
+ self.meta_interp(f, [10], listops=True)
+ self.check_resops(new_array=0, call=0)
+
class TestOOtype(ListTests, OOJitMixin):
pass
diff --git a/pypy/jit/tl/tlc.py b/pypy/jit/tl/tlc.py
--- a/pypy/jit/tl/tlc.py
+++ b/pypy/jit/tl/tlc.py
@@ -6,6 +6,8 @@
from pypy.jit.tl.tlopcode import *
from pypy.jit.tl import tlopcode
from pypy.rlib.jit import JitDriver, elidable
+from pypy.rlib.rarithmetic import is_valid_int
+
class Obj(object):
@@ -219,7 +221,7 @@
class Frame(object):
def __init__(self, args, pc):
- assert isinstance(pc, int)
+ assert is_valid_int(pc)
self.args = args
self.pc = pc
self.stack = []
@@ -239,7 +241,7 @@
return interp_eval(code, pc, args, pool).int_o()
def interp_eval(code, pc, args, pool):
- assert isinstance(pc, int)
+ assert is_valid_int(pc)
frame = Frame(args, pc)
pc = frame.pc
diff --git a/pypy/module/__builtin__/app_inspect.py b/pypy/module/__builtin__/app_inspect.py
--- a/pypy/module/__builtin__/app_inspect.py
+++ b/pypy/module/__builtin__/app_inspect.py
@@ -8,8 +8,6 @@
from __pypy__ import lookup_special
def _caller_locals():
- # note: the reason why this is working is because the functions in here are
- # compiled by geninterp, so they don't have a frame
return sys._getframe(0).f_locals
def vars(*obj):
@@ -26,17 +24,6 @@
except AttributeError:
raise TypeError, "vars() argument must have __dict__ attribute"
-# Replaced by the interp-level helper space.callable():
-##def callable(ob):
-## import __builtin__ # XXX this is insane but required for now for geninterp
-## for c in type(ob).__mro__:
-## if '__call__' in c.__dict__:
-## if isinstance(ob, __builtin__._instance): # old style instance!
-## return getattr(ob, '__call__', None) is not None
-## return True
-## else:
-## return False
-
def dir(*args):
"""dir([object]) -> list of strings
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
@@ -1,5 +1,5 @@
+import sys
-# Package initialisation
from pypy.interpreter.mixedmodule import MixedModule
from pypy.module.imp.importing import get_pyc_magic
@@ -12,6 +12,19 @@
"UnicodeBuilder": "interp_builders.W_UnicodeBuilder",
}
+class TimeModule(MixedModule):
+ appleveldefs = {}
+ interpleveldefs = {}
+ if sys.platform.startswith("linux"):
+ interpleveldefs["clock_gettime"] = "interp_time.clock_gettime"
+ interpleveldefs["clock_getres"] = "interp_time.clock_getres"
+ for name in [
+ "CLOCK_REALTIME", "CLOCK_MONOTONIC", "CLOCK_MONOTONIC_RAW",
+ "CLOCK_PROCESS_CPUTIME_ID", "CLOCK_THREAD_CPUTIME_ID"
+ ]:
+ interpleveldefs[name] = "space.wrap(interp_time.%s)" % name
+
+
class Module(MixedModule):
appleveldefs = {
}
@@ -32,6 +45,7 @@
submodules = {
"builders": BuildersModule,
+ "time": TimeModule,
}
def setup_after_space_initialization(self):
diff --git a/pypy/module/__pypy__/interp_time.py b/pypy/module/__pypy__/interp_time.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/interp_time.py
@@ -0,0 +1,64 @@
+import sys
+
+from pypy.interpreter.error import exception_from_errno
+from pypy.interpreter.gateway import unwrap_spec
+from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.rpython.tool import rffi_platform
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
+
+
+class CConfig:
+ _compilation_info_ = ExternalCompilationInfo(
+ includes=["time.h"],
+ libraries=["rt"],
+ )
+
+ HAS_CLOCK_GETTIME = rffi_platform.Has('clock_gettime')
+
+ CLOCK_REALTIME = rffi_platform.DefinedConstantInteger("CLOCK_REALTIME")
+ CLOCK_MONOTONIC = rffi_platform.DefinedConstantInteger("CLOCK_MONOTONIC")
+ CLOCK_MONOTONIC_RAW = rffi_platform.DefinedConstantInteger("CLOCK_MONOTONIC_RAW")
+ CLOCK_PROCESS_CPUTIME_ID = rffi_platform.DefinedConstantInteger("CLOCK_PROCESS_CPUTIME_ID")
+ CLOCK_THREAD_CPUTIME_ID = rffi_platform.DefinedConstantInteger("CLOCK_THREAD_CPUTIME_ID")
+
+ TIMESPEC = rffi_platform.Struct("struct timespec", [
+ ("tv_sec", rffi.TIME_T),
+ ("tv_nsec", rffi.LONG),
+ ])
+
+cconfig = rffi_platform.configure(CConfig)
+
+HAS_CLOCK_GETTIME = cconfig["HAS_CLOCK_GETTIME"]
+
+CLOCK_REALTIME = cconfig["CLOCK_REALTIME"]
+CLOCK_MONOTONIC = cconfig["CLOCK_MONOTONIC"]
+CLOCK_MONOTONIC_RAW = cconfig["CLOCK_MONOTONIC_RAW"]
+CLOCK_PROCESS_CPUTIME_ID = cconfig["CLOCK_PROCESS_CPUTIME_ID"]
+CLOCK_THREAD_CPUTIME_ID = cconfig["CLOCK_THREAD_CPUTIME_ID"]
+
+TIMESPEC = cconfig["TIMESPEC"]
+
+c_clock_gettime = rffi.llexternal("clock_gettime",
+ [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
+ compilation_info=CConfig._compilation_info_, threadsafe=False
+)
+c_clock_getres = rffi.llexternal("clock_getres",
+ [lltype.Signed, lltype.Ptr(TIMESPEC)], rffi.INT,
+ compilation_info=CConfig._compilation_info_, threadsafe=False
+)
+
+ at unwrap_spec(clk_id="c_int")
+def clock_gettime(space, clk_id):
+ with lltype.scoped_alloc(TIMESPEC) as tp:
+ ret = c_clock_gettime(clk_id, tp)
+ if ret != 0:
+ raise exception_from_errno(space, space.w_IOError)
+ return space.wrap(tp.c_tv_sec + tp.c_tv_nsec * 1e-9)
+
+ at unwrap_spec(clk_id="c_int")
+def clock_getres(space, clk_id):
+ with lltype.scoped_alloc(TIMESPEC) as tp:
+ ret = c_clock_getres(clk_id, tp)
+ if ret != 0:
+ raise exception_from_errno(space, space.w_IOError)
+ return space.wrap(tp.c_tv_sec + tp.c_tv_nsec * 1e-9)
diff --git a/pypy/module/__pypy__/test/test_time.py b/pypy/module/__pypy__/test/test_time.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__pypy__/test/test_time.py
@@ -0,0 +1,26 @@
+import py
+
+from pypy.module.__pypy__.interp_time import HAS_CLOCK_GETTIME
+
+
+class AppTestTime(object):
+ def setup_class(cls):
+ if not HAS_CLOCK_GETTIME:
+ py.test.skip("need time.clock_gettime")
+
+ def test_clock_realtime(self):
+ from __pypy__ import time
+ res = time.clock_gettime(time.CLOCK_REALTIME)
+ assert isinstance(res, float)
+
+ def test_clock_monotonic(self):
+ from __pypy__ import time
+ a = time.clock_gettime(time.CLOCK_MONOTONIC)
+ b = time.clock_gettime(time.CLOCK_MONOTONIC)
+ assert a <= b
+
+ def test_clock_getres(self):
+ from __pypy__ import time
+ res = time.clock_getres(time.CLOCK_REALTIME)
+ assert res > 0.0
+ assert res <= 1.0
diff --git a/pypy/module/_multiprocessing/test/test_semaphore.py b/pypy/module/_multiprocessing/test/test_semaphore.py
--- a/pypy/module/_multiprocessing/test/test_semaphore.py
+++ b/pypy/module/_multiprocessing/test/test_semaphore.py
@@ -2,6 +2,7 @@
from pypy.module._multiprocessing.interp_semaphore import (
RECURSIVE_MUTEX, SEMAPHORE)
+
class AppTestSemaphore:
def setup_class(cls):
space = gettestobjspace(usemodules=('_multiprocessing', 'thread'))
diff --git a/pypy/module/_ssl/test/test_ssl.py b/pypy/module/_ssl/test/test_ssl.py
--- a/pypy/module/_ssl/test/test_ssl.py
+++ b/pypy/module/_ssl/test/test_ssl.py
@@ -1,6 +1,8 @@
from pypy.conftest import gettestobjspace
import os
import py
+from pypy.rlib.rarithmetic import is_valid_int
+
class AppTestSSL:
def setup_class(cls):
@@ -29,7 +31,7 @@
assert isinstance(_ssl.SSL_ERROR_EOF, int)
assert isinstance(_ssl.SSL_ERROR_INVALID_ERROR_CODE, int)
- assert isinstance(_ssl.OPENSSL_VERSION_NUMBER, (int, long))
+ assert is_valid_int(_ssl.OPENSSL_VERSION_NUMBER)
assert isinstance(_ssl.OPENSSL_VERSION_INFO, tuple)
assert len(_ssl.OPENSSL_VERSION_INFO) == 5
assert isinstance(_ssl.OPENSSL_VERSION, str)
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -824,6 +824,8 @@
pypy_decls.append("#ifdef __cplusplus")
pypy_decls.append("extern \"C\" {")
pypy_decls.append("#endif\n")
+ pypy_decls.append('#define Signed long /* xxx temporary fix */\n')
+ pypy_decls.append('#define Unsigned unsigned long /* xxx temporary fix */\n')
for decl in FORWARD_DECLS:
pypy_decls.append("%s;" % (decl,))
@@ -855,6 +857,8 @@
typ = 'PyObject*'
pypy_decls.append('PyAPI_DATA(%s) %s;' % (typ, name))
+ pypy_decls.append('#undef Signed /* xxx temporary fix */\n')
+ pypy_decls.append('#undef Unsigned /* xxx temporary fix */\n')
pypy_decls.append("#ifdef __cplusplus")
pypy_decls.append("}")
pypy_decls.append("#endif")
diff --git a/pypy/module/cpyext/stringobject.py b/pypy/module/cpyext/stringobject.py
--- a/pypy/module/cpyext/stringobject.py
+++ b/pypy/module/cpyext/stringobject.py
@@ -130,6 +130,11 @@
@cpython_api([PyObject], rffi.CCHARP, error=0)
def PyString_AsString(space, ref):
+ if from_ref(space, rffi.cast(PyObject, ref.c_ob_type)) is space.w_str:
+ pass # typecheck returned "ok" without forcing 'ref' at all
+ elif not PyString_Check(space, ref): # otherwise, use the alternate way
+ raise OperationError(space.w_TypeError, space.wrap(
+ "PyString_AsString only support strings"))
ref_str = rffi.cast(PyStringObject, ref)
if not ref_str.c_buffer:
# copy string buffer
diff --git a/pypy/module/cpyext/test/test_longobject.py b/pypy/module/cpyext/test/test_longobject.py
--- a/pypy/module/cpyext/test/test_longobject.py
+++ b/pypy/module/cpyext/test/test_longobject.py
@@ -101,9 +101,9 @@
space.wrap((2, 7)))):
py.test.skip("unsupported before Python 2.7")
- assert api._PyLong_Sign(space.wrap(0L)) == 0
- assert api._PyLong_Sign(space.wrap(2L)) == 1
- assert api._PyLong_Sign(space.wrap(-2L)) == -1
+ assert api._PyLong_Sign(space.wraplong(0L)) == 0
+ assert api._PyLong_Sign(space.wraplong(2L)) == 1
+ assert api._PyLong_Sign(space.wraplong(-2L)) == -1
assert api._PyLong_NumBits(space.wrap(0)) == 0
assert api._PyLong_NumBits(space.wrap(1)) == 1
diff --git a/pypy/module/cpyext/test/test_number.py b/pypy/module/cpyext/test/test_number.py
--- a/pypy/module/cpyext/test/test_number.py
+++ b/pypy/module/cpyext/test/test_number.py
@@ -6,12 +6,12 @@
class TestIterator(BaseApiTest):
def test_check(self, space, api):
assert api.PyIndex_Check(space.wrap(12))
- assert api.PyIndex_Check(space.wrap(-12L))
+ assert api.PyIndex_Check(space.wraplong(-12L))
assert not api.PyIndex_Check(space.wrap(12.1))
assert not api.PyIndex_Check(space.wrap('12'))
assert api.PyNumber_Check(space.wrap(12))
- assert api.PyNumber_Check(space.wrap(-12L))
+ assert api.PyNumber_Check(space.wraplong(-12L))
assert api.PyNumber_Check(space.wrap(12.1))
assert not api.PyNumber_Check(space.wrap('12'))
assert not api.PyNumber_Check(space.wrap(1+3j))
@@ -21,7 +21,7 @@
assert api.PyLong_CheckExact(w_l)
def test_number_int(self, space, api):
- w_l = api.PyNumber_Int(space.wrap(123L))
+ w_l = api.PyNumber_Int(space.wraplong(123L))
assert api.PyInt_CheckExact(w_l)
w_l = api.PyNumber_Int(space.wrap(2 << 65))
assert api.PyLong_CheckExact(w_l)
@@ -29,7 +29,7 @@
assert api.PyInt_CheckExact(w_l)
def test_number_index(self, space, api):
- w_l = api.PyNumber_Index(space.wrap(123L))
+ w_l = api.PyNumber_Index(space.wraplong(123L))
assert api.PyLong_CheckExact(w_l)
w_l = api.PyNumber_Index(space.wrap(42.3))
assert w_l is None
diff --git a/pypy/module/cpyext/test/test_stringobject.py b/pypy/module/cpyext/test/test_stringobject.py
--- a/pypy/module/cpyext/test/test_stringobject.py
+++ b/pypy/module/cpyext/test/test_stringobject.py
@@ -105,6 +105,15 @@
)])
assert module.string_as_string("huheduwe") == "huhe"
+ def test_py_string_as_string_None(self):
+ module = self.import_extension('foo', [
+ ("string_None", "METH_VARARGS",
+ '''
+ return PyString_AsString(Py_None);
+ '''
+ )])
+ raises(TypeError, module.string_None)
+
def test_AsStringAndSize(self):
module = self.import_extension('foo', [
("getstring", "METH_NOARGS",
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
@@ -327,8 +327,10 @@
# %r not supported in rpython
#u.raise_exc('invalid typecode in unmarshal: %r' % tc)
c = ord(tc)
- if c < 32 or c > 126:
- s = '\\x' + hex(c)
+ if c < 16:
+ s = '\\x0%x' % c
+ elif c < 32 or c > 126:
+ s = '\\x%x' % c
elif tc == '\\':
s = r'\\'
else:
diff --git a/pypy/module/marshal/test/test_marshal.py b/pypy/module/marshal/test/test_marshal.py
--- a/pypy/module/marshal/test/test_marshal.py
+++ b/pypy/module/marshal/test/test_marshal.py
@@ -174,6 +174,11 @@
pass
raises(ValueError, marshal.dumps, subtype)
+ def test_bad_typecode(self):
+ import marshal
+ exc = raises(ValueError, marshal.loads, chr(1))
+ assert r"'\x01'" in exc.value.message
+
class AppTestRope(AppTestMarshal):
def setup_class(cls):
diff --git a/pypy/module/math/test/test_direct.py b/pypy/module/math/test/test_direct.py
--- a/pypy/module/math/test/test_direct.py
+++ b/pypy/module/math/test/test_direct.py
@@ -55,6 +55,12 @@
('frexp', (-1.25,), lambda x: x == (-0.625, 1)),
('modf', (4.25,), lambda x: x == (0.25, 4.0)),
('modf', (-4.25,), lambda x: x == (-0.25, -4.0)),
+ ('copysign', (1.5, 0.0), 1.5),
+ ('copysign', (1.5, -0.0), -1.5),
+ ('copysign', (1.5, INFINITY), 1.5),
+ ('copysign', (1.5, -INFINITY), -1.5),
+ ('copysign', (1.5, NAN), 1.5),
+ ('copysign', (1.75, -NAN), -1.75), # special case for -NAN here
]
OVFCASES = [
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
@@ -1,3 +1,4 @@
+from __future__ import with_statement
import sys
from pypy.conftest import gettestobjspace
from pypy.module.math.test import test_direct
@@ -268,3 +269,7 @@
def __trunc__(self):
return "truncated"
assert math.trunc(foo()) == "truncated"
+
+ def test_copysign_nan(self):
+ import math
+ assert math.copysign(1.0, float('-nan')) == -1.0
diff --git a/pypy/module/micronumpy/__init__.py b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -107,6 +107,9 @@
("multiply", "multiply"),
("negative", "negative"),
("not_equal", "not_equal"),
+ ("radians", "radians"),
+ ("degrees", "degrees"),
+ ("deg2rad", "radians"),
("reciprocal", "reciprocal"),
("sign", "sign"),
("sin", "sin"),
@@ -125,6 +128,12 @@
('logical_xor', 'logical_xor'),
('logical_not', 'logical_not'),
('logical_or', 'logical_or'),
+ ('log', 'log'),
+ ('log2', 'log2'),
+ ('log10', 'log10'),
+ ('log1p', 'log1p'),
+ ('power', 'power'),
+ ('floor_divide', 'floor_divide'),
]:
interpleveldefs[exposed] = "interp_ufuncs.get(space).%s" % impl
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
@@ -84,6 +84,7 @@
descr_mul = _binop_impl("multiply")
descr_div = _binop_impl("divide")
descr_truediv = _binop_impl("true_divide")
+ descr_floordiv = _binop_impl("floor_divide")
descr_mod = _binop_impl("mod")
descr_pow = _binop_impl("power")
descr_lshift = _binop_impl("left_shift")
@@ -104,6 +105,7 @@
descr_rmul = _binop_right_impl("multiply")
descr_rdiv = _binop_right_impl("divide")
descr_rtruediv = _binop_right_impl("true_divide")
+ descr_rfloordiv = _binop_right_impl("floor_divide")
descr_rmod = _binop_right_impl("mod")
descr_rpow = _binop_right_impl("power")
descr_rlshift = _binop_right_impl("left_shift")
@@ -273,6 +275,7 @@
__mul__ = interp2app(W_GenericBox.descr_mul),
__div__ = interp2app(W_GenericBox.descr_div),
__truediv__ = interp2app(W_GenericBox.descr_truediv),
+ __floordiv__ = interp2app(W_GenericBox.descr_floordiv),
__mod__ = interp2app(W_GenericBox.descr_mod),
__divmod__ = interp2app(W_GenericBox.descr_divmod),
__pow__ = interp2app(W_GenericBox.descr_pow),
@@ -287,6 +290,7 @@
__rmul__ = interp2app(W_GenericBox.descr_rmul),
__rdiv__ = interp2app(W_GenericBox.descr_rdiv),
__rtruediv__ = interp2app(W_GenericBox.descr_rtruediv),
+ __rfloordiv__ = interp2app(W_GenericBox.descr_rfloordiv),
__rmod__ = interp2app(W_GenericBox.descr_rmod),
__rdivmod__ = interp2app(W_GenericBox.descr_rdivmod),
__rpow__ = interp2app(W_GenericBox.descr_rpow),
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
@@ -101,6 +101,7 @@
descr_mul = _binop_impl("multiply")
descr_div = _binop_impl("divide")
descr_truediv = _binop_impl("true_divide")
+ descr_floordiv = _binop_impl("floor_divide")
descr_mod = _binop_impl("mod")
descr_pow = _binop_impl("power")
descr_lshift = _binop_impl("left_shift")
@@ -135,6 +136,7 @@
descr_rmul = _binop_right_impl("multiply")
descr_rdiv = _binop_right_impl("divide")
descr_rtruediv = _binop_right_impl("true_divide")
+ descr_rfloordiv = _binop_right_impl("floor_divide")
descr_rmod = _binop_right_impl("mod")
descr_rpow = _binop_right_impl("power")
descr_rlshift = _binop_right_impl("left_shift")
@@ -1261,6 +1263,7 @@
__mul__ = interp2app(BaseArray.descr_mul),
__div__ = interp2app(BaseArray.descr_div),
__truediv__ = interp2app(BaseArray.descr_truediv),
+ __floordiv__ = interp2app(BaseArray.descr_floordiv),
__mod__ = interp2app(BaseArray.descr_mod),
__divmod__ = interp2app(BaseArray.descr_divmod),
__pow__ = interp2app(BaseArray.descr_pow),
@@ -1275,6 +1278,7 @@
__rmul__ = interp2app(BaseArray.descr_rmul),
__rdiv__ = interp2app(BaseArray.descr_rdiv),
__rtruediv__ = interp2app(BaseArray.descr_rtruediv),
+ __rfloordiv__ = interp2app(BaseArray.descr_rfloordiv),
__rmod__ = interp2app(BaseArray.descr_rmod),
__rdivmod__ = interp2app(BaseArray.descr_rdivmod),
__rpow__ = interp2app(BaseArray.descr_rpow),
diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -388,6 +388,7 @@
"int_only": True}),
("bitwise_xor", "bitwise_xor", 2, {"int_only": True}),
("invert", "invert", 1, {"int_only": True}),
+ ("floor_divide", "floordiv", 2, {"promote_bools": True}),
("divide", "div", 2, {"promote_bools": True}),
("true_divide", "div", 2, {"promote_to_float": True}),
("mod", "mod", 2, {"promote_bools": True}),
@@ -441,6 +442,14 @@
("arcsinh", "arcsinh", 1, {"promote_to_float": True}),
("arccosh", "arccosh", 1, {"promote_to_float": True}),
("arctanh", "arctanh", 1, {"promote_to_float": True}),
+
+ ("radians", "radians", 1, {"promote_to_float": True}),
+ ("degrees", "degrees", 1, {"promote_to_float": True}),
+
+ ("log", "log", 1, {"promote_to_float": True}),
+ ("log2", "log2", 1, {"promote_to_float": True}),
+ ("log10", "log10", 1, {"promote_to_float": True}),
+ ("log1p", "log1p", 1, {"promote_to_float": True}),
]:
self.add_ufunc(space, *ufunc_def)
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
@@ -633,6 +633,56 @@
for i in range(5):
assert b[i] == i / 5.0
+ def test_floordiv(self):
+ from math import isnan
+ from _numpypy import array, dtype
+
+ a = array(range(1, 6))
+ b = a // a
+ assert (b == [1, 1, 1, 1, 1]).all()
+
+ a = array(range(1, 6), dtype=bool)
+ b = a // a
+ assert b.dtype is dtype("int8")
+ assert (b == [1, 1, 1, 1, 1]).all()
+
+ a = array([-1, 0, 1])
+ b = array([0, 0, 0])
+ c = a // b
+ assert (c == [0, 0, 0]).all()
+
+ a = array([-1.0, 0.0, 1.0])
+ b = array([0.0, 0.0, 0.0])
+ c = a // b
+ assert c[0] == float('-inf')
+ assert isnan(c[1])
+ assert c[2] == float('inf')
+
+ b = array([-0.0, -0.0, -0.0])
+ c = a // b
+ assert c[0] == float('inf')
+ assert isnan(c[1])
+ assert c[2] == float('-inf')
+
+ def test_floordiv_other(self):
+ from _numpypy import array
+ a = array(range(5))
+ b = array([2, 2, 2, 2, 2], float)
+ c = a // b
+ assert (c == [0, 0, 1, 1, 2]).all()
+
+ def test_rfloordiv(self):
+ from _numpypy import array
+ a = array(range(1, 6))
+ b = 3 // a
+ assert (b == [3, 1, 1, 0, 0]).all()
+
+ def test_floordiv_constant(self):
+ from _numpypy import array
+ a = array(range(5))
+ b = a // 2
+ assert (b == [0, 0, 1, 1, 2]).all()
+
def test_truediv(self):
from operator import truediv
from _numpypy import arange
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -376,6 +376,45 @@
assert math.isnan(sqrt(-1))
assert math.isnan(sqrt(nan))
+ def test_radians(self):
+ import math
+ from _numpypy import radians, array
+ a = array([
+ -181, -180, -179,
+ 181, 180, 179,
+ 359, 360, 361,
+ 400, -1, 0, 1,
+ float('inf'), float('-inf')])
+ b = radians(a)
+ for i in range(len(a)):
+ assert b[i] == math.radians(a[i])
+
+ def test_deg2rad(self):
+ import math
+ from _numpypy import deg2rad, array
+ a = array([
+ -181, -180, -179,
+ 181, 180, 179,
+ 359, 360, 361,
+ 400, -1, 0, 1,
+ float('inf'), float('-inf')])
+ b = deg2rad(a)
+ for i in range(len(a)):
+ assert b[i] == math.radians(a[i])
+
+ def test_degrees(self):
+ import math
+ from _numpypy import degrees, array
+ a = array([
+ -181, -180, -179,
+ 181, 180, 179,
+ 359, 360, 361,
+ 400, -1, 0, 1,
+ float('inf'), float('-inf')])
+ b = degrees(a)
+ for i in range(len(a)):
+ assert b[i] == math.degrees(a[i])
+
def test_reduce_errors(self):
from _numpypy import sin, add
@@ -481,3 +520,47 @@
assert (logical_xor([True, False, True, False], [1, 2, 0, 0])
== [False, True, True, False]).all()
assert (logical_not([True, False]) == [False, True]).all()
+
+ def test_logn(self):
+ import math
+ from _numpypy import log, log2, log10
+
+ for log_func, base in [(log, math.e), (log2, 2), (log10, 10)]:
+ for v in [float('-nan'), float('-inf'), -1, float('nan')]:
+ assert math.isnan(log_func(v))
+ for v in [-0.0, 0.0]:
+ assert log_func(v) == float("-inf")
+ assert log_func(float('inf')) == float('inf')
+ assert (log_func([1, base]) == [0, 1]).all()
+
+ def test_log1p(self):
+ import math
+ from _numpypy import log1p
+
+ for v in [float('-nan'), float('-inf'), -2, float('nan')]:
+ assert math.isnan(log1p(v))
+ for v in [-1]:
+ assert log1p(v) == float("-inf")
+ assert log1p(float('inf')) == float('inf')
+ assert (log1p([0, 1e-50, math.e - 1]) == [0, 1e-50, 1]).all()
+
+ def test_power(self):
+ import math
+ from _numpypy import power, array
+ a = array([1., 2., 3.])
+ b = power(a, 3)
+ for i in range(len(a)):
+ assert b[i] == a[i] ** 3
+
+ a = array([1., 2., 3.])
+ b = array([1., 2., 3.])
+ c = power(a, b)
+ for i in range(len(a)):
+ assert c[i] == a[i] ** b[i]
+
+ def test_floordiv(self):
+ from _numpypy import floor_divide, array
+ a = array([1., 2., 3., 4., 5., 6., 6.01])
+ b = floor_divide(a, 2.5)
+ for i in range(len(a)):
+ assert b[i] == a[i] // 2.5
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -15,6 +15,8 @@
VOID_STORAGE = lltype.Array(lltype.Char, hints={'nolength': True,
'render_as_void': True})
+degToRad = math.pi / 180.0
+log2 = math.log(2)
def simple_unary_op(func):
specialize.argtype(1)(func)
@@ -316,6 +318,12 @@
return v1 / v2
@simple_binary_op
+ def floordiv(self, v1, v2):
+ if v2 == 0:
+ return 0
+ return v1 // v2
+
+ @simple_binary_op
def mod(self, v1, v2):
return v1 % v2
@@ -503,6 +511,15 @@
return rfloat.copysign(rfloat.INFINITY, v1 * v2)
@simple_binary_op
+ def floordiv(self, v1, v2):
+ try:
+ return math.floor(v1 / v2)
+ except ZeroDivisionError:
+ if v1 == v2 == 0.0:
+ return rfloat.NAN
+ return rfloat.copysign(rfloat.INFINITY, v1 * v2)
+
+ @simple_binary_op
def mod(self, v1, v2):
return math.fmod(v1, v2)
@@ -618,6 +635,57 @@
def isinf(self, v):
return rfloat.isinf(v)
+ @simple_unary_op
+ def radians(self, v):
+ return v * degToRad
+ deg2rad = radians
+
+ @simple_unary_op
+ def degrees(self, v):
+ return v / degToRad
+
+ @simple_unary_op
+ def log(self, v):
+ try:
+ return math.log(v)
+ except ValueError:
+ if v == 0.0:
+ # CPython raises ValueError here, so we have to check
+ # the value to find the correct numpy return value
+ return -rfloat.INFINITY
+ return rfloat.NAN
+
+ @simple_unary_op
+ def log2(self, v):
+ try:
+ return math.log(v) / log2
+ except ValueError:
+ if v == 0.0:
+ # CPython raises ValueError here, so we have to check
+ # the value to find the correct numpy return value
+ return -rfloat.INFINITY
+ return rfloat.NAN
+
+ @simple_unary_op
+ def log10(self, v):
+ try:
+ return math.log10(v)
+ except ValueError:
+ if v == 0.0:
+ # CPython raises ValueError here, so we have to check
+ # the value to find the correct numpy return value
+ return -rfloat.INFINITY
+ return rfloat.NAN
+
+ @simple_unary_op
+ def log1p(self, v):
+ try:
+ return rfloat.log1p(v)
+ except OverflowError:
+ return -rfloat.INFINITY
+ except ValueError:
+ return rfloat.NAN
+
class NonNativeFloat(NonNativePrimitive, Float):
_mixin_ = True
diff --git a/pypy/module/mmap/__init__.py b/pypy/module/mmap/__init__.py
--- a/pypy/module/mmap/__init__.py
+++ b/pypy/module/mmap/__init__.py
@@ -18,7 +18,7 @@
def buildloaders(cls):
from pypy.module.mmap import interp_mmap
for constant, value in rmmap.constants.iteritems():
- if isinstance(value, int):
+ if isinstance(value, (int, long)):
Module.interpleveldefs[constant] = "space.wrap(%r)" % value
super(Module, cls).buildloaders()
diff --git a/pypy/module/pypyjit/policy.py b/pypy/module/pypyjit/policy.py
--- a/pypy/module/pypyjit/policy.py
+++ b/pypy/module/pypyjit/policy.py
@@ -138,8 +138,6 @@
if mod == 'pypy.rlib.rbigint' or mod == 'pypy.rlib.rlocale' or mod == 'pypy.rlib.rsocket':
return False
- if '_geninterp_' in func.func_globals: # skip all geninterped stuff
- return False
if mod.startswith('pypy.interpreter.astcompiler.'):
return False
if mod.startswith('pypy.interpreter.pyparser.'):
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
@@ -14,12 +14,6 @@
from pypy.rlib.rlocale import setlocale
assert not pypypolicy.look_inside_function(setlocale)
-def test_geninterp():
- d = {'_geninterp_': True}
- exec """def f():
- pass""" in d
- assert not pypypolicy.look_inside_function(d['f'])
-
def test_astcompiler():
from pypy.interpreter.astcompiler import ast
assert not pypypolicy.look_inside_function(ast.AST.walkabout)
diff --git a/pypy/module/rbench/__init__.py b/pypy/module/rbench/__init__.py
deleted file mode 100644
--- a/pypy/module/rbench/__init__.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# Package initialisation
-from pypy.interpreter.mixedmodule import MixedModule
-
-class Module(MixedModule):
- """geninterpreted benchmarks"""
-
- appleveldefs = {
- 'pystone': 'app_bench.pystone',
- 'richards': 'app_bench.richards',
- }
-
- interpleveldefs = {}
diff --git a/pypy/module/rbench/app_bench.py b/pypy/module/rbench/app_bench.py
deleted file mode 100644
--- a/pypy/module/rbench/app_bench.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from pypy.translator.test.rpystone import main as pystone
-from pypy.translator.goal.richards import main as richards
diff --git a/pypy/module/select/interp_kqueue.py b/pypy/module/select/interp_kqueue.py
--- a/pypy/module/select/interp_kqueue.py
+++ b/pypy/module/select/interp_kqueue.py
@@ -144,66 +144,65 @@
else:
changelist_len = space.len_w(w_changelist)
- with lltype.scoped_alloc(rffi.CArray(kevent), changelist_len) as changelist, \
- lltype.scoped_alloc(rffi.CArray(kevent), max_events) as eventlist, \
- lltype.scoped_alloc(timespec) as timeout:
+ with lltype.scoped_alloc(rffi.CArray(kevent), changelist_len) as changelist:
+ with lltype.scoped_alloc(rffi.CArray(kevent), max_events) as eventlist:
+ with lltype.scoped_alloc(timespec) as timeout:
- if not space.is_w(w_timeout, space.w_None):
- _timeout = space.float_w(w_timeout)
- if _timeout < 0:
- raise operationerrfmt(space.w_ValueError,
- "Timeout must be None or >= 0, got %s", str(_timeout)
- )
- sec = int(_timeout)
- nsec = int(1e9 * (_timeout - sec))
- rffi.setintfield(timeout, 'c_tv_sec', sec)
- rffi.setintfield(timeout, 'c_tv_nsec', nsec)
- ptimeout = timeout
- else:
- ptimeout = lltype.nullptr(timespec)
+ if not space.is_w(w_timeout, space.w_None):
+ _timeout = space.float_w(w_timeout)
+ if _timeout < 0:
+ raise operationerrfmt(space.w_ValueError,
+ "Timeout must be None or >= 0, got %s", str(_timeout)
+ )
+ sec = int(_timeout)
+ nsec = int(1e9 * (_timeout - sec))
+ rffi.setintfield(timeout, 'c_tv_sec', sec)
+ rffi.setintfield(timeout, 'c_tv_nsec', nsec)
+ ptimeout = timeout
+ else:
+ ptimeout = lltype.nullptr(timespec)
- if not space.is_w(w_changelist, space.w_None):
- i = 0
- for w_ev in space.listview(w_changelist):
- ev = space.interp_w(W_Kevent, w_ev)
- changelist[i].c_ident = ev.event.c_ident
- changelist[i].c_filter = ev.event.c_filter
- changelist[i].c_flags = ev.event.c_flags
- changelist[i].c_fflags = ev.event.c_fflags
- changelist[i].c_data = ev.event.c_data
- changelist[i].c_udata = ev.event.c_udata
- i += 1
- pchangelist = changelist
- else:
- pchangelist = lltype.nullptr(rffi.CArray(kevent))
+ if not space.is_w(w_changelist, space.w_None):
+ i = 0
+ for w_ev in space.listview(w_changelist):
+ ev = space.interp_w(W_Kevent, w_ev)
+ changelist[i].c_ident = ev.event.c_ident
+ changelist[i].c_filter = ev.event.c_filter
+ changelist[i].c_flags = ev.event.c_flags
+ changelist[i].c_fflags = ev.event.c_fflags
+ changelist[i].c_data = ev.event.c_data
+ changelist[i].c_udata = ev.event.c_udata
+ i += 1
+ pchangelist = changelist
+ else:
+ pchangelist = lltype.nullptr(rffi.CArray(kevent))
- nfds = syscall_kevent(self.kqfd,
- pchangelist,
- changelist_len,
- eventlist,
- max_events,
- ptimeout)
- if nfds < 0:
- raise exception_from_errno(space, space.w_IOError)
- else:
- elist_w = [None] * nfds
- for i in xrange(nfds):
+ nfds = syscall_kevent(self.kqfd,
+ pchangelist,
+ changelist_len,
+ eventlist,
+ max_events,
+ ptimeout)
+ if nfds < 0:
+ raise exception_from_errno(space, space.w_IOError)
+ else:
+ elist_w = [None] * nfds
+ for i in xrange(nfds):
- evt = eventlist[i]
+ evt = eventlist[i]
- w_event = W_Kevent(space)
- w_event.event = lltype.malloc(kevent, flavor="raw")
- w_event.event.c_ident = evt.c_ident
- w_event.event.c_filter = evt.c_filter
- w_event.event.c_flags = evt.c_flags
- w_event.event.c_fflags = evt.c_fflags
- w_event.event.c_data = evt.c_data
- w_event.event.c_udata = evt.c_udata
+ w_event = W_Kevent(space)
+ w_event.event = lltype.malloc(kevent, flavor="raw")
+ w_event.event.c_ident = evt.c_ident
+ w_event.event.c_filter = evt.c_filter
+ w_event.event.c_flags = evt.c_flags
+ w_event.event.c_fflags = evt.c_fflags
+ w_event.event.c_data = evt.c_data
+ w_event.event.c_udata = evt.c_udata
- elist_w[i] = w_event
+ elist_w[i] = w_event
- return space.newlist(elist_w)
-
+ return space.newlist(elist_w)
W_Kqueue.typedef = TypeDef("select.kqueue",
@@ -227,7 +226,7 @@
if self.event:
lltype.free(self.event, flavor="raw")
- @unwrap_spec(filter=int, flags=rffi.r_uint, fflags=rffi.r_uint, data=int, udata=rffi.r_uint)
+ @unwrap_spec(filter=int, flags='c_uint', fflags='c_uint', data=int, udata='c_uint')
def descr__init__(self, space, w_ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0):
ident = space.c_filedescriptor_w(w_ident)
@@ -246,8 +245,8 @@
r_filter = rffi.cast(lltype.Signed, other.event.c_filter)
l_flags = rffi.cast(lltype.Unsigned, self.event.c_flags)
r_flags = rffi.cast(lltype.Unsigned, other.event.c_flags)
- l_fflags = self.event.c_fflags
- r_fflags = other.event.c_fflags
+ l_fflags = rffi.cast(lltype.Unsigned, self.event.c_fflags)
+ r_fflags = rffi.cast(lltype.Unsigned, other.event.c_fflags)
l_data = self.event.c_data
r_data = other.event.c_data
l_udata = rffi.cast(lltype.Unsigned, self.event.c_udata)
diff --git a/pypy/module/select/test/test_kqueue.py b/pypy/module/select/test/test_kqueue.py
--- a/pypy/module/select/test/test_kqueue.py
+++ b/pypy/module/select/test/test_kqueue.py
@@ -75,7 +75,7 @@
assert ev == ev
assert ev != other
- bignum = sys.maxsize * 2 + 1
+ bignum = (sys.maxsize * 2 + 1) & 0xffffffff
fd = sys.maxsize
ev = select.kevent(fd, 1, 2, bignum, sys.maxsize, bignum)
assert ev.ident == fd
diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py
--- a/pypy/module/signal/interp_signal.py
+++ b/pypy/module/signal/interp_signal.py
@@ -11,11 +11,11 @@
import sys
from pypy.tool import autopath
from pypy.rlib import jit, rposix
-from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.rarithmetic import intmask, is_valid_int
def setup():
for key, value in cpy_signal.__dict__.items():
- if key.startswith('SIG') and isinstance(value, int):
+ if key.startswith('SIG') and is_valid_int(value):
globals()[key] = value
yield key
diff --git a/pypy/module/test_lib_pypy/ctypes_tests/test_errno.py b/pypy/module/test_lib_pypy/ctypes_tests/test_errno.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/test_lib_pypy/ctypes_tests/test_errno.py
@@ -0,0 +1,21 @@
+import py
+
+import ctypes
+from _ctypes import function
+
+_rawffi = py.test.importorskip("_rawffi")
+
+class TestErrno:
+
+ def test_errno_saved_and_restored(self):
+ def check():
+ assert _rawffi.get_errno() == 42
+ assert ctypes.get_errno() == old
+ check.free_temp_buffers = lambda *args: None
+ f = function.CFuncPtr()
+ old = _rawffi.get_errno()
+ f._flags_ = _rawffi.FUNCFLAG_USE_ERRNO
+ ctypes.set_errno(42)
+ f._call_funcptr(check)
+ assert _rawffi.get_errno() == old
+ ctypes.set_errno(0)
diff --git a/pypy/objspace/flow/model.py b/pypy/objspace/flow/model.py
--- a/pypy/objspace/flow/model.py
+++ b/pypy/objspace/flow/model.py
@@ -8,6 +8,8 @@
from pypy.tool.descriptor import roproperty
from pypy.tool.sourcetools import PY_IDENTIFIER, nice_repr_for_func
from pypy.tool.identity_dict import identity_dict
+from pypy.rlib.rarithmetic import is_valid_int
+
"""
memory size before and after introduction of __slots__
@@ -542,7 +544,7 @@
cases = [link.exitcase for link in block.exits]
has_default = cases[-1] == 'default'
for n in cases[:len(cases)-has_default]:
- if isinstance(n, (int, long)):
+ if is_valid_int(n):
continue
if isinstance(n, (str, unicode)) and len(n) == 1:
continue
diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py
--- a/pypy/objspace/flow/objspace.py
+++ b/pypy/objspace/flow/objspace.py
@@ -14,6 +14,7 @@
from pypy.objspace.flow import flowcontext, operation, specialcase
from pypy.rlib.unroll import unrolling_iterable, _unroller
from pypy.rlib import rstackovf, rarithmetic
+from pypy.rlib.rarithmetic import is_valid_int
# method-wrappers have not enough introspection in CPython
@@ -103,7 +104,7 @@
is_ = None # real version added by add_operations()
id = None # real version added by add_operations()
- def newdict(self):
+ def newdict(self, module="ignored"):
if self.concrete_mode:
return Constant({})
return self.do_operation('newdict')
@@ -116,7 +117,7 @@
else:
return Constant(tuple(content))
- def newlist(self, args_w):
+ def newlist(self, args_w, sizehint=None):
if self.concrete_mode:
content = [self.unwrap(w_arg) for w_arg in args_w]
return Constant(content)
@@ -141,7 +142,7 @@
def int_w(self, w_obj):
if isinstance(w_obj, Constant):
val = w_obj.value
- if type(val) not in (int,long):
+ if not is_valid_int(val):
raise TypeError("expected integer: " + repr(w_obj))
return val
return self.unwrap(w_obj)
@@ -221,10 +222,8 @@
except UnwrapException:
raise Exception, "non-constant except guard"
if check_class in (NotImplementedError, AssertionError):
- # if we are in geninterp, we cannot catch these exceptions
- if not self.config.translation.builtins_can_raise_exceptions:
- raise error.FlowingError("Catching %s is not valid in RPython" %
- check_class.__name__)
+ raise error.FlowingError("Catching %s is not valid in RPython" %
+ check_class.__name__)
if not isinstance(check_class, tuple):
# the simple case
return ObjSpace.exception_match(self, w_exc_type, w_check_class)
@@ -438,41 +437,33 @@
exceptions = [Exception] # *any* exception by default
if isinstance(w_callable, Constant):
c = w_callable.value
- if not self.config.translation.builtins_can_raise_exceptions:
- if (isinstance(c, (types.BuiltinFunctionType,
- types.BuiltinMethodType,
- types.ClassType,
- types.TypeType)) and
- c.__module__ in ['__builtin__', 'exceptions']):
- exceptions = operation.implicit_exceptions.get(c)
+ if (isinstance(c, (types.BuiltinFunctionType,
+ types.BuiltinMethodType,
+ types.ClassType,
+ types.TypeType)) and
+ c.__module__ in ['__builtin__', 'exceptions']):
+ exceptions = operation.implicit_exceptions.get(c)
self.handle_implicit_exceptions(exceptions)
return w_res
def handle_implicit_exceptions(self, exceptions):
if not exceptions:
return
- if not self.config.translation.builtins_can_raise_exceptions:
- # clean up 'exceptions' by removing the non-RPythonic exceptions
- # which might be listed for geninterp.
- exceptions = [exc for exc in exceptions
- if exc is not TypeError and
- exc is not AttributeError]
- if exceptions:
- # catch possible exceptions implicitly. If the OperationError
- # below is not caught in the same function, it will produce an
- # exception-raising return block in the flow graph. Note that
- # even if the interpreter re-raises the exception, it will not
- # be the same ImplicitOperationError instance internally.
- context = self.getexecutioncontext()
- outcome, w_exc_cls, w_exc_value = context.guessexception(*exceptions)
- if outcome is not None:
- # we assume that the caught exc_cls will be exactly the
- # one specified by 'outcome', and not a subclass of it,
- # unless 'outcome' is Exception.
- #if outcome is not Exception:
- #w_exc_cls = Constant(outcome) Now done by guessexception itself
- #pass
- raise operation.ImplicitOperationError(w_exc_cls, w_exc_value)
+ # catch possible exceptions implicitly. If the OperationError
+ # below is not caught in the same function, it will produce an
+ # exception-raising return block in the flow graph. Note that
+ # even if the interpreter re-raises the exception, it will not
+ # be the same ImplicitOperationError instance internally.
+ context = self.getexecutioncontext()
+ outcome, w_exc_cls, w_exc_value = context.guessexception(*exceptions)
+ if outcome is not None:
+ # we assume that the caught exc_cls will be exactly the
+ # one specified by 'outcome', and not a subclass of it,
+ # unless 'outcome' is Exception.
+ #if outcome is not Exception:
+ #w_exc_cls = Constant(outcome) Now done by guessexception itself
+ #pass
+ raise operation.ImplicitOperationError(w_exc_cls, w_exc_value)
def w_KeyboardInterrupt(self):
# the reason to do this is: if you interrupt the flowing of a function
diff --git a/pypy/objspace/flow/operation.py b/pypy/objspace/flow/operation.py
--- a/pypy/objspace/flow/operation.py
+++ b/pypy/objspace/flow/operation.py
@@ -30,10 +30,7 @@
def new_style_type(x):
"""Simulate a situation where every class is new-style"""
- t = getattr(x, '__class__', type(x))
- if t is types.ClassType: # guess who's here? exception classes...
- t = type
- return t
+ return getattr(x, '__class__', type(x))
def do_int(x):
return x.__int__()
@@ -257,8 +254,6 @@
OverflowError: 'ovf',
IndexError: 'idx',
KeyError: 'key',
- AttributeError: 'att',
- TypeError: 'typ',
ZeroDivisionError: 'zer',
ValueError: 'val',
}
@@ -293,12 +288,6 @@
lis.append(OverflowError)
implicit_exceptions[name+"_ovf"] = lis
-for _name in 'getattr', 'delattr':
- _add_exceptions(_name, AttributeError)
-for _name in 'iter', 'coerce':
- _add_exceptions(_name, TypeError)
-del _name
-
_add_exceptions("""div mod divmod truediv floordiv pow
inplace_div inplace_mod inplace_divmod inplace_truediv
inplace_floordiv inplace_pow""", ZeroDivisionError)
diff --git a/pypy/objspace/flow/specialcase.py b/pypy/objspace/flow/specialcase.py
--- a/pypy/objspace/flow/specialcase.py
+++ b/pypy/objspace/flow/specialcase.py
@@ -49,35 +49,9 @@
else:
raise Exception, "should call %r with exactly %d arguments" % (
fn, Arity[opname])
- if space.config.translation.builtins_can_raise_exceptions:
- # in this mode, avoid constant folding and raise an implicit Exception
- w_result = space.do_operation(opname, *args_w)
- space.handle_implicit_exceptions([Exception])
- return w_result
- else:
- # in normal mode, completely replace the call with the underlying
- # operation and its limited implicit exceptions semantic
- return getattr(space, opname)(*args_w)
-
-
-# This is not a space cache.
-# It is just collecting the compiled functions from all the source snippets.
-
-class FunctionCache(Cache):
- """A cache mapping applevel instances to dicts with simple functions"""
-
- def _build(app):
- """NOT_RPYTHON.
- Called indirectly by ApplevelClass.interphook().appcaller()."""
- dic = {}
- if not app.can_use_geninterp:
- return None
- if app.filename is not None:
- dic['__file__'] = app.filename
- dic['__name__'] = app.modname
- exec py.code.Source(app.source).compile() in dic
- return dic
- _build = staticmethod(_build)
+ # completely replace the call with the underlying
+ # operation and its limited implicit exceptions semantic
+ return getattr(space, opname)(*args_w)
# _________________________________________________________________________
# a simplified version of the basic printing routines, for RPython programs
@@ -99,29 +73,21 @@
s = '\n'
import os
os.write(1, s)
-# _________________________________________________________________________
-
-compiled_funcs = FunctionCache()
def sc_applevel(space, app, name, args_w):
- dic = compiled_funcs.getorbuild(app)
- if not dic:
- return None # signal that this is not RPython
- func = dic[name]
- if getattr(func, '_annspecialcase_', '').startswith('flowspace:'):
- # a hack to replace specific app-level helpers with simplified
- # RPython versions
- name = func._annspecialcase_[len('flowspace:'):]
- if name == 'print_item': # more special cases...
- w_s = space.do_operation('str', *args_w)
- args_w = (w_s,)
- func = globals()['rpython_' + name]
+ # special case only for print_item and print_newline
+ if 'pyopcode' in app.filename and name == 'print_item':
+ w_s = space.do_operation('str', *args_w)
+ args_w = (w_s,)
+ elif 'pyopcode' in app.filename and name == 'print_newline':
+ pass
else:
- # otherwise, just call the app-level helper and hope that it
- # is RPython enough
- pass
+ raise Exception("not RPython: calling %r from %r" % (name, app))
+ func = globals()['rpython_' + name]
return space.do_operation('simple_call', Constant(func), *args_w)
+# _________________________________________________________________________
+
def sc_r_uint(space, r_uint, args):
args_w, kwds_w = args.unpack()
assert not kwds_w
diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py
--- a/pypy/objspace/flow/test/test_objspace.py
+++ b/pypy/objspace/flow/test/test_objspace.py
@@ -849,16 +849,25 @@
c.co_filename, c.co_name, c.co_firstlineno,
c.co_lnotab)
+ def patch_opcodes(self, *opcodes):
+ flow_meth_names = flowcontext.FlowSpaceFrame.opcode_method_names
+ pyframe_meth_names = PyFrame.opcode_method_names
+ for name in opcodes:
+ num = bytecode_spec.opmap[name]
+ setattr(self, 'old_' + name, flow_meth_names[num])
+ flow_meth_names[num] = pyframe_meth_names[num]
+
+ def unpatch_opcodes(self, *opcodes):
+ flow_meth_names = flowcontext.FlowSpaceFrame.opcode_method_names
+ for name in opcodes:
+ num = bytecode_spec.opmap[name]
+ flow_meth_names[num] = getattr(self, 'old_' + name)
+
def test_callmethod_opcode(self):
""" Tests code generated by pypy-c compiled with CALL_METHOD
bytecode
"""
- flow_meth_names = flowcontext.FlowSpaceFrame.opcode_method_names
- pyframe_meth_names = PyFrame.opcode_method_names
- for name in ['CALL_METHOD', 'LOOKUP_METHOD']:
- num = bytecode_spec.opmap[name]
- locals()['old_' + name] = flow_meth_names[num]
- flow_meth_names[num] = pyframe_meth_names[num]
+ self.patch_opcodes('CALL_METHOD', 'LOOKUP_METHOD')
try:
class X:
def m(self):
@@ -878,9 +887,29 @@
assert all_ops['simple_call'] == 2
assert all_ops['getattr'] == 1
finally:
- for name in ['CALL_METHOD', 'LOOKUP_METHOD']:
- num = bytecode_spec.opmap[name]
- flow_meth_names[num] = locals()['old_' + name]
+ self.unpatch_opcodes('CALL_METHOD', 'LOOKUP_METHOD')
+
+ def test_build_list_from_arg_opcode(self):
+ """ Tests code generated by pypy-c compiled with BUILD_LIST_FROM_ARG
+ bytecode
+ """
+ self.patch_opcodes('BUILD_LIST_FROM_ARG')
+ try:
+ def f():
+ return [i for i in "abc"]
+
+ # this code is generated by pypy-c when compiling above f
+ pypy_code = 'd\x01\x00\xcb\x00\x00D]\x0c\x00}\x00\x00|\x00\x00^\x02\x00q\x07\x00S'
+ new_c = self.monkey_patch_code(f.func_code, 3, 67, pypy_code, (),
+ ('i',))
+ f2 = new.function(new_c, locals(), 'f')
+
+ graph = self.codetest(f2)
+ all_ops = self.all_operations(graph)
+ assert all_ops == {'newlist': 1, 'getattr': 1, 'simple_call': 1,
+ 'iter': 1, 'next': 1}
+ finally:
+ self.unpatch_opcodes('BUILD_LIST_FROM_ARG')
def test_dont_capture_RuntimeError(self):
class Foo:
@@ -968,61 +997,6 @@
g = self.codetest(f)
-class TestGenInterpStyle(Base):
- def setup_class(cls):
- cls.space = FlowObjSpace()
- cls.space.config.translation.builtins_can_raise_exceptions = True
-
- def reraiseAttributeError(v):
- try:
- x = getattr(v, "y")
- except AttributeError:
- raise
-
- def test_reraiseAttributeError(self):
- x = self.codetest(self.reraiseAttributeError)
- simplify_graph(x)
- self.show(x)
- excfound = []
- for link in x.iterlinks():
- if link.target is x.exceptblock:
- excfound.append(link.exitcase)
- assert len(excfound) == 2
- excfound.sort()
- expected = [Exception, AttributeError]
- expected.sort()
- assert excfound == expected
-
- def reraiseTypeError(dic):
- try:
- x = dic[5]
- except TypeError:
- raise
-
- def test_reraiseTypeError(self):
- x = self.codetest(self.reraiseTypeError)
- simplify_graph(x)
- self.show(x)
- excfound = []
- for link in x.iterlinks():
- if link.target is x.exceptblock:
- excfound.append(link.exitcase)
- assert len(excfound) == 2
- excfound.sort()
- expected = [Exception, TypeError]
- expected.sort()
- assert excfound == expected
-
- def test_can_catch_special_exceptions(self):
- def f():
- try:
- f()
- except NotImplementedError:
- pass
- graph = self.codetest(f)
- # assert did not crash
-
-
DATA = {'x': 5,
'y': 6}
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -2,6 +2,7 @@
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
from pypy.objspace.std.settype import set_typedef as settypedef
+from pypy.objspace.std.frozensettype import frozenset_typedef as frozensettypedef
from pypy.interpreter import gateway
from pypy.interpreter.argument import Signature
from pypy.interpreter.error import OperationError, operationerrfmt
@@ -488,7 +489,7 @@
class _UnwrappedIteratorMixin:
_mixin_ = True
-
+
def __init__(self, space, strategy, dictimplementation):
IteratorImplementation.__init__(self, space, dictimplementation)
self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
@@ -837,10 +838,12 @@
return all_contained_in(space, w_dictview, w_otherview)
return space.w_False
eq__DictViewKeys_settypedef = eq__DictViewKeys_DictViewKeys
+eq__DictViewKeys_frozensettypedef = eq__DictViewKeys_DictViewKeys
eq__DictViewKeys_DictViewItems = eq__DictViewKeys_DictViewKeys
eq__DictViewItems_DictViewItems = eq__DictViewKeys_DictViewKeys
eq__DictViewItems_settypedef = eq__DictViewItems_DictViewItems
+eq__DictViewItems_frozensettypedef = eq__DictViewItems_DictViewItems
def repr__DictViewKeys(space, w_dictview):
w_seq = space.call_function(space.w_list, w_dictview)
diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -6,7 +6,7 @@
from pypy.objspace.std.noneobject import W_NoneObject
from pypy.objspace.std.register_all import register_all
from pypy.rlib import jit
-from pypy.rlib.rarithmetic import ovfcheck, LONG_BIT, r_uint
+from pypy.rlib.rarithmetic import ovfcheck, LONG_BIT, r_uint, is_valid_int
from pypy.rlib.rbigint import rbigint
"""
@@ -42,6 +42,7 @@
from pypy.objspace.std.inttype import int_typedef as typedef
def __init__(w_self, intval):
+ assert is_valid_int(intval)
w_self.intval = intval
def __repr__(w_self):
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -7,7 +7,7 @@
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std import slicetype
from pypy.interpreter import gateway, baseobjspace
-from pypy.rlib.objectmodel import instantiate, specialize
+from pypy.rlib.objectmodel import instantiate, specialize, newlist_hint
from pypy.rlib.listsort import make_timsort_class
from pypy.rlib import rerased, jit, debug
from pypy.interpreter.argument import Signature
@@ -32,9 +32,11 @@
storage = strategy.erase(None)
return W_ListObject.from_storage_and_strategy(space, storage, strategy)
- at jit.look_inside_iff(lambda space, list_w: jit.isconstant(len(list_w)) and len(list_w) < UNROLL_CUTOFF)
-def get_strategy_from_list_objects(space, list_w):
+ at jit.look_inside_iff(lambda space, list_w, sizehint: jit.isconstant(len(list_w)) and len(list_w) < UNROLL_CUTOFF)
+def get_strategy_from_list_objects(space, list_w, sizehint):
if not list_w:
+ if sizehint != -1:
+ return SizeListStrategy(space, sizehint)
return space.fromcache(EmptyListStrategy)
# check for ints
@@ -75,11 +77,13 @@
class W_ListObject(W_AbstractListObject):
from pypy.objspace.std.listtype import list_typedef as typedef
- def __init__(w_self, space, wrappeditems):
+ def __init__(w_self, space, wrappeditems, sizehint=-1):
assert isinstance(wrappeditems, list)
w_self.space = space
if space.config.objspace.std.withliststrategies:
- w_self.strategy = get_strategy_from_list_objects(space, wrappeditems)
+ w_self.strategy = get_strategy_from_list_objects(space,
+ wrappeditems,
+ sizehint)
else:
w_self.strategy = space.fromcache(ObjectListStrategy)
w_self.init_from_list_w(wrappeditems)
@@ -255,6 +259,7 @@
class ListStrategy(object):
+ sizehint = -1
def __init__(self, space):
self.space = space
@@ -336,6 +341,7 @@
def sort(self, w_list, reverse):
raise NotImplementedError
+
class EmptyListStrategy(ListStrategy):
"""EmptyListStrategy is used when a W_List withouth elements is created.
The storage is None. When items are added to the W_List a new RPython list
@@ -397,7 +403,7 @@
else:
strategy = self.space.fromcache(ObjectListStrategy)
- storage = strategy.get_empty_storage()
+ storage = strategy.get_empty_storage(self.sizehint)
w_list.strategy = strategy
w_list.lstorage = storage
@@ -438,6 +444,13 @@
def reverse(self, w_list):
pass
+class SizeListStrategy(EmptyListStrategy):
+ """ Like empty, but when modified it'll preallocate the size to sizehint
+ """
+ def __init__(self, space, sizehint):
+ self.sizehint = sizehint
+ ListStrategy.__init__(self, space)
+
class RangeListStrategy(ListStrategy):
"""RangeListStrategy is used when a list is created using the range method.
The storage is a tuple containing only three integers start, step and length
@@ -660,8 +673,10 @@
l = [self.unwrap(w_item) for w_item in list_w]
w_list.lstorage = self.erase(l)
- def get_empty_storage(self):
- return self.erase([])
+ def get_empty_storage(self, sizehint):
+ if sizehint == -1:
+ return self.erase([])
+ return self.erase(newlist_hint(sizehint))
def clone(self, w_list):
l = self.unerase(w_list.lstorage)
diff --git a/pypy/objspace/std/newformat.py b/pypy/objspace/std/newformat.py
--- a/pypy/objspace/std/newformat.py
+++ b/pypy/objspace/std/newformat.py
@@ -10,6 +10,10 @@
@specialize.argtype(1)
+ at jit.look_inside_iff(lambda space, s, start, end:
+ jit.isconstant(s) and
+ jit.isconstant(start) and
+ jit.isconstant(end))
def _parse_int(space, s, start, end):
"""Parse a number and check for overflows"""
result = 0
@@ -91,9 +95,18 @@
if s[i] == "{":
i += 1
markup_follows = False
- # Attach literal data
+ # Attach literal data, ending with { or }
out.append_slice(s, last_literal, i - 1)
if not markup_follows:
+ if self.parser_list_w is not None:
+ end_literal = i - 1
+ assert end_literal > last_literal
+ literal = self.template[last_literal:end_literal]
+ w_entry = space.newtuple([
+ space.wrap(literal),
+ space.w_None, space.w_None, space.w_None])
+ self.parser_list_w.append(w_entry)
+ self.last_end = i
last_literal = i
continue
nested = 1
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -9,7 +9,7 @@
from pypy.objspace.descroperation import DescrOperation, raiseattrerror
from pypy.rlib.objectmodel import instantiate, r_dict, specialize, is_annotation_constant
from pypy.rlib.debug import make_sure_not_resized
-from pypy.rlib.rarithmetic import base_int, widen
+from pypy.rlib.rarithmetic import base_int, widen, maxint, is_valid_int
from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib import jit
@@ -195,6 +195,11 @@
"NOT_RPYTHON"
# _____ this code is here to support testing only _____
+ # we might get there in non-translated versions if 'x' is
+ # a long that fits the correct range.
+ if is_valid_int(x):
+ return self.newint(x)
+
# wrap() of a container works on CPython, but the code is
# not RPython. Don't use -- it is kept around mostly for tests.
# Use instead newdict(), newlist(), newtuple().
@@ -213,17 +218,7 @@
# The following cases are even stranger.
# Really really only for tests.
if type(x) is long:
- if self.config.objspace.std.withsmalllong:
- from pypy.rlib.rarithmetic import r_longlong
- try:
- rx = r_longlong(x)
- except OverflowError:
- pass
- else:
- from pypy.objspace.std.smalllongobject import \
- W_SmallLongObject
- return W_SmallLongObject(rx)
- return W_LongObject.fromlong(x)
+ return self.wraplong(x)
if isinstance(x, slice):
return W_SliceObject(self.wrap(x.start),
self.wrap(x.stop),
@@ -264,6 +259,20 @@
return w_result
return None
+ def wraplong(self, x):
+ "NOT_RPYTHON"
+ if self.config.objspace.std.withsmalllong:
+ from pypy.rlib.rarithmetic import r_longlong
+ try:
+ rx = r_longlong(x)
+ except OverflowError:
+ pass
+ else:
+ from pypy.objspace.std.smalllongobject import \
+ W_SmallLongObject
+ return W_SmallLongObject(rx)
+ return W_LongObject.fromlong(x)
+
def unwrap(self, w_obj):
"""NOT_RPYTHON"""
if isinstance(w_obj, Wrappable):
@@ -300,8 +309,9 @@
make_sure_not_resized(list_w)
return wraptuple(self, list_w)
- def newlist(self, list_w):
- return W_ListObject(self, list_w)
+ def newlist(self, list_w, sizehint=-1):
+ assert not list_w or sizehint == -1
+ return W_ListObject(self, list_w, sizehint)
def newlist_str(self, list_s):
return W_ListObject.newlist_str(self, list_s)
diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -56,9 +56,18 @@
return w_self._value
def unicode_w(w_self, space):
- # XXX should this use the default encoding?
- from pypy.objspace.std.unicodetype import plain_str2unicode
- return plain_str2unicode(space, w_self._value)
+ # Use the default encoding.
+ from pypy.objspace.std.unicodetype import unicode_from_string, \
+ decode_object
+ w_defaultencoding = space.call_function(space.sys.get(
+ 'getdefaultencoding'))
+ from pypy.objspace.std.unicodetype import _get_encoding_and_errors, \
+ unicode_from_string, decode_object
+ encoding, errors = _get_encoding_and_errors(space, w_defaultencoding,
+ space.w_None)
+ if encoding is None and errors is None:
+ return space.unicode_w(unicode_from_string(space, w_self))
+ return space.unicode_w(decode_object(space, w_self, encoding, errors))
registerimplementation(W_StringObject)
diff --git a/pypy/objspace/std/strutil.py b/pypy/objspace/std/strutil.py
--- a/pypy/objspace/std/strutil.py
+++ b/pypy/objspace/std/strutil.py
@@ -177,8 +177,10 @@
return INFINITY
elif low == "infinity" or low == "+infinity":
return INFINITY
- elif low == "nan" or low == "-nan" or low == "+nan":
+ elif low == "nan" or low == "+nan":
return NAN
+ elif low == "-nan":
+ return -NAN
try:
return rstring_to_float(s)
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -613,6 +613,7 @@
assert len(keys) == 2
assert set(keys) == set([1, "a"])
assert keys == set([1, "a"])
+ assert keys == frozenset([1, "a"])
assert keys != set([1, "a", "b"])
assert keys != set([1, "b"])
assert keys != set([1])
@@ -633,6 +634,7 @@
assert len(items) == 2
assert set(items) == set([(1, 10), ("a", "ABC")])
assert items == set([(1, 10), ("a", "ABC")])
+ assert items == frozenset([(1, 10), ("a", "ABC")])
assert items != set([(1, 10), ("a", "ABC"), "junk"])
assert items != set([(1, 10), ("a", "def")])
assert items != set([(1, 10)])
diff --git a/pypy/objspace/std/test/test_intobject.py b/pypy/objspace/std/test/test_intobject.py
--- a/pypy/objspace/std/test/test_intobject.py
+++ b/pypy/objspace/std/test/test_intobject.py
@@ -2,7 +2,7 @@
import sys
from pypy.objspace.std import intobject as iobj
from pypy.objspace.std.multimethod import FailedToImplement
-from pypy.rlib.rarithmetic import r_uint
+from pypy.rlib.rarithmetic import r_uint, is_valid_int
from pypy.rlib.rbigint import rbigint
@@ -15,7 +15,7 @@
while 1:
ires = x << n
lres = l << n
- if type(ires) is long or lres != ires:
+ if not is_valid_int(ires) or lres != ires:
return n
n += 1
diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py
--- a/pypy/objspace/std/test/test_listobject.py
+++ b/pypy/objspace/std/test/test_listobject.py
@@ -1,7 +1,9 @@
# coding: iso-8859-15
import random
-from pypy.objspace.std.listobject import W_ListObject
+from pypy.objspace.std.listobject import W_ListObject, SizeListStrategy,\
+ IntegerListStrategy, ObjectListStrategy
from pypy.interpreter.error import OperationError
+from pypy.rlib.rarithmetic import is_valid_int
from pypy.conftest import gettestobjspace, option
@@ -241,7 +243,7 @@
self.space.raises_w(self.space.w_IndexError,
self.space.setitem, w_list, w(key), w(42))
else:
- if isinstance(value, int): # non-slicing
+ if is_valid_int(value): # non-slicing
if random.random() < 0.25: # deleting
self.space.delitem(w_list, w(key))
del expected[key]
@@ -390,6 +392,16 @@
assert self.space.eq_w(self.space.le(w_list4, w_list3),
self.space.w_True)
+ def test_sizehint(self):
+ space = self.space
+ w_l = space.newlist([], sizehint=10)
+ assert isinstance(w_l.strategy, SizeListStrategy)
+ space.call_method(w_l, 'append', space.wrap(3))
+ assert isinstance(w_l.strategy, IntegerListStrategy)
+ w_l = space.newlist([], sizehint=10)
+ space.call_method(w_l, 'append', space.w_None)
+ assert isinstance(w_l.strategy, ObjectListStrategy)
+
class AppTestW_ListObject(object):
def setup_class(cls):
diff --git a/pypy/objspace/std/test/test_newformat.py b/pypy/objspace/std/test/test_newformat.py
--- a/pypy/objspace/std/test/test_newformat.py
+++ b/pypy/objspace/std/test/test_newformat.py
@@ -11,6 +11,7 @@
assert self.s("}}").format() == self.s("}")
assert self.s("{} {{ {}").format(1, 2) == self.s("1 { 2")
assert self.s("{{}}").format() == self.s("{}")
+ assert self.s("{{{{").format() == self.s("{{")
def test_empty(self):
assert self.s().format() == self.s()
@@ -385,6 +386,12 @@
for x in l[0]:
assert isinstance(x, unicode)
+ def test_formatter_parser_escape(self):
+ l = list("{{a}}"._formatter_parser())
+ assert l == [('{', None, None, None), ('a}', None, None, None)]
+ l = list("{{{{"._formatter_parser())
+ assert l == [('{', None, None, None), ('{', None, None, None)]
+
def test_formatter_field_name_split(self):
first, rest = ''._formatter_field_name_split()
assert first == ''
diff --git a/pypy/objspace/std/test/test_stringobject.py b/pypy/objspace/std/test/test_stringobject.py
--- a/pypy/objspace/std/test/test_stringobject.py
+++ b/pypy/objspace/std/test/test_stringobject.py
@@ -501,6 +501,37 @@
raises(TypeError, ''.join, [1])
raises(TypeError, ''.join, [[1]])
+ def test_unicode_join_str_arg_ascii(self):
+ raises(UnicodeDecodeError, u''.join, ['\xc3\xa1'])
+
+ def test_unicode_join_str_arg_utf8(self):
+ # Need default encoding utf-8, but sys.setdefaultencoding
+ # is removed after startup.
+ import sys
+ if not hasattr(sys, 'setdefaultencoding'):
+ skip("sys.setdefaultencoding() not available")
+ old_encoding = sys.getdefaultencoding()
+ # Duplicate unittest.test_support.CleanImport logic because it won't
+ # import.
+ self.original_modules = sys.modules.copy()
+ try:
+ import sys as temp_sys
+ module_name = 'sys'
+ if module_name in sys.modules:
+ module = sys.modules[module_name]
+ # It is possible that module_name is just an alias for
+ # another module (e.g. stub for modules renamed in 3.x).
+ # In that case, we also need delete the real module to
+ # clear the import cache.
+ if module.__name__ != module_name:
+ del sys.modules[module.__name__]
+ del sys.modules[module_name]
+ temp_sys.setdefaultencoding('utf-8')
+ assert u''.join(['\xc3\xa1']) == u'\xe1'
+ finally:
+ temp_sys.setdefaultencoding(old_encoding)
+ sys.modules.update(self.original_modules)
+
def test_unicode_join_endcase(self):
# This class inserts a Unicode object into its argument's natural
# iteration, in the 3rd position.
diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py
--- a/pypy/objspace/std/tupleobject.py
+++ b/pypy/objspace/std/tupleobject.py
@@ -6,8 +6,11 @@
from pypy.rlib.rarithmetic import intmask
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std import slicetype
-from pypy.interpreter import gateway
from pypy.rlib.debug import make_sure_not_resized
+from pypy.rlib import jit
+
+# Tuples of known length up to UNROLL_TUPLE_LIMIT have unrolled certain methods
+UNROLL_TUPLE_LIMIT = 10
class W_AbstractTupleObject(W_Object):
__slots__ = ()
@@ -114,18 +117,28 @@
def mul__ANY_Tuple(space, w_times, w_tuple):
return mul_tuple_times(space, w_tuple, w_times)
+def tuple_unroll_condition(space, w_tuple1, w_tuple2):
+ lgt1 = len(w_tuple1.wrappeditems)
+ lgt2 = len(w_tuple2.wrappeditems)
+ return ((jit.isconstant(lgt1) and lgt1 <= UNROLL_TUPLE_LIMIT) or
+ (jit.isconstant(lgt2) and lgt2 <= UNROLL_TUPLE_LIMIT))
+
+ at jit.look_inside_iff(tuple_unroll_condition)
def eq__Tuple_Tuple(space, w_tuple1, w_tuple2):
items1 = w_tuple1.wrappeditems
items2 = w_tuple2.wrappeditems
- if len(items1) != len(items2):
+ lgt1 = len(items1)
+ lgt2 = len(items2)
+ if lgt1 != lgt2:
return space.w_False
- for i in range(len(items1)):
+ for i in range(lgt1):
item1 = items1[i]
item2 = items2[i]
if not space.eq_w(item1, item2):
return space.w_False
return space.w_True
+ at jit.look_inside_iff(tuple_unroll_condition)
def lt__Tuple_Tuple(space, w_tuple1, w_tuple2):
items1 = w_tuple1.wrappeditems
items2 = w_tuple2.wrappeditems
@@ -137,6 +150,7 @@
# No more items to compare -- compare sizes
return space.newbool(len(items1) < len(items2))
+ at jit.look_inside_iff(tuple_unroll_condition)
def gt__Tuple_Tuple(space, w_tuple1, w_tuple2):
items1 = w_tuple1.wrappeditems
items2 = w_tuple2.wrappeditems
@@ -161,6 +175,9 @@
def hash__Tuple(space, w_tuple):
return space.wrap(hash_tuple(space, w_tuple.wrappeditems))
+ at jit.look_inside_iff(lambda space, wrappeditems:
+ jit.isconstant(len(wrappeditems)) and
+ len(wrappeditems) < UNROLL_TUPLE_LIMIT)
def hash_tuple(space, wrappeditems):
# this is the CPython 2.4 algorithm (changed from 2.3)
mult = 1000003
diff --git a/pypy/rlib/_rffi_stacklet.py b/pypy/rlib/_rffi_stacklet.py
--- a/pypy/rlib/_rffi_stacklet.py
+++ b/pypy/rlib/_rffi_stacklet.py
@@ -3,6 +3,7 @@
from pypy.rpython.lltypesystem import lltype, llmemory, rffi
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.rpython.tool import rffi_platform
+from pypy.rlib.rarithmetic import is_emulated_long
import sys
@@ -14,7 +15,11 @@
separate_module_sources = ['#include "src/stacklet/stacklet.c"\n'],
)
if sys.platform == 'win32':
- eci.separate_module_files += (cdir / "src/stacklet/switch_x86_msvc.asm", )
+ if is_emulated_long:
+ asmsrc = 'switch_x64_msvc.asm'
+ else:
+ asmsrc = 'switch_x86_msvc.asm'
+ eci.separate_module_files += (cdir / 'src' / 'stacklet' / asmsrc, )
eci.export_symbols += (
'stacklet_newthread',
'stacklet_deletethread',
diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -5,7 +5,7 @@
from pypy.rpython.tool import rffi_platform
from pypy.rpython.lltypesystem import lltype, rffi
from pypy.rlib.unroll import unrolling_iterable
-from pypy.rlib.rarithmetic import intmask, r_uint
+from pypy.rlib.rarithmetic import intmask, r_uint, is_emulated_long
from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib.rmmap import alloc
from pypy.rlib.rdynload import dlopen, dlclose, dlsym, dlsym_byordinal
@@ -27,6 +27,7 @@
_MSVC = platform.name == "msvc"
_MINGW = platform.name == "mingw32"
_WIN32 = _MSVC or _MINGW
+_WIN64 = _WIN32 and is_emulated_long
_MAC_OS = platform.name == "darwin"
_FREEBSD_7 = platform.name == "freebsd7"
@@ -119,6 +120,10 @@
])
else:
libffidir = py.path.local(pypydir).join('translator', 'c', 'src', 'libffi_msvc')
+ if not _WIN64:
+ asm_ifc = 'win32.c'
+ else:
+ asm_ifc = 'win64.asm'
eci = ExternalCompilationInfo(
includes = ['ffi.h', 'windows.h'],
libraries = ['kernel32'],
@@ -126,7 +131,7 @@
separate_module_sources = separate_module_sources,
separate_module_files = [libffidir.join('ffi.c'),
libffidir.join('prep_cif.c'),
- libffidir.join('win32.c'),
+ libffidir.join(asm_ifc),
libffidir.join('pypy_ffi.c'),
],
export_symbols = ['ffi_call', 'ffi_prep_cif', 'ffi_prep_closure',
@@ -142,7 +147,7 @@
FFI_OK = rffi_platform.ConstantInteger('FFI_OK')
FFI_BAD_TYPEDEF = rffi_platform.ConstantInteger('FFI_BAD_TYPEDEF')
FFI_DEFAULT_ABI = rffi_platform.ConstantInteger('FFI_DEFAULT_ABI')
- if _WIN32:
+ if _WIN32 and not _WIN64:
FFI_STDCALL = rffi_platform.ConstantInteger('FFI_STDCALL')
FFI_TYPE_STRUCT = rffi_platform.ConstantInteger('FFI_TYPE_STRUCT')
@@ -313,7 +318,7 @@
FFI_OK = cConfig.FFI_OK
FFI_BAD_TYPEDEF = cConfig.FFI_BAD_TYPEDEF
FFI_DEFAULT_ABI = cConfig.FFI_DEFAULT_ABI
-if _WIN32:
+if _WIN32 and not _WIN64:
FFI_STDCALL = cConfig.FFI_STDCALL
FFI_TYPE_STRUCT = cConfig.FFI_TYPE_STRUCT
FFI_CIFP = rffi.COpaquePtr('ffi_cif', compilation_info=eci)
@@ -459,7 +464,7 @@
FUNCFLAG_USE_LASTERROR = 16
def get_call_conv(flags, from_jit):
- if _WIN32 and (flags & FUNCFLAG_CDECL == 0):
+ if _WIN32 and not _WIN64 and (flags & FUNCFLAG_CDECL == 0):
return FFI_STDCALL
else:
return FFI_DEFAULT_ABI
diff --git a/pypy/rlib/debug.py b/pypy/rlib/debug.py
--- a/pypy/rlib/debug.py
+++ b/pypy/rlib/debug.py
@@ -1,5 +1,7 @@
import sys, time
from pypy.rpython.extregistry import ExtRegistryEntry
+from pypy.rlib.rarithmetic import is_valid_int
+
def ll_assert(x, msg):
"""After translation to C, this becomes an RPyAssert."""
@@ -335,7 +337,7 @@
"""Give a translation-time error if 'x' is not a plain int
(e.g. if it's a r_longlong or an r_uint).
"""
- assert type(x) is int
+ assert is_valid_int(x)
return x
class Entry(ExtRegistryEntry):
diff --git a/pypy/rlib/objectmodel.py b/pypy/rlib/objectmodel.py
--- a/pypy/rlib/objectmodel.py
+++ b/pypy/rlib/objectmodel.py
@@ -233,20 +233,22 @@
# ____________________________________________________________
-def newlist(sizehint=0):
+def newlist_hint(sizehint=0):
""" Create a new list, but pass a hint how big the size should be
preallocated
"""
return []
class Entry(ExtRegistryEntry):
- _about_ = newlist
+ _about_ = newlist_hint
def compute_result_annotation(self, s_sizehint):
from pypy.annotation.model import SomeInteger
assert isinstance(s_sizehint, SomeInteger)
- return self.bookkeeper.newlist()
+ s_l = self.bookkeeper.newlist()
+ s_l.listdef.listitem.resize()
+ return s_l
def specialize_call(self, orig_hop, i_sizehint=None):
from pypy.rpython.rlist import rtype_newlist
diff --git a/pypy/rlib/rarithmetic.py b/pypy/rlib/rarithmetic.py
--- a/pypy/rlib/rarithmetic.py
+++ b/pypy/rlib/rarithmetic.py
@@ -30,22 +30,54 @@
"""
-import sys
+import sys, struct
from pypy.rpython import extregistry
from pypy.rlib import objectmodel
-# set up of machine internals
-_bits = 0
-_itest = 1
-_Ltest = 1L
-while _itest == _Ltest and type(_itest) is int:
- _itest *= 2
- _Ltest *= 2
- _bits += 1
+"""
+Long-term target:
+We want to make pypy very flexible concerning its data type layout.
+This is a larger task for later.
-LONG_BIT = _bits+1
-LONG_MASK = _Ltest*2-1
-LONG_TEST = _Ltest
+Short-term target:
+We want to run PyPy on windows 64 bit.
+
+Problem:
+On windows 64 bit, integers are only 32 bit. This is a problem for PyPy
+right now, since it assumes that a c long can hold a pointer.
+We therefore set up the target machine constants to obey this rule.
+Right now this affects 64 bit Python only on windows.
+
+Note: We use the struct module, because the array module doesn's support
+all typecodes.
+"""
+
+def _get_bitsize(typecode):
+ return len(struct.pack(typecode, 1)) * 8
+
+_long_typecode = 'l'
+if _get_bitsize('P') > _get_bitsize('l'):
+ _long_typecode = 'P'
+
+def _get_long_bit():
+ # whatever size a long has, make it big enough for a pointer.
+ return _get_bitsize(_long_typecode)
+
+# exported for now for testing array values.
+# might go into its own module.
+def get_long_pattern(x):
+ """get the bit pattern for a long, adjusted to pointer size"""
+ return struct.pack(_long_typecode, x)
+
+# used in tests for ctypes and for genc and friends
+# to handle the win64 special case:
+is_emulated_long = _long_typecode <> 'l'
+
+LONG_BIT = _get_long_bit()
+LONG_MASK = (2**LONG_BIT)-1
+LONG_TEST = 2**(LONG_BIT-1)
+
+# XXX this is a good guess, but what if a long long is 128 bit?
LONGLONG_BIT = 64
LONGLONG_MASK = (2**LONGLONG_BIT)-1
LONGLONG_TEST = 2**(LONGLONG_BIT-1)
@@ -55,12 +87,21 @@
LONG_BIT_SHIFT += 1
assert LONG_BIT_SHIFT < 99, "LONG_BIT_SHIFT value not found?"
+"""
+int is no longer necessarily the same size as the target int.
+We therefore can no longer use the int type as it is, but need
+to use long everywhere.
+"""
+
+# XXX returning int(n) should not be necessary and should be simply n.
+# XXX TODO: replace all int(n) by long(n) and fix everything that breaks.
+# XXX Then relax it and replace int(n) by n.
def intmask(n):
- if isinstance(n, int):
- return int(n) # possibly bool->int
if isinstance(n, objectmodel.Symbolic):
return n # assume Symbolics don't overflow
assert not isinstance(n, float)
+ if is_valid_int(n):
+ return int(n)
n = long(n)
n &= LONG_MASK
if n >= LONG_TEST:
@@ -95,7 +136,15 @@
r_class.BITS == LONG_BIT and r_class.SIGNED)
_should_widen_type._annspecialcase_ = 'specialize:memo'
-del _bits, _itest, _Ltest
+# the replacement for sys.maxint
+maxint = int(LONG_TEST - 1)
+
+def is_valid_int(r):
+ if objectmodel.we_are_translated():
+ return isinstance(r, int)
+ return type(r) in (int, long, bool) and (
+ -maxint - 1 <= r <= maxint)
+is_valid_int._annspecialcase_ = 'specialize:argtype(0)'
def ovfcheck(r):
"NOT_RPYTHON"
@@ -103,8 +152,10 @@
# raise OverflowError if the operation did overflow
assert not isinstance(r, r_uint), "unexpected ovf check on unsigned"
assert not isinstance(r, r_longlong), "ovfcheck not supported on r_longlong"
- assert not isinstance(r,r_ulonglong),"ovfcheck not supported on r_ulonglong"
- if type(r) is long:
+ assert not isinstance(r, r_ulonglong), "ovfcheck not supported on r_ulonglong"
+ if type(r) is long and not is_valid_int(r):
+ # checks only if applicable to r's type.
+ # this happens in the garbage collector.
raise OverflowError, "signed integer expression did overflow"
return r
@@ -425,6 +476,11 @@
else:
r_int64 = int
+# needed for ll_os_stat.time_t_to_FILE_TIME in the 64 bit case
+r_uint32 = build_int('r_uint32', False, 32)
+
+# needed for ll_time.time_sleep_llimpl
+maxint32 = int((1 << 31) -1)
# the 'float' C type
diff --git a/pypy/rlib/rbigint.py b/pypy/rlib/rbigint.py
--- a/pypy/rlib/rbigint.py
+++ b/pypy/rlib/rbigint.py
@@ -1,5 +1,5 @@
from pypy.rlib.rarithmetic import LONG_BIT, intmask, r_uint, r_ulonglong
-from pypy.rlib.rarithmetic import ovfcheck, r_longlong, widen
+from pypy.rlib.rarithmetic import ovfcheck, r_longlong, widen, is_valid_int
from pypy.rlib.rarithmetic import most_neg_value_of_same_type
from pypy.rlib.rfloat import isfinite
from pypy.rlib.debug import make_sure_not_resized, check_regular_int
@@ -44,21 +44,19 @@
def _mask_digit(x):
- if not we_are_translated():
- assert type(x) is not long, "overflow occurred!"
return intmask(x & MASK)
_mask_digit._annspecialcase_ = 'specialize:argtype(0)'
def _widen_digit(x):
if not we_are_translated():
- assert type(x) is int, "widen_digit() takes an int, got a %r" % type(x)
+ assert is_valid_int(x), "widen_digit() takes an int, got a %r" % type(x)
if SHIFT <= 15:
return int(x)
return r_longlong(x)
def _store_digit(x):
if not we_are_translated():
- assert type(x) is int, "store_digit() takes an int, got a %r" % type(x)
+ assert is_valid_int(x), "store_digit() takes an int, got a %r" % type(x)
if SHIFT <= 15:
return rffi.cast(rffi.SHORT, x)
elif SHIFT <= 31:
diff --git a/pypy/rlib/rdtoa.py b/pypy/rlib/rdtoa.py
--- a/pypy/rlib/rdtoa.py
+++ b/pypy/rlib/rdtoa.py
@@ -58,8 +58,8 @@
try:
result = dg_strtod(ll_input, end_ptr)
- endpos = (rffi.cast(rffi.LONG, end_ptr[0]) -
- rffi.cast(rffi.LONG, ll_input))
+ endpos = (rffi.cast(lltype.Signed, end_ptr[0]) -
+ rffi.cast(lltype.Signed, ll_input))
if endpos == 0 or endpos < len(input):
raise ValueError("invalid input at position %d" % (endpos,))
@@ -244,8 +244,8 @@
# The only failure mode is no memory
raise MemoryError
try:
- buflen = (rffi.cast(rffi.LONG, end_ptr[0]) -
- rffi.cast(rffi.LONG, digits))
+ buflen = (rffi.cast(lltype.Signed, end_ptr[0]) -
+ rffi.cast(lltype.Signed, digits))
sign = rffi.cast(lltype.Signed, sign_ptr[0])
# Handle nan and inf
diff --git a/pypy/rlib/rerased.py b/pypy/rlib/rerased.py
--- a/pypy/rlib/rerased.py
+++ b/pypy/rlib/rerased.py
@@ -24,11 +24,11 @@
from pypy.rpython.lltypesystem.rclass import OBJECTPTR
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.error import TyperError
-
+from pypy.rlib.rarithmetic import is_valid_int
def erase_int(x):
- assert isinstance(x, int)
+ assert is_valid_int(x)
res = 2 * x + 1
if res > sys.maxint or res < -sys.maxint - 1:
raise OverflowError
@@ -36,7 +36,7 @@
def unerase_int(y):
assert y._identity is _identity_for_ints
- assert isinstance(y._x, int)
+ assert is_valid_int(y._x)
return y._x
diff --git a/pypy/rlib/rfloat.py b/pypy/rlib/rfloat.py
--- a/pypy/rlib/rfloat.py
+++ b/pypy/rlib/rfloat.py
@@ -295,7 +295,7 @@
return z
INFINITY = 1e200 * 1e200
-NAN = INFINITY / INFINITY
+NAN = abs(INFINITY / INFINITY) # bah, INF/INF gives us -NAN?
try:
# Try to get math functions added in 2.6.
@@ -375,8 +375,7 @@
def log1p(x):
"NOT_RPYTHON"
- from pypy.rlib import rfloat
- if abs(x) < rfloat.DBL_EPSILON // 2.:
+ if abs(x) < DBL_EPSILON // 2.:
return x
elif -.5 <= x <= 1.:
y = 1. + x
diff --git a/pypy/rlib/rwin32.py b/pypy/rlib/rwin32.py
--- a/pypy/rlib/rwin32.py
+++ b/pypy/rlib/rwin32.py
@@ -133,8 +133,8 @@
# Prior to Visual Studio 8, the MSVCRT dll doesn't export the
# _dosmaperr() function, which is available only when compiled
# against the static CRT library.
- from pypy.translator.platform import platform, Windows
- static_platform = Windows()
+ from pypy.translator.platform import host_factory
+ static_platform = host_factory()
if static_platform.name == 'msvc':
static_platform.cflags = ['/MT'] # static CRT
static_platform.version = 0 # no manifest
diff --git a/pypy/rlib/rzlib.py b/pypy/rlib/rzlib.py
--- a/pypy/rlib/rzlib.py
+++ b/pypy/rlib/rzlib.py
@@ -1,6 +1,7 @@
from __future__ import with_statement
import sys
+from pypy.rlib import rgc
from pypy.rlib.rstring import StringBuilder
from pypy.rpython.lltypesystem import rffi, lltype
from pypy.rpython.tool import rffi_platform
@@ -236,6 +237,7 @@
compress data.
"""
stream = lltype.malloc(z_stream, flavor='raw', zero=True)
+ rgc.add_memory_pressure(rffi.sizeof(z_stream))
err = _deflateInit2(stream, level, method, wbits, memLevel, strategy)
if err == Z_OK:
return stream
@@ -264,6 +266,7 @@
decompress data.
"""
stream = lltype.malloc(z_stream, flavor='raw', zero=True)
+ rgc.add_memory_pressure(rffi.sizeof(z_stream))
err = _inflateInit2(stream, wbits)
if err == Z_OK:
return stream
diff --git a/pypy/rlib/test/test_objectmodel.py b/pypy/rlib/test/test_objectmodel.py
--- a/pypy/rlib/test/test_objectmodel.py
+++ b/pypy/rlib/test/test_objectmodel.py
@@ -442,7 +442,7 @@
def test_newlist():
from pypy.annotation.model import SomeInteger
def f(z):
- x = newlist(sizehint=38)
+ x = newlist_hint(sizehint=38)
if z < 0:
x.append(1)
return len(x)
@@ -456,7 +456,7 @@
def test_newlist_nonconst():
from pypy.annotation.model import SomeInteger
def f(z):
- x = newlist(sizehint=z)
+ x = newlist_hint(sizehint=z)
return len(x)
graph = getgraph(f, [SomeInteger()])
diff --git a/pypy/rlib/test/test_rarithmetic.py b/pypy/rlib/test/test_rarithmetic.py
--- a/pypy/rlib/test/test_rarithmetic.py
+++ b/pypy/rlib/test/test_rarithmetic.py
@@ -330,6 +330,15 @@
return a == b
py.test.raises(MissingRTypeOperation, "self.interpret(f, [42.0])")
+ def test_is_valid_int(self):
+ def f(x):
+ return (is_valid_int(x) * 4 +
+ is_valid_int(x > 0) * 2 +
+ is_valid_int(x + 0.5))
+ assert f(123) == 4 + 2
+ res = self.interpret(f, [123])
+ assert res == 4 + 2
+
class TestLLtype(BaseTestRarithmetic, LLRtypeMixin):
pass
diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py
--- a/pypy/rpython/llinterp.py
+++ b/pypy/rpython/llinterp.py
@@ -1,6 +1,6 @@
from pypy.objspace.flow.model import FunctionGraph, Constant, Variable, c_last_exception
from pypy.rlib.rarithmetic import intmask, r_uint, ovfcheck, r_longlong
-from pypy.rlib.rarithmetic import r_ulonglong
+from pypy.rlib.rarithmetic import r_ulonglong, is_valid_int
from pypy.rpython.lltypesystem import lltype, llmemory, lloperation, llheap
from pypy.rpython.lltypesystem import rclass
from pypy.rpython.ootypesystem import ootype
@@ -1021,22 +1021,22 @@
# Overflow-detecting variants
def op_int_neg_ovf(self, x):
- assert type(x) is int
+ assert is_valid_int(x)
try:
return ovfcheck(-x)
except OverflowError:
self.make_llexception()
def op_int_abs_ovf(self, x):
- assert type(x) is int
+ assert is_valid_int(x)
try:
return ovfcheck(abs(x))
except OverflowError:
self.make_llexception()
def op_int_lshift_ovf(self, x, y):
- assert isinstance(x, int)
- assert isinstance(y, int)
+ assert is_valid_int(x)
+ assert is_valid_int(y)
try:
return ovfcheck(x << y)
except OverflowError:
@@ -1060,7 +1060,9 @@
return r
'''%locals()
elif operator == '%':
- code = '''r = %(checkfn)s(x %% y)
+ ## overflow check on % does not work with emulated int
+ code = '''%(checkfn)s(x // y)
+ r = x %% y
if x^y < 0 and x%%y != 0:
r -= y
return r
@@ -1077,15 +1079,15 @@
self.make_llexception()
""" % locals()).compile() in globals(), d
- _makefunc2('op_int_add_ovf', '+', '(int, llmemory.AddressOffset)')
- _makefunc2('op_int_mul_ovf', '*', '(int, llmemory.AddressOffset)', 'int')
- _makefunc2('op_int_sub_ovf', '-', 'int')
- _makefunc2('op_int_floordiv_ovf', '//', 'int') # XXX negative args
- _makefunc2('op_int_floordiv_zer', '//', 'int') # can get off-by-one
- _makefunc2('op_int_floordiv_ovf_zer', '//', 'int') # (see op_int_floordiv)
- _makefunc2('op_int_mod_ovf', '%', 'int')
- _makefunc2('op_int_mod_zer', '%', 'int')
- _makefunc2('op_int_mod_ovf_zer', '%', 'int')
+ _makefunc2('op_int_add_ovf', '+', '(int, long, llmemory.AddressOffset)')
+ _makefunc2('op_int_mul_ovf', '*', '(int, long, llmemory.AddressOffset)', '(int, long)')
+ _makefunc2('op_int_sub_ovf', '-', '(int, long)')
+ _makefunc2('op_int_floordiv_ovf', '//', '(int, long)') # XXX negative args
+ _makefunc2('op_int_floordiv_zer', '//', '(int, long)') # can get off-by-one
+ _makefunc2('op_int_floordiv_ovf_zer', '//', '(int, long)') # (see op_int_floordiv)
+ _makefunc2('op_int_mod_ovf', '%', '(int, long)')
+ _makefunc2('op_int_mod_zer', '%', '(int, long)')
+ _makefunc2('op_int_mod_ovf_zer', '%', '(int, long)')
_makefunc2('op_uint_floordiv_zer', '//', 'r_uint')
_makefunc2('op_uint_mod_zer', '%', 'r_uint')
@@ -1107,7 +1109,7 @@
x = x.default
# if type(x) is a subclass of Symbolic, bool(x) will usually raise
# a TypeError -- unless __nonzero__ has been explicitly overridden.
- assert isinstance(x, (int, Symbolic))
+ assert is_valid_int(x) or isinstance(x, Symbolic)
return bool(x)
# hack for jit.codegen.llgraph
@@ -1129,7 +1131,7 @@
def op_oonewarray(self, ARRAY, length):
assert isinstance(ARRAY, ootype.Array)
- assert isinstance(length, int)
+ assert is_valid_int(length)
return ootype.oonewarray(ARRAY, length)
def op_runtimenew(self, class_):
diff --git a/pypy/rpython/lltypesystem/ll2ctypes.py b/pypy/rpython/lltypesystem/ll2ctypes.py
--- a/pypy/rpython/lltypesystem/ll2ctypes.py
+++ b/pypy/rpython/lltypesystem/ll2ctypes.py
@@ -14,12 +14,14 @@
else:
load_library_kwargs = {}
-import os
+import os, platform as host_platform
+from pypy import conftest
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.extfunc import ExtRegistryEntry
from pypy.rlib.objectmodel import Symbolic, ComputedIntSymbolic
from pypy.tool.uid import fixid
from pypy.rlib.rarithmetic import r_singlefloat, r_longfloat, base_int, intmask
+from pypy.rlib.rarithmetic import is_emulated_long, maxint
from pypy.annotation import model as annmodel
from pypy.rpython.llinterp import LLInterpreter, LLException
from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
@@ -32,6 +34,12 @@
class tlsobject(object):
pass
+_POSIX = os.name == "posix"
+_MS_WINDOWS = os.name == "nt"
+_LINUX = "linux" in sys.platform
+_64BIT = "64bit" in host_platform.architecture()[0]
+
+
# ____________________________________________________________
far_regions = None
@@ -68,17 +76,22 @@
global far_regions
if not far_regions:
from pypy.rlib import rmmap
- if sys.maxint > 0x7FFFFFFF:
+ if _64BIT:
PIECESIZE = 0x80000000
else:
- if sys.platform == 'linux':
+ if _LINUX:
PIECESIZE = 0x10000000
else:
PIECESIZE = 0x08000000
PIECES = 10
- m = rmmap.mmap(-1, PIECES * PIECESIZE,
- rmmap.MAP_PRIVATE|rmmap.MAP_ANONYMOUS|rmmap.MAP_NORESERVE,
- rmmap.PROT_READ|rmmap.PROT_WRITE)
+ flags = (0,)
+ if _LINUX:
+ flags = (rmmap.MAP_PRIVATE|rmmap.MAP_ANONYMOUS|rmmap.MAP_NORESERVE,
+ rmmap.PROT_READ|rmmap.PROT_WRITE)
+ if _MS_WINDOWS:
+ flags = (rmmap.MEM_RESERVE,)
+ # XXX seems not to work
+ m = rmmap.mmap(-1, PIECES * PIECESIZE, *flags)
m.close = lambda : None # leak instead of giving a spurious
# error at CPython's shutdown
m._ll2ctypes_pieces = []
@@ -93,9 +106,17 @@
def _setup_ctypes_cache():
from pypy.rpython.lltypesystem import rffi
+
+ if is_emulated_long:
+ signed_as_ctype = ctypes.c_longlong
+ unsigned_as_ctypes = ctypes.c_ulonglong
+ else:
+ signed_as_ctype = ctypes.c_long
+ unsigned_as_ctypes = ctypes.c_ulong
+
_ctypes_cache.update({
- lltype.Signed: ctypes.c_long,
- lltype.Unsigned: ctypes.c_ulong,
+ lltype.Signed: signed_as_ctype,
+ lltype.Unsigned: unsigned_as_ctypes,
lltype.Char: ctypes.c_ubyte,
rffi.DOUBLE: ctypes.c_double,
rffi.FLOAT: ctypes.c_float,
@@ -176,10 +197,26 @@
assert max_n >= 0
ITEM = A.OF
ctypes_item = get_ctypes_type(ITEM, delayed_builders)
+ # Python 2.5 ctypes can raise OverflowError on 64-bit builds
+ for n in [maxint, 2**31]:
+ MAX_SIZE = n/64
+ try:
+ PtrType = ctypes.POINTER(MAX_SIZE * ctypes_item)
+ except (OverflowError, AttributeError), e:
+ pass # ^^^ bah, blame ctypes
+ else:
+ break
+ else:
+ raise e
class CArray(ctypes.Structure):
+ if is_emulated_long:
+ lentype = ctypes.c_longlong
+ else:
+ lentype = ctypes.c_long
+
if not A._hints.get('nolength'):
- _fields_ = [('length', ctypes.c_long),
+ _fields_ = [('length', lentype),
('items', max_n * ctypes_item)]
else:
_fields_ = [('items', max_n * ctypes_item)]
@@ -201,11 +238,16 @@
if cls._ptrtype:
return cls._ptrtype
# ctypes can raise OverflowError on 64-bit builds
- for n in [sys.maxint, 2**31]:
+ # on windows it raises AttributeError even for 2**31 (_length_ missing)
+ if _MS_WINDOWS:
+ other_limit = 2**31-1
+ else:
+ other_limit = 2**31
+ for n in [maxint, other_limit]:
cls.MAX_SIZE = n / ctypes.sizeof(ctypes_item)
try:
cls._ptrtype = ctypes.POINTER(cls.MAX_SIZE * ctypes_item)
- except OverflowError, e:
+ except (OverflowError, AttributeError), e:
pass
else:
break
@@ -566,7 +608,7 @@
def getbounds(self):
# we have no clue, so we allow whatever index
- return 0, sys.maxint
+ return 0, maxint
def getitem(self, index, uninitialized_ok=False):
res = self._storage.contents._getitem(index, boundscheck=False)
@@ -1326,8 +1368,8 @@
res = force_cast(lltype.Signed, addr.ptr)
else:
res = addr._cast_to_int()
- if res > sys.maxint:
- res = res - 2*(sys.maxint + 1)
+ if res > maxint:
+ res = res - 2*(maxint + 1)
assert int(res) == res
return int(res)
return res
diff --git a/pypy/rpython/lltypesystem/llarena.py b/pypy/rpython/lltypesystem/llarena.py
--- a/pypy/rpython/lltypesystem/llarena.py
+++ b/pypy/rpython/lltypesystem/llarena.py
@@ -1,5 +1,7 @@
import array, weakref
from pypy.rpython.lltypesystem import llmemory
+from pypy.rlib.rarithmetic import is_valid_int
+
# An "arena" is a large area of memory which can hold a number of
# objects, not necessarily all of the same type or size. It's used by
@@ -164,7 +166,7 @@
return '<arenaaddr %s + %d>' % (self.arena, self.offset)
def __add__(self, other):
- if isinstance(other, (int, long)):
+ if is_valid_int(other):
position = self.offset + other
elif isinstance(other, llmemory.AddressOffset):
# this is really some Do What I Mean logic. There are two
@@ -184,7 +186,7 @@
def __sub__(self, other):
if isinstance(other, llmemory.AddressOffset):
other = llmemory.raw_malloc_usage(other)
- if isinstance(other, (int, long)):
+ if is_valid_int(other):
return self.arena.getaddr(self.offset - other)
if isinstance(other, fakearenaaddress):
if self.arena is not other.arena:
diff --git a/pypy/rpython/lltypesystem/llmemory.py b/pypy/rpython/lltypesystem/llmemory.py
--- a/pypy/rpython/lltypesystem/llmemory.py
+++ b/pypy/rpython/lltypesystem/llmemory.py
@@ -8,6 +8,8 @@
from pypy.rlib.objectmodel import Symbolic
from pypy.rpython.lltypesystem import lltype
from pypy.tool.uid import uid
+from pypy.rlib.rarithmetic import is_valid_int
+
class AddressOffset(Symbolic):
@@ -28,7 +30,7 @@
def __ge__(self, other):
if self is other:
return True
- elif (isinstance(other, (int, long)) and other == 0 and
+ elif (is_valid_int(other) and other == 0 and
self.known_nonneg()):
return True
else:
@@ -58,7 +60,7 @@
return "<ItemOffset %r %r>" % (self.TYPE, self.repeat)
def __mul__(self, other):
- if not isinstance(other, int):
+ if not is_valid_int(other):
return NotImplemented
return ItemOffset(self.TYPE, self.repeat * other)
diff --git a/pypy/rpython/lltypesystem/lltype.py b/pypy/rpython/lltypesystem/lltype.py
--- a/pypy/rpython/lltypesystem/lltype.py
+++ b/pypy/rpython/lltypesystem/lltype.py
@@ -7,7 +7,7 @@
from pypy.tool.identity_dict import identity_dict
from pypy.tool import leakfinder
from types import NoneType
-from sys import maxint
+from pypy.rlib.rarithmetic import maxint, is_valid_int, is_emulated_long
import weakref
class State(object):
@@ -681,6 +681,11 @@
number = _numbertypes[type] = Number(name, type)
return number
+if is_emulated_long:
+ SignedFmt = 'q'
+else:
+ SignedFmt = 'l'
+
Signed = build_number("Signed", int)
Unsigned = build_number("Unsigned", r_uint)
SignedLongLong = build_number("SignedLongLong", r_longlong)
@@ -1654,7 +1659,7 @@
__slots__ = ('items',)
def __init__(self, TYPE, n, initialization=None, parent=None, parentindex=None):
- if not isinstance(n, int):
+ if not is_valid_int(n):
raise TypeError, "array length must be an int"
if n < 0:
raise ValueError, "negative array length"
diff --git a/pypy/rpython/lltypesystem/module/ll_math.py b/pypy/rpython/lltypesystem/module/ll_math.py
--- a/pypy/rpython/lltypesystem/module/ll_math.py
+++ b/pypy/rpython/lltypesystem/module/ll_math.py
@@ -114,10 +114,8 @@
while VERY_LARGE_FLOAT * 100.0 != INFINITY:
VERY_LARGE_FLOAT *= 64.0
-_lib_isnan = rffi.llexternal("_isnan", [lltype.Float], lltype.Signed,
- compilation_info=eci)
-_lib_finite = rffi.llexternal("_finite", [lltype.Float], lltype.Signed,
- compilation_info=eci)
+_lib_isnan = llexternal("_isnan", [lltype.Float], lltype.Signed)
+_lib_finite = llexternal("_finite", [lltype.Float], lltype.Signed)
def ll_math_isnan(y):
# By not calling into the external function the JIT can inline this.
diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -4,6 +4,8 @@
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.lltypesystem.lloperation import opimpls
from pypy.rlib import debug
+from pypy.rlib.rarithmetic import is_valid_int
+
# ____________________________________________________________
# Implementation of the 'canfold' operations
@@ -22,14 +24,14 @@
from pypy.rpython.lltypesystem.llmemory import AddressAsInt
if r_longlong is r_int:
- r_longlong_arg = (r_longlong, int)
- r_longlong_result = int
+ r_longlong_arg = (r_longlong, int, long)
+ r_longlong_result = long # XXX was int
else:
r_longlong_arg = r_longlong
r_longlong_result = r_longlong
argtype_by_name = {
- 'int': int,
+ 'int': (int, long),
'float': float,
'uint': r_uint,
'llong': r_longlong_arg,
@@ -173,7 +175,7 @@
def op_direct_ptradd(obj, index):
checkptr(obj)
- assert isinstance(index, int)
+ assert is_valid_int(index)
return lltype.direct_ptradd(obj, index)
@@ -182,29 +184,30 @@
return not b
def op_int_add(x, y):
- if not isinstance(x, (int, llmemory.AddressOffset)):
+ if not isinstance(x, (int, long, llmemory.AddressOffset)):
from pypy.rpython.lltypesystem import llgroup
assert isinstance(x, llgroup.CombinedSymbolic)
- assert isinstance(y, (int, llmemory.AddressOffset))
+ assert isinstance(y, (int, long, llmemory.AddressOffset))
return intmask(x + y)
def op_int_sub(x, y):
- if not isinstance(x, int):
+ if not is_valid_int(x):
from pypy.rpython.lltypesystem import llgroup
assert isinstance(x, llgroup.CombinedSymbolic)
- assert isinstance(y, int)
+ assert is_valid_int(y)
return intmask(x - y)
def op_int_ge(x, y):
# special case for 'AddressOffset >= 0'
- assert isinstance(x, (int, llmemory.AddressOffset))
- assert isinstance(y, int)
+ assert isinstance(x, (int, long, llmemory.AddressOffset))
+ assert is_valid_int(y)
return x >= y
def op_int_lt(x, y):
# special case for 'AddressOffset < 0'
- assert isinstance(x, (int, llmemory.AddressOffset))
- assert isinstance(y, int)
+ # hack for win64
+ assert isinstance(x, (int, long, llmemory.AddressOffset))
+ assert is_valid_int(y)
return x < y
def op_int_between(a, b, c):
@@ -214,50 +217,51 @@
return a <= b < c
def op_int_and(x, y):
- if not isinstance(x, int):
+ if not is_valid_int(x):
from pypy.rpython.lltypesystem import llgroup
assert isinstance(x, llgroup.CombinedSymbolic)
- assert isinstance(y, int)
+ assert is_valid_int(y)
return x & y
def op_int_or(x, y):
- if not isinstance(x, int):
+ if not is_valid_int(x):
from pypy.rpython.lltypesystem import llgroup
assert isinstance(x, llgroup.CombinedSymbolic)
- assert isinstance(y, int)
+ assert is_valid_int(y)
return x | y
def op_int_xor(x, y):
# used in computing hashes
if isinstance(x, AddressAsInt): x = llmemory.cast_adr_to_int(x.adr)
if isinstance(y, AddressAsInt): y = llmemory.cast_adr_to_int(y.adr)
- assert isinstance(x, int)
- assert isinstance(y, int)
+ assert is_valid_int(x)
+ assert is_valid_int(y)
return x ^ y
def op_int_mul(x, y):
- assert isinstance(x, (int, llmemory.AddressOffset))
- assert isinstance(y, (int, llmemory.AddressOffset))
+ assert isinstance(x, (int, long, llmemory.AddressOffset))
+ assert isinstance(y, (int, long, llmemory.AddressOffset))
return intmask(x * y)
def op_int_rshift(x, y):
- if not isinstance(x, int):
+ if not is_valid_int(x):
from pypy.rpython.lltypesystem import llgroup
assert isinstance(x, llgroup.CombinedSymbolic)
- assert isinstance(y, int)
+ assert is_valid_int(y)
return x >> y
def op_int_floordiv(x, y):
- assert isinstance(x, (int, llmemory.AddressOffset))
- assert isinstance(y, (int, llmemory.AddressOffset))
+ # hack for win64
+ assert isinstance(x, (int, long, llmemory.AddressOffset))
+ assert isinstance(y, (int, long, llmemory.AddressOffset))
r = x//y
if x^y < 0 and x%y != 0:
r += 1
return r
def op_int_mod(x, y):
- assert isinstance(x, (int, llmemory.AddressOffset))
- assert isinstance(y, (int, llmemory.AddressOffset))
+ assert isinstance(x, (int, long, llmemory.AddressOffset))
+ assert isinstance(y, (int, long, llmemory.AddressOffset))
r = x%y
if x^y < 0 and x%y != 0:
r -= y
@@ -281,22 +285,22 @@
def op_uint_lshift(x, y):
assert isinstance(x, r_uint)
- assert isinstance(y, int)
+ assert is_valid_int(y)
return r_uint(x << y)
def op_uint_rshift(x, y):
assert isinstance(x, r_uint)
- assert isinstance(y, int)
+ assert is_valid_int(y)
return r_uint(x >> y)
def op_llong_lshift(x, y):
assert isinstance(x, r_longlong_arg)
- assert isinstance(y, int)
+ assert is_valid_int(y)
return r_longlong_result(x << y)
def op_llong_rshift(x, y):
assert isinstance(x, r_longlong_arg)
- assert isinstance(y, int)
+ assert is_valid_int(y)
return r_longlong_result(x >> y)
def op_ullong_lshift(x, y):
@@ -306,7 +310,7 @@
def op_ullong_rshift(x, y):
assert isinstance(x, r_ulonglong)
- assert isinstance(y, int)
+ assert is_valid_int(y)
return r_ulonglong(x >> y)
def op_same_as(x):
@@ -318,7 +322,8 @@
op_cast_primitive.need_result_type = True
def op_cast_int_to_float(i):
- assert type(i) is int
+ # assert type(i) is int
+ assert is_valid_int(i)
return float(i)
def op_cast_uint_to_float(u):
@@ -340,7 +345,8 @@
return ui + li
def op_cast_int_to_char(b):
- assert type(b) is int
+ #assert type(b) is int
+ assert is_valid_int(b)
return chr(b)
def op_cast_bool_to_int(b):
@@ -384,11 +390,12 @@
return ord(b)
def op_cast_int_to_unichar(b):
- assert type(b) is int
+ assert is_valid_int(b)
return unichr(b)
def op_cast_int_to_uint(b):
- assert type(b) is int
+ # assert type(b) is int
+ assert is_valid_int(b)
return r_uint(b)
def op_cast_uint_to_int(b):
@@ -396,7 +403,7 @@
return intmask(b)
def op_cast_int_to_longlong(b):
- assert type(b) is int
+ assert is_valid_int(b)
return r_longlong_result(b)
def op_truncate_longlong_to_int(b):
@@ -570,7 +577,7 @@
if isinstance(memberoffset, llgroup.GroupMemberOffset):
return memberoffset.index != 0
else:
- assert isinstance(memberoffset, int)
+ assert is_valid_int(memberoffset)
return memberoffset != 0
def op_extract_ushort(combinedoffset):
diff --git a/pypy/rpython/lltypesystem/rffi.py b/pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py
+++ b/pypy/rpython/lltypesystem/rffi.py
@@ -649,6 +649,9 @@
# float *
FLOATP = lltype.Ptr(lltype.Array(FLOAT, hints={'nolength': True}))
+# SIGNED *
+SIGNEDP = lltype.Ptr(lltype.Array(lltype.Signed, hints={'nolength': True}))
+
# various type mapping
# conversions between str and char*
diff --git a/pypy/rpython/lltypesystem/rlist.py b/pypy/rpython/lltypesystem/rlist.py
--- a/pypy/rpython/lltypesystem/rlist.py
+++ b/pypy/rpython/lltypesystem/rlist.py
@@ -60,7 +60,6 @@
ITEMARRAY = GcArray(ITEM,
adtmeths = ADTIFixedList({
"ll_newlist": ll_fixed_newlist,
- "ll_newlist_hint": ll_fixed_newlist,
"ll_newemptylist": ll_fixed_newemptylist,
"ll_length": ll_fixed_length,
"ll_items": ll_fixed_items,
@@ -271,7 +270,7 @@
l.items = malloc(LIST.items.TO, lengthhint)
return l
ll_newlist_hint = typeMethod(ll_newlist_hint)
-ll_newlist_hint.oopspec = 'newlist(lengthhint)'
+ll_newlist_hint.oopspec = 'newlist_hint(lengthhint)'
# should empty lists start with no allocated memory, or with a preallocated
# minimal number of entries? XXX compare memory usage versus speed, and
@@ -315,16 +314,16 @@
# fixed size versions
+ at typeMethod
def ll_fixed_newlist(LIST, length):
ll_assert(length >= 0, "negative fixed list length")
l = malloc(LIST, length)
return l
-ll_fixed_newlist = typeMethod(ll_fixed_newlist)
ll_fixed_newlist.oopspec = 'newlist(length)'
+ at typeMethod
def ll_fixed_newemptylist(LIST):
return ll_fixed_newlist(LIST, 0)
-ll_fixed_newemptylist = typeMethod(ll_fixed_newemptylist)
def ll_fixed_length(l):
return len(l)
diff --git a/pypy/rpython/lltypesystem/test/test_ll2ctypes.py b/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
--- a/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
+++ b/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
@@ -16,12 +16,28 @@
from pypy.rpython.test.test_llinterp import interpret
from pypy.annotation.annrpython import RPythonAnnotator
from pypy.rpython.rtyper import RPythonTyper
-
+from pypy.rlib.rarithmetic import r_uint, get_long_pattern, is_emulated_long
+from pypy.rlib.rarithmetic import is_valid_int
if False: # for now, please keep it False by default
from pypy.rpython.lltypesystem import ll2ctypes
ll2ctypes.do_allocation_in_far_regions()
+"""
+Win64:
+To decouple the cpython machine level long from the faked integer
+of the target rpython, I replaced most 'lltype.Signed' by 'rffi.LONG'.
+It would be nicer to replace all lltypes constants by rffi equivalents,
+or better if we had a way to address the specific different types of
+the current and the target system layout explicitly.
+Let's think of that when we go further and make the target completely
+independent and configurable.
+Why most and not all replaced?
+Tests with direct tests become cumbersome, instead of direct number
+assignment rffi.setintfield(s, 'x', 123) must be used.
+So in cases with number constants, where the size is not relevant,
+I kept lltype.signed .
+"""
class TestLL2Ctypes(object):
@@ -46,15 +62,15 @@
res = ctypes2lltype(lltype.SingleFloat, ctypes.c_float(-3.5))
assert isinstance(res, rffi.r_singlefloat)
assert float(res) == -3.5
- assert lltype2ctypes(rffi.r_ulong(-1)) == sys.maxint * 2 + 1
+ assert lltype2ctypes(rffi.r_ulong(-1)) == (1 << rffi.r_ulong.BITS) - 1
res = ctypes2lltype(lltype.Unsigned, sys.maxint * 2 + 1)
- assert (res, type(res)) == (rffi.r_ulong(-1), rffi.r_ulong)
+ assert (res, type(res)) == (r_uint(-1), r_uint)
assert ctypes2lltype(lltype.Bool, 0) is False
assert ctypes2lltype(lltype.Bool, 1) is True
- res = lltype2ctypes(llmemory.sizeof(lltype.Signed))
+ res = lltype2ctypes(llmemory.sizeof(rffi.LONG))
assert res == struct.calcsize("l")
- S = lltype.Struct('S', ('x', lltype.Signed), ('y', lltype.Signed))
+ S = lltype.Struct('S', ('x', rffi.LONG), ('y', rffi.LONG))
res = lltype2ctypes(llmemory.sizeof(S))
assert res == struct.calcsize("ll")
@@ -69,7 +85,7 @@
def test_simple_struct(self):
S = lltype.Struct('S', ('x', lltype.Signed), ('y', lltype.Signed))
s = lltype.malloc(S, flavor='raw')
- s.x = 123
+ rffi.setintfield(s, 'x', 123)
sc = lltype2ctypes(s)
assert isinstance(sc.contents, ctypes.Structure)
assert sc.contents.x == 123
@@ -133,7 +149,11 @@
ac = lltype2ctypes(a, normalize=False)
assert isinstance(ac.contents, ctypes.Structure)
assert ac.contents.length == 10
- assert ac.contents._fields_[0] == ('length', ctypes.c_long)
+ if is_emulated_long:
+ lentype = ctypes.c_longlong
+ else:
+ lentype = ctypes.c_long
+ assert ac.contents._fields_[0] == ('length', lentype)
assert ac.contents.items[1] == 101
ac.contents.items[2] = 456
assert a[2] == 456
@@ -144,7 +164,7 @@
def test_array_inside_struct(self):
# like rstr.STR, but not Gc
- STR = lltype.Struct('STR', ('x', lltype.Signed), ('y', lltype.Array(lltype.Char)))
+ STR = lltype.Struct('STR', ('x', rffi.LONG), ('y', lltype.Array(lltype.Char)))
a = lltype.malloc(STR, 3, flavor='raw')
a.y[0] = 'x'
a.y[1] = 'y'
@@ -171,7 +191,7 @@
assert a[2] == 456
a[3] = 789
assert ac.contents.items[3] == 789
- assert ctypes.sizeof(ac.contents) == 10 * ctypes.sizeof(ctypes.c_long)
+ assert ctypes.sizeof(ac.contents) == 10 * rffi.sizeof(lltype.Signed)
lltype.free(a, flavor='raw')
assert not ALLOCATED # detects memory leaks in the test
@@ -223,20 +243,20 @@
def test_func_not_in_clib(self):
eci = ExternalCompilationInfo(libraries=['m'])
- foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed)
+ foobar = rffi.llexternal('I_really_dont_exist', [], rffi.LONG)
py.test.raises(NotImplementedError, foobar)
- foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed,
+ foobar = rffi.llexternal('I_really_dont_exist', [], rffi.LONG,
compilation_info=eci) # math library
py.test.raises(NotImplementedError, foobar)
eci = ExternalCompilationInfo(libraries=['m', 'z'])
- foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed,
+ foobar = rffi.llexternal('I_really_dont_exist', [], rffi.LONG,
compilation_info=eci) # math and zlib
py.test.raises(NotImplementedError, foobar)
eci = ExternalCompilationInfo(libraries=['I_really_dont_exist_either'])
- foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed,
+ foobar = rffi.llexternal('I_really_dont_exist', [], rffi.LONG,
compilation_info=eci)
py.test.raises(NotImplementedError, foobar)
assert not ALLOCATED # detects memory leaks in the test
@@ -399,10 +419,9 @@
b = rffi.cast(lltype.Ptr(B), a)
- checker = array.array('l')
+ expected = ''
for i in range(10):
- checker.append(i*i)
- expected = checker.tostring()
+ expected += get_long_pattern(i*i)
for i in range(len(expected)):
assert b[i] == expected[i]
@@ -418,7 +437,7 @@
assert e[i] == i*i
c = lltype.nullptr(rffi.VOIDP.TO)
- addr = rffi.cast(lltype.Signed, c)
+ addr = rffi.cast(rffi.LONG, c)
assert addr == 0
lltype.free(a, flavor='raw')
@@ -444,8 +463,13 @@
FUNCTYPE = lltype.FuncType([lltype.Signed], lltype.Signed)
cdummy = lltype2ctypes(llhelper(lltype.Ptr(FUNCTYPE), dummy))
- assert isinstance(cdummy,
- ctypes.CFUNCTYPE(ctypes.c_long, ctypes.c_long))
+ if not is_emulated_long:
+ assert isinstance(cdummy,
+ ctypes.CFUNCTYPE(ctypes.c_long, ctypes.c_long))
+ else:
+ # XXX maybe we skip this if it breaks on some platforms
+ assert isinstance(cdummy,
+ ctypes.CFUNCTYPE(ctypes.c_longlong, ctypes.c_longlong))
res = cdummy(41)
assert res == 42
lldummy = ctypes2lltype(lltype.Ptr(FUNCTYPE), cdummy)
@@ -455,7 +479,7 @@
assert not ALLOCATED # detects memory leaks in the test
def test_funcptr2(self):
- FUNCTYPE = lltype.FuncType([rffi.CCHARP], lltype.Signed)
+ FUNCTYPE = lltype.FuncType([rffi.CCHARP], rffi.LONG)
cstrlen = standard_c_lib.strlen
llstrlen = ctypes2lltype(lltype.Ptr(FUNCTYPE), cstrlen)
assert lltype.typeOf(llstrlen) == lltype.Ptr(FUNCTYPE)
@@ -545,8 +569,9 @@
checkval(uninitialized2ctypes(rffi.CHAR), 'B')
checkval(uninitialized2ctypes(rffi.SHORT), 'h')
- checkval(uninitialized2ctypes(rffi.INT), 'i')
- checkval(uninitialized2ctypes(rffi.UINT), 'I')
+ if not is_emulated_long:
+ checkval(uninitialized2ctypes(rffi.INT), 'i')
+ checkval(uninitialized2ctypes(rffi.UINT), 'I')
checkval(uninitialized2ctypes(rffi.LONGLONG), 'q')
checkval(uninitialized2ctypes(rffi.DOUBLE), 'd')
checkobj(uninitialized2ctypes(rffi.INTP),
@@ -554,7 +579,7 @@
checkobj(uninitialized2ctypes(rffi.CCHARP),
ctypes.sizeof(ctypes.c_void_p))
- S = lltype.Struct('S', ('x', lltype.Signed), ('y', lltype.Signed))
+ S = lltype.Struct('S', ('x', rffi.LONG), ('y', rffi.LONG))
s = lltype.malloc(S, flavor='raw')
sc = lltype2ctypes(s)
checkval(sc.contents.x, 'l')
@@ -717,9 +742,13 @@
assert not ALLOCATED # detects memory leaks in the test
def test_get_errno(self):
+ # win64: works with python 2.6.7, but not with 2.7.2
+ # XXX check what is different with ctypes!
eci = ExternalCompilationInfo(includes=['string.h'])
if sys.platform.startswith('win'):
underscore_on_windows = '_'
+ if sys.version.startswith('2.7.2 '):
+ py.test.skip('ctypes is buggy. errno crashes with win64 and python 2.7.2')
else:
underscore_on_windows = ''
strlen = rffi.llexternal('strlen', [rffi.CCHARP], rffi.SIZE_T,
@@ -730,7 +759,7 @@
buffer = lltype.malloc(rffi.CCHARP.TO, 5, flavor='raw')
written = os_write(12312312, buffer, 5)
lltype.free(buffer, flavor='raw')
- assert rffi.cast(lltype.Signed, written) < 0
+ assert rffi.cast(rffi.LONG, written) < 0
# the next line is a random external function call,
# to check that it doesn't reset errno
strlen("hi!")
@@ -849,9 +878,9 @@
return one + get_x()
def fy():
- one = rffi.cast(lltype.Signed, get_y())
+ one = rffi.cast(rffi.LONG, get_y())
set_y(rffi.cast(rffi.INT, 13))
- return one + rffi.cast(lltype.Signed, get_y())
+ return one + rffi.cast(rffi.LONG, get_y())
def g():
l = rffi.liststr2charpp(["a", "b", "c"])
@@ -916,7 +945,7 @@
lltype.free(a, flavor='raw')
def test_array_type_bug(self):
- A = lltype.Array(lltype.Signed)
+ A = lltype.Array(rffi.LONG)
a1 = lltype.malloc(A, 0, flavor='raw')
a2 = lltype.malloc(A, 0, flavor='raw')
c1 = lltype2ctypes(a1)
@@ -1006,7 +1035,7 @@
def test_recursive_struct_more(self):
NODE = lltype.ForwardReference()
- NODE.become(lltype.Struct('NODE', ('value', lltype.Signed),
+ NODE.become(lltype.Struct('NODE', ('value', rffi.LONG),
('next', lltype.Ptr(NODE))))
CNODEPTR = get_ctypes_type(NODE)
pc = CNODEPTR()
@@ -1034,11 +1063,11 @@
assert p.pong.ping == p
def test_typedef(self):
- assert ctypes2lltype(lltype.Typedef(lltype.Signed, 'test'), 6) == 6
+ assert ctypes2lltype(lltype.Typedef(rffi.LONG, 'test'), 6) == 6
assert ctypes2lltype(lltype.Typedef(lltype.Float, 'test2'), 3.4) == 3.4
- assert get_ctypes_type(lltype.Signed) == get_ctypes_type(
- lltype.Typedef(lltype.Signed, 'test3'))
+ assert get_ctypes_type(rffi.LONG) == get_ctypes_type(
+ lltype.Typedef(rffi.LONG, 'test3'))
def test_cast_adr_to_int(self):
class someaddr(object):
@@ -1046,7 +1075,7 @@
return sys.maxint/2 * 3
res = cast_adr_to_int(someaddr())
- assert isinstance(res, int)
+ assert is_valid_int(res)
assert res == -sys.maxint/2 - 3
def test_cast_gcref_back_and_forth(self):
@@ -1299,7 +1328,7 @@
p = lltype.malloc(S, flavor='raw')
a = llmemory.cast_ptr_to_adr(p)
i = llmemory.cast_adr_to_int(a, "forced")
- assert type(i) is int
+ assert is_valid_int(i)
assert i == llmemory.cast_adr_to_int(a, "forced")
lltype.free(p, flavor='raw')
diff --git a/pypy/rpython/lltypesystem/test/test_llmemory.py b/pypy/rpython/lltypesystem/test/test_llmemory.py
--- a/pypy/rpython/lltypesystem/test/test_llmemory.py
+++ b/pypy/rpython/lltypesystem/test/test_llmemory.py
@@ -1,6 +1,7 @@
from pypy.rpython.lltypesystem.llmemory import *
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.test.test_llinterp import interpret
+from pypy.rlib.rarithmetic import is_valid_int
import py
def test_simple():
@@ -639,12 +640,12 @@
assert cast_int_to_adr(0) == NULL
#
i = cast_adr_to_int(adr, mode="emulated")
- assert type(i) is int
+ assert is_valid_int(i)
i = cast_adr_to_int(NULL, mode="emulated")
- assert type(i) is int and i == 0
+ assert is_valid_int(i) and i == 0
#
i = cast_adr_to_int(adr, mode="forced")
- assert type(i) is int
+ assert is_valid_int(i)
#assert cast_int_to_adr(i) == adr -- depends on ll2ctypes details
i = cast_adr_to_int(NULL, mode="forced")
- assert type(i) is int and i == 0
+ assert is_valid_int(i) and i == 0
diff --git a/pypy/rpython/memory/gc/inspector.py b/pypy/rpython/memory/gc/inspector.py
--- a/pypy/rpython/memory/gc/inspector.py
+++ b/pypy/rpython/memory/gc/inspector.py
@@ -109,7 +109,7 @@
self.gc = gc
self.gcflag = gc.gcflag_extra
self.fd = rffi.cast(rffi.INT, fd)
- self.writebuffer = lltype.malloc(rffi.LONGP.TO, self.BUFSIZE,
+ self.writebuffer = lltype.malloc(rffi.SIGNEDP.TO, self.BUFSIZE,
flavor='raw')
self.buf_count = 0
if self.gcflag == 0:
diff --git a/pypy/rpython/memory/gc/markcompact.py b/pypy/rpython/memory/gc/markcompact.py
--- a/pypy/rpython/memory/gc/markcompact.py
+++ b/pypy/rpython/memory/gc/markcompact.py
@@ -11,6 +11,8 @@
from pypy.rlib.objectmodel import we_are_translated, running_on_llinterp
from pypy.rpython.lltypesystem import rffi
from pypy.rpython.memory.gcheader import GCHeaderBuilder
+from pypy.rlib.rarithmetic import is_valid_int
+
# Mark'n'compact garbage collector
#
@@ -353,7 +355,7 @@
# like header(), but asserts that we have a forwarding header
hdr = MovingGCBase.header(self, addr)
if not we_are_translated():
- assert isinstance(hdr.tid, int)
+ assert is_valid_int(hdr.tid)
return hdr
def combine(self, typeid16, flags):
diff --git a/pypy/rpython/memory/gc/test/test_direct.py b/pypy/rpython/memory/gc/test/test_direct.py
--- a/pypy/rpython/memory/gc/test/test_direct.py
+++ b/pypy/rpython/memory/gc/test/test_direct.py
@@ -9,7 +9,7 @@
import py
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.rpython.memory.gctypelayout import TypeLayoutBuilder
-from pypy.rlib.rarithmetic import LONG_BIT
+from pypy.rlib.rarithmetic import LONG_BIT, is_valid_int
WORD = LONG_BIT // 8
@@ -286,7 +286,7 @@
p = self.malloc(S)
hash = self.gc.identityhash(p)
print hash
- assert isinstance(hash, (int, long))
+ assert is_valid_int(hash)
assert hash == self.gc.identityhash(p)
self.stackroots.append(p)
for i in range(6):
@@ -299,7 +299,7 @@
self.gc.collect()
hash = self.gc.identityhash(self.stackroots[-1])
print hash
- assert isinstance(hash, (int, long))
+ assert is_valid_int(hash)
for i in range(6):
self.gc.collect()
assert hash == self.gc.identityhash(self.stackroots[-1])
@@ -311,7 +311,7 @@
self.gc.collect()
hash = self.gc.identityhash(self.stackroots[-1])
print hash
- assert isinstance(hash, (int, long))
+ assert is_valid_int(hash)
for i in range(2):
self.gc.collect()
assert hash == self.gc.identityhash(self.stackroots[-1])
@@ -319,7 +319,7 @@
# (4) p is a prebuilt object
hash = self.gc.identityhash(p_const)
print hash
- assert isinstance(hash, (int, long))
+ assert is_valid_int(hash)
assert hash == self.gc.identityhash(p_const)
# (5) p is actually moving (for the markcompact gc)
p0 = self.malloc(S)
diff --git a/pypy/rpython/memory/gctransform/asmgcroot.py b/pypy/rpython/memory/gctransform/asmgcroot.py
--- a/pypy/rpython/memory/gctransform/asmgcroot.py
+++ b/pypy/rpython/memory/gctransform/asmgcroot.py
@@ -533,10 +533,11 @@
# The initial gcmap table contains addresses to a JMP
# instruction that jumps indirectly to the real code.
# Replace them with the target addresses.
+ assert rffi.SIGNEDP is rffi.LONGP, "win64 support missing"
while start < end:
code = rffi.cast(rffi.CCHARP, start.address[0])[0]
if code == '\xe9': # jmp
- rel32 = rffi.cast(rffi.LONGP, start.address[0]+1)[0]
+ rel32 = rffi.cast(rffi.SIGNEDP, start.address[0]+1)[0]
target = start.address[0] + (rel32 + 5)
start.address[0] = target
start += arrayitemsize
diff --git a/pypy/rpython/memory/lltypelayout.py b/pypy/rpython/memory/lltypelayout.py
--- a/pypy/rpython/memory/lltypelayout.py
+++ b/pypy/rpython/memory/lltypelayout.py
@@ -1,4 +1,5 @@
from pypy.rpython.lltypesystem import lltype, llmemory, llarena
+from pypy.rlib.rarithmetic import is_emulated_long
import struct
@@ -12,7 +13,11 @@
lltype.Float: "d",
llmemory.Address: "P",
}
-
+if is_emulated_long:
+ primitive_to_fmt.update( {
+ lltype.Signed: "q",
+ lltype.Unsigned: "Q",
+ } )
#___________________________________________________________________________
# Utility functions that know about the memory layout of the lltypes
diff --git a/pypy/rpython/memory/test/test_transformed_gc.py b/pypy/rpython/memory/test/test_transformed_gc.py
--- a/pypy/rpython/memory/test/test_transformed_gc.py
+++ b/pypy/rpython/memory/test/test_transformed_gc.py
@@ -737,7 +737,7 @@
def f():
from pypy.rpython.lltypesystem import rffi
alist = [A() for i in range(50)]
- idarray = lltype.malloc(rffi.LONGP.TO, len(alist), flavor='raw')
+ idarray = lltype.malloc(rffi.SIGNEDP.TO, len(alist), flavor='raw')
# Compute the id of all the elements of the list. The goal is
# to not allocate memory, so that if the GC needs memory to
# remember the ids, it will trigger some collections itself
diff --git a/pypy/rpython/module/ll_os_stat.py b/pypy/rpython/module/ll_os_stat.py
--- a/pypy/rpython/module/ll_os_stat.py
+++ b/pypy/rpython/module/ll_os_stat.py
@@ -319,6 +319,7 @@
def attributes_to_mode(attributes):
m = 0
+ attributes = intmask(attributes)
if attributes & win32traits.FILE_ATTRIBUTE_DIRECTORY:
m |= win32traits._S_IFDIR | 0111 # IFEXEC for user,group,other
else:
diff --git a/pypy/rpython/module/test/test_ll_os.py b/pypy/rpython/module/test/test_ll_os.py
--- a/pypy/rpython/module/test/test_ll_os.py
+++ b/pypy/rpython/module/test/test_ll_os.py
@@ -80,8 +80,12 @@
pwd = os.getcwd()
import ctypes
buf = ctypes.create_string_buffer(1000)
- ctypes.windll.kernel32.GetEnvironmentVariableA('=%c:' % pwd[0], buf, 1000)
- assert str(buf.value) == pwd
+ len = ctypes.windll.kernel32.GetEnvironmentVariableA('=%c:' % pwd[0], buf, 1000)
+ if (len == 0) and "WINGDB_PYTHON" in os.environ:
+ # the ctypes call seems not to work in the Wing debugger
+ return
+ assert str(buf.value).lower() == pwd
+ # ctypes returns the drive letter in uppercase, os.getcwd does not
pwd = os.getcwd()
try:
diff --git a/pypy/rpython/module/test/test_ll_os_stat.py b/pypy/rpython/module/test/test_ll_os_stat.py
--- a/pypy/rpython/module/test/test_ll_os_stat.py
+++ b/pypy/rpython/module/test/test_ll_os_stat.py
@@ -26,7 +26,7 @@
assert wstat(unicode(f)).st_mtime == expected
check('c:/')
- check('c:/temp')
+ check(os.environ['TEMP'])
check('c:/pagefile.sys')
def test_fstat(self):
diff --git a/pypy/rpython/module/test/test_posix.py b/pypy/rpython/module/test/test_posix.py
--- a/pypy/rpython/module/test/test_posix.py
+++ b/pypy/rpython/module/test/test_posix.py
@@ -1,6 +1,8 @@
import py
from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
from pypy.tool.udir import udir
+from pypy.rlib.rarithmetic import is_valid_int
+
import os
exec 'import %s as posix' % os.name
@@ -18,10 +20,10 @@
def test_open(self):
def f():
- ff = posix.open(path,posix.O_RDONLY,0777)
+ ff = posix.open(path, posix.O_RDONLY, 0777)
return ff
- func = self.interpret(f,[])
- assert type(func) == int
+ func = self.interpret(f, [])
+ assert is_valid_int(func)
def test_fstat(self):
def fo(fi):
@@ -61,25 +63,25 @@
assert isinstance(times, tuple)
assert len(times) == 5
for value in times:
- assert isinstance(value, int)
+ assert is_valid_int(value)
def test_lseek(self):
- def f(fi,pos):
- posix.lseek(fi,pos,0)
- fi = os.open(path,os.O_RDONLY,0777)
- func = self.interpret(f,[fi,5])
- res = os.read(fi,2)
+ def f(fi, pos):
+ posix.lseek(fi, pos, 0)
+ fi = os.open(path, os.O_RDONLY, 0777)
+ func = self.interpret(f, [fi, 5])
+ res = os.read(fi, 2)
assert res =='is'
def test_isatty(self):
def f(fi):
posix.isatty(fi)
- fi = os.open(path,os.O_RDONLY,0777)
- func = self.interpret(f,[fi])
+ fi = os.open(path, os.O_RDONLY, 0777)
+ func = self.interpret(f, [fi])
assert not func
os.close(fi)
- func = self.interpret(f,[fi])
+ func = self.interpret(f, [fi])
assert not func
def test_getcwd(self):
diff --git a/pypy/rpython/rint.py b/pypy/rpython/rint.py
--- a/pypy/rpython/rint.py
+++ b/pypy/rpython/rint.py
@@ -7,7 +7,8 @@
SignedLongLong, build_number, Number, cast_primitive, typeOf
from pypy.rpython.rmodel import IntegerRepr, inputconst
from pypy.rpython.robject import PyObjRepr, pyobj_repr
-from pypy.rlib.rarithmetic import intmask, r_int, r_uint, r_ulonglong, r_longlong
+from pypy.rlib.rarithmetic import intmask, r_int, r_uint, r_ulonglong, \
+ r_longlong, is_emulated_long
from pypy.rpython.error import TyperError, MissingRTypeOperation
from pypy.rpython.rmodel import log
from pypy.rlib import objectmodel
@@ -437,6 +438,11 @@
Unsigned: ('RPyLong_AsUnsignedLong', lambda pyo: r_uint(pyo._obj.value)),
Signed: ('PyInt_AsLong', lambda pyo: int(pyo._obj.value))
}
+if is_emulated_long: # win64
+ py_to_ll_conversion_functions.update( {
+ Unsigned: ('RPyLong_AsUnsignedLongLong', lambda pyo: r_ulonglong(pyo._obj.value)),
+ Signed: ('RPyLong_AsLongLong', lambda pyo: r_longlong(pyo._obj.value)),
+ } )
ll_to_py_conversion_functions = {
UnsignedLongLong: ('PyLong_FromUnsignedLongLong', lambda i: pyobjectptr(i)),
@@ -444,6 +450,11 @@
Unsigned: ('PyLong_FromUnsignedLong', lambda i: pyobjectptr(i)),
Signed: ('PyInt_FromLong', lambda i: pyobjectptr(i)),
}
+if is_emulated_long: # win64
+ ll_to_py_conversion_functions.update( {
+ Unsigned: ('PyLong_FromUnsignedLongLong', lambda i: pyobjectptr(i)),
+ Signed: ('PyLong_FromLongLong', lambda i: pyobjectptr(i)),
+ } )
class __extend__(pairtype(PyObjRepr, IntegerRepr)):
diff --git a/pypy/rpython/rmodel.py b/pypy/rpython/rmodel.py
--- a/pypy/rpython/rmodel.py
+++ b/pypy/rpython/rmodel.py
@@ -339,11 +339,11 @@
def _get_opprefix(self):
if self._opprefix is None:
- raise TyperError("arithmetic not supported on %r" %
+ raise TyperError("arithmetic not supported on %r, it's size is too small" %
self.lowleveltype)
return self._opprefix
- opprefix =property(_get_opprefix)
+ opprefix = property(_get_opprefix)
class BoolRepr(IntegerRepr):
lowleveltype = Bool
diff --git a/pypy/rpython/test/test_llinterp.py b/pypy/rpython/test/test_llinterp.py
--- a/pypy/rpython/test/test_llinterp.py
+++ b/pypy/rpython/test/test_llinterp.py
@@ -353,13 +353,16 @@
try:
return ovfcheck((-sys.maxint - 1) % x)
except OverflowError:
- return 1
+ return 43
except ZeroDivisionError:
- return 0
+ return 42
res = interpret(f, [0])
- assert res == 0
+ assert res == 42
+ # the following test doesn't work any more before translation,
+ # but "too bad" is the best answer I suppose
res = interpret(f, [-1])
- assert res == 1
+ if 0:
+ assert res == 43
res = interpret(f, [30])
assert res == (-sys.maxint - 1) % 30
diff --git a/pypy/rpython/test/test_rbuiltin.py b/pypy/rpython/test/test_rbuiltin.py
--- a/pypy/rpython/test/test_rbuiltin.py
+++ b/pypy/rpython/test/test_rbuiltin.py
@@ -5,7 +5,7 @@
from pypy.rlib.debug import llinterpcall
from pypy.rpython.lltypesystem import lltype
from pypy.tool import udir
-from pypy.rlib.rarithmetic import intmask
+from pypy.rlib.rarithmetic import intmask, is_valid_int
from pypy.rlib.rarithmetic import r_int, r_uint, r_longlong, r_ulonglong
from pypy.annotation.builtin import *
from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
@@ -567,7 +567,7 @@
if r_longlong is not r_int:
assert isinstance(res, r_longlong)
else:
- assert isinstance(res, int)
+ assert is_valid_int(res)
#
def llfn(v):
return rffi.cast(rffi.ULONGLONG, v)
diff --git a/pypy/rpython/test/test_rlist.py b/pypy/rpython/test/test_rlist.py
--- a/pypy/rpython/test/test_rlist.py
+++ b/pypy/rpython/test/test_rlist.py
@@ -1362,13 +1362,12 @@
("y[*]" in immutable_fields)
def test_hints(self):
- from pypy.rlib.objectmodel import newlist
- from pypy.rpython.annlowlevel import hlstr
+ from pypy.rlib.objectmodel import newlist_hint
strings = ['abc', 'def']
def f(i):
z = strings[i]
- x = newlist(sizehint=13)
+ x = newlist_hint(sizehint=13)
x += z
return ''.join(x)
diff --git a/pypy/translator/c/primitive.py b/pypy/translator/c/primitive.py
--- a/pypy/translator/c/primitive.py
+++ b/pypy/translator/c/primitive.py
@@ -1,7 +1,7 @@
import sys
from pypy.rlib.objectmodel import Symbolic, ComputedIntSymbolic
from pypy.rlib.objectmodel import CDefinedIntSymbolic
-from pypy.rlib.rarithmetic import r_longlong
+from pypy.rlib.rarithmetic import r_longlong, is_emulated_long
from pypy.rlib.rfloat import isinf, isnan
from pypy.rpython.lltypesystem.lltype import *
from pypy.rpython.lltypesystem import rffi, llgroup
@@ -16,6 +16,15 @@
#
# Primitives
+# win64: we need different constants, since we emulate 64 bit long.
+# this function simply replaces 'L' by 'LL' in a format string
+if is_emulated_long:
+ def lll(fmt):
+ return fmt.replace('L', 'LL')
+else:
+ def lll(fmt):
+ return fmt
+
def name_signed(value, db):
if isinstance(value, Symbolic):
if isinstance(value, FieldOffset):
@@ -61,22 +70,22 @@
elif isinstance(value, llgroup.CombinedSymbolic):
name = name_small_integer(value.lowpart, db)
assert (value.rest & value.MASK) == 0
- return '(%s+%dL)' % (name, value.rest)
+ return lll('(%s+%dL)') % (name, value.rest)
elif isinstance(value, AddressAsInt):
- return '((long)%s)' % name_address(value.adr, db)
+ return '((Signed)%s)' % name_address(value.adr, db)
else:
raise Exception("unimplemented symbolic %r"%value)
if value is None:
assert not db.completed
return None
if value == -sys.maxint-1: # blame C
- return '(-%dL-1L)' % sys.maxint
+ return lll('(-%dL-1L)') % sys.maxint
else:
- return '%dL' % value
+ return lll('%dL') % value
def name_unsigned(value, db):
assert value >= 0
- return '%dUL' % value
+ return lll('%dUL') % value
def name_unsignedlonglong(value, db):
assert value >= 0
@@ -89,6 +98,12 @@
else:
return '%dLL' % value
+def is_positive_nan(value):
+ # bah. we don't have math.copysign() if we're running Python 2.5
+ import struct
+ c = struct.pack("!d", value)[0]
+ return {'\x7f': True, '\xff': False}[c]
+
def name_float(value, db):
if isinf(value):
if value > 0:
@@ -96,7 +111,10 @@
else:
return '(-Py_HUGE_VAL)'
elif isnan(value):
- return '(Py_HUGE_VAL/Py_HUGE_VAL)'
+ if is_positive_nan(value):
+ return '(Py_HUGE_VAL/Py_HUGE_VAL)'
+ else:
+ return '(-(Py_HUGE_VAL/Py_HUGE_VAL))'
else:
x = repr(value)
assert not x.startswith('n')
@@ -112,7 +130,10 @@
return '((float)-Py_HUGE_VAL)'
elif isnan(value):
# XXX are these expressions ok?
- return '((float)(Py_HUGE_VAL/Py_HUGE_VAL))'
+ if is_positive_nan(value):
+ return '((float)(Py_HUGE_VAL/Py_HUGE_VAL))'
+ else:
+ return '(-(float)(Py_HUGE_VAL/Py_HUGE_VAL))'
else:
return repr(value) + 'f'
@@ -172,6 +193,7 @@
# On 64 bit machines, SignedLongLong and Signed are the same, so the
# order matters, because we want the Signed implementation.
+# (some entries collapse during dict creation)
PrimitiveName = {
SignedLongLong: name_signedlonglong,
Signed: name_signed,
@@ -190,9 +212,9 @@
PrimitiveType = {
SignedLongLong: 'long long @',
- Signed: 'long @',
+ Signed: 'Signed @',
UnsignedLongLong: 'unsigned long long @',
- Unsigned: 'unsigned long @',
+ Unsigned: 'Unsigned @',
Float: 'double @',
SingleFloat: 'float @',
LongFloat: 'long double @',
diff --git a/pypy/translator/c/src/address.h b/pypy/translator/c/src/address.h
--- a/pypy/translator/c/src/address.h
+++ b/pypy/translator/c/src/address.h
@@ -16,5 +16,5 @@
#define OP_ADR_LT(x,y,r) r = ((x) < (y))
#define OP_ADR_GE(x,y,r) r = ((x) >= (y))
-#define OP_CAST_ADR_TO_INT(x, mode, r) r = ((long)x)
+#define OP_CAST_ADR_TO_INT(x, mode, r) r = ((Signed)x)
#define OP_CAST_INT_TO_ADR(x, r) r = ((void *)(x))
diff --git a/pypy/translator/c/src/asm.h b/pypy/translator/c/src/asm.h
--- a/pypy/translator/c/src/asm.h
+++ b/pypy/translator/c/src/asm.h
@@ -14,4 +14,8 @@
# include "src/asm_ppc.h"
#endif
+#if defined(MS_WINDOWS) && defined(_MSC_VER)
+# include "src/asm_msvc.h"
+#endif
+
#endif /* _PYPY_ASM_H */
diff --git a/pypy/translator/c/src/asm_gcc_x86.h b/pypy/translator/c/src/asm_gcc_x86.h
--- a/pypy/translator/c/src/asm_gcc_x86.h
+++ b/pypy/translator/c/src/asm_gcc_x86.h
@@ -124,10 +124,12 @@
{
//Read the CPU features.
int features;
- asm("mov $1, %%eax\n"
+ asm("movl $1, %%eax\n"
+ "pushl %%ebx\n"
"cpuid\n"
- "mov %%edx, %0"
- : "=g"(features) : : "eax", "ebx", "edx", "ecx");
+ "popl %%ebx\n"
+ "movl %%edx, %0"
+ : "=g"(features) : : "eax", "edx", "ecx");
//Check bits 25 and 26, this indicates SSE2 support
if (((features & (1 << 25)) == 0) || ((features & (1 << 26)) == 0))
diff --git a/pypy/translator/c/src/asm_gcc_x86_64.h b/pypy/translator/c/src/asm_gcc_x86_64.h
--- a/pypy/translator/c/src/asm_gcc_x86_64.h
+++ b/pypy/translator/c/src/asm_gcc_x86_64.h
@@ -2,7 +2,7 @@
*/
#define READ_TIMESTAMP(val) do { \
- unsigned long _rax, _rdx; \
+ Unsigned _rax, _rdx; \
asm volatile("rdtsc" : "=a"(_rax), "=d"(_rdx)); \
val = (_rdx << 32) | _rax; \
} while (0)
diff --git a/pypy/translator/c/src/asm_msvc.h b/pypy/translator/c/src/asm_msvc.h
new file mode 100644
--- /dev/null
+++ b/pypy/translator/c/src/asm_msvc.h
@@ -0,0 +1,31 @@
+
+#ifdef PYPY_X86_CHECK_SSE2
+#define PYPY_X86_CHECK_SSE2_DEFINED
+extern void pypy_x86_check_sse2(void);
+#endif
+
+
+/* implementations */
+
+#ifndef PYPY_NOT_MAIN_FILE
+#ifdef PYPY_X86_CHECK_SSE2
+#include <intrin.h>
+void pypy_x86_check_sse2(void)
+{
+ int features;
+ int CPUInfo[4];
+ CPUInfo[3] = 0;
+ __cpuid(CPUInfo, 1);
+ features = CPUInfo[3];
+
+ //Check bits 25 and 26, this indicates SSE2 support
+ if (((features & (1 << 25)) == 0) || ((features & (1 << 26)) == 0))
+ {
+ fprintf(stderr, "Old CPU with no SSE2 support, cannot continue.\n"
+ "You need to re-translate with "
+ "'--jit-backend=x86-without-sse2'\n");
+ abort();
+ }
+}
+#endif
+#endif
diff --git a/pypy/translator/c/src/commondefs.h b/pypy/translator/c/src/commondefs.h
--- a/pypy/translator/c/src/commondefs.h
+++ b/pypy/translator/c/src/commondefs.h
@@ -11,6 +11,21 @@
In particular, Win64 is not supported because it has sizeof(long) == 4.
To fix this, find and review all the places that cast a pointer to a long.
+
+ Update:
+ We are trying to lift this restriction for Win64:
+
+ Win64 int long long long void*
+ --64-bit-- 32 32 64 64
+
+ The migration to this platform is complicated and tedious, because
+ PyPy assumes that a void* fits into a long. Therefore, the created PyPy
+ will (first) have a 64 bit int type. The dependency of sys.maxint must
+ be removed in very many places, and the distinction between Python int
+ and long must be changed in explicit range checks.
+
+ This is work in progress with first successes.
+
*/
#include <limits.h>
@@ -54,16 +69,32 @@
/******************** 64-bit support ********************/
#else
-# if LONG_MAX != 9223372036854775807L
-# error "error in LONG_MAX (64-bit sources but a 32-bit compiler?)"
+# ifndef _WIN64
+# if LONG_MAX != 9223372036854775807L
+# error "error in LONG_MAX (64-bit sources but a 32-bit compiler?)"
+# endif
+# if LONG_MIN != -9223372036854775807L-1L
+# error "unsupported value for LONG_MIN"
+# endif
+
+# define SIZEOF_INT 4
+# define SIZEOF_LONG 8
+# define SIZEOF_LONG_LONG 8
+
+/******************** Win-64 support ********************/
+# else
+# if LONG_MAX != 2147483647L
+# error "error in LONG_MAX (64-bit sources but incompatible compiler?)"
+# endif
+# if LONG_MIN != -2147483647L-1L
+# error "unsupported value for LONG_MIN"
+# endif
+
+# define SIZEOF_INT 4
+# define SIZEOF_LONG 4
+# define SIZEOF_LONG_LONG 8
+
# endif
-# if LONG_MIN != -9223372036854775807L-1L
-# error "unsupported value for LONG_MIN"
-# endif
-
-# define SIZEOF_INT 4
-# define SIZEOF_LONG 8
-# define SIZEOF_LONG_LONG 8
#endif
diff --git a/pypy/translator/c/src/debug_print.c b/pypy/translator/c/src/debug_print.c
--- a/pypy/translator/c/src/debug_print.c
+++ b/pypy/translator/c/src/debug_print.c
@@ -13,6 +13,7 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif
+#include "common_header.h"
#include "src/profiling.h"
#include "src/debug_print.h"
diff --git a/pypy/translator/c/src/float.h b/pypy/translator/c/src/float.h
--- a/pypy/translator/c/src/float.h
+++ b/pypy/translator/c/src/float.h
@@ -31,8 +31,8 @@
/*** conversions ***/
-#define OP_CAST_FLOAT_TO_INT(x,r) r = (long)(x)
-#define OP_CAST_FLOAT_TO_UINT(x,r) r = (unsigned long)(x)
+#define OP_CAST_FLOAT_TO_INT(x,r) r = (Signed)(x)
+#define OP_CAST_FLOAT_TO_UINT(x,r) r = (Unsigned)(x)
#define OP_CAST_INT_TO_FLOAT(x,r) r = (double)(x)
#define OP_CAST_UINT_TO_FLOAT(x,r) r = (double)(x)
#define OP_CAST_LONGLONG_TO_FLOAT(x,r) r = (double)(x)
diff --git a/pypy/translator/c/src/int.h b/pypy/translator/c/src/int.h
--- a/pypy/translator/c/src/int.h
+++ b/pypy/translator/c/src/int.h
@@ -5,18 +5,31 @@
/*** unary operations ***/
+/************ win64 support:
+
+ 'Signed' must be defined as
+
+ __int64 in case of win64
+ long in all other cases
+
+ 'SIGNED_MIN' must be defined as
+
+ LLONG_MIN in case of win64
+ LONG_MIN in all other cases
+ */
+
#define OP_INT_IS_TRUE(x,r) r = ((x) != 0)
#define OP_INT_INVERT(x,r) r = ~(x)
#define OP_INT_NEG(x,r) r = -(x)
#define OP_INT_NEG_OVF(x,r) \
- if ((x) == LONG_MIN) FAIL_OVF("integer negate"); \
+ if ((x) == SIGNED_MIN) FAIL_OVF("integer negate"); \
OP_INT_NEG(x,r)
#define OP_INT_ABS(x,r) r = (x) >= 0 ? x : -(x)
#define OP_INT_ABS_OVF(x,r) \
- if ((x) == LONG_MIN) FAIL_OVF("integer absolute"); \
+ if ((x) == SIGNED_MIN) FAIL_OVF("integer absolute"); \
OP_INT_ABS(x,r)
/*** binary operations ***/
@@ -33,8 +46,8 @@
for the case of a == 0 (both subtractions are then constant-folded).
Note that the following line only works if a <= c in the first place,
which we assume is true. */
-#define OP_INT_BETWEEN(a,b,c,r) r = (((unsigned long)b - (unsigned long)a) \
- < ((unsigned long)c - (unsigned long)a))
+#define OP_INT_BETWEEN(a,b,c,r) r = (((Unsigned)b - (Unsigned)a) \
+ < ((Unsigned)c - (Unsigned)a))
/* addition, subtraction */
@@ -42,22 +55,22 @@
/* cast to avoid undefined behaviour on overflow */
#define OP_INT_ADD_OVF(x,y,r) \
- r = (long)((unsigned long)x + y); \
+ r = (Signed)((Unsigned)x + y); \
if ((r^x) < 0 && (r^y) < 0) FAIL_OVF("integer addition")
#define OP_INT_ADD_NONNEG_OVF(x,y,r) /* y can be assumed >= 0 */ \
- r = (long)((unsigned long)x + y); \
+ r = (Signed)((Unsigned)x + y); \
if ((r&~x) < 0) FAIL_OVF("integer addition")
#define OP_INT_SUB(x,y,r) r = (x) - (y)
#define OP_INT_SUB_OVF(x,y,r) \
- r = (long)((unsigned long)x - y); \
+ r = (Signed)((Unsigned)x - y); \
if ((r^x) < 0 && (r^~y) < 0) FAIL_OVF("integer subtraction")
#define OP_INT_MUL(x,y,r) r = (x) * (y)
-#if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
+#if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG && !defined(_WIN64)
#define OP_INT_MUL_OVF(x,y,r) \
{ \
long long _lr = (long long)x * y; \
@@ -78,7 +91,7 @@
#define OP_INT_RSHIFT(x,y,r) CHECK_SHIFT_RANGE(y, PYPY_LONG_BIT); \
- r = Py_ARITHMETIC_RIGHT_SHIFT(long, x, (y))
+ r = Py_ARITHMETIC_RIGHT_SHIFT(Signed, x, (y))
#define OP_UINT_RSHIFT(x,y,r) CHECK_SHIFT_RANGE(y, PYPY_LONG_BIT); \
r = (x) >> (y)
#define OP_LLONG_RSHIFT(x,y,r) CHECK_SHIFT_RANGE(y, PYPY_LONGLONG_BIT); \
@@ -98,7 +111,7 @@
#define OP_INT_LSHIFT_OVF(x,y,r) \
OP_INT_LSHIFT(x,y,r); \
- if ((x) != Py_ARITHMETIC_RIGHT_SHIFT(long, r, (y))) \
+ if ((x) != Py_ARITHMETIC_RIGHT_SHIFT(Signed, r, (y))) \
FAIL_OVF("x<<y losing bits or changing sign")
/* floor division */
@@ -109,7 +122,7 @@
#define OP_ULLONG_FLOORDIV(x,y,r) r = (x) / (y)
#define OP_INT_FLOORDIV_OVF(x,y,r) \
- if ((y) == -1 && (x) == LONG_MIN) \
+ if ((y) == -1 && (x) == SIGNED_MIN) \
{ FAIL_OVF("integer division"); r=0; } \
else \
r = (x) / (y)
@@ -149,7 +162,7 @@
#define OP_ULLONG_MOD(x,y,r) r = (x) % (y)
#define OP_INT_MOD_OVF(x,y,r) \
- if ((y) == -1 && (x) == LONG_MIN) \
+ if ((y) == -1 && (x) == SIGNED_MIN) \
{ FAIL_OVF("integer modulo"); r=0; } \
else \
r = (x) % (y)
@@ -188,18 +201,18 @@
/*** conversions ***/
-#define OP_CAST_BOOL_TO_INT(x,r) r = (long)(x)
-#define OP_CAST_BOOL_TO_UINT(x,r) r = (unsigned long)(x)
-#define OP_CAST_UINT_TO_INT(x,r) r = (long)(x)
-#define OP_CAST_INT_TO_UINT(x,r) r = (unsigned long)(x)
+#define OP_CAST_BOOL_TO_INT(x,r) r = (Signed)(x)
+#define OP_CAST_BOOL_TO_UINT(x,r) r = (Unsigned)(x)
+#define OP_CAST_UINT_TO_INT(x,r) r = (Signed)(x)
+#define OP_CAST_INT_TO_UINT(x,r) r = (Unsigned)(x)
#define OP_CAST_INT_TO_LONGLONG(x,r) r = (long long)(x)
-#define OP_CAST_CHAR_TO_INT(x,r) r = (long)((unsigned char)(x))
+#define OP_CAST_CHAR_TO_INT(x,r) r = (Signed)((unsigned char)(x))
#define OP_CAST_INT_TO_CHAR(x,r) r = (char)(x)
-#define OP_CAST_PTR_TO_INT(x,r) r = (long)(x) /* XXX */
+#define OP_CAST_PTR_TO_INT(x,r) r = (Signed)(x) /* XXX */
-#define OP_TRUNCATE_LONGLONG_TO_INT(x,r) r = (long)(x)
+#define OP_TRUNCATE_LONGLONG_TO_INT(x,r) r = (Signed)(x)
-#define OP_CAST_UNICHAR_TO_INT(x,r) r = (long)((unsigned long)(x)) /*?*/
+#define OP_CAST_UNICHAR_TO_INT(x,r) r = (Signed)((Unsigned)(x)) /*?*/
#define OP_CAST_INT_TO_UNICHAR(x,r) r = (unsigned int)(x)
/* bool operations */
diff --git a/pypy/translator/c/src/main.h b/pypy/translator/c/src/main.h
--- a/pypy/translator/c/src/main.h
+++ b/pypy/translator/c/src/main.h
@@ -41,11 +41,14 @@
#endif
instrument_setup();
+#ifndef MS_WINDOWS
+ /* this message does no longer apply to win64 :-) */
if (sizeof(void*) != SIZEOF_LONG) {
errmsg = "only support platforms where sizeof(void*) == sizeof(long),"
" for now";
goto error;
}
+#endif
#ifdef MS_WINDOWS
pypy_Windows_startup();
diff --git a/pypy/translator/c/src/mem.h b/pypy/translator/c/src/mem.h
--- a/pypy/translator/c/src/mem.h
+++ b/pypy/translator/c/src/mem.h
@@ -53,7 +53,7 @@
extern void* __gcmapstart;
extern void* __gcmapend;
extern char* __gccallshapes;
-extern long pypy_asm_stackwalk(void*, void*);
+extern Signed pypy_asm_stackwalk(void*, void*);
/* With the msvc Microsoft Compiler, the optimizer seems free to move
any code (even asm) that involves local memory (registers and stack).
@@ -66,14 +66,20 @@
pypy_asm_gcroot(void* _r1)
{
static volatile int _constant_always_one_ = 1;
- (long)_r1 *= _constant_always_one_;
+ (Signed)_r1 *= _constant_always_one_;
_ReadWriteBarrier();
return _r1;
}
#define pypy_asm_gc_nocollect(f) "/* GC_NOCOLLECT " #f " */"
-#define pypy_asm_keepalive(v) __asm { }
+#ifndef _WIN64
+# define pypy_asm_keepalive(v) __asm { }
+#else
+ /* is there something cheaper? */
+# define pypy_asm_keepalive(v) _ReadWriteBarrier();
+#endif
+
static __declspec(noinline) void pypy_asm_stack_bottom() { }
#define OP_GC_ASMGCROOT_STATIC(i, r) r = \
@@ -86,7 +92,7 @@
/* used by pypy.rlib.rstack, but also by asmgcc */
-#define OP_STACK_CURRENT(r) r = (long)&r
+#define OP_STACK_CURRENT(r) r = (Signed)&r
#define RAW_MALLOC_ZERO_FILLED 0
diff --git a/pypy/translator/c/src/obmalloc.c b/pypy/translator/c/src/obmalloc.c
--- a/pypy/translator/c/src/obmalloc.c
+++ b/pypy/translator/c/src/obmalloc.c
@@ -224,10 +224,10 @@
#define uint unsigned int /* assuming >= 16 bits */
#undef ulong
-#define ulong unsigned long /* assuming >= 32 bits */
+#define ulong Unsigned /* assuming >= 32 bits */
#undef uptr
-#define uptr unsigned long
+#define uptr Unsigned
/* When you say memory, my mind reasons in terms of (pointers to) blocks */
typedef uchar block;
diff --git a/pypy/translator/c/src/rtyper.h b/pypy/translator/c/src/rtyper.h
--- a/pypy/translator/c/src/rtyper.h
+++ b/pypy/translator/c/src/rtyper.h
@@ -30,7 +30,7 @@
char *RPyString_AsCharP(RPyString *rps)
{
- long len = RPyString_Size(rps);
+ Signed len = RPyString_Size(rps);
struct _RPyString_dump_t *dump = \
malloc(sizeof(struct _RPyString_dump_t) + len);
if (!dump)
diff --git a/pypy/translator/c/src/signals.h b/pypy/translator/c/src/signals.h
--- a/pypy/translator/c/src/signals.h
+++ b/pypy/translator/c/src/signals.h
@@ -54,7 +54,7 @@
/* When a signal is received, pypysig_counter is set to -1. */
/* This is a struct for the JIT. See interp_signal.py. */
struct pypysig_long_struct {
- long value;
+ Signed value;
};
extern struct pypysig_long_struct pypysig_counter;
diff --git a/pypy/translator/c/test/test_database.py b/pypy/translator/c/test/test_database.py
--- a/pypy/translator/c/test/test_database.py
+++ b/pypy/translator/c/test/test_database.py
@@ -232,7 +232,7 @@
B = Signed
db = LowLevelDatabase()
assert db.gettype(A) == "int @"
- assert db.gettype(B) == "long @"
+ assert db.gettype(B) == "Signed @"
def test_recursive_struct():
diff --git a/pypy/translator/c/test/test_genc.py b/pypy/translator/c/test/test_genc.py
--- a/pypy/translator/c/test/test_genc.py
+++ b/pypy/translator/c/test/test_genc.py
@@ -16,6 +16,8 @@
def compile(fn, argtypes, view=False, gcpolicy="ref", backendopt=True,
annotatorpolicy=None):
+ if argtypes is not None and "__pypy__" in sys.builtin_module_names:
+ py.test.skip("requires building cpython extension modules")
t = Translation(fn, argtypes, gc=gcpolicy, backend="c",
policy=annotatorpolicy)
if not backendopt:
diff --git a/pypy/translator/c/test/test_newgc.py b/pypy/translator/c/test/test_newgc.py
--- a/pypy/translator/c/test/test_newgc.py
+++ b/pypy/translator/c/test/test_newgc.py
@@ -675,8 +675,8 @@
gc.collect()
p_a1 = rffi.cast(rffi.VOIDPP, ll_args[0])[0]
p_a2 = rffi.cast(rffi.VOIDPP, ll_args[1])[0]
- a1 = rffi.cast(rffi.LONGP, p_a1)[0]
- a2 = rffi.cast(rffi.LONGP, p_a2)[0]
+ a1 = rffi.cast(rffi.SIGNEDP, p_a1)[0]
+ a2 = rffi.cast(rffi.SIGNEDP, p_a2)[0]
res = rffi.cast(rffi.INTP, ll_res)
if a1 > a2:
res[0] = rffi.cast(rffi.INT, 1)
@@ -692,7 +692,7 @@
ptr = CallbackFuncPtr([ffi_type_pointer, ffi_type_pointer],
ffi_type_sint, callback)
- TP = rffi.CArray(rffi.LONG)
+ TP = rffi.CArray(lltype.Signed)
to_sort = lltype.malloc(TP, 4, flavor='raw')
to_sort[0] = 4
to_sort[1] = 3
@@ -700,7 +700,7 @@
to_sort[3] = 2
qsort.push_arg(rffi.cast(rffi.VOIDP, to_sort))
qsort.push_arg(rffi.cast(rffi.SIZE_T, 4))
- qsort.push_arg(rffi.cast(rffi.SIZE_T, rffi.sizeof(rffi.LONG)))
+ qsort.push_arg(rffi.cast(rffi.SIZE_T, rffi.sizeof(lltype.Signed)))
qsort.push_arg(rffi.cast(rffi.VOIDP, ptr.ll_closure))
qsort.call(lltype.Void)
result = [to_sort[i] for i in range(4)] == [1,2,3,4]
@@ -1202,7 +1202,7 @@
def f():
from pypy.rpython.lltypesystem import lltype, rffi
alist = [A() for i in range(50000)]
- idarray = lltype.malloc(rffi.LONGP.TO, len(alist), flavor='raw')
+ idarray = lltype.malloc(rffi.SIGNEDP.TO, len(alist), flavor='raw')
# Compute the id of all elements of the list. The goal is
# to not allocate memory, so that if the GC needs memory to
# remember the ids, it will trigger some collections itself
diff --git a/pypy/translator/geninterplevel.py b/pypy/translator/geninterplevel.py
deleted file mode 100644
--- a/pypy/translator/geninterplevel.py
+++ /dev/null
@@ -1,1550 +0,0 @@
-"""
-Implementation of a translator from application Python to
-interpreter level RPython.
-
-The idea is that we can automatically transform application level
-implementations of methods into some equivalent representation at
-interpreter level. Then, the RPython to C translation might
-hopefully spit out some more efficient code than always interpreting
-these methods.
-
-Note that the application level functions are treated as rpythonic,
-in a sense that globals are constants, for instance. This definition
-is not exact and might change.
-
-The interface for this module is
-
- (initfunc, newsrc) = translate_as_module(
- sourcetext,
- filename=None,
- modname="app2interpexec",
- tmpname=None)
-
-If filename is given, it is used as a reference where
-this sourcetext can be literally found, to produce
-real line numbers. It cannot be just any name but
-must exist and contain the source code somewhere.
-
-modname is optional and will be put into the dictionary
-to be created.
-
-tmpname is optional. If given, a temporary file will
-be created for debugging purposes.
-
-The returned newsrc is the generated source text.
-It is used in gateway.py's caching mechanism.
-The initfunc result is a function named "init"+modname
-It must be called with a space instance and returns
-a wrapped dict which is suitable to use as a module dict,
-containing all trnaslatedobjects with their originalname.
-
-Integration of this module is finished.
-There are no longer hand-generated source
-pieces in pypy svn.
-"""
-
-import autopath, os, sys, types
-import inspect
-import cPickle as pickle, __builtin__
-from copy_reg import _HEAPTYPE
-from pypy.objspace.flow.model import Variable, Constant, SpaceOperation
-from pypy.objspace.flow.model import c_last_exception, checkgraph
-from pypy.interpreter.pycode import CO_VARARGS, CO_VARKEYWORDS
-from types import FunctionType, CodeType, ModuleType, MethodType
-from pypy.interpreter.error import OperationError
-from pypy.interpreter.argument import ArgumentsForTranslation, Arguments
-from pypy.translator.backendopt.ssa import SSI_to_SSA
-
-from pypy.translator.translator import TranslationContext
-from pypy.objspace.flow.objspace import FlowObjSpace
-
-from pypy.tool.sourcetools import render_docstr, NiceCompile
-
-from pypy.translator.gensupp import ordered_blocks, UniqueList, builtin_base, \
- uniquemodulename, C_IDENTIFIER, NameManager
-from pypy.tool.identity_dict import identity_dict
-
-import pypy # __path__
-import py.path
-from pypy.tool.ansi_print import ansi_log
-
-log = py.log.Producer("geninterp")
-py.log.setconsumer("geninterp", ansi_log)
-
-GI_VERSION = '1.2.9' # bump this for substantial changes
-# ____________________________________________________________
-
-try:
- set
-except NameError:
- class fake_set(object):
- pass
- class fake_frozenset(object):
- pass
- builtin_set = fake_set
- builtin_frozenset = fake_frozenset
- faked_set = True
-else:
- builtin_set = set
- builtin_frozenset = frozenset
- faked_set = False
-
-def eval_helper(self, typename, expr):
- name = self.uniquename("gtype_%s" % typename)
- unique = self.uniquenameofprebuilt("eval_helper", eval_helper)
- self.initcode.append1(
- 'def %s(expr):\n'
- ' dic = space.newdict()\n'
- ' if "types." in expr:\n'
- ' space.exec_("import types", dic, dic, hidden_applevel=True)\n'
- ' else:\n'
- ' space.exec_("", dic, dic, hidden_applevel=True)\n'
- ' return space.eval(expr, dic, dic, hidden_applevel=True)' % (unique, ))
- self.initcode.append1('%s = %s(%r)' % (name, unique, expr))
- return name
-
-def unpickle_helper(self, name, value):
- unique = self.uniquenameofprebuilt("unpickle_helper", unpickle_helper)
- self.initcode.append1(
- 'def %s(value):\n'
- ' dic = space.newdict()\n'
- ' space.exec_("import cPickle as pickle", dic, dic, hidden_applevel=True)\n'
- ' return space.eval("pickle.loads(%%r)" %% value, dic, dic, hidden_applevel=True)' % unique)
- self.initcode.append1('%s = %s(%r)' % (
- name, unique, pickle.dumps(value, 2)) )
-
-# hey, for longs we can do even easier:
-def long_helper(self, name, value):
- unique = self.uniquenameofprebuilt("long_helper", long_helper)
- self.initcode.append1(
- 'def %s(value):\n'
- ' dic = space.newdict()\n'
- ' space.exec_("", dic, dic, hidden_applevel=True) # init __builtins__\n'
- ' return space.eval(value, dic, dic, hidden_applevel=True)' % unique)
- self.initcode.append1('%s = %s(%r)' % (
- name, unique, repr(value) ) )
-
-def bltinmod_helper(self, mod):
- name = self.uniquename("mod_%s" % mod.__name__)
- unique = self.uniquenameofprebuilt("bltinmod_helper", bltinmod_helper)
- self.initcode.append1(
- 'def %s(name):\n'
- ' dic = space.newdict()\n'
- ' space.exec_("import %%s" %% name, dic, dic, hidden_applevel=True)\n'
- ' return space.eval("%%s" %% name, dic, dic, hidden_applevel=True)' % (unique, ))
- self.initcode.append1('%s = %s(%r)' % (name, unique, mod.__name__))
- return name
-
-class GenRpy:
- def __init__(self, translator, entrypoint=None, modname=None, moddict=None):
- self.translator = translator
- if entrypoint is None:
- entrypoint = translator.entrypoint
- self.entrypoint = entrypoint
- self.modname = self.trans_funcname(modname or
- uniquemodulename(entrypoint))
- self.moddict = moddict # the dict if we translate a module
-
- def late_OperationError():
- self.initcode.append1(
- 'from pypy.interpreter.error import OperationError as gOperationError')
- return 'gOperationError'
- def late_Arguments():
- self.initcode.append1('from pypy.interpreter import gateway')
- return 'gateway.Arguments'
-
- self.rpynames = {Constant(None).key: 'space.w_None',
- Constant(False).key: 'space.w_False',
- Constant(True).key: 'space.w_True',
- Constant(Ellipsis).key: 'space.w_Ellipsis',
- Constant(NotImplemented).key: 'space.w_NotImplemented',
- Constant(OperationError).key: late_OperationError,
- Constant(Arguments).key: late_Arguments,
- }
- self.initcode = UniqueList() # list of lines for the module's initxxx()
- self.latercode = UniqueList()
- # list of generators generating extra lines
- # for later in initxxx() -- for recursive
- # objects
- self.namespace = NameManager()
- self.namespace.make_reserved_names('__doc__ __args__ space goto')
- self.globaldecl = []
- self.globalobjects = []
- self.pendingfunctions = []
- self.currentfunc = None
- self.debugstack = () # linked list of nested nameof()
-
- # special constructors:
- self.has_listarg = {}
- for name in "newtuple newlist".split():
- self.has_listarg[name] = name
-
- # catching all builtins in advance, to avoid problems
- # with modified builtins
-
- # add a dummy _issubtype() to builtins
- if not hasattr(__builtin__, '_issubtype'):
- def _issubtype(cls1, cls2):
- raise TypeError, "this dummy should *not* be reached"
- __builtin__._issubtype = _issubtype
-
- class bltinstub:
- def __init__(self, name):
- self.__name__ = name
- def __repr__(self):
- return '<%s>' % self.__name__
-
- self.ibuiltin_ids = identity_dict()
- self.ibuiltin_ids.update([
- (value, bltinstub(key))
- for key, value in __builtin__.__dict__.items()
- if callable(value) and type(value) not in [types.ClassType, type] ] )
-
- self.space = FlowObjSpace() # for introspection
-
- self.use_fast_call = True
- self.specialize_goto = False
- self._labeltable = {} # unique label names, reused per func
-
- self._space_arities = None
-
- self._signature_cache = {}
- self._defaults_cache = {}
-
- def expr(self, v, localscope, wrapped = True):
- if isinstance(v, Variable):
- return localscope.localname(v.name, wrapped)
- elif isinstance(v, Constant):
- return self.nameof(v.value,
- debug=('Constant in the graph of', self.currentfunc))
- else:
- raise TypeError, "expr(%r)" % (v,)
-
- def arglist(self, args, localscope):
- res = [self.expr(arg, localscope) for arg in args]
- return ", ".join(res)
-
- def oper(self, op, localscope):
- if op.opname in ('issubtype', 'isinstance'):
- arg = op.args[1]
- if (not isinstance(arg, Constant)
- or not isinstance(arg.value, (type, types.ClassType))):
- func = issubclass if op.opname == 'issubtype' else isinstance
- op = SpaceOperation("simple_call",
- [Constant(func)]+op.args,
- op.result)
- if op.opname == "simple_call":
- v = op.args[0]
- space_shortcut = self.try_space_shortcut_for_builtin(v, len(op.args)-1,
- op.args[1:])
- if space_shortcut is not None:
- # space method call
- exv = space_shortcut
- fmt = "%(res)s = %(func)s(%(args)s)"
- else:
- # import sys|__builtin__|_codecs avoid going through __import__
- if isinstance(v, Constant) and v.value is __builtin__.__import__:
- name, glb, loc, frm_lst = op.args[1:]
- if (isinstance(name, Constant) and name.value in ('sys', '__builtin__', '_codecs') and
- isinstance(loc, Constant) and loc.value is None and
- isinstance(frm_lst, Constant) and frm_lst.value is None):
- return "%s = space.getbuiltinmodule(%r)" % (self.expr(op.result, localscope),
- name.value)
- exv = self.expr(v, localscope)
- # default for a spacecall:
- fmt = "%(res)s = space.call_function(%(func)s, %(args)s)"
- # see if we can optimize for a fast call.
- # we just do the very simple ones.
- if self.use_fast_call and (isinstance(v, Constant)
- and exv.startswith('gfunc_')):
- func = v.value
- if (not func.func_code.co_flags & CO_VARARGS) and (
- func.func_defaults is None):
- fmt = "%(res)s = fastf_%(func)s(space, %(args)s)"
- exv = exv[6:]
- return fmt % {"res" : self.expr(op.result, localscope),
- "func": exv,
- "args": self.arglist(op.args[1:], localscope) }
- if op.opname == "call_args":
- v = op.args[0]
- exv = self.expr(v, localscope)
- fmt = (
- "_args = %(Arg)s(space, [%(args_w)s], %(keywords)s, [%(keywords_w)s], %(w_stararg)s, %(w_starstararg)s)\n"
- "%(res)s = space.call_args(%(func)s, _args)")
- assert isinstance(op.args[1], Constant)
- shape = op.args[1].value
- # make a list out of the second shape elt.
- shape = shape[0], list(shape[1]), shape[2], shape[3]
- arglist = [self.expr(arg, localscope) for arg in op.args[2:]]
- args = ArgumentsForTranslation.fromshape(None, shape, arglist)
- return fmt % {"res": self.expr(op.result, localscope),
- "func": exv,
- "args_w": ", ".join(args.arguments_w),
- "keywords": args.keywords,
- "keywords_w": ", ".join(args.keywords_w),
- "w_stararg": args.w_stararg,
- "w_starstararg": args.w_starstararg,
- 'Arg': self.nameof(Arguments) }
- if op.opname == "hint":
- return "%s = %s" % (self.expr(op.result, localscope),
- self.expr(op.args[0], localscope))
- if op.opname in self.has_listarg:
- fmt = "%s = %s([%s])"
- else:
- fmt = "%s = %s(%s)"
- # special case is_true
- opname = op.opname
- if opname.startswith('getitem_'):
- opname = 'getitem'
- wrapped = opname != "is_true"
- oper = "space.%s" % opname
- return fmt % (self.expr(op.result, localscope, wrapped), oper,
- self.arglist(op.args, localscope))
-
- def large_assignment(self, left, right, margin=65):
- expr = "(%s) = (%s)" % (", ".join(left), ", ".join(right))
- pieces = expr.split(",")
- res = [pieces.pop(0)]
- for piece in pieces:
- if len(res[-1])+len(piece)+1 > margin:
- res[-1] += ","
- res.append(piece)
- else:
- res[-1] += (","+piece)
- return res
-
- def large_initialize(self, vars, margin=65):
- res = []
- nonestr = "None"
- margin -= len(nonestr)
- for var in vars:
- ass = var+"="
- if not res or len(res[-1]) >= margin:
- res.append(ass)
- else:
- res[-1] += ass
- res = [line + nonestr for line in res]
- return res
-
- def mklabel(self, blocknum):
- if self.specialize_goto:
- lbname = self._labeltable.get(blocknum)
- if not lbname:
- self.initcode.append1(
- 'from pypy.objspace.flow.framestate import SpecTag')
- lbname = self.uniquename("glabel_%d" % blocknum)
- self._labeltable[blocknum] = lbname
- self.initcode.append1('%s = SpecTag()' % lbname)
- return lbname
- else:
- return repr(blocknum)
-
- def gen_link(self, link, localscope, blocknum, block, linklocalvars=None):
- "Generate the code to jump across the given Link."
- linklocalvars = linklocalvars or {}
- left, right = [], []
- for a1, a2 in zip(link.args, link.target.inputargs):
- if a1 in linklocalvars:
- src = linklocalvars[a1]
- else:
- src = self.expr(a1, localscope)
- dest = self.expr(a2, localscope)
- if src != dest:
- left.append(dest)
- right.append(src)
- if left: # anything at all?
- txt = "%s = %s" % (", ".join(left), ", ".join(right))
- if len(txt) <= 65: # arbitrary
- yield txt
- else:
- for line in self.large_assignment(left, right):
- yield line
- goto = blocknum[link.target]
- yield 'goto = %s' % self.mklabel(goto)
- if goto <= blocknum[block]:
- yield 'continue'
-
- def register_early(self, obj, name):
- # this was needed for recursive lists.
- # note that self.latercode led to too late initialization.
- key = Constant(obj).key
- self.rpynames[key] = name
-
- def nameof(self, obj, debug=None, namehint=None):
- key = Constant(obj).key
- try:
- txt = self.rpynames[key]
- if type(txt) is not str:
- # this is a predefined constant, initialized on first use
- func = txt
- txt = func()
- self.rpynames[key] = txt
- return txt
-
- except KeyError:
- if debug:
- stackentry = debug, obj
- else:
- stackentry = obj
- self.debugstack = (self.debugstack, stackentry)
- obj_builtin_base = builtin_base(obj)
- if obj_builtin_base in (object, int, long) and type(obj) is not obj_builtin_base:
- # assume it's a user defined thingy
- name = self.nameof_instance(obj)
- else:
- # shortcutting references to __builtin__
- if obj in self.ibuiltin_ids:
- func = self.ibuiltin_ids[obj]
- #name = self.get_nameof_builtin_func(func)
- # the above is quicker in principle, but pulls more
- # stuff in, so it is slower right now.
- name = "(space.builtin.get(space.str_w(%s)))" % self.nameof(func.__name__)
- else:
- for cls in type(obj).__mro__:
- meth = getattr(self,
- 'nameof_' + cls.__name__.replace(' ', ''),
- None)
- if meth:
- break
- else:
- raise Exception, "nameof(%r)" % (obj,)
-
- code = meth.im_func.func_code
- if namehint and 'namehint' in code.co_varnames[:code.co_argcount]:
- name = meth(obj, namehint=namehint)
- else:
- name = meth(obj)
- self.debugstack, x = self.debugstack
- assert x is stackentry
- self.rpynames[key] = name
- return name
-
- def get_nameof_builtin_func(self, func):
- # this is a hack!
- # in some cases, like exceptions, we don't have space.builtin available,
- #so we crate a fall-back...
- name = self.uniquename('gbltin_' + func.__name__)
- self.initcode.append1('''\
-try:
- # see if we have space.builtin in this context
- space.builtin
-except AttributeError:
- print "didn\'t get", %(bltin)r
- def %(name)s(space, __args__):
- w_func = space.builtin.get(%(bltin)r)
- return space.call_args(w_func, __args__)
- %(name)s = space.wrap(gateway.interp2app(%(name)s, unwrap_spec=[gateway.ObjSpace, gateway.Arguments]))
-else:
- print "got it:", %(bltin)r
- %(name)s = space.builtin.get(%(bltin)r)'''
- % {'name': name, 'bltin': func.__name__} )
- return name
-
- def uniquename(self, basename):
- name = self.namespace.uniquename(basename)
- self.globalobjects.append(name)
- self.globaldecl.append('# global object %s' % (name,))
- return name
-
- def uniquenameofprebuilt(self, basename, obj):
- # identifying an object and giving it a name,
- # without the attempt to render it.
- key = Constant(obj).key
- try:
- txt = self.rpynames[key]
- except KeyError:
- self.rpynames[key] = txt = self.uniquename(basename)
- return txt
-
- def nameof_object(self, value):
- if type(value) is not object:
- # try to just wrap it?
- name = self.uniquename('g_%sinst_%r' % (type(value).__name__, value))
- self.initcode.append1('%s = space.wrap(%r)' % (name, value))
- return name
- name = self.uniquename('g_object')
- self.initcode.append('_tup = space.newtuple([])\n'
- '%s = space.call(space.w_object, _tup)'
- % name)
- return name
-
- def is_module_builtin(self, mod):
- if not hasattr(mod, "__file__") or mod.__file__ is None:
- return True
- if not (mod.__file__.endswith('.pyc') or
- mod.__file__.endswith('.py') or
- mod.__file__.endswith('.pyo')):
- return True
- if mod.__file__.endswith('*.py'): # on top of PyPy, a mixed module
- return True
- return False
-
- def nameof_module(self, value):
- if value is os or self.is_module_builtin(value):
- return bltinmod_helper(self, value)
-
- # we might have createda reference to a module
- # that is non-standard.
-
- # SKIPPING
- return "space.w_None"
-
- # check whether we can import
- try:
- import value
- need_extra_path = False
- except ImportError:
- need_extra_path = True
- name = self.uniquename('mod_%s' % value.__name__)
- if need_extra_path:
- assert False
- ## self.initcode.append1('import pypy')
- ## self.initcode.append1('import sys')
- ## self.initcode.append1('import os')
- ## self.initcode.append1('for pkgdir in pypy.__path__:\n'
- ## ' libdir = os.path.join(pkgdir, "lib")\n'
- ## ' if os.path.isdir(libdir):\n'
- ## ' break\n'
- ## 'else:\n'
- ## ' raise Exception, "cannot find pypy/lib directory"\n'
- ## 'sys.path.insert(0, libdir)\n')
- ## self.initcode.append1('try:\n'
- ## ' import %s as _tmp\n'
- ## 'finally:\n'
- ## ' if libdir in sys.path:\n'
- ## ' sys.path.remove(libdir)\n' % value.__name__)
- else:
- self.initcode.append1('import %s as _tmp' % value.__name__)
- self.initcode.append1('%s = space.wrap(_tmp)' % (name))
- return name
-
-
- def nameof_int(self, value):
- if value >= 0:
- name = 'gi_%d' % value
- else:
- # make sure that the type ident is completely described by
- # the prefixbefore the initial '_' for easy postprocessing
- name = 'gi_minus_%d' % abs(value)
- name = self.uniquename(name)
- self.initcode.append1('%s = space.wrap(%d)' % (name, value))
- return name
-
- def nameof_long(self, value):
- # assume we want them in hex most of the time
- if value < 256L:
- s = "%dL" % value
- else:
- s = "0x%08xL" % value
- if value >= 0:
- name = 'glong_%s' % s
- else:
- # mae sure that the type ident is completely described by
- # the prefix before the initial '_'
- name = 'glong_minus_%d' % abs(value)
- name = self.uniquename(name)
- # allow literally short longs only, meaning they
- # must fit into a machine word.
- if (sys.maxint*2+1)&value == value:
- self.initcode.append1('%s = space.wrap(%s) # XXX implement long!' % (name, s))
- else:
- long_helper(self, name, value)
- return name
-
- def nameof_float(self, value):
- name = 'gfloat_%s' % value
- name = (name.replace('-', 'minus')
- .replace('.', 'dot'))
- name = self.uniquename(name)
- # handle overflows
- if value != 0.0 and 2*value == value:
- self.initcode.append1('float_inf = 1e200\nfloat_inf *= float_inf')
- sign = '-+'[value >= 0]
- self.initcode.append('%s = space.wrap(%sfloat_inf)' % (name, sign))
- else:
- self.initcode.append('%s = space.wrap(%r)' % (name, value))
- return name
-
- def nameof_str(self, value):
- if [c for c in value if c<' ' or c>'~' or c=='"' or c=='\\']:
- # non-printable string
- namestr = repr(value)[1:-1]
- else:
- # printable string
- namestr = value
- if not namestr:
- namestr = "_emptystr_"
- name = self.uniquename('gs_' + namestr[:32])
- if len(value) < 30 and "\n" not in value:
- txt = '%s = space.new_interned_str(%r)' % (name, value)
- else:
- txt = render_docstr(value, '%s = space.new_interned_str(\n' % name, ')')
- txt = txt, # not splitted
- self.initcode.append(txt)
- return name
-
- def skipped_function(self, func):
- # debugging only! Generates a placeholder for missing functions
- # that raises an exception when called.
- name = self.uniquename('gskippedfunc_' + func.__name__)
- self.globaldecl.append('# global decl %s' % (name, ))
- self.initcode.append('# build func %s' % name)
- return name
-
- def skipped_class(self, cls):
- # debugging only! Generates a placeholder for missing classes
- # that raises an exception when called.
- name = self.uniquename('gskippedclass_' + cls.__name__)
- self.globaldecl.append('# global decl %s' % (name, ))
- self.initcode.append1('# build class %s' % name)
- return name
-
- def trans_funcname(self, s):
- return s.translate(C_IDENTIFIER)
-
- def nameof_function(self, func, namehint=''):
- if hasattr(func, 'geninterplevel_name'):
- return func.geninterplevel_name(self)
- if func.func_globals is None:
- # built-in functions on top of PyPy
- return self.nameof_builtin_function(func)
-
- printable_name = '(%s:%d) %s' % (
- self.trans_funcname(func.func_globals.get('__name__', '?')),
- func.func_code.co_firstlineno,
- func.__name__)
- if (func.func_doc and
- func.func_doc.lstrip().startswith('NOT_RPYTHON')):
- log.WARNING("skipped %s" % printable_name)
- return self.skipped_function(func)
- name = self.uniquename('gfunc_' + self.trans_funcname(
- namehint + func.__name__))
-
- positional, varargs, varkwds, defs = inspect.getargspec(func)
- if varargs is varkwds is defs is None:
- unwrap = ', '.join(['gateway.W_Root']*len(positional))
- interp_name = 'fastf_' + name[6:]
- else:
- unwrap = 'gateway.Arguments'
- interp_name = 'f_' + name[6:]
-
- self.initcode.append1('from pypy.interpreter import gateway')
- self.initcode.append1('%s = space.wrap(gateway.interp2app(%s, unwrap_spec=[gateway.ObjSpace, %s]))' %
- (name, interp_name, unwrap))
- self.pendingfunctions.append(func)
- return name
-
- def nameof_staticmethod(self, sm):
- # XXX XXX XXXX
- func = sm.__get__(42.5)
- name = self.uniquename('gsm_' + func.__name__)
- functionname = self.nameof(func)
- self.initcode.append1('%s = space.wrap(%s)' % (name, functionname))
- return name
-
- def nameof_instancemethod(self, meth):
- if (not hasattr(meth.im_func, 'func_globals') or
- meth.im_func.func_globals is None):
- # built-in methods (bound or not) on top of PyPy or possibly 2.4
- return self.nameof_builtin_method(meth)
- if meth.im_self is None:
- # no error checking here
- return self.nameof(meth.im_func, namehint="%s_" % meth.im_class.__name__)
- else:
- ob = self.nameof(meth.im_self)
- func = self.nameof(meth.im_func)
- typ = self.nameof(meth.im_class)
- name = self.uniquename('gmeth_' + meth.im_func.__name__)
- funcname = self.nameof(meth.im_func.__name__)
- self.initcode.append1(
- '%s = space.getattr(%s, %s)' % (name, ob, funcname))
- return name
-
- nameof_method = nameof_instancemethod # when run on top of PyPy
-
- def should_translate_attr(self, pbc, attr):
- ignore = getattr(pbc.__class__, 'NOT_RPYTHON_ATTRIBUTES', [])
- if attr in ignore:
- return False
- else:
- return "probably" # True
-
- def later(self, gen):
- self.latercode.append1((gen, self.debugstack))
-
- def nameof_instance(self, instance):
- klass = instance.__class__
- name = self.uniquename('ginst_' + klass.__name__)
- cls = self.nameof(klass)
- if hasattr(klass, '__base__'):
- base_class = builtin_base(instance)
- base = self.nameof(base_class)
- else:
- base_class = None
- base = cls
- def initinstance():
- content = instance.__dict__.items()
- content.sort()
- for key, value in content:
- if self.should_translate_attr(instance, key):
- try:
- yield 'space.setattr(%s, %s, %s)' % (
- name, self.nameof(key), self.nameof(value))
- except:
- log.ERROR("Problem while generating %s of %r" % (
- name, instance))
- raise
- self.initcode.append1("%s = space.call_method(%s, '__new__', %s)" % (
- name, cls, cls))
- self.later(initinstance())
- return name
-
- def space_arities(self):
- if self._space_arities is None:
- arities = self._space_arities = {}
- for name, sym, arity, specnames in self.space.MethodTable:
- arities[name] = arity
- del arities["isinstance"]
- return self._space_arities
-
- def try_space_shortcut_for_builtin(self, v, nargs, args):
- if isinstance(v, Constant) and v.value in self.ibuiltin_ids:
- name = self.ibuiltin_ids[v.value].__name__
- if (hasattr(self.space, name) and
- self.space_arities().get(name, -1) == nargs):
- return "space.%s" % name
- return None
-
- def nameof_builtin_function_or_method(self, func):
- if func.__self__ is None:
- return self.nameof_builtin_function(func)
- else:
- return self.nameof_builtin_method(func)
-
- def nameof_builtin_function(self, func):
- # builtin function
- if func in self.ibuiltin_ids:
- func = self.ibuiltin_ids[func]
- return "(space.builtin.get(space.str_w(%s)))" % self.nameof(func.__name__)
- # where does it come from? Python2.2 doesn't have func.__module__
- for modname, module in sys.modules.items():
- if not self.is_module_builtin(module):
- continue # skip non-builtin modules
- if func is getattr(module, func.__name__, None):
- break
- else:
- raise Exception, '%r not found in any built-in module' % (func,)
- #if modname == '__builtin__':
- # # be lazy
- # return "(space.builtin.get(space.str_w(%s)))" % self.nameof(func.__name__)
- if modname == 'sys':
- # be lazy
- return "(space.sys.get(space.str_w(%s)))" % self.nameof(func.__name__)
- else:
- name = self.uniquename('gbltin_' + func.__name__)
- self.initcode.append1('%s = space.getattr(%s, %s)' % (
- name, self.nameof(module), self.nameof(func.__name__)))
- return name
-
- def nameof_builtin_method(self, meth):
- try:
- im_self = meth.__self__
- except AttributeError:
- im_self = meth.im_self # on top of PyPy
- if im_self is None:
- # builtin unbound method (only on top of PyPy)
- name = self.nameof_wrapper_descriptor(meth)
- else:
- # builtin (bound) method
- name = self.uniquename('gbltinmethod_' + meth.__name__)
- self.initcode.append1('%s = space.getattr(%s, %s)' % (
- name, self.nameof(im_self), self.nameof(meth.__name__)))
- return name
-
- def nameof_classobj(self, cls):
- initcode = []
- printable_name = cls.__name__
- if cls.__doc__ and cls.__doc__.lstrip().startswith('NOT_RPYTHON'):
- #raise Exception, "%r should never be reached" % (cls,)
- log.WARNING("skipped class %s" % printable_name)
- return self.skipped_class(cls)
-
- metaclass = "space.w_type"
- name = self.uniquename('gcls_' + cls.__name__)
-
- if issubclass(cls, py.builtin.BaseException):
- # if cls.__module__ == 'exceptions':
- # don't rely on this, py.magic redefines AssertionError
- if getattr(__builtin__,cls.__name__,None) is cls:
- # exception are defined on the space
- return 'space.w_%s' % cls.__name__
-
- if not isinstance(cls, type):
- assert type(cls) is types.ClassType
- # do *not* change metaclass, but leave the
- # decision to what PyPy thinks is correct.
- # metaclass = 'space.w_classobj'
-
- basenames = [self.nameof(base) for base in cls.__bases__]
-
- def initclassobj():
- content = cls.__dict__.items()
- content.sort()
- for key, value in content:
- if key.startswith('__'):
- if key in ['__module__', '__doc__', '__dict__',
- '__weakref__', '__metaclass__', '__slots__',
- '__new__', '__del__']:
- continue
-
- # redirect value through class interface, in order to
- # get methods instead of functions.
- value = getattr(cls, key)
-
- if isinstance(value, staticmethod) and value.__get__(1) not in self.translator.flowgraphs and self.translator.frozen:
- log.WARNING("skipped staticmethod: %s" % value)
- continue
- if isinstance(value, MethodType) and value.im_self is cls:
- log.WARNING("skipped classmethod: %s" % value)
- continue
-
- yield 'space.setattr(%s, %s, %s)' % (
- name, self.nameof(key), self.nameof(value))
-
- baseargs = ", ".join(basenames)
- initcode.append('_dic = space.newdict()')
- for key, value in cls.__dict__.items():
- if key.startswith('__'):
- if key in ['__module__', '__metaclass__', '__slots__',
- '__new__', '__del__']:
- keyname = self.nameof(key)
- valname = self.nameof(value)
- initcode.append("space.setitem(_dic, %s, %s)" % (
- keyname, valname))
-
- if cls.__doc__ is not None:
- sdoc = self.nameof("__doc__")
- docobj = cls.__dict__["__doc__"]
- if type(docobj) in (str, unicode):
- docstr = render_docstr(cls, "_doc = space.wrap(", ")")
- initcode.append((docstr,)) # not splitted
- else:
- initcode.append("_doc = %s" % self.nameof(docobj) )
- initcode.append("space.setitem(_dic, %s, _doc)" % (sdoc,))
- cls_name = self.nameof(cls.__name__)
- for l in initcode:
- self.initcode.append(l)
- self.initcode.append1('_bases = space.newtuple([%(bases)s])\n'
- '_args = space.newtuple([%(name)s, _bases, _dic])\n'
- '%(klass)s = space.call(%(meta)s, _args)'
- % {"bases": baseargs,
- "klass": name,
- "name" : cls_name,
- "meta" : metaclass} )
-
- self.later(initclassobj())
- return name
-
- nameof_class = nameof_classobj # for Python 2.2
-
- typename_mapping = {
- object: 'space.w_object',
- int: 'space.w_int',
- long: 'space.w_long',
- bool: 'space.w_bool',
- list: 'space.w_list',
- tuple: 'space.w_tuple',
- dict: 'space.w_dict',
- str: 'space.w_str',
- float: 'space.w_float',
- slice: 'space.w_slice',
- types.InstanceType: (eval_helper, 'InstanceType', 'types.InstanceType'),
- type: 'space.w_type',
- complex: (eval_helper, 'complex', 'types.ComplexType'),
- unicode:'space.w_unicode',
- basestring: (eval_helper, 'basestring', 'basestring'),
- file: (eval_helper, 'file', 'file'),
- type(None): (eval_helper, 'NoneType', 'type(None)'),
- CodeType: (eval_helper, 'code', 'type((lambda:42).func_code)'),
- ModuleType: (eval_helper, 'ModuleType', 'types.ModuleType'),
- xrange: (eval_helper, 'xrange', 'xrange'),
-
- ##r_int: 'space.w_int',
- ##r_uint: 'space.w_int',
-
- type(len): (eval_helper, 'FunctionType', 'type(lambda:42)'),
- # type 'method_descriptor':
- # XXX small problem here:
- # XXX with space.eval, we get <W_TypeObject(method)>
- # XXX but with wrap, we get <W_TypeObject(instancemethod)>
- type(list.append): (eval_helper, "method_descriptor", "type(list.append)"),
- # type 'wrapper_descriptor':
- type(type(None).__repr__): (eval_helper, "wrapper_descriptor",
- "type(type(None).__repr__)"),
- # type 'getset_descriptor':
- # XXX here we get <W_TypeObject(FakeDescriptor)>,
- # while eval gives us <W_TypeObject(GetSetProperty)>
- type(type.__dict__['__dict__']): (eval_helper, "getset_descriptor",
- "type(type.__dict__[\'__dict__\'])"),
- # type 'member_descriptor':
- # XXX this does not work in eval!
- # type(type.__dict__['__basicsize__']): "cannot eval type(type.__dict__['__basicsize__'])",
- # XXX there seems to be no working support for member descriptors ???
- type(types.GeneratorType.gi_frame):
- (eval_helper, "member_descriptor", 'type(property.fdel)'),
- types.ClassType: 'space.w_classobj',
- types.MethodType: (eval_helper, "instancemethod",
- "type((lambda:42).__get__(42))"),
- type(Ellipsis): (eval_helper, 'EllipsisType', 'types.EllipsisType'),
- builtin_set: (eval_helper, "set", "set"),
- builtin_frozenset: (eval_helper, "frozenset", "frozenset"),
- buffer: (eval_helper, "buffer", "buffer"),
- }
-
- def nameof_type(self, cls):
- if cls in self.typename_mapping:
- ret = self.typename_mapping[cls]
- if type(ret) is tuple:
- ret = ret[0](self, ret[1], ret[2])
- return ret
- if issubclass(cls, py.builtin.BaseException): # Python 2.5 only
- # if cls.__module__ == 'exceptions':
- # don't rely on this, py.magic redefines AssertionError
- if getattr(__builtin__,cls.__name__,None) is cls:
- # exception are defined on the space
- return 'space.w_%s' % cls.__name__
- assert cls.__module__ != '__builtin__' or cls.__flags__&_HEAPTYPE, (
- "built-in class %r not found in typename_mapping "
- "while compiling %s" % (cls, self.currentfunc and
- self.currentfunc.__name__ or "*no function at all*"))
- return self.nameof_classobj(cls)
-
- def nameof_tuple(self, tup):
- name = self.uniquename('g%dtuple' % len(tup))
- args = [self.nameof(x) for x in tup]
- args = ', '.join(args)
- self.initcode.append1('%s = space.newtuple([%s])' % (name, args))
- return name
-
- def nameof_list(self, lis):
- name = self.uniquename('g%dlist' % len(lis))
- # note that self.latercode led to too late initialization.
- self.register_early(lis, name)
- # try to save at least one assignment.
- if lis and lis[0] is not lis:
- default = lis[0]
- else:
- default = None
- self.initcode.append('%s = space.newlist([%s])' % (name, self.nameof(default)))
- self.initcode.append('%s = space.mul(%s, %s)' % (name, name, self.nameof(len(lis))))
- for i in range(len(lis)):
- if lis[i] is not default:
- item = self.nameof(lis[i])
- self.initcode.append('space.setitem(%s, %s, %s);' % (
- name, self.nameof(i), item))
- return name
-
- def nameof_dict(self, dic):
- assert dic is not __builtins__
- name = self.uniquename('g%ddict' % len(dic))
- self.register_early(dic, name)
- self.initcode.append('%s = space.newdict()' % (name,))
- for k in dic:
- if k == '__builtins__':
- continue
- self.initcode.append('space.setitem(%s, %s, %s)'%(
- name, self.nameof(k), self.nameof(dic[k])))
- return name
-
- # strange prebuilt instances below, don't look too closely
- # XXX oh well.
- def nameof_member_descriptor(self, md):
- try:
- im_class = md.__objclass__
- except AttributeError:
- im_class = md.im_class # on top of PyPy
- name = self.uniquename('gdescriptor_%s_%s' % (
- im_class.__name__, md.__name__))
- cls = self.nameof(im_class)
- self.initcode.append1('%s = space.getattr(%s, %s)' %
- (name, cls, self.nameof(md.__name__)))
- return name
- nameof_getset_descriptor = nameof_member_descriptor
- nameof_method_descriptor = nameof_member_descriptor
- nameof_wrapper_descriptor = nameof_member_descriptor
-
- def nameof_property(self, prop):
- origin = prop.__doc__ # XXX quite a hack
- if not origin:
- raise ValueError("sorry, cannot build properties"
- " without a helper in __doc__")
- name = self.uniquename('gprop_' + origin)
- # property is lazy loaded app-level as well, trigger it*s creation
- self.initcode.append1('space.builtin.get("property") # pull it in')
- globname = self.nameof(self.moddict)
- self.initcode.append('space.setitem(%s, space.new_interned_str("__builtins__"), '
- 'space.builtin.w_dict)' % globname)
- self.initcode.append('%s = space.eval("property(%s)", %s, %s, hidden_applevel=True)' %(
- name, origin, globname, globname) )
- self.initcode.append('space.delitem(%s, space.new_interned_str("__builtins__"))'
- % globname)
- return name
-
- def nameof_file(self, fil):
- if fil is sys.stdin:
- return 'space.sys.get("stdin")'
- if fil is sys.stdout:
- return 'space.sys.get("stdout")'
- if fil is sys.stderr:
- return 'space.sys.get("stderr")'
- raise Exception, 'Cannot translate an already-open file: %r' % (fil,)
-
- def gen_source(self, fname, ftmpname=None, file=file):
- self.fname = fname
- self.ftmpname = ftmpname
-
- # generate unordered source file, first.
- # I prefer this over ordering everything in memory.
- fname = self.fname
- if self.ftmpname:
- fname = self.ftmpname
- f = file(fname, "w")
- # generate ordered source file
- try:
- self.f = f
- self.gen_source_temp()
- finally:
- f.close()
-
- def copyfile(source, target):
- f = file(source)
- data = f.read()
- f.close()
- f = file(target, "w")
- f.write(data)
- f.close()
-
- def order_sections(fname):
- sep = "\n##SECTION##\n"
- f = file(fname)
- txt = f.read()
- f.close()
- pieces = txt.split(sep)
- prelude = pieces.pop(0)
- postlude = pieces.pop()
- dic = {}
- while pieces:
- func = pieces.pop()
- head = pieces.pop()
- key = makekey(head, len(pieces))
- dic[key] = head + sep + func
- lis = dic.items()
- lis.sort()
- lis = [prelude] + [func for head, func in lis] + [postlude]
- txt = sep.join(lis)
- f = file(fname, "w")
- f.write(txt)
- f.close()
-
- def makekey(txt, uniqueno):
- dic = {}
- for line in txt.split("\n"):
- ign, name, value = line.split(None, 2)
- dic[name] = eval(value, {})
- key = (dic["filename"], dic["firstlineno"],
- dic["function"], uniqueno)
- return key
-
- order_sections(fname)
- if self.ftmpname:
- copyfile(self.ftmpname, self.fname)
-
- def gen_source_temp(self):
- f = self.f
-
- # header
- print >> f, self.RPY_HEADER
- print >> f
-
- info = {
- 'modname': self.modname,
- # the side-effects of this is kick-start the process
- 'entrypoint': None # self.nameof(self.entrypoint),
- }
- # header """def initmodule(space):"""
- print >> f, self.RPY_INIT_HEADER % info
-
- # doc
- if self.moddict and self.moddict.get("__doc__"):
- doc = self.moddict["__doc__"]
- print >> f, render_docstr(doc, " __doc__ = \\\n")
- print >> f
- # make sure it is not rendered again
- key = Constant(doc).key
- self.rpynames[key] = "w__doc__"
- self.initcode.append("w__doc__ = space.new_interned_str(__doc__)")
-
- # info.entrypoint must be done *after* __doc__ is handled,
- # because nameof(entrypoint) might touch __doc__ early.
- info["entrypoint"] = self.nameof(self.entrypoint)
-
- # function implementations
- while self.pendingfunctions or self.latercode:
- if self.pendingfunctions:
- func = self.pendingfunctions.pop()
- self.currentfunc = func
- self.gen_rpyfunction(func)
- # collect more of the latercode after each function
- while self.latercode:
- gen, self.debugstack = self.latercode.pop()
- #self.initcode.extend(gen) -- eats TypeError! bad CPython!
- for line in gen:
- self.initcode.append1(line)
- self.debugstack = ()
- self.gen_global_declarations()
-
- # set the final splitter
- print >> f, "##SECTION##"
- # footer, init code
- for codelines in self.initcode:
- # keep docstrings unindented
- indent = " "
- if type(codelines) is tuple:
- codelines = codelines[0].split("\n", 1)
- codelines[0] = indent + codelines[0]
- indent = ""
- else:
- codelines = codelines.split("\n")
- for codeline in codelines:
- print >> f, indent + codeline
-
- self.gen_trailer(info, " ")
- # do not close the file here!
-
- def gen_trailer(self, info, indent):
- if self.moddict:
- # we are generating a module, no __main__ etc.
- print >> self.f, indent + "return %s" % self.nameof(self.entrypoint)
- print >> self.f
- else:
- # we should have an entrypoint function
- info['entrypointname'] = self.trans_funcname(self.entrypoint.__name__)
- print >> self.f, self.RPY_INIT_FOOTER % info
-
- def gen_global_declarations(self):
- g = self.globaldecl
- if g:
- f = self.f
- print >> f, '# global declaration%s' % ('s'*(len(g)>1))
- for line in g:
- print >> f, line
- print >> f
- del g[:]
- g = self.globalobjects
- for name in g:
- pass # self.initcode.append1('# REGISTER_GLOBAL(%s)' % (name,))
- del g[:]
-
- def rel_filename(self, name):
- # try to find a name relative to pypy and unify.
- # if not possible, stick with the original.
- ref = py.path.local(pypy.__path__[0])
- rel = py.path.local(name).relto(ref)
- if rel:
- # make it os independent
- return rel.replace('\\', '/')
- return name # no success
-
- def getsignature(self, argnamelist, varargname, varkwname):
- key = (argnamelist, varargname, varkwname)
- try:
- return self._signature_cache[key]
- except KeyError:
- pass
- signame = self.uniquename('sig')
- self._signature_cache[key] = signame
- self.initcode.append("%s = gateway.Signature(%r, %r, %r)" % (
- signame, list(argnamelist), varargname, varkwname))
- return signame
-
- def getdefaults(self, names):
- key = tuple(names)
- try:
- return self._defaults_cache[key]
- except KeyError:
- pass
- defaultsname = self.uniquename('default')
- self._defaults_cache[key] = defaultsname
- self.initcode.append("%s = [%s]" % (defaultsname, ', '.join(names)))
- return defaultsname
-
- def gen_rpyfunction(self, func):
- try:
- graph = self.translator.buildflowgraph(func, True)
- except Exception, e:
- print 20*"*", e
- print func
- raise
- SSI_to_SSA(graph)
- checkgraph(graph)
-
- f = self.f
- print >> f, "##SECTION##" # simple to split, afterwards
- print >> f, ("## filename %r\n"
- "## function %r\n"
- "## firstlineno %d") % (
- self.rel_filename(func.func_code.co_filename),
- func.func_code.co_name,
- func.func_code.co_firstlineno)
- print >> f, "##SECTION##"
- localscope = self.namespace.localScope()
- body = list(self.rpyfunction_body(graph, localscope))
- name_of_defaults = [self.nameof(x, debug=('Default argument of', func))
- for x in (func.func_defaults or ())]
- self.gen_global_declarations()
-
- # print header
- docstr = render_docstr(func, " ")
- cname = self.nameof(func)
- assert cname.startswith('gfunc_')
- f_name = 'f_' + cname[6:]
-
- # collect all the arguments
- vararg = varkw = None
- varargname = varkwname = None
- all_args = graph.getargs()
- p = len(all_args)
- if func.func_code.co_flags & CO_VARKEYWORDS:
- p -= 1
- varkw = graph.getargs()[p]
- varkwname = func.func_code.co_varnames[p]
- if func.func_code.co_flags & CO_VARARGS:
- p -= 1
- vararg = graph.getargs()[p]
- varargname = func.func_code.co_varnames[p]
- positional_args = all_args[:p]
- argnamelist = func.func_code.co_varnames[:func.func_code.co_argcount]
-
- fast_args = [self.expr(a, localscope) for a in positional_args]
- if vararg is not None:
- vararg = self.expr(vararg, localscope)
- fast_args.append(vararg)
- if varkw is not None:
- varkw = self.expr(varkw, localscope)
- fast_args.append(varkw)
- fast_name = 'fast' + f_name
-
- fast_set = dict(zip(fast_args, fast_args))
-
- simple = (varargname is varkwname is None) and not name_of_defaults
-
- # create function declaration
- name = self.trans_funcname(func.__name__) # for <lambda>
- argstr = ", ".join(['space'] + fast_args)
- fast_function_header = (' def %s(%s):'
- % (name, argstr))
-
- def install_func(f_name, name):
- yield ''
- yield ' %s = %s' % (f_name, name)
- yield ' %s.__name__ = %r' % (f_name, f_name)
- #import __builtin__
- #dic = __builtin__.__dict__
- #if dic.get(name):
- # yield 'del %s # hiding a builtin!' % name
- #else:
- # self.initcode.append1('del m.%s' % (name,))
-
- def tupstr(seq):
- if len(seq) == 1:
- fmt = '%s,'
- else:
- fmt = '%s'
- return fmt % ', '.join(seq)
- def tupassstr(seq):
- if not seq:
- return ""
- else:
- return tupstr(seq) + " = "
-
- if not simple:
- print >> f, ' def %s(space, __args__):' % (name,)
- if docstr is not None:
- print >> f, docstr
- print >> f
-
- signame = self.getsignature(argnamelist, varargname, varkwname)
- defaultsname = self.getdefaults(name_of_defaults)
- print >> f, ' %s__args__.parse_obj(None, %r, %s, %s)' % (
- tupassstr(fast_args), func.__name__, signame, defaultsname)
- print >> f, ' return %s(%s)' % (fast_name,
- ', '.join(["space"]+fast_args))
-
- for line in install_func(f_name, name):
- print >> f, line
-
- print >> f
-
- print >> f, fast_function_header
- if docstr is not None:
- print >> f, docstr
-
- # print the body
- for line in body:
- print >> f, line
- for line in install_func("fast"+f_name, name):
- print >> f, line
- print >> f
-
- # print the PyMethodDef
- # skipped
-
-
- def rpyfunction_body(self, graph, localscope):
- start = graph.startblock
- allblocks = ordered_blocks(graph)
- nblocks = len(allblocks)
-
- blocknum = {}
- for block in allblocks:
- blocknum[block] = len(blocknum)+1
-
- yield " goto = %s # startblock" % self.mklabel(blocknum[start])
- yield " while True:"
-
- def render_block(block):
- catch_exception = block.exitswitch == c_last_exception
- regular_op = len(block.operations) - catch_exception
- # render all but maybe the last op
- for op in block.operations[:regular_op]:
- for line in self.oper(op, localscope).split("\n"):
- yield "%s" % line
- # render the last op if it is exception handled
- for op in block.operations[regular_op:]:
- yield "try:"
- for line in self.oper(op, localscope).split("\n"):
- yield " %s" % line
-
- if len(block.exits) == 0:
- if len(block.inputargs) == 2: # exc_cls, exc_value
- # exceptional return block
- exc_cls = self.expr(block.inputargs[0], localscope)
- exc_val = self.expr(block.inputargs[1], localscope)
- yield "raise %s(%s, %s)" % (self.nameof(OperationError),
- exc_cls, exc_val)
- else:
- # regular return block
- retval = self.expr(block.inputargs[0], localscope)
- yield "return %s" % retval
- return
- elif block.exitswitch is None:
- # single-exit block
- assert len(block.exits) == 1
- for op in self.gen_link(block.exits[0], localscope, blocknum, block):
- yield "%s" % op
- elif catch_exception:
- # block catching the exceptions raised by its last operation
- # we handle the non-exceptional case first
- link = block.exits[0]
- assert link.exitcase is None
- for op in self.gen_link(link, localscope, blocknum, block):
- yield " %s" % op
- # we must catch the exception raised by the last operation,
- # which goes to the last err%d_%d label written above.
- # Since we only have OperationError, we need to select:
- yield "except %s, e:" % (self.nameof(OperationError),)
- yield " e.normalize_exception(space)"
- q = "if"
- for link in block.exits[1:]:
- assert issubclass(link.exitcase, py.builtin.BaseException)
- # Exeption classes come unwrapped in link.exitcase
- yield " %s e.match(space, %s):" % (q,
- self.nameof(link.exitcase))
- q = "elif"
- for op in self.gen_link(link, localscope, blocknum, block, {
- link.last_exception: 'e.w_type',
- link.last_exc_value: 'e.get_w_value(space)'}):
- yield " %s" % op
- yield " else:raise # unhandled case, should not happen"
- else:
- # block ending in a switch on a value
- exits = list(block.exits)
- if len(exits) == 2 and (
- exits[0].exitcase is False and exits[1].exitcase is True):
- # order these guys like Python does
- exits.reverse()
- q = "if"
- for link in exits[:-1]:
- yield "%s %s == %s:" % (q, self.expr(block.exitswitch,
- localscope),
- link.exitcase)
- for op in self.gen_link(link, localscope, blocknum, block):
- yield " %s" % op
- q = "elif"
- link = exits[-1]
- yield "else:"
- for op in self.gen_link(exits[-1], localscope, blocknum, block):
- yield " %s" % op
-
- cmpop = ('==', 'is') [self.specialize_goto]
- for block in allblocks:
- blockno = blocknum[block]
- yield ""
- yield " if goto %s %s:" % (cmpop, self.mklabel(blockno))
- for line in render_block(block):
- yield " %s" % line
-
-# ____________________________________________________________
-
- RPY_HEADER = '''#!/bin/env python
-# -*- coding: LATIN-1 -*-'''
-
- RPY_SEP = "#*************************************************************"
-
- RPY_INIT_HEADER = RPY_SEP + '''
-__name__ = "_geninterp_"+%(modname)r
-_geninterp_ = True
-
-def init%(modname)s(space):
- """NOT_RPYTHON"""
-'''
-
- RPY_INIT_FOOTER = '''
-# entry point: %(entrypointname)s, %(entrypoint)s
-if __name__ == "__main__":
- from pypy.objspace.std import StdObjSpace
- from pypy.objspace.std.model import UnwrapError
- space = StdObjSpace()
- init%(modname)s(space)
- ret = space.call(%(entrypoint)s, space.newtuple([]))
- try:
- print space.unwrap(ret)
- except UnwrapError:
- print "cannot unwrap, here the wrapped result:"
- print ret
-'''
-
-# _____________________________________________________________________
-
-# implementation of the interface that is finally only
-# used: translate_as_module
-
-import py.code
-import cStringIO as StringIO
-
-class memfile(object):
- _storage = {}
- def __init__(self, name, mode="r"):
- if mode == "w":
- self._storage[name] = StringIO.StringIO()
- elif mode == "r":
- try:
- data = self._storage[name].getvalue()
- except IndexError:
- f = file(name)
- data = f.read()
- f.close()
- self._storage[name] = StringIO.StringIO(data)
- else:
- raise ValueError, "mode %s not supported" % mode
- self._file = self._storage[name]
- def __getattr__(self, name):
- return getattr(self._file, name)
- def close(self):
- pass
-
-def translate_as_module(sourcetext, filename=None, modname="app2interpexec",
- do_imports_immediately=False, tmpname=None):
- """ compile sourcetext as a module, translating to interp level.
- The result is the init function that creates the wrapped module dict,
- together with the generated source text.
- This init function needs a space as argument.
- tmpname can be passed for debugging purposes.
-
- Example:
-
- initfunc, newsrc = translate_as_module(text)
- from pypy.objspace.std import Space
- space = Space()
- dic = initfunc(space)
- # and now use the members of the dict
- """
- from pypy.tool.lib_pypy import LIB_PYPY
- # create something like a module
- if type(sourcetext) is str:
- code = py.code.Source(sourcetext).compile()
- else:
- # assume we got an already compiled source
- code = sourcetext
- dic = {'__name__': modname}
- if filename:
- dic['__file__'] = filename
-
- # XXX allow the app-level code to contain e.g. "import _formatting"
- libdir = str(LIB_PYPY)
- sys.path.insert(0, libdir)
- try:
- if faked_set:
- import __builtin__
- __builtin__.set = fake_set
- __builtin__.frozenset = fake_frozenset
- try:
- exec code in dic
- finally:
- if libdir in sys.path:
- sys.path.remove(libdir)
-
- entrypoint = dic
- t = TranslationContext(verbose=False, simplifying=True,
- builtins_can_raise_exceptions=True,
- list_comprehension_operations=False)
- t.no_annotator_but_do_imports_immediately = do_imports_immediately
- gen = GenRpy(t, entrypoint, modname, dic)
-
- finally:
- if faked_set:
- del __builtin__.set
- del __builtin__.frozenset
-
- if tmpname:
- _file = file
- else:
- _file = memfile
- tmpname = 'nada'
- out = _file(tmpname, 'w')
- gen.f = out
- try:
- if faked_set:
- import __builtin__
- __builtin__.set = fake_set
- __builtin__.frozenset = fake_frozenset
- gen.gen_source(tmpname, file=_file)
- finally:
- if faked_set:
- del __builtin__.set
- del __builtin__.frozenset
- out.close()
- f = _file(tmpname)
- newsrc = f.read()
- f.close()
- code = py.code.Source(newsrc).compile()
- dic = {}
- exec code in dic
- # now we just need to return the init function,
- # which then needs to be called with the space to return the dict.
- return dic['init%s' % modname], newsrc
-
-#___________________________________________________________________
-
-# some testing code
-
-testcode = """
-def f(a, b):
- return a + b
-
-def g():
- return f(f(1, 2), f(4, 8))
-"""
-
-if __name__ == '__main__':
- res = translate_as_module(testcode, tmpname='/tmp/look.py')
diff --git a/pypy/translator/gensupp.py b/pypy/translator/gensupp.py
--- a/pypy/translator/gensupp.py
+++ b/pypy/translator/gensupp.py
@@ -5,61 +5,6 @@
import sys
-from pypy.objspace.flow.model import Block
-
-# ordering the blocks of a graph by source position
-
-def ordered_blocks(graph):
- # collect all blocks
- allblocks = []
- for block in graph.iterblocks():
- # first we order by offset in the code string
- if block.operations:
- ofs = block.operations[0].offset
- else:
- ofs = sys.maxint
- # then we order by input variable name or value
- if block.inputargs:
- txt = str(block.inputargs[0])
- else:
- txt = "dummy"
- allblocks.append((ofs, txt, block))
- allblocks.sort()
- #for ofs, txt, block in allblocks:
- # print ofs, txt, block
- return [block for ofs, txt, block in allblocks]
-
-# a unique list, similar to a list.
-# append1 appends an object only if it is not there, already.
-
-class UniqueList(list):
- def __init__(self, *args, **kwds):
- list.__init__(self, *args, **kwds)
- self.dic = {}
-
- def append1(self, arg):
- try:
- self.dic[arg]
- except KeyError:
- self.dic[arg] = 1
- list.append(self, arg)
- except TypeError: # not hashable
- if arg not in self:
- list.append(self, arg)
-
-def builtin_base(obj):
- typ = type(obj)
- return builtin_type_base(typ)
-
-def builtin_type_base(typ):
- from copy_reg import _HEAPTYPE
- while typ.__flags__&_HEAPTYPE:
- typ = typ.__base__
- return typ
-
-def c_string(s):
- return '"%s"' % (s.replace('\\', '\\\\').replace('"', '\"'),)
-
def uniquemodulename(name, SEEN={}):
# never reuse the same module name within a Python session!
i = 0
diff --git a/pypy/translator/goal/targetpypystandalone.py b/pypy/translator/goal/targetpypystandalone.py
--- a/pypy/translator/goal/targetpypystandalone.py
+++ b/pypy/translator/goal/targetpypystandalone.py
@@ -242,7 +242,6 @@
filename = os.path.join(this_dir, 'app_main.py')
app = gateway.applevel(open(filename).read(), 'app_main.py', 'app_main')
app.hidden_applevel = False
- app.can_use_geninterp = False
w_dict = app.getwdict(space)
entry_point = create_entry_point(space, w_dict)
diff --git a/pypy/translator/goal/win32/gc_patch_windows.py b/pypy/translator/goal/win32/gc_patch_windows.py
--- a/pypy/translator/goal/win32/gc_patch_windows.py
+++ b/pypy/translator/goal/win32/gc_patch_windows.py
@@ -1,6 +1,9 @@
# patches for the Boehm GC for PyPy under Windows
"""
+This file is obsolete now since gc-7.0 / gc-7.1 .
+Please use the instructions in pypy\doc\windows.rst .
+
How to build a pypy compatible version of the Boehm collector
for Windows and Visual Studio .net 2003.
diff --git a/pypy/translator/oosupport/test_template/overflow.py b/pypy/translator/oosupport/test_template/overflow.py
--- a/pypy/translator/oosupport/test_template/overflow.py
+++ b/pypy/translator/oosupport/test_template/overflow.py
@@ -3,9 +3,12 @@
class BaseTestOverflow:
- def check(self, fn, args):
+ def check(self, fn, args, expected=None):
res1 = self.interpret(fn, args)
- res2 = fn(*args)
+ if expected is not None:
+ res2 = expected
+ else:
+ res2 = fn(*args)
assert res1 == res2
def test_add(self):
@@ -63,7 +66,9 @@
return ovfcheck(x % y)
except OverflowError:
return 42
- self.check(fn, [-sys.maxint-1, -1])
+ # force the expected result to be 42, because direct run of ovfcheck()
+ # cannot detect this particular overflow case
+ self.check(fn, [-sys.maxint-1, -1], expected=42)
def test_div(self):
def fn(x, y):
diff --git a/pypy/translator/platform/__init__.py b/pypy/translator/platform/__init__.py
--- a/pypy/translator/platform/__init__.py
+++ b/pypy/translator/platform/__init__.py
@@ -272,8 +272,12 @@
else:
host_factory = OpenBSD_64
elif os.name == 'nt':
- from pypy.translator.platform.windows import Windows
- host_factory = Windows
+ from pypy.translator.platform.windows import Windows, Windows_x64
+ import platform
+ if platform.architecture()[0] == '32bit':
+ host_factory = Windows
+ else:
+ host_factory = Windows_x64
else:
# pray
from pypy.translator.platform.distutils_platform import DistutilsPlatform
diff --git a/pypy/translator/platform/windows.py b/pypy/translator/platform/windows.py
--- a/pypy/translator/platform/windows.py
+++ b/pypy/translator/platform/windows.py
@@ -11,15 +11,24 @@
if cc == 'mingw32':
return MingwPlatform(cc)
else:
- return MsvcPlatform(cc)
+ return MsvcPlatform(cc, False)
+
+def Windows_x64(cc=None):
+ return MsvcPlatform(cc, True)
-def _get_msvc_env(vsver):
+def _get_msvc_env(vsver, x64flag):
try:
toolsdir = os.environ['VS%sCOMNTOOLS' % vsver]
except KeyError:
return None
- vcvars = os.path.join(toolsdir, 'vsvars32.bat')
+ if x64flag:
+ vsinstalldir = os.path.abspath(os.path.join(toolsdir, '..', '..'))
+ vcinstalldir = os.path.join(vsinstalldir, 'VC')
+ vcbindir = os.path.join(vcinstalldir, 'BIN')
+ vcvars = os.path.join(vcbindir, 'amd64', 'vcvarsamd64.bat')
+ else:
+ vcvars = os.path.join(toolsdir, 'vsvars32.bat')
import subprocess
popen = subprocess.Popen('"%s" & set' % (vcvars,),
@@ -42,21 +51,21 @@
## log.msg("Updated environment with %s" % (vcvars,))
return env
-def find_msvc_env():
+def find_msvc_env(x64flag=False):
# First, try to get the compiler which served to compile python
msc_pos = sys.version.find('MSC v.')
if msc_pos != -1:
msc_ver = int(sys.version[msc_pos+6:msc_pos+10])
# 1300 -> 70, 1310 -> 71, 1400 -> 80, 1500 -> 90
vsver = (msc_ver / 10) - 60
- env = _get_msvc_env(vsver)
+ env = _get_msvc_env(vsver, x64flag)
if env is not None:
return env
# Then, try any other version
for vsver in (100, 90, 80, 71, 70): # All the versions I know
- env = _get_msvc_env(vsver)
+ env = _get_msvc_env(vsver, x64flag)
if env is not None:
return env
@@ -64,13 +73,14 @@
log.error("Could not find a Microsoft Compiler")
# Assume that the compiler is already part of the environment
-msvc_compiler_environ = find_msvc_env()
+msvc_compiler_environ32 = find_msvc_env(False)
+msvc_compiler_environ64 = find_msvc_env(True)
class MsvcPlatform(Platform):
name = "msvc"
so_ext = 'dll'
exe_ext = 'exe'
-
+
relevant_environ = ('PATH', 'INCLUDE', 'LIB')
cc = 'cl.exe'
@@ -81,8 +91,13 @@
standalone_only = ()
shared_only = ()
environ = None
-
+
def __init__(self, cc=None, x64=False):
+ self.x64 = x64
+ if x64:
+ msvc_compiler_environ = msvc_compiler_environ64
+ else:
+ msvc_compiler_environ = msvc_compiler_environ32
Platform.__init__(self, 'cl.exe')
if msvc_compiler_environ:
self.c_environ = os.environ.copy()
@@ -288,7 +303,10 @@
('CC_LINK', self.link),
('LINKFILES', eci.link_files),
('MASM', self.masm),
+ ('_WIN32', '1'),
]
+ if self.x64:
+ definitions.append(('_WIN64', '1'))
for args in definitions:
m.definition(*args)
diff --git a/pypy/translator/test/snippet.py b/pypy/translator/test/snippet.py
--- a/pypy/translator/test/snippet.py
+++ b/pypy/translator/test/snippet.py
@@ -648,48 +648,6 @@
return result
-# specifically for geninterp testing
-
-def t_isinstance(x, y):
- return isinstance(x, (int, long)) and isinstance(y, int)
-
-def t_issubclass(x, y):
- return issubclass(type(x), (int, long)) and issubclass(type(y), int)
-
-def t_neg_long():
- return -132L
-
-def t_attrerror(x):
- try:
- return x.foobar
- except AttributeError:
- return 567
-
-
-class Exc(Exception):
- def __init__(self, v):
- Exception.__init__(self, v)
-
-def exception_subclass_sanity(x):
- try:
- raise Exc(x)
- except Exception, e:
- return e.args[0]
-
-
-class HaveProp(object):
-
- def __init__(self, v):
- self.v = v
-
- def _hi(self):
- return self.v
- hi = property(_hi, doc="HaveProp._hi")
-
-
-def run_prop(v):
- return HaveProp(v).hi
-
# --------------------(Currently) Non runnable Functions ---------------------
def _somebug1(n=int):
diff --git a/pypy/translator/test/test_geninterp.py b/pypy/translator/test/test_geninterp.py
deleted file mode 100644
--- a/pypy/translator/test/test_geninterp.py
+++ /dev/null
@@ -1,310 +0,0 @@
-"""
-Description
-_____________________________
-
-This test is almost a copy of test_genc.py
-The setup code is slightly different:
-Instead of compiling single functions from
-snippets.py, almost all of snippets is translated,
-up to the point where they are untranslatable.
-snippets has been slightly re-ordered for that.
-
-The idea was to create a couple of tests without much
-extra work, in a sense derived from the test_genc.
-
-A problem with that is, that the tests actually should
-be run at application level. The test code checks real
-Python values,so we have to do tricks to unwrap things.
-This is limited:
-Some tests cannot work, since they mutate their arguments.
-Some tests operate with un-unwrappable things.
-Those are disabled for the moment by an 'needapp_' prefix.
-
-XXX think about a way to produce more tests from a common
-XXX basis. Should we write generators for such tests like this?
-"""
-import autopath
-import py
-from pypy.tool.udir import udir
-from pypy.objspace.flow.model import *
-from pypy.translator.geninterplevel import translate_as_module
-from pypy.translator.test import snippet
-from pypy.interpreter.error import OperationError
-from py.code import Source
-
-class TestGenRpyTestCase:
- objspacename = 'std'
-
- snippet_ad = """if 1:
- def import_func():
- import copy_reg
- return copy_reg._reconstructor.func_code.co_name
-
- def import_sys_func():
- import sys
- return sys.__name__
-
- def unicode_test(x):
- return unicode(x, 'ascii')
-"""
-
- def setup_class(cls):
- # simply compile snippets just once
- src = str(Source(snippet))
- # truncate non-compilable stuff for now:
- p = src.index('Non compilable Functions')
- src = src[:p] + '\n'
- # put our ad into snippet
- exec cls.snippet_ad in snippet.__dict__
- src += cls.snippet_ad
- # just in case of trouble, we produce a tempfile
- ini, newsrc = translate_as_module(src, tmpname = str(
- udir.join("_geninterp_test.py")))
- cls.w_glob = ini(cls.space)
-
- def build_interpfunc(self, func, *morefuncs):
- # we ignore morefuncs, since they live in snippets
- space = self.space
- func = space.getitem(self.w_glob, space.wrap(func.__name__))
- def wrapunwrap(*args):
- w_args = space.wrap(args)
- try:
- w_res = space.call(func, w_args)
- except OperationError, e:
- w_typ = e.w_type
- # XXX how to unwrap an exception?
- name = space.unwrap(space.getattr(w_typ, space.wrap('__name__')))
- exc = __builtins__[name]
- raise exc
- return space.unwrap(w_res)
- return wrapunwrap
-
- # small addition to see whether imports look fine
- def test_import(self):
- import copy_reg
- impfunc = self.build_interpfunc(snippet.import_func)
- assert impfunc() == '_reconstructor'
-
- def test_import_sys(self):
- impfunc = self.build_interpfunc(snippet.import_sys_func)
- assert impfunc() == 'sys'
-
- def test_simple_func(self):
- cfunc = self.build_interpfunc(snippet.simple_func)
- assert cfunc(1) == 2
-
- def test_while_func(self):
- while_func = self.build_interpfunc(snippet.while_func)
- assert while_func(10) == 55
-
- def test_nested_whiles(self):
- nested_whiles = self.build_interpfunc(snippet.nested_whiles)
- assert nested_whiles(111, 114) == (
- '...!...!...!...!...!')
-
- def test_poor_man_range(self):
- poor_man_range = self.build_interpfunc(snippet.poor_man_range)
- assert poor_man_range(10) == range(10)
-
- def poor_man_rev_range(self):
- poor_man_rev_range = self.build_interpfunc(snippet.poor_man_rev_range)
- assert poor_man_rev_range(10) == range(9,-1,-1)
-
- def test_simple_id(self):
- #we just want to see, if renaming of parameter works correctly
- #if the first branch is the end branch
- simple_id = self.build_interpfunc(snippet.simple_id)
- assert simple_id(9) == 9
-
- def test_branch_id(self):
- branch_id = self.build_interpfunc(snippet.branch_id)
- assert branch_id(1, 2, 3) == 2
- assert branch_id(0, 2, 3) == 3
-
- def test_int_id(self):
- int_id = self.build_interpfunc(snippet.int_id)
- assert int_id(3) == 3
-
- def dont_test_attrs(self):
- attrs = self.build_interpfunc(snippet.attrs)
- assert attrs() == 9
-
- def test_builtinusage(self):
- fun = self.build_interpfunc(snippet.builtinusage)
- assert fun() == 4
-
- def xpensive_test_sieve(self):
- sieve = self.build_interpfunc(snippet.sieve_of_eratosthenes)
- assert sieve() == 1028
-
- def test_slice(self):
- half = self.build_interpfunc(snippet.half_of_n)
- assert half(10) == 5
-
- def test_poly_branch(self):
- poly_branch = self.build_interpfunc(snippet.poly_branch)
- assert poly_branch(10) == [1,2,3]*2
- assert poly_branch(0) == ['a','b','c']*2
-
- def test_and(self):
- sand = self.build_interpfunc(snippet.s_and)
- assert sand(5, 6) == "yes"
- assert sand(5, 0) == "no"
- assert sand(0, 6) == "no"
- assert sand(0, 0) == "no"
-
- def test_yast(self):
- yast = self.build_interpfunc(snippet.yast)
- assert yast([1000,100,10,1]) == 1111
- assert yast(range(100)) == (99*100)/2
-
- def test_with_init(self):
- with_init = self.build_interpfunc(snippet.with_init)
- assert with_init(0) == 0
- assert with_init(-100) == -100
-
- def test_with_more_init(self):
- with_more_init = self.build_interpfunc(snippet.with_more_init)
- assert with_more_init(10, False) == -10
- assert with_more_init(20, True) == 20
-
- def needapp_test_global_instance(self):
- global_instance = self.build_interpfunc(snippet.global_instance)
- assert global_instance() == 42
-
- def needapp_test_global_newstyle_instance(self):
- global_newstyle_instance = self.build_interpfunc(snippet.global_newstyle_instance)
- assert global_newstyle_instance().a == 1
-
- def needapp_test_global_recursive_list(self):
- global_recursive_list = self.build_interpfunc(snippet.global_recursive_list)
- lst = global_recursive_list()
- assert len(lst) == 1
- assert lst[0] is lst
-
-## def test_global_badinit(self):
-## global_badinit = self.build_interpfunc(snippet.global_badinit)
-## self.assertEquals(global_badinit(), 1)
-
- def test_multiple_inheritance(self):
- multiple_inheritance = self.build_interpfunc(snippet.multiple_inheritance)
- assert multiple_inheritance() == 1+2+3+4
-
- def test_call_star_args0(self):
- call_star_args = self.build_interpfunc(snippet.call_star_args0)
- assert call_star_args(42) == 21
-
- def test_call_star_args1(self):
- call_star_args = self.build_interpfunc(snippet.call_star_args1)
- assert call_star_args(30) == 40
-
- def test_call_star_args1def(self):
- call_star_args = self.build_interpfunc(snippet.call_star_args1def)
- assert call_star_args(7) == 45
-
- def test_call_star_args(self):
- call_star_args = self.build_interpfunc(snippet.call_star_args)
- assert call_star_args(42) == 52
-
- def test_call_default_args(self):
- call_default_args = self.build_interpfunc(snippet.call_default_args)
- assert call_default_args(42) == 111+42+3
-
- def test_call_default_and_star_args(self):
- call_default_and_star_args = self.build_interpfunc(
- snippet.call_default_and_star_args)
- assert call_default_and_star_args(42) == (
- (111+42+3+0, -1000-2000-3000+2))
-
- def test_call_with_star(self):
- call_with_star = self.build_interpfunc(snippet.call_with_star)
- assert call_with_star(()) == -15L
- assert call_with_star((4,)) == -13L
- assert call_with_star((4,7)) == -9L
- assert call_with_star([]) == -15L
- assert call_with_star([4]) == -13L
- assert call_with_star([4,7]) == -9L
- raises(TypeError, call_with_star, (4,7,12))
- raises(TypeError, call_with_star, [4,7,12,63])
- raises(TypeError, call_with_star, 521)
-
- def test_call_with_keyword(self):
- call_with_keyword = self.build_interpfunc(snippet.call_with_keyword)
- assert call_with_keyword(100) == 82
-
- def test_call_very_complex(self):
- call_very_complex = self.build_interpfunc(snippet.call_very_complex,
- snippet.default_args)
- assert call_very_complex(5, (3,), {}) == -12
- assert call_very_complex(5, (), {'y': 3}) == -12
- raises(TypeError, call_very_complex, 5, (3,), {'y': 4})
-
- def test_finallys(self):
- finallys = self.build_interpfunc(snippet.finallys)
- assert finallys(['hello']) == 8
- assert finallys('X') == 8
- assert finallys([]) == 6
- assert finallys('XY') == 6
-
- def needapp_test_finally2(self):
- finally2 = self.build_interpfunc(snippet.finally2)
- lst = range(10)
- finally2(lst, 5)
- assert lst == [0,1,2,3,4, 6, 6,7,8, 'done']
- dic = {}
- raises(KeyError, finally2, dic, "won't find this key")
- assert dic == {-1: 'done'}
-
- def test_bare_raise(self):
- bare_raise = self.build_interpfunc(snippet.bare_raise)
- assert bare_raise(range(0, 100, 10), False) == 50
- assert bare_raise(range(0, 100, 10), True) == 50
- raises(IndexError, bare_raise, range(0, 30, 10), False)
- assert bare_raise(range(0, 30, 10), True) == None
-
- def needapp_test_get_set_del_slice(self):
- fn = self.build_interpfunc(snippet.get_set_del_slice)
- l = list('abcdefghij')
- result = fn(l)
- assert l == [3, 'c', 8, 11, 'h', 9]
- assert result == ([3, 'c'], [9], [11, 'h'])
-
- def test_do_try_raise_choose(self):
- fn = self.build_interpfunc(snippet.do_try_raise_choose)
- result = fn()
- assert result == [-1,0,1,2]
-
-
- def test_t_isinstance(self):
- fn = self.build_interpfunc(snippet.t_isinstance)
- result = fn(1, 2)
- assert result == True
-
- def test_t_issubclass(self):
- fn = self.build_interpfunc(snippet.t_issubclass)
- result = fn(1, 2)
- assert result == True
-
- def test_negative_long(self):
- fn = self.build_interpfunc(snippet.t_neg_long)
- result = fn()
- assert result == -132L and type(result) is long
-
- def test_unicode_with_encoding(self):
- fn = self.build_interpfunc(snippet.unicode_test)
- result = fn("abc")
- assert result == u"abc" and type(result) is unicode
-
- def test_attributeerror(self):
- fn = self.build_interpfunc(snippet.t_attrerror)
- result = fn(42)
- assert result == 567
-
- def test_Exception_subclass(self):
- fn = self.build_interpfunc(snippet.exception_subclass_sanity)
- result = fn(7)
- assert result == 7
-
- def test_property(self):
- fn = self.build_interpfunc(snippet.run_prop)
- assert fn(23) == 23
diff --git a/pypy/translator/test/test_rpystone.py b/pypy/translator/test/test_rpystone.py
deleted file mode 100644
--- a/pypy/translator/test/test_rpystone.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from pypy.translator.geninterplevel import translate_as_module, __file__ as __
-from pypy.objspace.std import Space
-import os
-fname = os.path.join(os.path.dirname(__), "test", "rpystone.py")
-src = file(fname).read()
-init, ign = translate_as_module(src)#, tmpname="/tmp/look.py")
-
-LOOPS = 25
-
-def test_rpystone():
- space = Space()
- modic = init(space)
- entry = space.getitem(modic, space.wrap("entrypoint"))
- # warm-up,to get everything translated
- space.call(entry, space.newtuple([space.wrap(-1)]))
- # now this is the real one
- space.call(entry, space.newtuple([space.wrap(LOOPS)]))
-
-if __name__ == "__main__":
- test_rpystone()
\ No newline at end of file
diff --git a/pypy/translator/tool/cbuild.py b/pypy/translator/tool/cbuild.py
--- a/pypy/translator/tool/cbuild.py
+++ b/pypy/translator/tool/cbuild.py
@@ -320,4 +320,13 @@
#define __XSI_VISIBLE 700
/* Windows: winsock/winsock2 mess */
#define WIN32_LEAN_AND_MEAN
+#ifdef _WIN64
+ typedef __int64 Signed;
+ typedef unsigned __int64 Unsigned;
+# define SIGNED_MIN LLONG_MIN
+#else
+ typedef long Signed;
+ typedef unsigned long Unsigned;
+# define SIGNED_MIN LONG_MIN
+#endif
'''
diff --git a/pypy/translator/translator.py b/pypy/translator/translator.py
--- a/pypy/translator/translator.py
+++ b/pypy/translator/translator.py
@@ -21,7 +21,6 @@
FLOWING_FLAGS = {
'verbose': False,
'simplifying': True,
- 'builtins_can_raise_exceptions': False,
'list_comprehension_operations': False, # True, - not super-tested
}
@@ -31,7 +30,6 @@
config = get_pypy_config(translating=True)
# ZZZ should go away in the end
for attr in ['verbose', 'simplifying',
- 'builtins_can_raise_exceptions',
'list_comprehension_operations']:
if attr in flowing_flags:
setattr(config.translation, attr, flowing_flags[attr])
More information about the pypy-commit
mailing list