[pypy-commit] pypy win_ffi: test, add WinDLL in _ffi

mattip noreply at buildbot.pypy.org
Fri Jun 1 15:25:37 CEST 2012


Author: Matti Picus <matti.picus at gmail.com>
Branch: win_ffi
Changeset: r55256:3dbd7782528b
Date: 2012-06-01 16:25 +0300
http://bitbucket.org/pypy/pypy/changeset/3dbd7782528b/

Log:	test, add WinDLL in _ffi

diff --git a/pypy/module/_ffi/__init__.py b/pypy/module/_ffi/__init__.py
--- a/pypy/module/_ffi/__init__.py
+++ b/pypy/module/_ffi/__init__.py
@@ -1,4 +1,5 @@
 from pypy.interpreter.mixedmodule import MixedModule
+import os
 
 class Module(MixedModule):
 
@@ -10,7 +11,8 @@
         '_StructDescr': 'interp_struct.W__StructDescr',
         'Field':     'interp_struct.W_Field',
     }
-
+    if os.name == 'nt':
+        interpleveldefs['WinDLL'] = 'interp_funcptr.W_WinDLL'
     appleveldefs = {
         'Structure': 'app_struct.Structure',
         }
diff --git a/pypy/module/_ffi/interp_funcptr.py b/pypy/module/_ffi/interp_funcptr.py
--- a/pypy/module/_ffi/interp_funcptr.py
+++ b/pypy/module/_ffi/interp_funcptr.py
@@ -9,6 +9,7 @@
 #
 from pypy.rlib import jit
 from pypy.rlib import libffi
+from pypy.rlib.clibffi import get_libc_name, StackCheckError
 from pypy.rlib.rdynload import DLOpenError
 from pypy.rlib.rarithmetic import intmask, r_uint
 from pypy.rlib.objectmodel import we_are_translated
@@ -59,7 +60,10 @@
         self = jit.promote(self)
         argchain = self.build_argchain(space, args_w)
         func_caller = CallFunctionConverter(space, self.func, argchain)
-        return func_caller.do_and_wrap(self.w_restype)
+        try:
+            return func_caller.do_and_wrap(self.w_restype)
+        except StackCheckError, e:
+            raise OperationError(space.w_ValueError, space.wrap(e.message))
         #return self._do_call(space, argchain)
 
     def free_temp_buffers(self, space):
@@ -254,6 +258,7 @@
 
 class W_CDLL(Wrappable):
     def __init__(self, space, name, mode):
+        self.flags = libffi.FUNCFLAG_CDECL
         self.space = space
         if name is None:
             self.name = "<None>"
@@ -271,7 +276,8 @@
                                                                    w_argtypes,
                                                                    w_restype)
         try:
-            func = self.cdll.getpointer(name, argtypes, restype)
+            func = self.cdll.getpointer(name, argtypes, restype, 
+                                            flags = self.flags)
         except KeyError:
             raise operationerrfmt(space.w_AttributeError,
                                   "No symbol %s found in library %s", name, self.name)
@@ -300,10 +306,26 @@
     getaddressindll = interp2app(W_CDLL.getaddressindll),
     )
 
+class W_WinDLL(W_CDLL):
+    def __init__(self, space, name, mode):
+        W_CDLL.__init__(self, space, name, mode)
+        self.flags = libffi.FUNCFLAG_STDCALL
+
+ at unwrap_spec(name='str_or_None', mode=int)
+def descr_new_windll(space, w_type, name, mode=-1):
+    return space.wrap(W_WinDLL(space, name, mode))
+
+
+W_WinDLL.typedef = TypeDef(
+    '_ffi.WinDLL',
+    __new__     = interp2app(descr_new_windll),
+    getfunc     = interp2app(W_WinDLL.getfunc),
+    getaddressindll = interp2app(W_WinDLL.getaddressindll),
+    )
+
 # ========================================================================
 
 def get_libc(space):
-    from pypy.rlib.clibffi import get_libc_name
     try:
         return space.wrap(W_CDLL(space, get_libc_name(), -1))
     except OSError, e:
diff --git a/pypy/module/_ffi/test/test_funcptr.py b/pypy/module/_ffi/test/test_funcptr.py
--- a/pypy/module/_ffi/test/test_funcptr.py
+++ b/pypy/module/_ffi/test/test_funcptr.py
@@ -93,7 +93,7 @@
 
     def test_getaddressindll(self):
         import sys
-        from _ffi import CDLL, types
+        from _ffi import CDLL
         libm = CDLL(self.libm_name)
         pow_addr = libm.getaddressindll('pow')
         fff = sys.maxint*2-1
@@ -102,7 +102,6 @@
         assert pow_addr == self.pow_addr & fff
 
     def test_func_fromaddr(self):
-        import sys
         from _ffi import CDLL, types, FuncPtr
         libm = CDLL(self.libm_name)
         pow_addr = libm.getaddressindll('pow')
@@ -566,3 +565,37 @@
             skip("unix specific")
         libnone = CDLL(None)
         raises(AttributeError, "libnone.getfunc('I_do_not_exist', [], types.void)")
+
+    def test_calling_convention1(self):
+        if not self.iswin32:
+            skip("windows specific")
+        from _ffi import WinDLL, types
+        libm = WinDLL(self.libm_name)
+        pow = libm.getfunc('pow', [types.double, types.double], types.double)
+        try:
+            pow(2, 3)
+        except ValueError, e:
+            assert e.message.startswith('Procedure called with')
+        else:
+            assert 0, 'test must assert, wrong calling convention'
+
+    def test_calling_convention2(self):
+        if not self.iswin32:
+            skip("windows specific")
+        from _ffi import WinDLL, types
+        kernel = WinDLL('Kernel32.dll')
+        sleep = kernel.getfunc('Sleep', [types.uint], types.void)
+        sleep(10)
+
+    def test_calling_convention3(self):
+        if not self.iswin32:
+            skip("windows specific")
+        from _ffi import CDLL, types
+        wrong_kernel = CDLL('Kernel32.dll')
+        wrong_sleep = wrong_kernel.getfunc('Sleep', [types.uint], types.void)
+        try:
+            wrong_sleep(10)
+        except ValueError, e:
+            assert e.message.startswith('Procedure called with')
+        else:
+            assert 0, 'test must assert, wrong calling convention'


More information about the pypy-commit mailing list