Author: Christian Tismer <[email protected]>
Branch: win64 test
Changeset: r45358:f412af2f88c1
Date: 2011-07-05 18:53 +0200
http://bitbucket.org/pypy/pypy/changeset/f412af2f88c1/
Log: Making much progress with win64 and test_ll2ctypes. Compiler
configuration works with Visual Studio 8.
Checking in since there might be a problem in PyPy that is dependant
of the test selection both on 32 and 64 bit. test_arrayofstruct
seems to fail at assert a1[2].x == 102 result is always array[0]
which is 100. I will check the trunk first before reporting an
error.
diff --git a/pypy/rlib/rarithmetic.py b/pypy/rlib/rarithmetic.py
--- a/pypy/rlib/rarithmetic.py
+++ b/pypy/rlib/rarithmetic.py
@@ -33,24 +33,53 @@
"""
-import sys
+import sys, struct
from pypy.rpython import extregistry
from pypy.rlib import objectmodel
-# set up of machine internals, using sys.maxint only.
-# if sys.maxsize exists and is greater, it is used instead.
-_maxnumber = sys.maxint
-if hasattr(sys, "maxsize"):
- _maxnumber = max(sys.maxint, sys.maxsize)
-_bits = 1
-_test = _maxnumber
-while _test:
- _bits += 1
- _test >>= 1
+"""
+Long-term target:
+We want to make pypy very flexible concerning its data type layout.
+This is a larger task for later.
+
+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:
+is_emulated_long = _long_typecode <> 'l'
-LONG_BIT = _bits
+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)
@@ -107,8 +136,6 @@
r_class.BITS == LONG_BIT and r_class.SIGNED)
_should_widen_type._annspecialcase_ = 'specialize:memo'
-del _bits, _test, _maxnumber
-
def is_valid_int(r):
return -sys.maxint - 1 <= r <= sys.maxint
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
@@ -17,6 +17,7 @@
from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib.rstring import StringBuilder, UnicodeBuilder
from pypy.rpython.lltypesystem import llmemory
+from pypy.rlib.rarithmetic import LONG_BIT
import os, sys
class CConstant(Symbolic):
@@ -884,7 +885,7 @@
return 4
assert isinstance(tp, lltype.Number)
if tp is lltype.Signed:
- return ULONG._type.BITS/8
+ return LONG_BIT/8
return tp._type.BITS/8
sizeof._annspecialcase_ = 'specialize:memo'
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
@@ -15,7 +15,7 @@
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
+from pypy.rlib.rarithmetic import r_uint, get_long_pattern, is_emulated_long
if False: # for now, please keep it False by default
from pypy.rpython.lltypesystem import ll2ctypes
@@ -154,11 +154,6 @@
assert not ALLOCATED
def test_array_nolength(self):
- # XXX cannot fix this test when lltype.Signed is faked for win64.
- # Replacement with rffi.LONG does not work because then I cannot
- # index an array. So I have to use lltype.Signed . But the rffi.sizeof
- # at the end has a hard-coded mapping to LONG and ignores the faked
- # maxint. So what should I do?
A = lltype.Array(lltype.Signed, hints={'nolength': True})
a = lltype.malloc(A, 10, flavor='raw')
a[0] = 100
@@ -399,10 +394,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]
@@ -442,10 +436,15 @@
def dummy(n):
return n+1
- FUNCTYPE = lltype.FuncType([rffi.LONG], rffi.LONG)
+ 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)
@@ -479,13 +478,13 @@
export_symbols=['get_mul'])
get_mul = rffi.llexternal(
'get_mul', [],
- lltype.Ptr(lltype.FuncType([rffi.LONG], rffi.LONG)),
+ lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Signed)),
compilation_info=eci)
# This call returns a pointer to a function taking one argument
funcptr = get_mul()
# cast it to the "real" function type
- FUNCTYPE2 = lltype.FuncType([rffi.LONG, rffi.LONG],
- rffi.LONG)
+ FUNCTYPE2 = lltype.FuncType([lltype.Signed, lltype.Signed],
+ lltype.Signed)
cmul = rffi.cast(lltype.Ptr(FUNCTYPE2), funcptr)
# and it can be called with the expected number of arguments
res = cmul(41, 42)
@@ -502,12 +501,12 @@
lltype.Void)
lst = [23, 43, 24, 324, 242, 34, 78, 5, 3, 10]
- A = lltype.Array(rffi.LONG, hints={'nolength': True})
+ A = lltype.Array(lltype.Signed, hints={'nolength': True})
a = lltype.malloc(A, 10, flavor='raw')
for i in range(10):
a[i] = lst[i]
- SIGNEDPTR = lltype.Ptr(lltype.FixedSizeArray(rffi.LONG, 1))
+ SIGNEDPTR = lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1))
def my_compar(p1, p2):
p1 = rffi.cast(SIGNEDPTR, p1)
@@ -517,7 +516,7 @@
qsort(rffi.cast(rffi.VOIDP, a),
rffi.cast(rffi.SIZE_T, 10),
- rffi.cast(rffi.SIZE_T, llmemory.sizeof(rffi.LONG)),
+ rffi.cast(rffi.SIZE_T, llmemory.sizeof(lltype.Signed)),
llhelper(lltype.Ptr(CMPFUNC), my_compar))
for i in range(10):
@@ -545,8 +544,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),
@@ -563,7 +563,7 @@
assert not ALLOCATED # detects memory leaks in the test
def test_substructures(self):
- S1 = lltype.Struct('S1', ('x', rffi.LONG))
+ S1 = lltype.Struct('S1', ('x', lltype.Signed))
BIG = lltype.Struct('BIG', ('s1a', S1), ('s1b', S1))
s = lltype.malloc(BIG, flavor='raw')
s.s1a.x = 123
@@ -613,7 +613,7 @@
def test_recursive_struct(self):
SX = lltype.ForwardReference()
- S1 = lltype.Struct('S1', ('p', lltype.Ptr(SX)), ('x', rffi.LONG))
+ S1 = lltype.Struct('S1', ('p', lltype.Ptr(SX)), ('x', lltype.Signed))
SX.become(S1)
# a chained list
s1 = lltype.malloc(S1, flavor='raw')
@@ -691,7 +691,7 @@
assert not ALLOCATED # detects memory leaks in the test
def test_arrayofstruct(self):
- S1 = lltype.Struct('S1', ('x', rffi.LONG))
+ S1 = lltype.Struct('S1', ('x', lltype.Signed))
A = lltype.Array(S1, hints={'nolength': True})
a = lltype.malloc(A, 5, flavor='raw')
a[0].x = 100
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
@@ -253,8 +253,12 @@
else:
host_factory = Freebsd_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
@@ -12,14 +12,23 @@
return MingwPlatform(cc)
else:
return MsvcPlatform(cc)
+
+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,7 +73,8 @@
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"
@@ -80,7 +90,11 @@
shared_only = ()
environ = None
- def __init__(self, cc=None):
+ def __init__(self, cc=None, x64=False):
+ 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()
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit