[pypy-commit] pypy default: Fix for stdcall.

arigo noreply at buildbot.pypy.org
Wed Aug 31 21:39:16 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r46960:df4c638240d8
Date: 2011-08-31 21:09 +0200
http://bitbucket.org/pypy/pypy/changeset/df4c638240d8/

Log:	Fix for stdcall.

diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -34,6 +34,7 @@
 from pypy.rlib.debug import (debug_print, debug_start, debug_stop,
                              have_debug_prints)
 from pypy.rlib import rgc
+from pypy.rlib.clibffi import FFI_DEFAULT_ABI
 from pypy.jit.backend.x86.jump import remap_frame_layout
 from pypy.jit.metainterp.history import ConstInt, BoxInt
 from pypy.jit.codewriter.effectinfo import EffectInfo
@@ -1120,7 +1121,7 @@
         return genop_cmp_guard_float
 
     def _emit_call(self, force_index, x, arglocs, start=0, tmp=eax,
-                   argtypes=None):
+                   argtypes=None, callconv=FFI_DEFAULT_ABI):
         if IS_X86_64:
             return self._emit_call_64(force_index, x, arglocs, start, argtypes)
 
@@ -1149,6 +1150,16 @@
         # x is a location
         self.mc.CALL(x)
         self.mark_gc_roots(force_index)
+        #
+        if callconv != FFI_DEFAULT_ABI:
+            self._fix_stdcall(callconv, p)
+
+    def _fix_stdcall(self, callconv, p):
+        from pypy.rlib.clibffi import FFI_STDCALL
+        assert callconv == FFI_STDCALL
+        # it's a bit stupid, but we're just going to cancel the fact that
+        # the called function just added 'p' to ESP, by subtracting it again.
+        self.mc.SUB_ri(esp.value, p)
 
     def _emit_call_64(self, force_index, x, arglocs, start, argtypes):
         src_locs = []
@@ -2127,7 +2138,8 @@
             tmp = eax
 
         self._emit_call(force_index, x, arglocs, 3, tmp=tmp,
-                        argtypes=op.getdescr().get_arg_types())
+                        argtypes=op.getdescr().get_arg_types(),
+                        callconv=op.getdescr().get_call_conv())
 
         if IS_X86_32 and isinstance(resloc, StackLoc) and resloc.width == 8:
             # a float or a long long return
diff --git a/pypy/jit/backend/x86/test/test_runner.py b/pypy/jit/backend/x86/test/test_runner.py
--- a/pypy/jit/backend/x86/test/test_runner.py
+++ b/pypy/jit/backend/x86/test/test_runner.py
@@ -439,20 +439,18 @@
         from pypy.jit.backend.x86.regloc import eax, edx
         from pypy.jit.backend.x86 import codebuf
         from pypy.jit.codewriter.effectinfo import EffectInfo
-        from pypy.rlib.libffi import types
-        from pypy.rlib.clibffi import FFI_DEFAULT_ABI
-        try:
-            from pypy.rlib.clibffi import FFI_STDCALL
-        except ImportError:
-            FFI_STDCALL = 12345     # not on Windows, but we can still test
-
-        for ffi in [FFI_DEFAULT_ABI, FFI_STDCALL]:
+        from pypy.rlib.libffi import types, clibffi
+        had_stdcall = hasattr(clibffi, 'FFI_STDCALL')
+        if not had_stdcall:    # not running on Windows, but we can still test
+            clibffi.FFI_STDCALL = 12345
+        #
+        for ffi in [clibffi.FFI_DEFAULT_ABI, clibffi.FFI_STDCALL]:
             cpu = self.cpu
             mc = codebuf.MachineCodeBlockWrapper()
             mc.MOV_rs(eax.value, 4)      # argument 1
             mc.MOV_rs(edx.value, 40)     # argument 10
             mc.SUB_rr(eax.value, edx.value)     # return arg1 - arg10
-            if ffi == FFI_DEFAULT_ABI:
+            if ffi == clibffi.FFI_DEFAULT_ABI:
                 mc.RET()
             else:
                 mc.RET16_i(40)
@@ -516,6 +514,9 @@
             assert self.cpu.get_latest_value_int(2) == 42
             assert self.cpu.get_latest_value_int(3) == 42
 
+        if not had_stdcall:
+            del clibffi.FFI_STDCALL
+
 
 class TestDebuggingAssembler(object):
     def setup_method(self, meth):


More information about the pypy-commit mailing list