Author: Armin Rigo <[email protected]>
Branch: errno-again
Changeset: r75338:1aeb4e18a1a3
Date: 2015-01-15 11:33 +0100
http://bitbucket.org/pypy/pypy/changeset/1aeb4e18a1a3/
Log: rffi.RFFI_READSAVED_ERRNO
diff --git a/rpython/jit/backend/llsupport/callbuilder.py
b/rpython/jit/backend/llsupport/callbuilder.py
--- a/rpython/jit/backend/llsupport/callbuilder.py
+++ b/rpython/jit/backend/llsupport/callbuilder.py
@@ -50,9 +50,10 @@
self.prepare_arguments()
self.push_gcmap_for_call_release_gil()
self.call_releasegil_addr_and_move_real_arguments(fastgil)
+ self.write_real_errno(save_err)
self.emit_raw_call()
self.restore_stack_pointer()
- self.save_errno(save_err)
+ self.read_real_errno(save_err)
self.move_real_result_and_call_reacqgil_addr(fastgil)
self.pop_gcmap()
self.load_result()
@@ -63,7 +64,10 @@
def move_real_result_and_call_reacqgil_addr(self, fastgil):
raise NotImplementedError
- def save_errno(self, save_err):
+ def write_real_errno(self, save_err):
+ raise NotImplementedError
+
+ def read_real_errno(self, save_err):
raise NotImplementedError
def select_call_release_gil_mode(self):
diff --git a/rpython/jit/backend/test/runner_test.py
b/rpython/jit/backend/test/runner_test.py
--- a/rpython/jit/backend/test/runner_test.py
+++ b/rpython/jit/backend/test/runner_test.py
@@ -2961,7 +2961,45 @@
assert result == 24 # not touched
def test_call_release_gil_readsaved_errno(self):
- XXX
+ from rpython.translator.tool.cbuild import ExternalCompilationInfo
+ from rpython.rlib.libffi import types
+ from rpython.jit.backend.llsupport import llerrno
+ #
+ eci = ExternalCompilationInfo(
+ separate_module_sources=[r'''
+ #include <stdio.h>
+ #include <errno.h>
+ RPY_EXPORTED int test_call_release_gil_readsaved_errno(void) {
+ int r = errno;
+ printf("read saved errno: %d\n", r);
+ return r;
+ }
+ '''])
+ fn_name = 'test_call_release_gil_readsaved_errno'
+ func1_ptr = rffi.llexternal(fn_name, [], rffi.INT,
+ compilation_info=eci, _nowrapper=True)
+ func1_adr = rffi.cast(lltype.Signed, func1_ptr)
+ calldescr = self.cpu._calldescr_dynamic_for_tests([], types.sint32)
+ #
+ for saveerr in [rffi.RFFI_READSAVED_ERRNO]:
+ faildescr = BasicFailDescr(1)
+ i1 = BoxInt()
+ ops = [
+ ResOperation(rop.CALL_RELEASE_GIL,
+ [ConstInt(saveerr), ConstInt(func1_adr)], i1,
+ descr=calldescr),
+ ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr),
+ ResOperation(rop.FINISH, [i1], None, descr=BasicFinalDescr(0))
+ ]
+ ops[-2].setfailargs([])
+ looptoken = JitCellToken()
+ self.cpu.compile_loop([], ops, looptoken)
+ #
+ llerrno.set_debug_saved_errno(self.cpu, 24)
+ deadframe = self.cpu.execute_token(looptoken)
+ result = self.cpu.get_int_value(deadframe, 0)
+ assert llerrno.get_debug_saved_errno(self.cpu) == 24
+ assert result == 24
def test_call_release_gil_zero_errno_before(self):
XXX
diff --git a/rpython/jit/backend/x86/callbuilder.py
b/rpython/jit/backend/x86/callbuilder.py
--- a/rpython/jit/backend/x86/callbuilder.py
+++ b/rpython/jit/backend/x86/callbuilder.py
@@ -149,7 +149,21 @@
if not we_are_translated(): # for testing: we should not access
self.mc.ADD(ebp, imm(1)) # ebp any more
- def save_errno(self, save_err):
+ def write_real_errno(self, save_err):
+ if save_err & rffi.RFFI_READSAVED_ERRNO:
+ # Just before a call, read 'rpy_errno' and write it into the
+ # real 'errno'. Most registers are free here, including the
+ # callee-saved ones, except 'ebx' and except the ones used to
+ # pass the arguments on x86-64.
+ rpy_errno = llerrno.get_rpy_errno_offset(self.asm.cpu)
+ p_errno = llerrno.get_p_errno_offset(self.asm.cpu)
+ mc = self.mc
+ mc.MOV_rs(eax.value, THREADLOCAL_OFS - self.current_esp)
+ mc.MOV_rm(edx.value, (eax.value, p_errno))
+ mc.MOV32_rm(eax.value, (eax.value, rpy_errno))
+ mc.MOV32_mr((edx.value, 0), eax.value)
+
+ def read_real_errno(self, save_err):
if save_err & rffi.RFFI_SAVE_ERRNO:
# Just after a call, read the real 'errno' and save a copy of
# it inside our thread-local 'rpy_errno'. Most registers are
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit