[pypy-svn] r55005 - in pypy/branch/win32port/pypy: lib lib/_ctypes module/_rawffi module/_rawffi/test rlib rlib/test

afa at codespeak.net afa at codespeak.net
Tue May 20 16:17:29 CEST 2008


Author: afa
Date: Tue May 20 16:17:22 2008
New Revision: 55005

Modified:
   pypy/branch/win32port/pypy/lib/_ctypes/builtin.py
   pypy/branch/win32port/pypy/lib/msvcrt.py
   pypy/branch/win32port/pypy/module/_rawffi/__init__.py
   pypy/branch/win32port/pypy/module/_rawffi/interp_rawffi.py
   pypy/branch/win32port/pypy/module/_rawffi/test/test__rawffi.py
   pypy/branch/win32port/pypy/rlib/libffi.py
   pypy/branch/win32port/pypy/rlib/rwin32.py
   pypy/branch/win32port/pypy/rlib/test/test_libffi.py
Log:
Maciej was right: it's better to dynamically get the name of the msvcrt library:
the same generated sources may be recompiled, e.g. in debug mode.

I hope I got it right: in pypy-c.exe, we compile a function that 
retrieves the dll containing the "fopen" pointer address.

Hardcoded "libc.so.6" on posix platforms.
There must be a better way.


Modified: pypy/branch/win32port/pypy/lib/_ctypes/builtin.py
==============================================================================
--- pypy/branch/win32port/pypy/lib/_ctypes/builtin.py	(original)
+++ pypy/branch/win32port/pypy/lib/_ctypes/builtin.py	Tue May 20 16:17:22 2008
@@ -5,8 +5,8 @@
     encoding = 'ascii'
     errors = 'strict'
 
-_memmove_addr = ('memmove', _rawffi.libc_name)
-_memset_addr = ('memset', _rawffi.libc_name)
+_memmove_addr = _rawffi.get_libc().getaddressindll('memmove')
+_memset_addr = _rawffi.get_libc().getaddressindll('memset')
 
 def _string_at_addr(addr, lgt):
     # address here can be almost anything

Modified: pypy/branch/win32port/pypy/lib/msvcrt.py
==============================================================================
--- pypy/branch/win32port/pypy/lib/msvcrt.py	(original)
+++ pypy/branch/win32port/pypy/lib/msvcrt.py	Tue May 20 16:17:22 2008
@@ -1,7 +1,15 @@
+"""
+Python interface to the Microsoft Visual C Runtime
+Library, providing access to those non-portable, but
+still useful routines.
+"""
+
+# XXX incomplete: implemented only functions needed by subprocess.py
+
 import _rawffi
 import ctypes
 
-_c = ctypes.CDLL(_rawffi.libc_name)
+_c = ctypes.CDLL('msvcrt', _rawffi.get_libc())
 
 open_osfhandle = _c._open_osfhandle
 open_osfhandle.argtypes = [ctypes.c_int, ctypes.c_int]
@@ -9,6 +17,6 @@
 
 get_osfhandle = _c._get_osfhandle
 get_osfhandle.argtypes = [ctypes.c_int]
-open_osfhandle.restype = ctypes.c_int
+get_osfhandle.restype = ctypes.c_int
 
 del ctypes

Modified: pypy/branch/win32port/pypy/module/_rawffi/__init__.py
==============================================================================
--- pypy/branch/win32port/pypy/module/_rawffi/__init__.py	(original)
+++ pypy/branch/win32port/pypy/module/_rawffi/__init__.py	Tue May 20 16:17:22 2008
@@ -25,6 +25,7 @@
         'charp2rawstring'    : 'interp_rawffi.charp2rawstring',
         'CallbackPtr'        : 'callback.W_CallbackPtr',
         '_num_of_allocated_objects' : 'tracker.num_of_allocated_objects',
+        'get_libc'           : 'interp_rawffi.get_libc',
     }
 
     appleveldefs = {
@@ -44,10 +45,6 @@
                      ]:
             if hasattr(libffi, name):
                 Module.interpleveldefs[name] = "space.wrap(%r)" % getattr(libffi, name)
