Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r46959:9dab2e7df18f Date: 2011-08-31 20:50 +0200 http://bitbucket.org/pypy/pypy/changeset/9dab2e7df18f/
Log: A test for the STDCALL calling convention, which runs also on non- windows (but 32-bits only). diff --git a/pypy/jit/backend/x86/rx86.py b/pypy/jit/backend/x86/rx86.py --- a/pypy/jit/backend/x86/rx86.py +++ b/pypy/jit/backend/x86/rx86.py @@ -527,6 +527,7 @@ NOP = insn('\x90') RET = insn('\xC3') + RET16_i = insn('\xC2', immediate(1, 'h')) PUSH_r = insn(rex_nw, register(1), '\x50') PUSH_b = insn(rex_nw, '\xFF', orbyte(6<<3), stack_bp(1)) 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 @@ -433,6 +433,90 @@ ops_offset[operations[2]] <= ops_offset[None]) + def test_calling_convention(self): + if WORD != 4: + py.test.skip("32-bit only test") + 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]: + 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: + mc.RET() + else: + mc.RET16_i(40) + rawstart = mc.materialize(cpu.asmmemmgr, []) + # + calldescr = cpu.calldescrof_dynamic([types.slong] * 10, + types.slong, + EffectInfo.MOST_GENERAL, + ffi_flags=-1) + calldescr.get_call_conv = lambda: ffi # <==== hack + funcbox = ConstInt(rawstart) + i1 = BoxInt() + i2 = BoxInt() + i3 = BoxInt() + i4 = BoxInt() + i5 = BoxInt() + i6 = BoxInt() + c = ConstInt(-1) + faildescr = BasicFailDescr(1) + # we must call it repeatedly: if the stack pointer gets increased + # by 40 bytes by the STDCALL call, and if we don't expect it, + # then we are going to get our stack emptied unexpectedly by + # several repeated calls + ops = [ + ResOperation(rop.CALL_RELEASE_GIL, + [funcbox, i1, c, c, c, c, c, c, c, c, i2], + i3, descr=calldescr), + ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), + + ResOperation(rop.CALL_RELEASE_GIL, + [funcbox, i1, c, c, c, c, c, c, c, c, i2], + i4, descr=calldescr), + ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), + + ResOperation(rop.CALL_RELEASE_GIL, + [funcbox, i1, c, c, c, c, c, c, c, c, i2], + i5, descr=calldescr), + ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), + + ResOperation(rop.CALL_RELEASE_GIL, + [funcbox, i1, c, c, c, c, c, c, c, c, i2], + i6, descr=calldescr), + ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), + + ResOperation(rop.FINISH, [i3, i4, i5, i6], None, + descr=BasicFailDescr(0)) + ] + ops[1].setfailargs([]) + ops[3].setfailargs([]) + ops[5].setfailargs([]) + ops[7].setfailargs([]) + looptoken = LoopToken() + self.cpu.compile_loop([i1, i2], ops, looptoken) + + self.cpu.set_future_value_int(0, 123450) + self.cpu.set_future_value_int(1, 123408) + fail = self.cpu.execute_token(looptoken) + assert fail.identifier == 0 + assert self.cpu.get_latest_value_int(0) == 42 + assert self.cpu.get_latest_value_int(1) == 42 + assert self.cpu.get_latest_value_int(2) == 42 + assert self.cpu.get_latest_value_int(3) == 42 + + class TestDebuggingAssembler(object): def setup_method(self, meth): self.cpu = CPU(rtyper=None, stats=FakeStats()) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit