Author: Christian Tismer <tis...@stackless.com>
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
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to