FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
cpython/Modules/_testinternalcapi/interpreter.c at 3.15 · python/cpython · GitHub
python
cpython
Repository navigation
Code
Issues
5k+
(5k+)
Pull requests
2.5k
(2.5k)
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
cpython
/
Modules
/
_testinternalcapi
/
interpreter.c
Copy path
More file actions
More file actions
Latest commit
History
History
History
161 lines (145 loc) · 5.28 KB
Breadcrumbs
cpython
/
Modules
/
_testinternalcapi
/
interpreter.c
Copy path
File metadata and controls
161 lines (145 loc) · 5.28 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#ifndef
Py_BUILD_CORE
#define
Py_BUILD_CORE
#endif
#ifndef
Py_BUILD_CORE_MODULE
#define
Py_BUILD_CORE_MODULE
#endif
#include
"../../Python/ceval.h"
#include
"../../Python/ceval_macros.h"
#undef
IS_PEP523_HOOKED
#define
IS_PEP523_HOOKED
(
tstate
) (tstate->interp->eval_frame != NULL && !tstate->interp->eval_frame_allow_specialization)
int
Test_EvalFrame_Resumes
,
Test_EvalFrame_Loads
;
#ifdef
_Py_TIER2
static
int
stop_tracing_and_jit
(
PyThreadState
*
tstate
,
_PyInterpreterFrame
*
frame
)
{
(
void
)(
frame
);
// Don't actually JIT-compile in this test eval-frame, but we still must
// finalize the tracer so the thread-global is_tracing flag is reset.
// Otherwise a trace started inside this duplicated interpreter loop
// (reachable under low JIT thresholds, e.g. PYTHON_JIT_STRESS=1) would
// leave is_tracing stuck true and permanently disable the JIT.
_PyJit_FinalizeTracing
(
tstate
,
0
);
return
0
;
}
#endif
_PyJitEntryFuncPtr
_Py_jit_entry
;
#if
_Py_TAIL_CALL_INTERP
#include
"test_targets.h"
#include
"test_cases.c.h"
#endif
PyObject
*
_Py_HOT_FUNCTION
Test_EvalFrame
(
PyThreadState
*
tstate
,
_PyInterpreterFrame
*
frame
,
int
throwflag
)
{
_Py_EnsureTstateNotNULL
(
tstate
);
check_invalid_reentrancy
();
CALL_STAT_INC
(
pyeval_calls
);
#if
USE_COMPUTED_GOTOS
&&
!
_Py_TAIL_CALL_INTERP
/* Import the static jump table */
#include
"test_targets.h"
void
*
*
opcode_targets
=
opcode_targets_table
;
#endif
#ifdef
Py_STATS
int
lastopcode
=
0
;
#endif
#if
!
_Py_TAIL_CALL_INTERP
uint8_t
opcode
;
/* Current opcode */
int
oparg
;
/* Current opcode argument, if any */
assert
(
tstate
->
current_frame
==
NULL
||
tstate
->
current_frame
->
stackpointer
!=
NULL
);
#if
!
USE_COMPUTED_GOTOS
uint8_t
tracing_mode
=
0
;
uint8_t
dispatch_code
;
#endif
#endif
_PyEntryFrame
entry
;
if
(
_Py_EnterRecursiveCallTstate
(
tstate
,
""
)) {
assert
(
frame
->
owner
!=
FRAME_OWNED_BY_INTERPRETER
);
_PyEval_FrameClearAndPop
(
tstate
,
frame
);
return
NULL
;
}
/* Local "register" variables.
* These are cached values from the frame and code object. */
_Py_CODEUNIT
*
next_instr
;
_PyStackRef
*
stack_pointer
;
entry
.
stack
[
0
]
=
PyStackRef_NULL
;
#ifdef
Py_STACKREF_DEBUG
entry
.
frame
.
f_funcobj
=
PyStackRef_None
;
#elif
defined(
Py_DEBUG
)
/* Set these to invalid but identifiable values for debugging. */
entry
.
frame
.
f_funcobj
=
(
_PyStackRef
){.
bits
=
0xaaa0
};
entry
.
frame
.
f_locals
=
(
PyObject
*
)
0xaaa1
;
entry
.
frame
.
frame_obj
=
(
PyFrameObject
*
)
0xaaa2
;
entry
.
frame
.
f_globals
=
(
PyObject
*
)
0xaaa3
;
entry
.
frame
.
f_builtins
=
(
PyObject
*
)
0xaaa4
;
#endif
entry
.
frame
.
f_executable
=
PyStackRef_None
;
entry
.
frame
.
instr_ptr
=
(
_Py_CODEUNIT
*
)
_Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS_PTR
+
1
;
entry
.
frame
.
stackpointer
=
entry
.
stack
;
entry
.
frame
.
owner
=
FRAME_OWNED_BY_INTERPRETER
;
entry
.
frame
.
visited
=
0
;
entry
.
frame
.
return_offset
=
0
;
#ifdef
Py_DEBUG
entry
.
frame
.
lltrace
=
0
;
#endif
/* Push frame */
entry
.
frame
.
previous
=
tstate
->
current_frame
;
frame
->
previous
=
&
entry
.
frame
;
tstate
->
current_frame
=
frame
;
entry
.
frame
.
localsplus
[
0
]
=
PyStackRef_NULL
;
/* support for generator.throw() */
if
(
throwflag
) {
if
(
_Py_EnterRecursivePy
(
tstate
)) {
goto
early_exit
;
}
#ifdef
Py_GIL_DISABLED
/* Load thread-local bytecode */
if
(
frame
->
tlbc_index
!=
((
_PyThreadStateImpl
*
)
tstate
)
->
tlbc_index
) {
_Py_CODEUNIT
*
bytecode
=
_PyEval_GetExecutableCode
(
tstate
,
_PyFrame_GetCode
(
frame
));
if
(
bytecode
==
NULL
) {
goto
early_exit
;
}
ptrdiff_t
off
=
frame
->
instr_ptr
-
_PyFrame_GetBytecode
(
frame
);
frame
->
tlbc_index
=
((
_PyThreadStateImpl
*
)
tstate
)
->
tlbc_index
;
frame
->
instr_ptr
=
bytecode
+
off
;
}
#endif
/* Because this avoids the RESUME, we need to update instrumentation */
_Py_Instrument
(
_PyFrame_GetCode
(
frame
),
tstate
->
interp
);
next_instr
=
frame
->
instr_ptr
;
monitor_throw
(
tstate
,
frame
,
next_instr
);
stack_pointer
=
_PyFrame_GetStackPointer
(
frame
);
#if
_Py_TAIL_CALL_INTERP
# if
Py_STATS
return
_TAIL_CALL_error
(
frame
,
stack_pointer
,
tstate
,
next_instr
,
instruction_funcptr_handler_table
,
0
,
lastopcode
);
# else
return
_TAIL_CALL_error
(
frame
,
stack_pointer
,
tstate
,
next_instr
,
instruction_funcptr_handler_table
,
0
);
# endif
#else
goto
error
;
#endif
}
#if
_Py_TAIL_CALL_INTERP
# if
Py_STATS
return
_TAIL_CALL_start_frame
(
frame
,
NULL
,
tstate
,
NULL
,
instruction_funcptr_handler_table
,
0
,
lastopcode
);
# else
return
_TAIL_CALL_start_frame
(
frame
,
NULL
,
tstate
,
NULL
,
instruction_funcptr_handler_table
,
0
);
# endif
#else
goto
start_frame
;
#include
"test_cases.c.h"
#endif
early_exit
:
assert
(
_PyErr_Occurred
(
tstate
));
_Py_LeaveRecursiveCallPy
(
tstate
);
assert
(
frame
->
owner
!=
FRAME_OWNED_BY_INTERPRETER
);
// GH-99729: We need to unlink the frame *before* clearing it:
_PyInterpreterFrame
*
dying
=
frame
;
frame
=
tstate
->
current_frame
=
dying
->
previous
;
_PyEval_FrameClearAndPop
(
tstate
,
dying
);
frame
->
return_offset
=
0
;
assert
(
frame
->
owner
==
FRAME_OWNED_BY_INTERPRETER
);
/* Restore previous frame and exit */
tstate
->
current_frame
=
frame
->
previous
;
return
NULL
;
}
Back
|
FazBrowse Home
|
New Git URL