Skip to content

_op_stack

Modified from https://gist.github.com/crusaderky/cf0575cfeeee8faa1bb1b3480bc4a87a, to remove all feature besides getting items from the top of the stack.

Frame

Bases: Structure

ctypes Structure (https://docs.python.org/3/library/ctypes.html#structures-and-unions) for a Python frame object, so we can access the top of the stack.

Source code in lineapy/system_tracing/_op_stack.py
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
class Frame(Structure):
    """
    ctypes Structure (https://docs.python.org/3/library/ctypes.html#structures-and-unions) for a Python frame
    object, so we can access the top of the stack.
    """

    if sys.version_info < (3, 10):
        _fields_: Tuple[Tuple[str, object], ...] = (
            ("ob_refcnt", c_ssize_t),
            ("ob_type", c_void_p),
            ("ob_size", c_ssize_t),
            ("f_back", c_void_p),
            ("f_code", c_void_p),
            ("f_builtins", POINTER(py_object)),
            ("f_globals", POINTER(py_object)),
            ("f_locals", POINTER(py_object)),
            ("f_valuestack", POINTER(py_object)),
            ("f_stacktop", POINTER(py_object)),
            ("f_trace", POINTER(py_object)),
        )
    else:
        _fields_: Tuple[Tuple[str, object], ...] = (
            ("ob_refcnt", c_ssize_t),
            ("ob_type", c_void_p),
            ("ob_size", c_ssize_t),
            ("f_back", c_void_p),
            ("f_code", c_void_p),
            ("f_builtins", POINTER(py_object)),
            ("f_globals", POINTER(py_object)),
            ("f_locals", POINTER(py_object)),
            ("f_valuestack", POINTER(py_object)),
            ("f_trace", POINTER(py_object)),
            ("f_stackdepth", c_int),
        )

OpStack

Only support negative access

Source code in lineapy/system_tracing/_op_stack.py
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
class OpStack:
    """
    Only support negative access
    """

    def __init__(self, frame: FrameType):
        self._frame = Frame.from_address(id(frame))
        if sys.version_info < (3, 10):
            stack_start_addr = c_ssize_t.from_address(
                id(frame) + F_VALUESTACK_OFFSET
            ).value
            stack_top_addr = c_ssize_t.from_address(
                id(frame) + F_STACKTOP_OFFSET
            ).value
            self._len = (stack_top_addr - stack_start_addr) // PTR_SIZE
        else:
            self._len = c_int.from_address(
                id(frame) + F_STACKDEPTH_OFFSET
            ).value

    def __getitem__(self, item: int) -> Any:
        if item < -self._len or item >= 0:
            raise IndexError(item)
        if item < 0:
            if sys.version_info < (3, 10):
                return self._frame.f_stacktop[item]
            else:
                return self._frame.f_valuestack[item + self._len]

Was this helpful?

Help us improve docs with your feedback!