File: callbuilder.py

package info (click to toggle)
pypy 5.6.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 97,040 kB
  • ctags: 185,069
  • sloc: python: 1,147,862; ansic: 49,642; cpp: 5,245; asm: 5,169; makefile: 529; sh: 481; xml: 232; lisp: 45
file content (104 lines) | stat: -rw-r--r-- 3,429 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
from rpython.rlib.clibffi import FFI_DEFAULT_ABI
from rpython.rlib import rgil
from rpython.rtyper.lltypesystem import lltype, rffi


class AbstractCallBuilder(object):

    # this is the calling convention (can be FFI_STDCALL on Windows)
    callconv = FFI_DEFAULT_ABI

    # is it for the main CALL of a call_release_gil?
    is_call_release_gil = False

    # this can be set to guide more complex calls: gives the detailed
    # type of the arguments
    argtypes = ""
    ressign = False


    def __init__(self, assembler, fnloc, arglocs, resloc, restype, ressize):
        self.fnloc = fnloc
        self.arglocs = arglocs
        self.asm = assembler
        self.mc = assembler.mc
        self.resloc = resloc
        self.restype = restype
        self.ressize = ressize

    def emit_no_collect(self):
        """Emit a call that cannot collect."""
        self.prepare_arguments()
        self.emit_raw_call()
        self.restore_stack_pointer()
        self.load_result()

    def emit(self):
        """Emit a regular call; not for CALL_RELEASE_GIL."""
        self.prepare_arguments()
        self.push_gcmap()
        self.emit_raw_call()
        self.restore_stack_pointer()
        self.pop_gcmap()
        self.load_result()

    def emit_call_release_gil(self, save_err):
        """Emit a CALL_RELEASE_GIL, including calls to releasegil_addr
        and reacqgil_addr.  'save_err' is a combination of rffi.RFFI_*ERR*."""
        fastgil = rffi.cast(lltype.Signed, rgil.gil_fetch_fastgil())
        self.select_call_release_gil_mode()
        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.read_real_errno(save_err)
        self.move_real_result_and_call_reacqgil_addr(fastgil)
        self.pop_gcmap()
        self.load_result()

    def call_releasegil_addr_and_move_real_arguments(self, fastgil):
        raise NotImplementedError

    def move_real_result_and_call_reacqgil_addr(self, fastgil):
        raise NotImplementedError

    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):
        """Overridden in CallBuilder64"""
        self.is_call_release_gil = True

    def prepare_arguments(self):
        raise NotImplementedError

    def push_gcmap(self):
        raise NotImplementedError

    def push_gcmap_for_call_release_gil(self):
        assert self.is_call_release_gil
        # we put the gcmap now into the frame before releasing the GIL,
        # and pop it after reacquiring the GIL.  The assumption
        # is that this gcmap describes correctly the situation at any
        # point in-between: all values containing GC pointers should
        # be safely saved out of registers by now, and will not be
        # manipulated by any of the following CALLs.
        gcmap = self.asm._regalloc.get_gcmap(noregs=True)
        self.asm.push_gcmap(self.mc, gcmap, store=True)

    def pop_gcmap(self):
        raise NotImplementedError

    def emit_raw_call(self):
        raise NotImplementedError

    def restore_stack_pointer(self):
        raise NotImplementedError

    def load_result(self):
        raise NotImplementedError