-
-        # Name of C runtime library
-        from pypy.rpython.lltypesystem.ll2ctypes import get_libc_name
-        Module.interpleveldefs['libc_name'] = "space.wrap(%r)" % get_libc_name()
                 
         super(Module, cls).buildloaders()
     buildloaders = classmethod(buildloaders)

Modified: pypy/branch/win32port/pypy/module/_rawffi/interp_rawffi.py
==============================================================================
--- pypy/branch/win32port/pypy/module/_rawffi/interp_rawffi.py	(original)
+++ pypy/branch/win32port/pypy/module/_rawffi/interp_rawffi.py	Tue May 20 16:17:22 2008
@@ -468,3 +468,9 @@
             raise OperationError(space.w_WindowsError, space.wrap(hresult))
         return space.wrap(hresult)
     check_HRESULT.unwrap_spec = [ObjSpace, int]
+
+def get_libc(space):
+    try:
+        return space.wrap(W_CDLL(space, get_libc_name()))
+    except OSError, e:
+        raise wrap_oserror(space, e)

Modified: pypy/branch/win32port/pypy/module/_rawffi/test/test__rawffi.py
==============================================================================
--- pypy/branch/win32port/pypy/module/_rawffi/test/test__rawffi.py	(original)
+++ pypy/branch/win32port/pypy/module/_rawffi/test/test__rawffi.py	Tue May 20 16:17:22 2008
@@ -180,9 +180,13 @@
         import _rawffi
         _rawffi.CDLL(self.libc_name)
 
+    def test_libc_load(self):
+        import _rawffi
+        _rawffi.get_libc()
+
     def test_getattr(self):
         import _rawffi
-        libc = _rawffi.CDLL(self.libc_name)
+        libc = _rawffi.get_libc()
         func = libc.ptr('rand', [], 'i')
         assert libc.ptr('rand', [], 'i') is func # caching
         assert libc.ptr('rand', [], 'l') is not func
@@ -292,7 +296,7 @@
 
     def test_time(self):
         import _rawffi
-        libc = _rawffi.CDLL(self.libc_name)
+        libc = _rawffi.get_libc()
         time = libc.ptr('time', ['z'], 'l')  # 'z' instead of 'P' just for test
         arg = _rawffi.Array('P')(1)
         arg[0] = 0
@@ -306,7 +310,7 @@
         import _rawffi
         struct_type = _rawffi.Structure([('tv_sec', 'l'), ('tv_usec', 'l')])
         structure = struct_type()
-        libc = _rawffi.CDLL(self.libc_name)
+        libc = _rawffi.get_libc()
         gettimeofday = libc.ptr('gettimeofday', ['P', 'P'], 'i')
 
         arg1 = structure.byptr()
@@ -341,7 +345,7 @@
                                 ("tm_wday", 'i'),
                                 ("tm_yday", 'i'),
                                 ("tm_isdst", 'i')])
-        libc = _rawffi.CDLL(self.libc_name)
+        libc = _rawffi.get_libc()
         gmtime = libc.ptr('gmtime', ['P'], 'P')
 
         arg = x.byptr()
@@ -452,7 +456,7 @@
         skip("FIXME: compare actually receives a pair of int**")
         import _rawffi
         import struct
-        libc = _rawffi.CDLL(self.libc_name)
+        libc = _rawffi.get_libc()
         ll_to_sort = _rawffi.Array('i')(4)
         for i in range(4):
             ll_to_sort[i] = 4-i

Modified: pypy/branch/win32port/pypy/rlib/libffi.py
==============================================================================
--- pypy/branch/win32port/pypy/rlib/libffi.py	(original)
+++ pypy/branch/win32port/pypy/rlib/libffi.py	Tue May 20 16:17:22 2008
@@ -37,15 +37,31 @@
 else:
     libffidir = py.path.local(pypydir).join('translator', 'c', 'src', 'libffi_msvc')
     eci = ExternalCompilationInfo(
+        pre_include_lines = ['#define _WIN32_WINNT 0x501'],
         includes = ['ffi.h', 'windows.h'],
         libraries = ['kernel32'],
         include_dirs = [libffidir],
+        separate_module_sources = ['''
+        #include <stdio.h>
+
+        /* Get the module where the "fopen" function resides in */
+        HANDLE get_libc_handle() {
+            MEMORY_BASIC_INFORMATION  mi;
+            memset(&mi, 0, sizeof(mi));
+
+            if( !VirtualQueryEx(GetCurrentProcess(), &fopen, &mi, sizeof(mi)) )
+                return 0;
+
+            return (HMODULE)mi.AllocationBase;
+        }
+        '''],
         separate_module_files = [libffidir.join('ffi.c'),
                                  libffidir.join('prep_cif.c'),
                                  libffidir.join('win32.c'),
                                  libffidir.join('pypy_ffi.c'),
                                  ],
-        export_symbols = ['ffi_call', 'ffi_prep_cif', 'ffi_prep_closure'],
+        export_symbols = ['ffi_call', 'ffi_prep_cif', 'ffi_prep_closure',
+                          'get_libc_handle'],
         )
 
 FFI_TYPE_P = lltype.Ptr(lltype.ForwardReference())
@@ -193,6 +209,9 @@
         # XXX rffi.cast here...
         return res
 
+    def get_libc_name():
+        return 'libc.so.6'
+
 if _MS_WINDOWS:
     def dlopen(name):
         res = rwin32.LoadLibrary(name)
@@ -218,6 +237,12 @@
     FormatError = rwin32.FormatError
     LoadLibrary = rwin32.LoadLibrary
 
+    get_libc_handle = external('get_libc_handle', [], rwin32.HANDLE)
+
+    def get_libc_name():
+        return rwin32.GetModuleFileName(get_libc_handle())
+        
+
 FFI_OK = cConfig.FFI_OK
 FFI_BAD_TYPEDEF = cConfig.FFI_BAD_TYPEDEF
 FFI_DEFAULT_ABI = rffi.cast(rffi.USHORT, cConfig.FFI_DEFAULT_ABI)
@@ -518,3 +543,4 @@
 
     def getaddressindll(self, name):
         return dlsym(self.lib, name)
+

Modified: pypy/branch/win32port/pypy/rlib/rwin32.py
==============================================================================
--- pypy/branch/win32port/pypy/rlib/rwin32.py	(original)
+++ pypy/branch/win32port/pypy/rlib/rwin32.py	Tue May 20 16:17:22 2008
@@ -56,6 +56,7 @@
 if WIN32:
     HANDLE = rffi.ULONG
     LPHANDLE = rffi.CArrayPtr(HANDLE)
+    HMODULE = HANDLE
 
     GetLastError = winexternal('GetLastError', [], DWORD)
 
@@ -95,4 +96,16 @@
 
     def FAILED(hr):
         return rffi.cast(HRESULT, hr) < 0
-    
+
+    _GetModuleFileName = winexternal('GetModuleFileNameA',
+                                     [HMODULE, rffi.CCHARP, DWORD],
+                                     DWORD)
+
+    def GetModuleFileName(module):
+        size = 255 # MAX_PATH
+        buf = lltype.malloc(rffi.CCHARP.TO, size, flavor='raw')
+        res = _GetModuleFileName(module, buf, size)
+        if not res:
+            return ''
+        else:
+            return ''.join([buf[i] for i in range(res)])

Modified: pypy/branch/win32port/pypy/rlib/test/test_libffi.py
==============================================================================
--- pypy/branch/win32port/pypy/rlib/test/test_libffi.py	(original)
+++ pypy/branch/win32port/pypy/rlib/test/test_libffi.py	Tue May 20 16:17:22 2008
@@ -360,3 +360,11 @@
         del lib
 
         assert not ALLOCATED
+
+class TestWin32Handles:
+    def test_get_libc_handle(self):
+        handle = get_libc_handle()
+        print get_libc_name()
+        print hex(handle)
+        assert handle != 0
+        assert handle % 0x1000 == 0



More information about the Pypy-commit mailing list