File: frameobject.py

package info (click to toggle)
pypy3 7.3.19%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 212,236 kB
  • sloc: python: 2,098,316; ansic: 540,565; sh: 21,462; asm: 14,419; cpp: 4,451; makefile: 4,209; objc: 761; xml: 530; exp: 499; javascript: 314; pascal: 244; lisp: 45; csh: 12; awk: 4
file content (137 lines) | stat: -rw-r--r-- 5,297 bytes parent folder | download | duplicates (2)
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
from rpython.rtyper.lltypesystem import rffi, lltype
from pypy.module.cpyext.api import (
    cpython_api, bootstrap_function, PyObjectFields, cpython_struct,
    CANNOT_FAIL, slot_function)
from pypy.module.cpyext.pyobject import (
    PyObject, decref, make_ref, from_ref, track_reference,
    make_typedescr, get_typedescr)
from pypy.module.cpyext.state import State
from pypy.module.cpyext.pystate import PyThreadState
from pypy.module.cpyext.funcobject import PyCodeObject
from pypy.interpreter.pyframe import PyFrame
from pypy.interpreter.pycode import PyCode
from pypy.interpreter.pytraceback import PyTraceback

PyFrameObjectStruct = lltype.ForwardReference()
PyFrameObject = lltype.Ptr(PyFrameObjectStruct)
PyFrameObjectFields = (PyObjectFields +
    (("f_code", PyCodeObject),
     ("f_globals", PyObject),
     ("f_locals", PyObject),
     ("f_lineno", rffi.INT),
     ("f_back", PyFrameObject),
     ))
cpython_struct("PyFrameObject", PyFrameObjectFields, PyFrameObjectStruct)

@bootstrap_function
def init_frameobject(space):
    make_typedescr(PyFrame.typedef,
                   basestruct=PyFrameObject.TO,
                   attach=frame_attach,
                   dealloc=frame_dealloc,
                   realize=frame_realize)

def frame_attach(space, py_obj, w_obj, w_userdata=None):
    "Fills a newly allocated PyFrameObject with a frame object"
    frame = space.interp_w(PyFrame, w_obj)
    py_frame = rffi.cast(PyFrameObject, py_obj)
    py_frame.c_f_code = rffi.cast(PyCodeObject, make_ref(space, frame.pycode))
    py_frame.c_f_globals = make_ref(space, frame.get_w_globals())
    py_frame.c_f_locals = make_ref(space, frame.get_w_locals())
    f_back = frame.get_f_back()
    if f_back:
        py_frame.c_f_back = rffi.cast(PyFrameObject, make_ref(space, f_back))
    else:
        py_frame.c_f_back = rffi.cast(PyFrameObject, 0)
    rffi.setintfield(py_frame, 'c_f_lineno', frame.getorcreatedebug().f_lineno)

@slot_function([PyObject], lltype.Void)
def frame_dealloc(space, py_obj):
    py_frame = rffi.cast(PyFrameObject, py_obj)
    py_code = rffi.cast(PyObject, py_frame.c_f_code)
    decref(space, py_code)
    decref(space, py_frame.c_f_globals)
    decref(space, py_frame.c_f_locals)
    decref(space, py_frame.c_f_back)
    from pypy.module.cpyext.object import _dealloc
    _dealloc(space, py_obj)

def frame_realize(space, py_obj):
    """
    Creates the frame in the interpreter. The PyFrameObject structure must not
    be modified after this call.
    """
    py_frame = rffi.cast(PyFrameObject, py_obj)
    py_code = rffi.cast(PyObject, py_frame.c_f_code)
    w_code = from_ref(space, py_code)
    code = space.interp_w(PyCode, w_code)
    w_globals = from_ref(space, py_frame.c_f_globals)

    frame = space.FrameClass(space, code, w_globals, outer_func=None)
    d = frame.getorcreatedebug()
    d.f_lineno = rffi.getintfield(py_frame, 'c_f_lineno')
    track_reference(space, py_obj, frame)
    return frame

@cpython_api([PyThreadState, PyCodeObject, PyObject, PyObject], PyFrameObject,
             result_is_ll=True)
def PyFrame_New(space, tstate, w_code, w_globals, w_locals):
    typedescr = get_typedescr(PyFrame.typedef)
    py_obj = typedescr.allocate(space, space.gettypeobject(PyFrame.typedef))
    py_frame = rffi.cast(PyFrameObject, py_obj)
    space.interp_w(PyCode, w_code) # sanity check
    py_frame.c_f_code = rffi.cast(PyCodeObject, make_ref(space, w_code))
    py_frame.c_f_globals = make_ref(space, w_globals)
    py_frame.c_f_locals = make_ref(space, w_locals)
    return py_frame

@cpython_api([PyFrameObject], rffi.INT_real, error=-1)
def PyTraceBack_Here(space, w_frame):
    from pypy.interpreter.pytraceback import record_application_traceback
    state = space.fromcache(State)
    if state.get_exception() is None:
        return -1
    frame = space.interp_w(PyFrame, w_frame)
    record_application_traceback(space, state.get_exception(), frame, 0)
    return 0

@cpython_api([PyObject], rffi.INT_real, error=CANNOT_FAIL)
def PyTraceBack_Check(space, w_obj):
    return isinstance(w_obj, PyTraceback)

@cpython_api([PyFrameObject], PyObject)
def PyFrame_GetGlobals(space, w_frame):
    frame = space.interp_w(PyFrame, w_frame)
    return frame.get_w_globals()

@cpython_api([PyFrameObject], PyObject)
def PyFrame_GetLocals(space, w_frame):
    frame = space.interp_w(PyFrame, w_frame)
    return frame.get_w_locals()

@cpython_api([PyFrameObject], PyObject)
def PyFrame_GetGenerator(space, w_frame):
    frame = space.interp_w(PyFrame, w_frame)
    return frame.get_generator()

@cpython_api([PyFrameObject], PyObject)
def PyFrame_GetBuiltins(space, w_frame):
    frame = space.interp_w(PyFrame, w_frame)
    return frame.fget_f_builtins(space)

@cpython_api([PyFrameObject], rffi.INT_real, error=-1)
def PyFrame_GetLasti(space, w_frame):
    frame = space.interp_w(PyFrame, w_frame)
    w_lasti = frame.fget_f_lasti(space)
    return space.int_w(w_lasti)

@cpython_api([PyFrameObject], rffi.INT_real, error=-1)
def PyFrame_GetLineNumber(space, w_frame):
    frame = space.interp_w(PyFrame, w_frame)
    return frame.get_last_lineno()

@cpython_api([PyThreadState], PyFrameObject)
def PyThreadState_GetFrame(space, tstate):
    ec = space.getexecutioncontext()
    caller = ec.gettopframe_nohidden()
    return caller