1 /**
2   Mirror _ceval.h
3   */
4 module deimos.python.ceval;
5 
6 import deimos.python.pyport;
7 import deimos.python.object;
8 import deimos.python.frameobject;
9 import deimos.python.pystate;
10 import deimos.python.pythonrun;
11 import deimos.python.compile;
12 
13 extern(C):
14 // Python-header-file: Include/ceval.h:
15 
16 /// _
17 PyObject* PyEval_CallObjectWithKeywords(
18         PyObject* func, PyObject* args, PyObject* kwargs);
19 
20 version(Python_2_5_Or_Later){
21     /// _
22     PyObject* PyEval_CallObject()(PyObject* func, PyObject* arg) {
23         return PyEval_CallObjectWithKeywords(func, arg, null);
24     }
25 }else{
26     /// _
27     PyObject* PyEval_CallObject(PyObject* , PyObject* );
28 }
29 /// _
30 PyObject* PyEval_CallFunction(PyObject* obj, const(char)* format, ...);
31 /// _
32 PyObject* PyEval_CallMethod(
33         PyObject* obj,
34         const(char)* methodname,
35         const(char)* format, ...);
36 
37 /// _
38 void PyEval_SetProfile(Py_tracefunc, PyObject*);
39 /// _
40 void PyEval_SetTrace(Py_tracefunc, PyObject*);
41 /// _
42 Borrowed!PyObject* PyEval_GetBuiltins();
43 /// _
44 Borrowed!PyObject* PyEval_GetGlobals();
45 /// _
46 Borrowed!PyObject* PyEval_GetLocals();
47 /// _
48 Borrowed!PyFrameObject* PyEval_GetFrame();
49 version(Python_3_0_Or_Later) {
50 }else {
51     /// Availability: 2.*
52     int PyEval_GetRestricted();
53     /// Availability: 2.*
54     int Py_FlushLine();
55 }
56 
57 /** Look at the current frame's (if any) code's co_flags, and turn on
58    the corresponding compiler flags in cf->cf_flags.  Return 1 if any
59    flag was set, else return 0. */
60 int PyEval_MergeCompilerFlags(PyCompilerFlags* cf);
61 /// _
62 int Py_AddPendingCall(int function(void*) func, void* arg);
63 /// _
64 int Py_MakePendingCalls();
65 /// _
66 void Py_SetRecursionLimit(int);
67 /// _
68 int Py_GetRecursionLimit();
69 
70 // d translation of c macro:
71 /// _
72 int Py_EnterRecursiveCall()(char* where) {
73     return _Py_MakeRecCheck(PyThreadState_GET().recursion_depth) &&
74         _Py_CheckRecursiveCall(where);
75 }
76 /// _
77 void Py_LeaveRecursiveCall()() {
78     version(Python_3_0_Or_Later) {
79         if(_Py_MakeEndRecCheck(PyThreadState_GET().recursion_depth))
80             PyThreadState_GET().overflowed = 0;
81     }else {
82         --PyThreadState_GET().recursion_depth;
83     }
84 }
85 /// _
86 int _Py_CheckRecursiveCall(char* where);
87 /// _
88 mixin(PyAPI_DATA!"int _Py_CheckRecursionLimit");
89 
90 // TODO: version(STACKCHECK)
91 /// _
92 int _Py_MakeRecCheck()(int x) {
93     return (++(x) > _Py_CheckRecursionLimit);
94 }
95 
96 version(Python_3_0_Or_Later) {
97     // d translation of c macro:
98     /// Availability: 3.*
99     auto _Py_MakeEndRecCheck()(x) {
100         return (--(x) < ((_Py_CheckRecursionLimit > 100)
101                     ? (_Py_CheckRecursionLimit - 50)
102                     : (3 * (_Py_CheckRecursionLimit >> 2))));
103     }
104     /*
105     auto Py_ALLOW_RECURSION()() {
106         do{
107         ubyte _old = PyThreadState_GET()->recursion_critical;
108         PyThreadState_GET()->recursion_critical = 1;
109     }
110 
111     auto Py_END_ALLOW_RECURSION()() {
112         PyThreadState_GET()->recursion_critical = _old;
113         }while(0);
114     }
115     */
116 
117     /**
118       D's answer to C's
119       ---
120       Py_ALLOW_RECURSION
121       ..code..
122       Py_END_ALLOW_RECURSION
123       ---
124 
125       is
126       ---
127       mixin(Py_ALLOW_RECURSION(q{
128         ..code..
129       }));
130       ---
131       */
132     string Py_ALLOW_RECURSION()(string inner_code) {
133         import std.array;
134         return replace(q{
135                 {
136                 ubyte _old = PyThreadState_GET().recursion_critical;
137                 PyThreadState_GET().recursion_critical = 1;
138                 $inner_code;
139                 PyThreadState_GET().recursion_critical = _old;
140                 }
141         }, "$inner_code", inner_code);
142     }
143 }
144 
145 /// _
146 const(char)* PyEval_GetFuncName(PyObject*);
147 /// _
148 const(char)* PyEval_GetFuncDesc(PyObject*);
149 
150 version(Python_3_7_Or_Later) {
151 }else{
152     /// _
153     PyObject* PyEval_GetCallStats(PyObject*);
154 }
155 /// _
156 PyObject* PyEval_EvalFrame(PyFrameObject*);
157 version(Python_2_5_Or_Later){
158     /// Availability: >= 2.5
159     PyObject* PyEval_EvalFrameEx(PyFrameObject*, int);
160 }
161 
162 version(Python_3_0_Or_Later) {
163 }else{
164     /// _
165     mixin(PyAPI_DATA!"/*volatile*/ int _Py_Ticker");
166     /// _
167     mixin(PyAPI_DATA!"int _Py_CheckInterval");
168 }
169 
170 /// _
171 PyThreadState* PyEval_SaveThread();
172 /// _
173 void PyEval_RestoreThread(PyThreadState*);
174 
175 // version(WITH_THREAD) assumed?
176 /// _
177 int PyEval_ThreadsInitialized();
178 /// _
179 void PyEval_InitThreads();
180 version(Python_3_8_Or_Later) {
181 }else version(Python_3_0_Or_Later) {
182     /// Availability: 3.0 - 3.7
183     void _PyEval_FiniThreads();
184 }
185 /// _
186 void PyEval_AcquireLock();
187 /// _
188 void PyEval_ReleaseLock();
189 /// _
190 void PyEval_AcquireThread(PyThreadState* tstate);
191 /// _
192 void PyEval_ReleaseThread(PyThreadState* tstate);
193 version(Python_3_8_Or_Later) {
194 }else {
195     /// Availability: < 3.8
196     void PyEval_ReInitThreads();
197 }
198 
199 version(Python_3_0_Or_Later) {
200     /// Availability: 3.*
201     void _PyEval_SetSwitchInterval(C_ulong microseconds);
202     /// Availability: 3.*
203     C_ulong _PyEval_GetSwitchInterval();
204 }
205 
206 /* ??
207 #define Py_BLOCK_THREADS        PyEval_RestoreThread(_save);
208 #define Py_UNBLOCK_THREADS      _save = PyEval_SaveThread();
209 */
210 
211 /**
212   D's answer to C's
213   ---
214   Py_BEGIN_ALLOW_THREADS
215   ..code..
216   Py_END_ALLOW_THREADS
217   ---
218   is
219   ---
220   mixin(Py_ALLOW_THREADS(q{
221   ..code..
222   }));
223   ---
224   */
225 string Py_ALLOW_THREADS()(string inner_code) {
226     import std.array;
227     return replace(q{
228             {
229             PyThreadState* _save = PyEval_SaveThread();
230             $inner_code;
231             PyEval_RestoreThread(_save);
232             }
233     }, "$inner_code", inner_code);
234 }
235 
236 ///_
237 int _PyEval_SliceIndex(PyObject*, Py_ssize_t*);
238 version(Python_3_8_Or_Later) {
239 }else version(Python_3_0_Or_Later) {
240     /// Availability: 3.0 - 3.7
241     void _PyEval_SignalAsyncExc();
242 }