annotate cos/python/Python/ceval.c @ 27:7f74363f4c82

Added some files for the python port
author windel
date Tue, 27 Dec 2011 18:59:02 +0100
parents
children
rev   line source
27
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2 /* Execute compiled code */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4 /* XXX TO DO:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
5 XXX speed up searching for keywords by using a dictionary
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
6 XXX document it!
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
7 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
8
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
9 /* enable more aggressive intra-module optimizations, where available */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
10 #define PY_LOCAL_AGGRESSIVE
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
11
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
12 #include "Python.h"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
13
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
14 #include "code.h"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
15 #include "frameobject.h"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
16 #include "opcode.h"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
17 #include "structmember.h"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
18
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
19 #include <ctype.h>
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
20
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
21 typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
22
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
23 /* Forward declarations */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
24 static PyObject * call_function(PyObject ***, int);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
25 static PyObject * fast_function(PyObject *, PyObject ***, int, int, int);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
26 static PyObject * do_call(PyObject *, PyObject ***, int, int);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
27 static PyObject * ext_do_call(PyObject *, PyObject ***, int, int, int);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
28 static PyObject * update_keyword_args(PyObject *, int, PyObject ***,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
29 PyObject *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
30 static PyObject * update_star_args(int, int, PyObject *, PyObject ***);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
31 static PyObject * load_args(PyObject ***, int);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
32 #define CALL_FLAG_VAR 1
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
33 #define CALL_FLAG_KW 2
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
34
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
35 static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
36 int, PyObject *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
37 static int call_trace_protected(Py_tracefunc, PyObject *,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
38 PyFrameObject *, int, PyObject *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
39 static void call_exc_trace(Py_tracefunc, PyObject *, PyFrameObject *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
40 static int maybe_call_line_trace(Py_tracefunc, PyObject *,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
41 PyFrameObject *, int *, int *, int *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
42
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
43 static PyObject * cmp_outcome(int, PyObject *, PyObject *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
44 static PyObject * import_from(PyObject *, PyObject *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
45 static int import_all_from(PyObject *, PyObject *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
46 static void format_exc_check_arg(PyObject *, const char *, PyObject *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
47 static void format_exc_unbound(PyCodeObject *co, int oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
48 static PyObject * unicode_concatenate(PyObject *, PyObject *,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
49 PyFrameObject *, unsigned char *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
50 static PyObject * special_lookup(PyObject *, char *, PyObject **);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
51
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
52 #define NAME_ERROR_MSG \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
53 "name '%.200s' is not defined"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
54 #define GLOBAL_NAME_ERROR_MSG \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
55 "global name '%.200s' is not defined"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
56 #define UNBOUNDLOCAL_ERROR_MSG \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
57 "local variable '%.200s' referenced before assignment"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
58 #define UNBOUNDFREE_ERROR_MSG \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
59 "free variable '%.200s' referenced before assignment" \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
60 " in enclosing scope"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
61
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
62 #define PCALL(O)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
63
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
64 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
65 PyEval_GetCallStats(PyObject *self)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
66 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
67 Py_INCREF(Py_None);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
68 return Py_None;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
69 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
70
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
71
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
72 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
73 #define GIL_REQUEST _Py_atomic_load_relaxed(&gil_drop_request)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
74 #else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
75 #define GIL_REQUEST 0
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
76 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
77
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
78 /* This can set eval_breaker to 0 even though gil_drop_request became
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
79 1. We believe this is all right because the eval loop will release
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
80 the GIL eventually anyway. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
81 #define COMPUTE_EVAL_BREAKER() \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
82 _Py_atomic_store_relaxed( \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
83 &eval_breaker, \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
84 GIL_REQUEST | \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
85 _Py_atomic_load_relaxed(&pendingcalls_to_do) | \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
86 pending_async_exc)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
87
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
88 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
89
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
90 #define SET_GIL_DROP_REQUEST() \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
91 do { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
92 _Py_atomic_store_relaxed(&gil_drop_request, 1); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
93 _Py_atomic_store_relaxed(&eval_breaker, 1); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
94 } while (0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
95
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
96 #define RESET_GIL_DROP_REQUEST() \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
97 do { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
98 _Py_atomic_store_relaxed(&gil_drop_request, 0); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
99 COMPUTE_EVAL_BREAKER(); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
100 } while (0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
101
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
102 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
103
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
104 /* Pending calls are only modified under pending_lock */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
105 #define SIGNAL_PENDING_CALLS() \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
106 do { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
107 _Py_atomic_store_relaxed(&pendingcalls_to_do, 1); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
108 _Py_atomic_store_relaxed(&eval_breaker, 1); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
109 } while (0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
110
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
111 #define UNSIGNAL_PENDING_CALLS() \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
112 do { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
113 _Py_atomic_store_relaxed(&pendingcalls_to_do, 0); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
114 COMPUTE_EVAL_BREAKER(); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
115 } while (0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
116
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
117 #define SIGNAL_ASYNC_EXC() \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
118 do { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
119 pending_async_exc = 1; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
120 _Py_atomic_store_relaxed(&eval_breaker, 1); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
121 } while (0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
122
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
123 #define UNSIGNAL_ASYNC_EXC() \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
124 do { pending_async_exc = 0; COMPUTE_EVAL_BREAKER(); } while (0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
125
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
126
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
127 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
128
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
129 #include "pythread.h"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
130
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
131 static PyThread_type_lock pending_lock = 0; /* for pending calls */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
132 static long main_thread = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
133 /* This single variable consolidates all requests to break out of the fast path
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
134 in the eval loop. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
135 static _Py_atomic_int eval_breaker = {0};
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
136 /* Request for dropping the GIL */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
137 static _Py_atomic_int gil_drop_request = {0};
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
138 /* Request for running pending calls. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
139 static _Py_atomic_int pendingcalls_to_do = {0};
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
140 /* Request for looking at the `async_exc` field of the current thread state.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
141 Guarded by the GIL. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
142 static int pending_async_exc = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
143
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
144 #include "ceval_gil.h"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
145
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
146 int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
147 PyEval_ThreadsInitialized(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
148 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
149 return gil_created();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
150 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
151
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
152 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
153 PyEval_InitThreads(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
154 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
155 if (gil_created())
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
156 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
157 create_gil();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
158 take_gil(PyThreadState_GET());
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
159 main_thread = PyThread_get_thread_ident();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
160 if (!pending_lock)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
161 pending_lock = PyThread_allocate_lock();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
162 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
163
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
164 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
165 _PyEval_FiniThreads(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
166 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
167 if (!gil_created())
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
168 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
169 destroy_gil();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
170 assert(!gil_created());
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
171 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
172
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
173 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
174 PyEval_AcquireLock(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
175 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
176 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
177 if (tstate == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
178 Py_FatalError("PyEval_AcquireLock: current thread state is NULL");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
179 take_gil(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
180 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
181
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
182 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
183 PyEval_ReleaseLock(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
184 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
185 /* This function must succeed when the current thread state is NULL.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
186 We therefore avoid PyThreadState_GET() which dumps a fatal error
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
187 in debug mode.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
188 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
189 drop_gil((PyThreadState*)_Py_atomic_load_relaxed(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
190 &_PyThreadState_Current));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
191 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
192
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
193 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
194 PyEval_AcquireThread(PyThreadState *tstate)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
195 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
196 if (tstate == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
197 Py_FatalError("PyEval_AcquireThread: NULL new thread state");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
198 /* Check someone has called PyEval_InitThreads() to create the lock */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
199 assert(gil_created());
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
200 take_gil(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
201 if (PyThreadState_Swap(tstate) != NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
202 Py_FatalError(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
203 "PyEval_AcquireThread: non-NULL old thread state");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
204 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
205
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
206 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
207 PyEval_ReleaseThread(PyThreadState *tstate)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
208 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
209 if (tstate == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
210 Py_FatalError("PyEval_ReleaseThread: NULL thread state");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
211 if (PyThreadState_Swap(NULL) != tstate)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
212 Py_FatalError("PyEval_ReleaseThread: wrong thread state");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
213 drop_gil(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
214 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
215
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
216 /* This function is called from PyOS_AfterFork to ensure that newly
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
217 created child processes don't hold locks referring to threads which
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
218 are not running in the child process. (This could also be done using
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
219 pthread_atfork mechanism, at least for the pthreads implementation.) */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
220
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
221 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
222 PyEval_ReInitThreads(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
223 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
224 _Py_IDENTIFIER(_after_fork);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
225 PyObject *threading, *result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
226 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
227
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
228 if (!gil_created())
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
229 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
230 recreate_gil();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
231 pending_lock = PyThread_allocate_lock();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
232 take_gil(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
233 main_thread = PyThread_get_thread_ident();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
234
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
235 /* Update the threading module with the new state.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
236 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
237 tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
238 threading = PyMapping_GetItemString(tstate->interp->modules,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
239 "threading");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
240 if (threading == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
241 /* threading not imported */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
242 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
243 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
244 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
245 result = _PyObject_CallMethodId(threading, &PyId__after_fork, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
246 if (result == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
247 PyErr_WriteUnraisable(threading);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
248 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
249 Py_DECREF(result);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
250 Py_DECREF(threading);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
251 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
252
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
253 #else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
254 static _Py_atomic_int eval_breaker = {0};
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
255 static int pending_async_exc = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
256 #endif /* WITH_THREAD */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
257
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
258 /* This function is used to signal that async exceptions are waiting to be
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
259 raised, therefore it is also useful in non-threaded builds. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
260
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
261 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
262 _PyEval_SignalAsyncExc(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
263 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
264 SIGNAL_ASYNC_EXC();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
265 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
266
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
267 /* Functions save_thread and restore_thread are always defined so
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
268 dynamically loaded modules needn't be compiled separately for use
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
269 with and without threads: */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
270
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
271 PyThreadState *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
272 PyEval_SaveThread(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
273 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
274 PyThreadState *tstate = PyThreadState_Swap(NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
275 if (tstate == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
276 Py_FatalError("PyEval_SaveThread: NULL tstate");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
277 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
278 if (gil_created())
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
279 drop_gil(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
280 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
281 return tstate;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
282 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
283
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
284 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
285 PyEval_RestoreThread(PyThreadState *tstate)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
286 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
287 if (tstate == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
288 Py_FatalError("PyEval_RestoreThread: NULL tstate");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
289 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
290 if (gil_created()) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
291 int err = errno;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
292 take_gil(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
293 /* _Py_Finalizing is protected by the GIL */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
294 if (_Py_Finalizing && tstate != _Py_Finalizing) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
295 drop_gil(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
296 PyThread_exit_thread();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
297 assert(0); /* unreachable */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
298 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
299 errno = err;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
300 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
301 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
302 PyThreadState_Swap(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
303 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
304
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
305
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
306 /* Mechanism whereby asynchronously executing callbacks (e.g. UNIX
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
307 signal handlers or Mac I/O completion routines) can schedule calls
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
308 to a function to be called synchronously.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
309 The synchronous function is called with one void* argument.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
310 It should return 0 for success or -1 for failure -- failure should
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
311 be accompanied by an exception.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
312
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
313 If registry succeeds, the registry function returns 0; if it fails
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
314 (e.g. due to too many pending calls) it returns -1 (without setting
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
315 an exception condition).
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
316
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
317 Note that because registry may occur from within signal handlers,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
318 or other asynchronous events, calling malloc() is unsafe!
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
319
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
320 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
321 Any thread can schedule pending calls, but only the main thread
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
322 will execute them.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
323 There is no facility to schedule calls to a particular thread, but
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
324 that should be easy to change, should that ever be required. In
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
325 that case, the static variables here should go into the python
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
326 threadstate.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
327 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
328 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
329
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
330 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
331
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
332 /* The WITH_THREAD implementation is thread-safe. It allows
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
333 scheduling to be made from any thread, and even from an executing
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
334 callback.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
335 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
336
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
337 #define NPENDINGCALLS 32
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
338 static struct {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
339 int (*func)(void *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
340 void *arg;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
341 } pendingcalls[NPENDINGCALLS];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
342 static int pendingfirst = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
343 static int pendinglast = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
344
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
345 int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
346 Py_AddPendingCall(int (*func)(void *), void *arg)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
347 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
348 int i, j, result=0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
349 PyThread_type_lock lock = pending_lock;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
350
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
351 /* try a few times for the lock. Since this mechanism is used
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
352 * for signal handling (on the main thread), there is a (slim)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
353 * chance that a signal is delivered on the same thread while we
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
354 * hold the lock during the Py_MakePendingCalls() function.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
355 * This avoids a deadlock in that case.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
356 * Note that signals can be delivered on any thread. In particular,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
357 * on Windows, a SIGINT is delivered on a system-created worker
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
358 * thread.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
359 * We also check for lock being NULL, in the unlikely case that
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
360 * this function is called before any bytecode evaluation takes place.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
361 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
362 if (lock != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
363 for (i = 0; i<100; i++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
364 if (PyThread_acquire_lock(lock, NOWAIT_LOCK))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
365 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
366 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
367 if (i == 100)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
368 return -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
369 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
370
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
371 i = pendinglast;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
372 j = (i + 1) % NPENDINGCALLS;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
373 if (j == pendingfirst) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
374 result = -1; /* Queue full */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
375 } else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
376 pendingcalls[i].func = func;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
377 pendingcalls[i].arg = arg;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
378 pendinglast = j;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
379 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
380 /* signal main loop */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
381 SIGNAL_PENDING_CALLS();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
382 if (lock != NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
383 PyThread_release_lock(lock);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
384 return result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
385 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
386
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
387 int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
388 Py_MakePendingCalls(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
389 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
390 static int busy = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
391 int i;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
392 int r = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
393
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
394 if (!pending_lock) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
395 /* initial allocation of the lock */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
396 pending_lock = PyThread_allocate_lock();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
397 if (pending_lock == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
398 return -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
399 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
400
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
401 /* only service pending calls on main thread */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
402 if (main_thread && PyThread_get_thread_ident() != main_thread)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
403 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
404 /* don't perform recursive pending calls */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
405 if (busy)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
406 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
407 busy = 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
408 /* perform a bounded number of calls, in case of recursion */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
409 for (i=0; i<NPENDINGCALLS; i++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
410 int j;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
411 int (*func)(void *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
412 void *arg = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
413
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
414 /* pop one item off the queue while holding the lock */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
415 PyThread_acquire_lock(pending_lock, WAIT_LOCK);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
416 j = pendingfirst;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
417 if (j == pendinglast) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
418 func = NULL; /* Queue empty */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
419 } else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
420 func = pendingcalls[j].func;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
421 arg = pendingcalls[j].arg;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
422 pendingfirst = (j + 1) % NPENDINGCALLS;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
423 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
424 if (pendingfirst != pendinglast)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
425 SIGNAL_PENDING_CALLS();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
426 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
427 UNSIGNAL_PENDING_CALLS();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
428 PyThread_release_lock(pending_lock);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
429 /* having released the lock, perform the callback */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
430 if (func == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
431 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
432 r = func(arg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
433 if (r)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
434 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
435 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
436 busy = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
437 return r;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
438 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
439
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
440 #else /* if ! defined WITH_THREAD */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
441
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
442 /*
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
443 WARNING! ASYNCHRONOUSLY EXECUTING CODE!
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
444 This code is used for signal handling in python that isn't built
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
445 with WITH_THREAD.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
446 Don't use this implementation when Py_AddPendingCalls() can happen
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
447 on a different thread!
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
448
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
449 There are two possible race conditions:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
450 (1) nested asynchronous calls to Py_AddPendingCall()
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
451 (2) AddPendingCall() calls made while pending calls are being processed.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
452
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
453 (1) is very unlikely because typically signal delivery
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
454 is blocked during signal handling. So it should be impossible.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
455 (2) is a real possibility.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
456 The current code is safe against (2), but not against (1).
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
457 The safety against (2) is derived from the fact that only one
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
458 thread is present, interrupted by signals, and that the critical
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
459 section is protected with the "busy" variable. On Windows, which
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
460 delivers SIGINT on a system thread, this does not hold and therefore
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
461 Windows really shouldn't use this version.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
462 The two threads could theoretically wiggle around the "busy" variable.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
463 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
464
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
465 #define NPENDINGCALLS 32
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
466 static struct {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
467 int (*func)(void *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
468 void *arg;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
469 } pendingcalls[NPENDINGCALLS];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
470 static volatile int pendingfirst = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
471 static volatile int pendinglast = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
472 static _Py_atomic_int pendingcalls_to_do = {0};
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
473
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
474 int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
475 Py_AddPendingCall(int (*func)(void *), void *arg)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
476 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
477 static volatile int busy = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
478 int i, j;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
479 /* XXX Begin critical section */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
480 if (busy)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
481 return -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
482 busy = 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
483 i = pendinglast;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
484 j = (i + 1) % NPENDINGCALLS;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
485 if (j == pendingfirst) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
486 busy = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
487 return -1; /* Queue full */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
488 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
489 pendingcalls[i].func = func;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
490 pendingcalls[i].arg = arg;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
491 pendinglast = j;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
492
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
493 SIGNAL_PENDING_CALLS();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
494 busy = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
495 /* XXX End critical section */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
496 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
497 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
498
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
499 int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
500 Py_MakePendingCalls(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
501 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
502 static int busy = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
503 if (busy)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
504 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
505 busy = 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
506 UNSIGNAL_PENDING_CALLS();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
507 for (;;) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
508 int i;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
509 int (*func)(void *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
510 void *arg;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
511 i = pendingfirst;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
512 if (i == pendinglast)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
513 break; /* Queue empty */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
514 func = pendingcalls[i].func;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
515 arg = pendingcalls[i].arg;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
516 pendingfirst = (i + 1) % NPENDINGCALLS;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
517 if (func(arg) < 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
518 busy = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
519 SIGNAL_PENDING_CALLS(); /* We're not done yet */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
520 return -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
521 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
522 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
523 busy = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
524 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
525 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
526
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
527 #endif /* WITH_THREAD */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
528
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
529
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
530 /* The interpreter's recursion limit */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
531
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
532 #ifndef Py_DEFAULT_RECURSION_LIMIT
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
533 #define Py_DEFAULT_RECURSION_LIMIT 1000
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
534 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
535 static int recursion_limit = Py_DEFAULT_RECURSION_LIMIT;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
536 int _Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
537
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
538 /* the macro Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall()
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
539 if the recursion_depth reaches _Py_CheckRecursionLimit.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
540 If USE_STACKCHECK, the macro decrements _Py_CheckRecursionLimit
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
541 to guarantee that _Py_CheckRecursiveCall() is regularly called.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
542 Without USE_STACKCHECK, there is no need for this. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
543 int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
544 _Py_CheckRecursiveCall(char *where)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
545 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
546 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
547
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
548 #ifdef USE_STACKCHECK
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
549 if (PyOS_CheckStack()) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
550 --tstate->recursion_depth;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
551 PyErr_SetString(PyExc_MemoryError, "Stack overflow");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
552 return -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
553 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
554 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
555 _Py_CheckRecursionLimit = recursion_limit;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
556 if (tstate->recursion_critical)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
557 /* Somebody asked that we don't check for recursion. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
558 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
559 if (tstate->overflowed) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
560 if (tstate->recursion_depth > recursion_limit + 50) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
561 /* Overflowing while handling an overflow. Give up. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
562 Py_FatalError("Cannot recover from stack overflow.");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
563 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
564 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
565 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
566 if (tstate->recursion_depth > recursion_limit) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
567 --tstate->recursion_depth;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
568 tstate->overflowed = 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
569 PyErr_Format(PyExc_RuntimeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
570 "maximum recursion depth exceeded%s",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
571 where);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
572 return -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
573 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
574 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
575 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
576
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
577 /* Status code for main loop (reason for stack unwind) */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
578 enum why_code {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
579 WHY_NOT = 0x0001, /* No error */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
580 WHY_EXCEPTION = 0x0002, /* Exception occurred */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
581 WHY_RERAISE = 0x0004, /* Exception re-raised by 'finally' */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
582 WHY_RETURN = 0x0008, /* 'return' statement */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
583 WHY_BREAK = 0x0010, /* 'break' statement */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
584 WHY_CONTINUE = 0x0020, /* 'continue' statement */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
585 WHY_YIELD = 0x0040, /* 'yield' operator */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
586 WHY_SILENCED = 0x0080 /* Exception silenced by 'with' */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
587 };
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
588
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
589 static void save_exc_state(PyThreadState *, PyFrameObject *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
590 static void swap_exc_state(PyThreadState *, PyFrameObject *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
591 static void restore_and_clear_exc_state(PyThreadState *, PyFrameObject *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
592 static enum why_code do_raise(PyObject *, PyObject *);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
593 static int unpack_iterable(PyObject *, int, int, PyObject **);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
594
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
595 /* Records whether tracing is on for any thread. Counts the number of
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
596 threads for which tstate->c_tracefunc is non-NULL, so if the value
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
597 is 0, we know we don't have to check this thread's c_tracefunc.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
598 This speeds up the if statement in PyEval_EvalFrameEx() after
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
599 fast_next_opcode*/
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
600 static int _Py_TracingPossible = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
601
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
602
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
603
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
604 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
605 PyEval_EvalCode(PyObject *co, PyObject *globals, PyObject *locals)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
606 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
607 return PyEval_EvalCodeEx(co,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
608 globals, locals,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
609 (PyObject **)NULL, 0,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
610 (PyObject **)NULL, 0,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
611 (PyObject **)NULL, 0,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
612 NULL, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
613 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
614
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
615
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
616 /* Interpreter main loop */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
617
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
618 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
619 PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
620 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
621 register PyObject **stack_pointer; /* Next free slot in value stack */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
622 register unsigned char *next_instr;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
623 register int opcode; /* Current opcode */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
624 register int oparg; /* Current opcode argument, if any */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
625 register enum why_code why; /* Reason for block stack unwind */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
626 register int err; /* Error status -- nonzero if error */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
627 register PyObject *x; /* Result object -- NULL if error */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
628 register PyObject *v; /* Temporary objects popped off stack */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
629 register PyObject *w;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
630 register PyObject *u;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
631 register PyObject *t;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
632 register PyObject **fastlocals, **freevars;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
633 PyObject *retval = NULL; /* Return value */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
634 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
635 PyCodeObject *co;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
636
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
637 /* when tracing we set things up so that
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
638
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
639 not (instr_lb <= current_bytecode_offset < instr_ub)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
640
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
641 is true when the line being executed has changed. The
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
642 initial values are such as to make this false the first
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
643 time it is tested. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
644 int instr_ub = -1, instr_lb = 0, instr_prev = -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
645
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
646 unsigned char *first_instr;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
647 PyObject *names;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
648 PyObject *consts;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
649
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
650 /* Computed GOTOs, or
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
651 the-optimization-commonly-but-improperly-known-as-"threaded code"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
652 using gcc's labels-as-values extension
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
653 (http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html).
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
654
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
655 The traditional bytecode evaluation loop uses a "switch" statement, which
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
656 decent compilers will optimize as a single indirect branch instruction
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
657 combined with a lookup table of jump addresses. However, since the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
658 indirect jump instruction is shared by all opcodes, the CPU will have a
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
659 hard time making the right prediction for where to jump next (actually,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
660 it will be always wrong except in the uncommon case of a sequence of
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
661 several identical opcodes).
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
662
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
663 "Threaded code" in contrast, uses an explicit jump table and an explicit
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
664 indirect jump instruction at the end of each opcode. Since the jump
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
665 instruction is at a different address for each opcode, the CPU will make a
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
666 separate prediction for each of these instructions, which is equivalent to
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
667 predicting the second opcode of each opcode pair. These predictions have
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
668 a much better chance to turn out valid, especially in small bytecode loops.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
669
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
670 A mispredicted branch on a modern CPU flushes the whole pipeline and
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
671 can cost several CPU cycles (depending on the pipeline depth),
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
672 and potentially many more instructions (depending on the pipeline width).
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
673 A correctly predicted branch, however, is nearly free.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
674
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
675 At the time of this writing, the "threaded code" version is up to 15-20%
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
676 faster than the normal "switch" version, depending on the compiler and the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
677 CPU architecture.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
678
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
679 We disable the optimization if DYNAMIC_EXECUTION_PROFILE is defined,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
680 because it would render the measurements invalid.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
681
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
682
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
683 NOTE: care must be taken that the compiler doesn't try to "optimize" the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
684 indirect jumps by sharing them between all opcodes. Such optimizations
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
685 can be disabled on gcc by using the -fno-gcse flag (or possibly
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
686 -fno-crossjumping).
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
687 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
688
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
689 #ifdef DYNAMIC_EXECUTION_PROFILE
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
690 #undef USE_COMPUTED_GOTOS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
691 #define USE_COMPUTED_GOTOS 0
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
692 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
693
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
694 #ifdef HAVE_COMPUTED_GOTOS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
695 #ifndef USE_COMPUTED_GOTOS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
696 #define USE_COMPUTED_GOTOS 1
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
697 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
698 #else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
699 #if defined(USE_COMPUTED_GOTOS) && USE_COMPUTED_GOTOS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
700 #error "Computed gotos are not supported on this compiler."
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
701 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
702 #undef USE_COMPUTED_GOTOS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
703 #define USE_COMPUTED_GOTOS 0
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
704 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
705
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
706 #if USE_COMPUTED_GOTOS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
707 /* Import the static jump table */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
708 #include "opcode_targets.h"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
709
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
710 /* This macro is used when several opcodes defer to the same implementation
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
711 (e.g. SETUP_LOOP, SETUP_FINALLY) */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
712 #define TARGET_WITH_IMPL(op, impl) \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
713 TARGET_##op: \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
714 opcode = op; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
715 if (HAS_ARG(op)) \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
716 oparg = NEXTARG(); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
717 case op: \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
718 goto impl; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
719
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
720 #define TARGET(op) \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
721 TARGET_##op: \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
722 opcode = op; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
723 if (HAS_ARG(op)) \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
724 oparg = NEXTARG(); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
725 case op:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
726
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
727
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
728 #define DISPATCH() \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
729 { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
730 if (!_Py_atomic_load_relaxed(&eval_breaker)) { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
731 FAST_DISPATCH(); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
732 } \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
733 continue; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
734 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
735
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
736 #ifdef LLTRACE
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
737 #define FAST_DISPATCH() \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
738 { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
739 if (!lltrace && !_Py_TracingPossible) { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
740 f->f_lasti = INSTR_OFFSET(); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
741 goto *opcode_targets[*next_instr++]; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
742 } \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
743 goto fast_next_opcode; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
744 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
745 #else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
746 #define FAST_DISPATCH() \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
747 { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
748 if (!_Py_TracingPossible) { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
749 f->f_lasti = INSTR_OFFSET(); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
750 goto *opcode_targets[*next_instr++]; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
751 } \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
752 goto fast_next_opcode; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
753 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
754 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
755
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
756 #else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
757 #define TARGET(op) \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
758 case op:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
759 #define TARGET_WITH_IMPL(op, impl) \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
760 /* silence compiler warnings about `impl` unused */ \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
761 if (0) goto impl; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
762 case op:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
763 #define DISPATCH() continue
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
764 #define FAST_DISPATCH() goto fast_next_opcode
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
765 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
766
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
767
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
768 /* Tuple access macros */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
769
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
770 #ifndef Py_DEBUG
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
771 #define GETITEM(v, i) PyTuple_GET_ITEM((PyTupleObject *)(v), (i))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
772 #else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
773 #define GETITEM(v, i) PyTuple_GetItem((v), (i))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
774 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
775
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
776 #ifdef WITH_TSC
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
777 /* Use Pentium timestamp counter to mark certain events:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
778 inst0 -- beginning of switch statement for opcode dispatch
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
779 inst1 -- end of switch statement (may be skipped)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
780 loop0 -- the top of the mainloop
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
781 loop1 -- place where control returns again to top of mainloop
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
782 (may be skipped)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
783 intr1 -- beginning of long interruption
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
784 intr2 -- end of long interruption
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
785
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
786 Many opcodes call out to helper C functions. In some cases, the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
787 time in those functions should be counted towards the time for the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
788 opcode, but not in all cases. For example, a CALL_FUNCTION opcode
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
789 calls another Python function; there's no point in charge all the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
790 bytecode executed by the called function to the caller.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
791
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
792 It's hard to make a useful judgement statically. In the presence
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
793 of operator overloading, it's impossible to tell if a call will
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
794 execute new Python code or not.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
795
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
796 It's a case-by-case judgement. I'll use intr1 for the following
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
797 cases:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
798
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
799 IMPORT_STAR
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
800 IMPORT_FROM
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
801 CALL_FUNCTION (and friends)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
802
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
803 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
804 uint64 inst0, inst1, loop0, loop1, intr0 = 0, intr1 = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
805 int ticked = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
806
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
807 READ_TIMESTAMP(inst0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
808 READ_TIMESTAMP(inst1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
809 READ_TIMESTAMP(loop0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
810 READ_TIMESTAMP(loop1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
811
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
812 /* shut up the compiler */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
813 opcode = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
814 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
815
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
816 /* Code access macros */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
817
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
818 #define INSTR_OFFSET() ((int)(next_instr - first_instr))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
819 #define NEXTOP() (*next_instr++)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
820 #define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
821 #define PEEKARG() ((next_instr[2]<<8) + next_instr[1])
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
822 #define JUMPTO(x) (next_instr = first_instr + (x))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
823 #define JUMPBY(x) (next_instr += (x))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
824
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
825 /* OpCode prediction macros
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
826 Some opcodes tend to come in pairs thus making it possible to
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
827 predict the second code when the first is run. For example,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
828 COMPARE_OP is often followed by JUMP_IF_FALSE or JUMP_IF_TRUE. And,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
829 those opcodes are often followed by a POP_TOP.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
830
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
831 Verifying the prediction costs a single high-speed test of a register
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
832 variable against a constant. If the pairing was good, then the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
833 processor's own internal branch predication has a high likelihood of
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
834 success, resulting in a nearly zero-overhead transition to the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
835 next opcode. A successful prediction saves a trip through the eval-loop
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
836 including its two unpredictable branches, the HAS_ARG test and the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
837 switch-case. Combined with the processor's internal branch prediction,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
838 a successful PREDICT has the effect of making the two opcodes run as if
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
839 they were a single new opcode with the bodies combined.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
840
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
841 If collecting opcode statistics, your choices are to either keep the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
842 predictions turned-on and interpret the results as if some opcodes
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
843 had been combined or turn-off predictions so that the opcode frequency
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
844 counter updates for both opcodes.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
845
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
846 Opcode prediction is disabled with threaded code, since the latter allows
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
847 the CPU to record separate branch prediction information for each
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
848 opcode.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
849
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
850 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
851
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
852 #if defined(DYNAMIC_EXECUTION_PROFILE) || USE_COMPUTED_GOTOS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
853 #define PREDICT(op) if (0) goto PRED_##op
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
854 #define PREDICTED(op) PRED_##op:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
855 #define PREDICTED_WITH_ARG(op) PRED_##op:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
856 #else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
857 #define PREDICT(op) if (*next_instr == op) goto PRED_##op
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
858 #define PREDICTED(op) PRED_##op: next_instr++
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
859 #define PREDICTED_WITH_ARG(op) PRED_##op: oparg = PEEKARG(); next_instr += 3
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
860 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
861
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
862
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
863 /* Stack manipulation macros */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
864
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
865 /* The stack can grow at most MAXINT deep, as co_nlocals and
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
866 co_stacksize are ints. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
867 #define STACK_LEVEL() ((int)(stack_pointer - f->f_valuestack))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
868 #define EMPTY() (STACK_LEVEL() == 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
869 #define TOP() (stack_pointer[-1])
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
870 #define SECOND() (stack_pointer[-2])
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
871 #define THIRD() (stack_pointer[-3])
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
872 #define FOURTH() (stack_pointer[-4])
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
873 #define PEEK(n) (stack_pointer[-(n)])
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
874 #define SET_TOP(v) (stack_pointer[-1] = (v))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
875 #define SET_SECOND(v) (stack_pointer[-2] = (v))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
876 #define SET_THIRD(v) (stack_pointer[-3] = (v))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
877 #define SET_FOURTH(v) (stack_pointer[-4] = (v))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
878 #define SET_VALUE(n, v) (stack_pointer[-(n)] = (v))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
879 #define BASIC_STACKADJ(n) (stack_pointer += n)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
880 #define BASIC_PUSH(v) (*stack_pointer++ = (v))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
881 #define BASIC_POP() (*--stack_pointer)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
882
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
883 #define PUSH(v) BASIC_PUSH(v)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
884 #define POP() BASIC_POP()
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
885 #define STACKADJ(n) BASIC_STACKADJ(n)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
886 #define EXT_POP(STACK_POINTER) (*--(STACK_POINTER))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
887
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
888 /* Local variable macros */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
889
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
890 #define GETLOCAL(i) (fastlocals[i])
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
891
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
892 /* The SETLOCAL() macro must not DECREF the local variable in-place and
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
893 then store the new value; it must copy the old value to a temporary
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
894 value, then store the new value, and then DECREF the temporary value.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
895 This is because it is possible that during the DECREF the frame is
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
896 accessed by other code (e.g. a __del__ method or gc.collect()) and the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
897 variable would be pointing to already-freed memory. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
898 #define SETLOCAL(i, value) do { PyObject *tmp = GETLOCAL(i); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
899 GETLOCAL(i) = value; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
900 Py_XDECREF(tmp); } while (0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
901
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
902
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
903 #define UNWIND_BLOCK(b) \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
904 while (STACK_LEVEL() > (b)->b_level) { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
905 PyObject *v = POP(); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
906 Py_XDECREF(v); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
907 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
908
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
909 #define UNWIND_EXCEPT_HANDLER(b) \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
910 { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
911 PyObject *type, *value, *traceback; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
912 assert(STACK_LEVEL() >= (b)->b_level + 3); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
913 while (STACK_LEVEL() > (b)->b_level + 3) { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
914 value = POP(); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
915 Py_XDECREF(value); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
916 } \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
917 type = tstate->exc_type; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
918 value = tstate->exc_value; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
919 traceback = tstate->exc_traceback; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
920 tstate->exc_type = POP(); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
921 tstate->exc_value = POP(); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
922 tstate->exc_traceback = POP(); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
923 Py_XDECREF(type); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
924 Py_XDECREF(value); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
925 Py_XDECREF(traceback); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
926 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
927
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
928 /* Start of code */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
929
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
930 /* push frame */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
931 if (Py_EnterRecursiveCall(""))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
932 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
933
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
934 tstate->frame = f;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
935
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
936 if (tstate->use_tracing) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
937 if (tstate->c_tracefunc != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
938 /* tstate->c_tracefunc, if defined, is a
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
939 function that will be called on *every* entry
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
940 to a code block. Its return value, if not
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
941 None, is a function that will be called at
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
942 the start of each executed line of code.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
943 (Actually, the function must return itself
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
944 in order to continue tracing.) The trace
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
945 functions are called with three arguments:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
946 a pointer to the current frame, a string
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
947 indicating why the function is called, and
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
948 an argument which depends on the situation.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
949 The global trace function is also called
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
950 whenever an exception is detected. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
951 if (call_trace_protected(tstate->c_tracefunc,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
952 tstate->c_traceobj,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
953 f, PyTrace_CALL, Py_None)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
954 /* Trace function raised an error */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
955 goto exit_eval_frame;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
956 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
957 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
958 if (tstate->c_profilefunc != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
959 /* Similar for c_profilefunc, except it needn't
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
960 return itself and isn't called for "line" events */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
961 if (call_trace_protected(tstate->c_profilefunc,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
962 tstate->c_profileobj,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
963 f, PyTrace_CALL, Py_None)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
964 /* Profile function raised an error */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
965 goto exit_eval_frame;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
966 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
967 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
968 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
969
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
970 co = f->f_code;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
971 names = co->co_names;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
972 consts = co->co_consts;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
973 fastlocals = f->f_localsplus;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
974 freevars = f->f_localsplus + co->co_nlocals;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
975 first_instr = (unsigned char*) PyBytes_AS_STRING(co->co_code);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
976 /* An explanation is in order for the next line.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
977
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
978 f->f_lasti now refers to the index of the last instruction
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
979 executed. You might think this was obvious from the name, but
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
980 this wasn't always true before 2.3! PyFrame_New now sets
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
981 f->f_lasti to -1 (i.e. the index *before* the first instruction)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
982 and YIELD_VALUE doesn't fiddle with f_lasti any more. So this
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
983 does work. Promise.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
984
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
985 When the PREDICT() macros are enabled, some opcode pairs follow in
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
986 direct succession without updating f->f_lasti. A successful
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
987 prediction effectively links the two codes together as if they
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
988 were a single new opcode; accordingly,f->f_lasti will point to
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
989 the first code in the pair (for instance, GET_ITER followed by
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
990 FOR_ITER is effectively a single opcode and f->f_lasti will point
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
991 at to the beginning of the combined pair.)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
992 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
993 next_instr = first_instr + f->f_lasti + 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
994 stack_pointer = f->f_stacktop;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
995 assert(stack_pointer != NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
996 f->f_stacktop = NULL; /* remains NULL unless yield suspends frame */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
997
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
998 if (co->co_flags & CO_GENERATOR && !throwflag) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
999 if (f->f_exc_type != NULL && f->f_exc_type != Py_None) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1000 /* We were in an except handler when we left,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1001 restore the exception state which was put aside
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1002 (see YIELD_VALUE). */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1003 swap_exc_state(tstate, f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1004 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1005 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1006 save_exc_state(tstate, f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1007 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1008
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1009 why = WHY_NOT;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1010 err = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1011 x = Py_None; /* Not a reference, just anything non-NULL */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1012 w = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1013
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1014 if (throwflag) { /* support for generator.throw() */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1015 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1016 goto on_error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1017 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1018
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1019 for (;;) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1020 assert(stack_pointer >= f->f_valuestack); /* else underflow */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1021 assert(STACK_LEVEL() <= co->co_stacksize); /* else overflow */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1022
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1023 /* Do periodic things. Doing this every time through
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1024 the loop would add too much overhead, so we do it
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1025 only every Nth instruction. We also do it if
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1026 ``pendingcalls_to_do'' is set, i.e. when an asynchronous
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1027 event needs attention (e.g. a signal handler or
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1028 async I/O handler); see Py_AddPendingCall() and
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1029 Py_MakePendingCalls() above. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1030
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1031 if (_Py_atomic_load_relaxed(&eval_breaker)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1032 if (*next_instr == SETUP_FINALLY) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1033 /* Make the last opcode before
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1034 a try: finally: block uninterruptible. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1035 goto fast_next_opcode;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1036 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1037 tstate->tick_counter++;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1038 if (_Py_atomic_load_relaxed(&pendingcalls_to_do)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1039 if (Py_MakePendingCalls() < 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1040 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1041 goto on_error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1042 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1043 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1044 #ifdef WITH_THREAD
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1045 if (_Py_atomic_load_relaxed(&gil_drop_request)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1046 /* Give another thread a chance */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1047 if (PyThreadState_Swap(NULL) != tstate)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1048 Py_FatalError("ceval: tstate mix-up");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1049 drop_gil(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1050
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1051 /* Other threads may run now */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1052
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1053 take_gil(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1054 if (PyThreadState_Swap(tstate) != NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1055 Py_FatalError("ceval: orphan tstate");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1056 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1057 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1058 /* Check for asynchronous exceptions. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1059 if (tstate->async_exc != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1060 x = tstate->async_exc;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1061 tstate->async_exc = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1062 UNSIGNAL_ASYNC_EXC();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1063 PyErr_SetNone(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1064 Py_DECREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1065 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1066 goto on_error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1067 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1068 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1069
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1070 fast_next_opcode:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1071 f->f_lasti = INSTR_OFFSET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1072
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1073 /* line-by-line tracing support */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1074
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1075 if (_Py_TracingPossible &&
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1076 tstate->c_tracefunc != NULL && !tstate->tracing) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1077 /* see maybe_call_line_trace
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1078 for expository comments */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1079 f->f_stacktop = stack_pointer;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1080
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1081 err = maybe_call_line_trace(tstate->c_tracefunc,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1082 tstate->c_traceobj,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1083 f, &instr_lb, &instr_ub,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1084 &instr_prev);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1085 /* Reload possibly changed frame fields */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1086 JUMPTO(f->f_lasti);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1087 if (f->f_stacktop != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1088 stack_pointer = f->f_stacktop;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1089 f->f_stacktop = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1090 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1091 if (err) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1092 /* trace function raised an exception */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1093 goto on_error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1094 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1095 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1096
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1097 /* Extract opcode and argument */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1098
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1099 opcode = NEXTOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1100 oparg = 0; /* allows oparg to be stored in a register because
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1101 it doesn't have to be remembered across a full loop */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1102 if (HAS_ARG(opcode))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1103 oparg = NEXTARG();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1104 dispatch_opcode:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1105
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1106 /* Main switch on opcode */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1107
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1108 switch (opcode) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1109
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1110 /* BEWARE!
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1111 It is essential that any operation that fails sets either
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1112 x to NULL, err to nonzero, or why to anything but WHY_NOT,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1113 and that no operation that succeeds does this! */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1114
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1115 TARGET(NOP)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1116 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1117
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1118 TARGET(LOAD_FAST)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1119 x = GETLOCAL(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1120 if (x != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1121 Py_INCREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1122 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1123 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1124 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1125 format_exc_check_arg(PyExc_UnboundLocalError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1126 UNBOUNDLOCAL_ERROR_MSG,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1127 PyTuple_GetItem(co->co_varnames, oparg));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1128 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1129
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1130 TARGET(LOAD_CONST)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1131 x = GETITEM(consts, oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1132 Py_INCREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1133 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1134 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1135
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1136 PREDICTED_WITH_ARG(STORE_FAST);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1137 TARGET(STORE_FAST)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1138 v = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1139 SETLOCAL(oparg, v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1140 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1141
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1142 TARGET(POP_TOP)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1143 v = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1144 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1145 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1146
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1147 TARGET(ROT_TWO)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1148 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1149 w = SECOND();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1150 SET_TOP(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1151 SET_SECOND(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1152 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1153
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1154 TARGET(ROT_THREE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1155 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1156 w = SECOND();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1157 x = THIRD();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1158 SET_TOP(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1159 SET_SECOND(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1160 SET_THIRD(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1161 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1162
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1163 TARGET(DUP_TOP)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1164 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1165 Py_INCREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1166 PUSH(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1167 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1168
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1169 TARGET(DUP_TOP_TWO)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1170 x = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1171 Py_INCREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1172 w = SECOND();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1173 Py_INCREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1174 STACKADJ(2);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1175 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1176 SET_SECOND(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1177 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1178
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1179 TARGET(UNARY_POSITIVE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1180 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1181 x = PyNumber_Positive(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1182 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1183 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1184 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1185 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1186
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1187 TARGET(UNARY_NEGATIVE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1188 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1189 x = PyNumber_Negative(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1190 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1191 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1192 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1193 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1194
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1195 TARGET(UNARY_NOT)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1196 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1197 err = PyObject_IsTrue(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1198 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1199 if (err == 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1200 Py_INCREF(Py_True);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1201 SET_TOP(Py_True);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1202 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1203 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1204 else if (err > 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1205 Py_INCREF(Py_False);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1206 SET_TOP(Py_False);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1207 err = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1208 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1209 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1210 STACKADJ(-1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1211 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1212
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1213 TARGET(UNARY_INVERT)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1214 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1215 x = PyNumber_Invert(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1216 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1217 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1218 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1219 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1220
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1221 TARGET(BINARY_POWER)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1222 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1223 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1224 x = PyNumber_Power(v, w, Py_None);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1225 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1226 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1227 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1228 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1229 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1230
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1231 TARGET(BINARY_MULTIPLY)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1232 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1233 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1234 x = PyNumber_Multiply(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1235 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1236 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1237 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1238 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1239 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1240
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1241 TARGET(BINARY_TRUE_DIVIDE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1242 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1243 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1244 x = PyNumber_TrueDivide(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1245 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1246 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1247 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1248 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1249 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1250
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1251 TARGET(BINARY_FLOOR_DIVIDE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1252 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1253 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1254 x = PyNumber_FloorDivide(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1255 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1256 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1257 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1258 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1259 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1260
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1261 TARGET(BINARY_MODULO)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1262 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1263 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1264 if (PyUnicode_CheckExact(v))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1265 x = PyUnicode_Format(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1266 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1267 x = PyNumber_Remainder(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1268 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1269 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1270 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1271 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1272 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1273
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1274 TARGET(BINARY_ADD)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1275 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1276 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1277 if (PyUnicode_CheckExact(v) &&
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1278 PyUnicode_CheckExact(w)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1279 x = unicode_concatenate(v, w, f, next_instr);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1280 /* unicode_concatenate consumed the ref to v */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1281 goto skip_decref_vx;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1282 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1283 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1284 x = PyNumber_Add(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1285 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1286 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1287 skip_decref_vx:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1288 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1289 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1290 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1291 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1292
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1293 TARGET(BINARY_SUBTRACT)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1294 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1295 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1296 x = PyNumber_Subtract(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1297 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1298 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1299 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1300 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1301 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1302
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1303 TARGET(BINARY_SUBSCR)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1304 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1305 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1306 x = PyObject_GetItem(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1307 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1308 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1309 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1310 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1311 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1312
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1313 TARGET(BINARY_LSHIFT)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1314 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1315 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1316 x = PyNumber_Lshift(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1317 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1318 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1319 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1320 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1321 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1322
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1323 TARGET(BINARY_RSHIFT)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1324 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1325 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1326 x = PyNumber_Rshift(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1327 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1328 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1329 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1330 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1331 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1332
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1333 TARGET(BINARY_AND)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1334 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1335 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1336 x = PyNumber_And(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1337 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1338 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1339 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1340 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1341 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1342
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1343 TARGET(BINARY_XOR)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1344 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1345 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1346 x = PyNumber_Xor(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1347 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1348 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1349 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1350 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1351 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1352
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1353 TARGET(BINARY_OR)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1354 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1355 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1356 x = PyNumber_Or(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1357 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1358 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1359 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1360 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1361 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1362
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1363 TARGET(LIST_APPEND)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1364 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1365 v = PEEK(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1366 err = PyList_Append(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1367 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1368 if (err == 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1369 PREDICT(JUMP_ABSOLUTE);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1370 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1371 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1372 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1373
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1374 TARGET(SET_ADD)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1375 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1376 v = stack_pointer[-oparg];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1377 err = PySet_Add(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1378 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1379 if (err == 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1380 PREDICT(JUMP_ABSOLUTE);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1381 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1382 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1383 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1384
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1385 TARGET(INPLACE_POWER)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1386 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1387 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1388 x = PyNumber_InPlacePower(v, w, Py_None);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1389 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1390 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1391 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1392 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1393 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1394
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1395 TARGET(INPLACE_MULTIPLY)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1396 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1397 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1398 x = PyNumber_InPlaceMultiply(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1399 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1400 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1401 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1402 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1403 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1404
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1405 TARGET(INPLACE_TRUE_DIVIDE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1406 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1407 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1408 x = PyNumber_InPlaceTrueDivide(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1409 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1410 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1411 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1412 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1413 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1414
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1415 TARGET(INPLACE_FLOOR_DIVIDE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1416 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1417 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1418 x = PyNumber_InPlaceFloorDivide(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1419 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1420 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1421 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1422 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1423 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1424
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1425 TARGET(INPLACE_MODULO)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1426 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1427 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1428 x = PyNumber_InPlaceRemainder(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1429 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1430 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1431 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1432 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1433 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1434
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1435 TARGET(INPLACE_ADD)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1436 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1437 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1438 if (PyUnicode_CheckExact(v) &&
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1439 PyUnicode_CheckExact(w)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1440 x = unicode_concatenate(v, w, f, next_instr);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1441 /* unicode_concatenate consumed the ref to v */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1442 goto skip_decref_v;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1443 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1444 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1445 x = PyNumber_InPlaceAdd(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1446 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1447 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1448 skip_decref_v:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1449 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1450 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1451 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1452 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1453
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1454 TARGET(INPLACE_SUBTRACT)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1455 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1456 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1457 x = PyNumber_InPlaceSubtract(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1458 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1459 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1460 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1461 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1462 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1463
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1464 TARGET(INPLACE_LSHIFT)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1465 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1466 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1467 x = PyNumber_InPlaceLshift(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1468 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1469 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1470 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1471 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1472 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1473
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1474 TARGET(INPLACE_RSHIFT)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1475 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1476 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1477 x = PyNumber_InPlaceRshift(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1478 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1479 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1480 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1481 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1482 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1483
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1484 TARGET(INPLACE_AND)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1485 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1486 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1487 x = PyNumber_InPlaceAnd(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1488 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1489 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1490 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1491 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1492 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1493
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1494 TARGET(INPLACE_XOR)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1495 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1496 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1497 x = PyNumber_InPlaceXor(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1498 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1499 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1500 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1501 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1502 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1503
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1504 TARGET(INPLACE_OR)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1505 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1506 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1507 x = PyNumber_InPlaceOr(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1508 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1509 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1510 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1511 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1512 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1513
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1514 TARGET(STORE_SUBSCR)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1515 w = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1516 v = SECOND();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1517 u = THIRD();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1518 STACKADJ(-3);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1519 /* v[w] = u */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1520 err = PyObject_SetItem(v, w, u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1521 Py_DECREF(u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1522 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1523 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1524 if (err == 0) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1525 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1526
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1527 TARGET(DELETE_SUBSCR)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1528 w = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1529 v = SECOND();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1530 STACKADJ(-2);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1531 /* del v[w] */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1532 err = PyObject_DelItem(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1533 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1534 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1535 if (err == 0) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1536 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1537
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1538 TARGET(PRINT_EXPR)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1539 v = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1540 w = PySys_GetObject("displayhook");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1541 if (w == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1542 PyErr_SetString(PyExc_RuntimeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1543 "lost sys.displayhook");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1544 err = -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1545 x = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1546 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1547 if (err == 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1548 x = PyTuple_Pack(1, v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1549 if (x == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1550 err = -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1551 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1552 if (err == 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1553 w = PyEval_CallObject(w, x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1554 Py_XDECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1555 if (w == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1556 err = -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1557 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1558 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1559 Py_XDECREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1560 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1561
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1562 TARGET(RAISE_VARARGS)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1563 v = w = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1564 switch (oparg) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1565 case 2:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1566 v = POP(); /* cause */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1567 case 1:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1568 w = POP(); /* exc */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1569 case 0: /* Fallthrough */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1570 why = do_raise(w, v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1571 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1572 default:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1573 PyErr_SetString(PyExc_SystemError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1574 "bad RAISE_VARARGS oparg");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1575 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1576 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1577 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1578 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1579
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1580 TARGET(STORE_LOCALS)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1581 x = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1582 v = f->f_locals;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1583 Py_XDECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1584 f->f_locals = x;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1585 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1586
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1587 TARGET(RETURN_VALUE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1588 retval = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1589 why = WHY_RETURN;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1590 goto fast_block_end;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1591
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1592 TARGET(YIELD_VALUE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1593 retval = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1594 f->f_stacktop = stack_pointer;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1595 why = WHY_YIELD;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1596 goto fast_yield;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1597
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1598 TARGET(POP_EXCEPT)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1599 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1600 PyTryBlock *b = PyFrame_BlockPop(f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1601 if (b->b_type != EXCEPT_HANDLER) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1602 PyErr_SetString(PyExc_SystemError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1603 "popped block is not an except handler");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1604 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1605 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1606 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1607 UNWIND_EXCEPT_HANDLER(b);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1608 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1609 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1610
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1611 TARGET(POP_BLOCK)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1612 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1613 PyTryBlock *b = PyFrame_BlockPop(f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1614 UNWIND_BLOCK(b);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1615 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1616 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1617
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1618 PREDICTED(END_FINALLY);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1619 TARGET(END_FINALLY)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1620 v = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1621 if (PyLong_Check(v)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1622 why = (enum why_code) PyLong_AS_LONG(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1623 assert(why != WHY_YIELD);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1624 if (why == WHY_RETURN ||
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1625 why == WHY_CONTINUE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1626 retval = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1627 if (why == WHY_SILENCED) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1628 /* An exception was silenced by 'with', we must
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1629 manually unwind the EXCEPT_HANDLER block which was
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1630 created when the exception was caught, otherwise
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1631 the stack will be in an inconsistent state. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1632 PyTryBlock *b = PyFrame_BlockPop(f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1633 assert(b->b_type == EXCEPT_HANDLER);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1634 UNWIND_EXCEPT_HANDLER(b);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1635 why = WHY_NOT;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1636 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1637 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1638 else if (PyExceptionClass_Check(v)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1639 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1640 u = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1641 PyErr_Restore(v, w, u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1642 why = WHY_RERAISE;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1643 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1644 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1645 else if (v != Py_None) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1646 PyErr_SetString(PyExc_SystemError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1647 "'finally' pops bad exception");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1648 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1649 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1650 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1651 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1652
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1653 TARGET(LOAD_BUILD_CLASS)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1654 x = PyDict_GetItemString(f->f_builtins,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1655 "__build_class__");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1656 if (x == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1657 PyErr_SetString(PyExc_ImportError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1658 "__build_class__ not found");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1659 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1660 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1661 Py_INCREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1662 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1663 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1664
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1665 TARGET(STORE_NAME)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1666 w = GETITEM(names, oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1667 v = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1668 if ((x = f->f_locals) != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1669 if (PyDict_CheckExact(x))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1670 err = PyDict_SetItem(x, w, v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1671 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1672 err = PyObject_SetItem(x, w, v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1673 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1674 if (err == 0) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1675 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1676 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1677 PyErr_Format(PyExc_SystemError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1678 "no locals found when storing %R", w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1679 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1680
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1681 TARGET(DELETE_NAME)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1682 w = GETITEM(names, oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1683 if ((x = f->f_locals) != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1684 if ((err = PyObject_DelItem(x, w)) != 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1685 format_exc_check_arg(PyExc_NameError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1686 NAME_ERROR_MSG,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1687 w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1688 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1689 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1690 PyErr_Format(PyExc_SystemError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1691 "no locals when deleting %R", w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1692 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1693
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1694 PREDICTED_WITH_ARG(UNPACK_SEQUENCE);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1695 TARGET(UNPACK_SEQUENCE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1696 v = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1697 if (PyTuple_CheckExact(v) &&
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1698 PyTuple_GET_SIZE(v) == oparg) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1699 PyObject **items = \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1700 ((PyTupleObject *)v)->ob_item;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1701 while (oparg--) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1702 w = items[oparg];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1703 Py_INCREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1704 PUSH(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1705 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1706 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1707 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1708 } else if (PyList_CheckExact(v) &&
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1709 PyList_GET_SIZE(v) == oparg) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1710 PyObject **items = \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1711 ((PyListObject *)v)->ob_item;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1712 while (oparg--) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1713 w = items[oparg];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1714 Py_INCREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1715 PUSH(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1716 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1717 } else if (unpack_iterable(v, oparg, -1,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1718 stack_pointer + oparg)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1719 STACKADJ(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1720 } else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1721 /* unpack_iterable() raised an exception */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1722 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1723 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1724 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1725 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1726
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1727 TARGET(UNPACK_EX)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1728 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1729 int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1730 v = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1731
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1732 if (unpack_iterable(v, oparg & 0xFF, oparg >> 8,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1733 stack_pointer + totalargs)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1734 stack_pointer += totalargs;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1735 } else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1736 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1737 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1738 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1739 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1740 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1741
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1742 TARGET(STORE_ATTR)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1743 w = GETITEM(names, oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1744 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1745 u = SECOND();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1746 STACKADJ(-2);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1747 err = PyObject_SetAttr(v, w, u); /* v.w = u */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1748 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1749 Py_DECREF(u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1750 if (err == 0) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1751 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1752
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1753 TARGET(DELETE_ATTR)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1754 w = GETITEM(names, oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1755 v = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1756 err = PyObject_SetAttr(v, w, (PyObject *)NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1757 /* del v.w */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1758 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1759 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1760
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1761 TARGET(STORE_GLOBAL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1762 w = GETITEM(names, oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1763 v = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1764 err = PyDict_SetItem(f->f_globals, w, v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1765 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1766 if (err == 0) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1767 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1768
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1769 TARGET(DELETE_GLOBAL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1770 w = GETITEM(names, oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1771 if ((err = PyDict_DelItem(f->f_globals, w)) != 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1772 format_exc_check_arg(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1773 PyExc_NameError, GLOBAL_NAME_ERROR_MSG, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1774 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1775
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1776 TARGET(LOAD_NAME)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1777 w = GETITEM(names, oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1778 if ((v = f->f_locals) == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1779 PyErr_Format(PyExc_SystemError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1780 "no locals when loading %R", w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1781 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1782 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1783 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1784 if (PyDict_CheckExact(v)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1785 x = PyDict_GetItem(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1786 Py_XINCREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1787 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1788 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1789 x = PyObject_GetItem(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1790 if (x == NULL && PyErr_Occurred()) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1791 if (!PyErr_ExceptionMatches(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1792 PyExc_KeyError))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1793 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1794 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1795 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1796 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1797 if (x == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1798 x = PyDict_GetItem(f->f_globals, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1799 if (x == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1800 x = PyDict_GetItem(f->f_builtins, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1801 if (x == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1802 format_exc_check_arg(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1803 PyExc_NameError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1804 NAME_ERROR_MSG, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1805 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1806 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1807 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1808 Py_INCREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1809 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1810 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1811 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1812
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1813 TARGET(LOAD_GLOBAL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1814 w = GETITEM(names, oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1815 if (PyUnicode_CheckExact(w)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1816 /* Inline the PyDict_GetItem() calls.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1817 WARNING: this is an extreme speed hack.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1818 Do not try this at home. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1819 Py_hash_t hash = ((PyASCIIObject *)w)->hash;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1820 if (hash != -1) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1821 PyDictObject *d;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1822 PyDictEntry *e;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1823 d = (PyDictObject *)(f->f_globals);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1824 e = d->ma_lookup(d, w, hash);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1825 if (e == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1826 x = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1827 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1828 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1829 x = e->me_value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1830 if (x != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1831 Py_INCREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1832 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1833 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1834 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1835 d = (PyDictObject *)(f->f_builtins);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1836 e = d->ma_lookup(d, w, hash);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1837 if (e == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1838 x = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1839 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1840 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1841 x = e->me_value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1842 if (x != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1843 Py_INCREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1844 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1845 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1846 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1847 goto load_global_error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1848 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1849 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1850 /* This is the un-inlined version of the code above */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1851 x = PyDict_GetItem(f->f_globals, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1852 if (x == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1853 x = PyDict_GetItem(f->f_builtins, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1854 if (x == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1855 load_global_error:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1856 format_exc_check_arg(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1857 PyExc_NameError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1858 GLOBAL_NAME_ERROR_MSG, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1859 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1860 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1861 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1862 Py_INCREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1863 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1864 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1865
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1866 TARGET(DELETE_FAST)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1867 x = GETLOCAL(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1868 if (x != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1869 SETLOCAL(oparg, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1870 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1871 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1872 format_exc_check_arg(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1873 PyExc_UnboundLocalError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1874 UNBOUNDLOCAL_ERROR_MSG,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1875 PyTuple_GetItem(co->co_varnames, oparg)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1876 );
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1877 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1878
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1879 TARGET(DELETE_DEREF)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1880 x = freevars[oparg];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1881 if (PyCell_GET(x) != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1882 PyCell_Set(x, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1883 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1884 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1885 err = -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1886 format_exc_unbound(co, oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1887 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1888
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1889 TARGET(LOAD_CLOSURE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1890 x = freevars[oparg];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1891 Py_INCREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1892 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1893 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1894 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1895
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1896 TARGET(LOAD_DEREF)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1897 x = freevars[oparg];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1898 w = PyCell_Get(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1899 if (w != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1900 PUSH(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1901 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1902 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1903 err = -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1904 format_exc_unbound(co, oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1905 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1906
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1907 TARGET(STORE_DEREF)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1908 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1909 x = freevars[oparg];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1910 PyCell_Set(x, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1911 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1912 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1913
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1914 TARGET(BUILD_TUPLE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1915 x = PyTuple_New(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1916 if (x != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1917 for (; --oparg >= 0;) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1918 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1919 PyTuple_SET_ITEM(x, oparg, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1920 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1921 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1922 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1923 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1924 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1925
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1926 TARGET(BUILD_LIST)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1927 x = PyList_New(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1928 if (x != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1929 for (; --oparg >= 0;) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1930 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1931 PyList_SET_ITEM(x, oparg, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1932 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1933 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1934 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1935 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1936 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1937
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1938 TARGET(BUILD_SET)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1939 x = PySet_New(NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1940 if (x != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1941 for (; --oparg >= 0;) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1942 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1943 if (err == 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1944 err = PySet_Add(x, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1945 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1946 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1947 if (err != 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1948 Py_DECREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1949 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1950 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1951 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1952 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1953 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1954 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1955
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1956 TARGET(BUILD_MAP)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1957 x = _PyDict_NewPresized((Py_ssize_t)oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1958 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1959 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1960 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1961
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1962 TARGET(STORE_MAP)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1963 w = TOP(); /* key */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1964 u = SECOND(); /* value */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1965 v = THIRD(); /* dict */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1966 STACKADJ(-2);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1967 assert (PyDict_CheckExact(v));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1968 err = PyDict_SetItem(v, w, u); /* v[w] = u */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1969 Py_DECREF(u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1970 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1971 if (err == 0) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1972 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1973
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1974 TARGET(MAP_ADD)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1975 w = TOP(); /* key */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1976 u = SECOND(); /* value */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1977 STACKADJ(-2);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1978 v = stack_pointer[-oparg]; /* dict */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1979 assert (PyDict_CheckExact(v));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1980 err = PyDict_SetItem(v, w, u); /* v[w] = u */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1981 Py_DECREF(u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1982 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1983 if (err == 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1984 PREDICT(JUMP_ABSOLUTE);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1985 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1986 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1987 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1988
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1989 TARGET(LOAD_ATTR)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1990 w = GETITEM(names, oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1991 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1992 x = PyObject_GetAttr(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1993 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1994 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1995 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1996 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1997
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1998 TARGET(COMPARE_OP)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
1999 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2000 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2001 x = cmp_outcome(oparg, v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2002 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2003 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2004 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2005 if (x == NULL) break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2006 PREDICT(POP_JUMP_IF_FALSE);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2007 PREDICT(POP_JUMP_IF_TRUE);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2008 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2009
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2010 TARGET(IMPORT_NAME)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2011 w = GETITEM(names, oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2012 x = PyDict_GetItemString(f->f_builtins, "__import__");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2013 if (x == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2014 PyErr_SetString(PyExc_ImportError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2015 "__import__ not found");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2016 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2017 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2018 Py_INCREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2019 v = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2020 u = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2021 if (PyLong_AsLong(u) != -1 || PyErr_Occurred())
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2022 w = PyTuple_Pack(5,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2023 w,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2024 f->f_globals,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2025 f->f_locals == NULL ?
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2026 Py_None : f->f_locals,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2027 v,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2028 u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2029 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2030 w = PyTuple_Pack(4,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2031 w,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2032 f->f_globals,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2033 f->f_locals == NULL ?
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2034 Py_None : f->f_locals,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2035 v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2036 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2037 Py_DECREF(u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2038 if (w == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2039 u = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2040 Py_DECREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2041 x = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2042 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2043 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2044 READ_TIMESTAMP(intr0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2045 v = x;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2046 x = PyEval_CallObject(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2047 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2048 READ_TIMESTAMP(intr1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2049 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2050 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2051 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2052 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2053
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2054 TARGET(IMPORT_STAR)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2055 v = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2056 PyFrame_FastToLocals(f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2057 if ((x = f->f_locals) == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2058 PyErr_SetString(PyExc_SystemError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2059 "no locals found during 'import *'");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2060 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2061 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2062 READ_TIMESTAMP(intr0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2063 err = import_all_from(x, v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2064 READ_TIMESTAMP(intr1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2065 PyFrame_LocalsToFast(f, 0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2066 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2067 if (err == 0) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2068 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2069
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2070 TARGET(IMPORT_FROM)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2071 w = GETITEM(names, oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2072 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2073 READ_TIMESTAMP(intr0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2074 x = import_from(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2075 READ_TIMESTAMP(intr1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2076 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2077 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2078 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2079
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2080 TARGET(JUMP_FORWARD)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2081 JUMPBY(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2082 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2083
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2084 PREDICTED_WITH_ARG(POP_JUMP_IF_FALSE);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2085 TARGET(POP_JUMP_IF_FALSE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2086 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2087 if (w == Py_True) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2088 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2089 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2090 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2091 if (w == Py_False) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2092 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2093 JUMPTO(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2094 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2095 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2096 err = PyObject_IsTrue(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2097 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2098 if (err > 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2099 err = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2100 else if (err == 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2101 JUMPTO(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2102 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2103 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2104 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2105
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2106 PREDICTED_WITH_ARG(POP_JUMP_IF_TRUE);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2107 TARGET(POP_JUMP_IF_TRUE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2108 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2109 if (w == Py_False) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2110 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2111 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2112 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2113 if (w == Py_True) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2114 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2115 JUMPTO(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2116 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2117 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2118 err = PyObject_IsTrue(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2119 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2120 if (err > 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2121 err = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2122 JUMPTO(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2123 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2124 else if (err == 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2125 ;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2126 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2127 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2128 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2129
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2130 TARGET(JUMP_IF_FALSE_OR_POP)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2131 w = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2132 if (w == Py_True) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2133 STACKADJ(-1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2134 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2135 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2136 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2137 if (w == Py_False) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2138 JUMPTO(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2139 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2140 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2141 err = PyObject_IsTrue(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2142 if (err > 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2143 STACKADJ(-1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2144 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2145 err = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2146 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2147 else if (err == 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2148 JUMPTO(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2149 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2150 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2151 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2152
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2153 TARGET(JUMP_IF_TRUE_OR_POP)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2154 w = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2155 if (w == Py_False) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2156 STACKADJ(-1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2157 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2158 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2159 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2160 if (w == Py_True) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2161 JUMPTO(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2162 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2163 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2164 err = PyObject_IsTrue(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2165 if (err > 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2166 err = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2167 JUMPTO(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2168 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2169 else if (err == 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2170 STACKADJ(-1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2171 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2172 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2173 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2174 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2175 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2176
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2177 PREDICTED_WITH_ARG(JUMP_ABSOLUTE);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2178 TARGET(JUMP_ABSOLUTE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2179 JUMPTO(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2180 #if FAST_LOOPS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2181 /* Enabling this path speeds-up all while and for-loops by bypassing
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2182 the per-loop checks for signals. By default, this should be turned-off
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2183 because it prevents detection of a control-break in tight loops like
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2184 "while 1: pass". Compile with this option turned-on when you need
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2185 the speed-up and do not need break checking inside tight loops (ones
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2186 that contain only instructions ending with FAST_DISPATCH).
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2187 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2188 FAST_DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2189 #else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2190 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2191 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2192
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2193 TARGET(GET_ITER)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2194 /* before: [obj]; after [getiter(obj)] */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2195 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2196 x = PyObject_GetIter(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2197 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2198 if (x != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2199 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2200 PREDICT(FOR_ITER);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2201 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2202 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2203 STACKADJ(-1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2204 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2205
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2206 PREDICTED_WITH_ARG(FOR_ITER);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2207 TARGET(FOR_ITER)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2208 /* before: [iter]; after: [iter, iter()] *or* [] */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2209 v = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2210 x = (*v->ob_type->tp_iternext)(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2211 if (x != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2212 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2213 PREDICT(STORE_FAST);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2214 PREDICT(UNPACK_SEQUENCE);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2215 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2216 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2217 if (PyErr_Occurred()) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2218 if (!PyErr_ExceptionMatches(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2219 PyExc_StopIteration))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2220 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2221 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2222 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2223 /* iterator ended normally */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2224 x = v = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2225 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2226 JUMPBY(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2227 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2228
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2229 TARGET(BREAK_LOOP)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2230 why = WHY_BREAK;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2231 goto fast_block_end;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2232
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2233 TARGET(CONTINUE_LOOP)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2234 retval = PyLong_FromLong(oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2235 if (!retval) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2236 x = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2237 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2238 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2239 why = WHY_CONTINUE;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2240 goto fast_block_end;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2241
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2242 TARGET_WITH_IMPL(SETUP_LOOP, _setup_finally)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2243 TARGET_WITH_IMPL(SETUP_EXCEPT, _setup_finally)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2244 TARGET(SETUP_FINALLY)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2245 _setup_finally:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2246 /* NOTE: If you add any new block-setup opcodes that
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2247 are not try/except/finally handlers, you may need
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2248 to update the PyGen_NeedsFinalizing() function.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2249 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2250
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2251 PyFrame_BlockSetup(f, opcode, INSTR_OFFSET() + oparg,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2252 STACK_LEVEL());
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2253 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2254
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2255 TARGET(SETUP_WITH)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2256 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2257 static PyObject *exit, *enter;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2258 w = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2259 x = special_lookup(w, "__exit__", &exit);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2260 if (!x)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2261 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2262 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2263 u = special_lookup(w, "__enter__", &enter);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2264 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2265 if (!u) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2266 x = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2267 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2268 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2269 x = PyObject_CallFunctionObjArgs(u, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2270 Py_DECREF(u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2271 if (!x)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2272 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2273 /* Setup the finally block before pushing the result
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2274 of __enter__ on the stack. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2275 PyFrame_BlockSetup(f, SETUP_FINALLY, INSTR_OFFSET() + oparg,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2276 STACK_LEVEL());
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2277
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2278 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2279 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2280 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2281
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2282 TARGET(WITH_CLEANUP)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2283 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2284 /* At the top of the stack are 1-3 values indicating
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2285 how/why we entered the finally clause:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2286 - TOP = None
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2287 - (TOP, SECOND) = (WHY_{RETURN,CONTINUE}), retval
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2288 - TOP = WHY_*; no retval below it
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2289 - (TOP, SECOND, THIRD) = exc_info()
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2290 (FOURTH, FITH, SIXTH) = previous exception for EXCEPT_HANDLER
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2291 Below them is EXIT, the context.__exit__ bound method.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2292 In the last case, we must call
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2293 EXIT(TOP, SECOND, THIRD)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2294 otherwise we must call
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2295 EXIT(None, None, None)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2296
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2297 In the first two cases, we remove EXIT from the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2298 stack, leaving the rest in the same order. In the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2299 third case, we shift the bottom 3 values of the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2300 stack down, and replace the empty spot with NULL.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2301
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2302 In addition, if the stack represents an exception,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2303 *and* the function call returns a 'true' value, we
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2304 push WHY_SILENCED onto the stack. END_FINALLY will
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2305 then not re-raise the exception. (But non-local
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2306 gotos should still be resumed.)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2307 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2308
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2309 PyObject *exit_func;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2310 u = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2311 if (u == Py_None) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2312 (void)POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2313 exit_func = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2314 SET_TOP(u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2315 v = w = Py_None;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2316 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2317 else if (PyLong_Check(u)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2318 (void)POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2319 switch(PyLong_AsLong(u)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2320 case WHY_RETURN:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2321 case WHY_CONTINUE:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2322 /* Retval in TOP. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2323 exit_func = SECOND();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2324 SET_SECOND(TOP());
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2325 SET_TOP(u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2326 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2327 default:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2328 exit_func = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2329 SET_TOP(u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2330 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2331 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2332 u = v = w = Py_None;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2333 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2334 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2335 PyObject *tp, *exc, *tb;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2336 PyTryBlock *block;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2337 v = SECOND();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2338 w = THIRD();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2339 tp = FOURTH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2340 exc = PEEK(5);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2341 tb = PEEK(6);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2342 exit_func = PEEK(7);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2343 SET_VALUE(7, tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2344 SET_VALUE(6, exc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2345 SET_VALUE(5, tp);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2346 /* UNWIND_EXCEPT_HANDLER will pop this off. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2347 SET_FOURTH(NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2348 /* We just shifted the stack down, so we have
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2349 to tell the except handler block that the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2350 values are lower than it expects. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2351 block = &f->f_blockstack[f->f_iblock - 1];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2352 assert(block->b_type == EXCEPT_HANDLER);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2353 block->b_level--;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2354 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2355 /* XXX Not the fastest way to call it... */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2356 x = PyObject_CallFunctionObjArgs(exit_func, u, v, w,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2357 NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2358 Py_DECREF(exit_func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2359 if (x == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2360 break; /* Go to error exit */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2361
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2362 if (u != Py_None)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2363 err = PyObject_IsTrue(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2364 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2365 err = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2366 Py_DECREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2367
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2368 if (err < 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2369 break; /* Go to error exit */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2370 else if (err > 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2371 err = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2372 /* There was an exception and a True return */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2373 PUSH(PyLong_FromLong((long) WHY_SILENCED));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2374 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2375 PREDICT(END_FINALLY);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2376 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2377 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2378
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2379 TARGET(CALL_FUNCTION)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2380 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2381 PyObject **sp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2382 PCALL(PCALL_ALL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2383 sp = stack_pointer;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2384 x = call_function(&sp, oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2385 stack_pointer = sp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2386 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2387 if (x != NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2388 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2389 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2390 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2391
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2392 TARGET_WITH_IMPL(CALL_FUNCTION_VAR, _call_function_var_kw)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2393 TARGET_WITH_IMPL(CALL_FUNCTION_KW, _call_function_var_kw)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2394 TARGET(CALL_FUNCTION_VAR_KW)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2395 _call_function_var_kw:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2396 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2397 int na = oparg & 0xff;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2398 int nk = (oparg>>8) & 0xff;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2399 int flags = (opcode - CALL_FUNCTION) & 3;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2400 int n = na + 2 * nk;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2401 PyObject **pfunc, *func, **sp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2402 PCALL(PCALL_ALL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2403 if (flags & CALL_FLAG_VAR)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2404 n++;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2405 if (flags & CALL_FLAG_KW)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2406 n++;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2407 pfunc = stack_pointer - n - 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2408 func = *pfunc;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2409
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2410 if (PyMethod_Check(func)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2411 && PyMethod_GET_SELF(func) != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2412 PyObject *self = PyMethod_GET_SELF(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2413 Py_INCREF(self);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2414 func = PyMethod_GET_FUNCTION(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2415 Py_INCREF(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2416 Py_DECREF(*pfunc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2417 *pfunc = self;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2418 na++;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2419 /* n++; */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2420 } else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2421 Py_INCREF(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2422 sp = stack_pointer;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2423 READ_TIMESTAMP(intr0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2424 x = ext_do_call(func, &sp, flags, na, nk);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2425 READ_TIMESTAMP(intr1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2426 stack_pointer = sp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2427 Py_DECREF(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2428
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2429 while (stack_pointer > pfunc) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2430 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2431 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2432 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2433 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2434 if (x != NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2435 DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2436 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2437 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2438
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2439 TARGET_WITH_IMPL(MAKE_CLOSURE, _make_function)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2440 TARGET(MAKE_FUNCTION)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2441 _make_function:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2442 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2443 int posdefaults = oparg & 0xff;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2444 int kwdefaults = (oparg>>8) & 0xff;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2445 int num_annotations = (oparg >> 16) & 0x7fff;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2446
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2447 w = POP(); /* qualname */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2448 v = POP(); /* code object */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2449 x = PyFunction_NewWithQualName(v, f->f_globals, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2450 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2451 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2452
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2453 if (x != NULL && opcode == MAKE_CLOSURE) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2454 v = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2455 if (PyFunction_SetClosure(x, v) != 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2456 /* Can't happen unless bytecode is corrupt. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2457 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2458 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2459 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2460 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2461
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2462 if (x != NULL && num_annotations > 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2463 Py_ssize_t name_ix;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2464 u = POP(); /* names of args with annotations */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2465 v = PyDict_New();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2466 if (v == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2467 Py_DECREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2468 x = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2469 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2470 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2471 name_ix = PyTuple_Size(u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2472 assert(num_annotations == name_ix+1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2473 while (name_ix > 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2474 --name_ix;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2475 t = PyTuple_GET_ITEM(u, name_ix);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2476 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2477 /* XXX(nnorwitz): check for errors */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2478 PyDict_SetItem(v, t, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2479 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2480 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2481
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2482 if (PyFunction_SetAnnotations(x, v) != 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2483 /* Can't happen unless
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2484 PyFunction_SetAnnotations changes. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2485 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2486 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2487 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2488 Py_DECREF(u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2489 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2490
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2491 /* XXX Maybe this should be a separate opcode? */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2492 if (x != NULL && posdefaults > 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2493 v = PyTuple_New(posdefaults);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2494 if (v == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2495 Py_DECREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2496 x = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2497 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2498 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2499 while (--posdefaults >= 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2500 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2501 PyTuple_SET_ITEM(v, posdefaults, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2502 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2503 if (PyFunction_SetDefaults(x, v) != 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2504 /* Can't happen unless
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2505 PyFunction_SetDefaults changes. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2506 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2507 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2508 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2509 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2510 if (x != NULL && kwdefaults > 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2511 v = PyDict_New();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2512 if (v == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2513 Py_DECREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2514 x = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2515 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2516 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2517 while (--kwdefaults >= 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2518 w = POP(); /* default value */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2519 u = POP(); /* kw only arg name */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2520 /* XXX(nnorwitz): check for errors */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2521 PyDict_SetItem(v, u, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2522 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2523 Py_DECREF(u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2524 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2525 if (PyFunction_SetKwDefaults(x, v) != 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2526 /* Can't happen unless
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2527 PyFunction_SetKwDefaults changes. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2528 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2529 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2530 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2531 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2532 PUSH(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2533 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2534 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2535
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2536 TARGET(BUILD_SLICE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2537 if (oparg == 3)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2538 w = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2539 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2540 w = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2541 v = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2542 u = TOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2543 x = PySlice_New(u, v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2544 Py_DECREF(u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2545 Py_DECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2546 Py_XDECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2547 SET_TOP(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2548 if (x != NULL) DISPATCH();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2549 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2550
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2551 TARGET(EXTENDED_ARG)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2552 opcode = NEXTOP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2553 oparg = oparg<<16 | NEXTARG();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2554 goto dispatch_opcode;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2555
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2556 #if USE_COMPUTED_GOTOS
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2557 _unknown_opcode:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2558 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2559 default:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2560 fprintf(stderr,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2561 "XXX lineno: %d, opcode: %d\n",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2562 PyFrame_GetLineNumber(f),
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2563 opcode);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2564 PyErr_SetString(PyExc_SystemError, "unknown opcode");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2565 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2566 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2567
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2568
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2569 } /* switch */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2570
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2571 on_error:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2572
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2573 READ_TIMESTAMP(inst1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2574
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2575 /* Quickly continue if no error occurred */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2576
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2577 if (why == WHY_NOT) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2578 if (err == 0 && x != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2579 #ifdef CHECKEXC
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2580 /* This check is expensive! */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2581 if (PyErr_Occurred())
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2582 fprintf(stderr,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2583 "XXX undetected error\n");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2584 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2585 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2586 READ_TIMESTAMP(loop1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2587 continue; /* Normal, fast path */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2588 #ifdef CHECKEXC
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2589 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2590 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2591 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2592 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2593 x = Py_None;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2594 err = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2595 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2596
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2597 /* Double-check exception status */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2598
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2599 if (why == WHY_EXCEPTION || why == WHY_RERAISE) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2600 if (!PyErr_Occurred()) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2601 PyErr_SetString(PyExc_SystemError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2602 "error return without exception set");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2603 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2604 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2605 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2606 #ifdef CHECKEXC
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2607 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2608 /* This check is expensive! */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2609 if (PyErr_Occurred()) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2610 char buf[128];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2611 sprintf(buf, "Stack unwind with exception "
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2612 "set and why=%d", why);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2613 Py_FatalError(buf);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2614 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2615 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2616 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2617
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2618 /* Log traceback info if this is a real exception */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2619
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2620 if (why == WHY_EXCEPTION) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2621 PyTraceBack_Here(f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2622
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2623 if (tstate->c_tracefunc != NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2624 call_exc_trace(tstate->c_tracefunc,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2625 tstate->c_traceobj, f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2626 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2627
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2628 /* For the rest, treat WHY_RERAISE as WHY_EXCEPTION */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2629
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2630 if (why == WHY_RERAISE)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2631 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2632
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2633 /* Unwind stacks if a (pseudo) exception occurred */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2634
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2635 fast_block_end:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2636 while (why != WHY_NOT && f->f_iblock > 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2637 /* Peek at the current block. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2638 PyTryBlock *b = &f->f_blockstack[f->f_iblock - 1];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2639
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2640 assert(why != WHY_YIELD);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2641 if (b->b_type == SETUP_LOOP && why == WHY_CONTINUE) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2642 why = WHY_NOT;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2643 JUMPTO(PyLong_AS_LONG(retval));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2644 Py_DECREF(retval);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2645 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2646 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2647 /* Now we have to pop the block. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2648 f->f_iblock--;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2649
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2650 if (b->b_type == EXCEPT_HANDLER) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2651 UNWIND_EXCEPT_HANDLER(b);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2652 continue;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2653 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2654 UNWIND_BLOCK(b);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2655 if (b->b_type == SETUP_LOOP && why == WHY_BREAK) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2656 why = WHY_NOT;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2657 JUMPTO(b->b_handler);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2658 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2659 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2660 if (why == WHY_EXCEPTION && (b->b_type == SETUP_EXCEPT
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2661 || b->b_type == SETUP_FINALLY)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2662 PyObject *exc, *val, *tb;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2663 int handler = b->b_handler;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2664 /* Beware, this invalidates all b->b_* fields */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2665 PyFrame_BlockSetup(f, EXCEPT_HANDLER, -1, STACK_LEVEL());
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2666 PUSH(tstate->exc_traceback);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2667 PUSH(tstate->exc_value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2668 if (tstate->exc_type != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2669 PUSH(tstate->exc_type);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2670 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2671 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2672 Py_INCREF(Py_None);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2673 PUSH(Py_None);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2674 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2675 PyErr_Fetch(&exc, &val, &tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2676 /* Make the raw exception data
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2677 available to the handler,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2678 so a program can emulate the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2679 Python main loop. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2680 PyErr_NormalizeException(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2681 &exc, &val, &tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2682 PyException_SetTraceback(val, tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2683 Py_INCREF(exc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2684 tstate->exc_type = exc;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2685 Py_INCREF(val);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2686 tstate->exc_value = val;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2687 tstate->exc_traceback = tb;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2688 if (tb == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2689 tb = Py_None;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2690 Py_INCREF(tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2691 PUSH(tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2692 PUSH(val);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2693 PUSH(exc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2694 why = WHY_NOT;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2695 JUMPTO(handler);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2696 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2697 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2698 if (b->b_type == SETUP_FINALLY) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2699 if (why & (WHY_RETURN | WHY_CONTINUE))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2700 PUSH(retval);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2701 PUSH(PyLong_FromLong((long)why));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2702 why = WHY_NOT;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2703 JUMPTO(b->b_handler);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2704 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2705 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2706 } /* unwind stack */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2707
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2708 /* End the loop if we still have an error (or return) */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2709
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2710 if (why != WHY_NOT)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2711 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2712 READ_TIMESTAMP(loop1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2713
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2714 } /* main loop */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2715
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2716 assert(why != WHY_YIELD);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2717 /* Pop remaining stack entries. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2718 while (!EMPTY()) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2719 v = POP();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2720 Py_XDECREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2721 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2722
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2723 if (why != WHY_RETURN)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2724 retval = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2725
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2726 fast_yield:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2727 if (co->co_flags & CO_GENERATOR && (why == WHY_YIELD || why == WHY_RETURN)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2728 /* The purpose of this block is to put aside the generator's exception
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2729 state and restore that of the calling frame. If the current
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2730 exception state is from the caller, we clear the exception values
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2731 on the generator frame, so they are not swapped back in latter. The
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2732 origin of the current exception state is determined by checking for
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2733 except handler blocks, which we must be in iff a new exception
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2734 state came into existence in this frame. (An uncaught exception
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2735 would have why == WHY_EXCEPTION, and we wouldn't be here). */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2736 int i;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2737 for (i = 0; i < f->f_iblock; i++)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2738 if (f->f_blockstack[i].b_type == EXCEPT_HANDLER)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2739 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2740 if (i == f->f_iblock)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2741 /* We did not create this exception. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2742 restore_and_clear_exc_state(tstate, f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2743 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2744 swap_exc_state(tstate, f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2745 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2746
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2747 if (tstate->use_tracing) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2748 if (tstate->c_tracefunc) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2749 if (why == WHY_RETURN || why == WHY_YIELD) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2750 if (call_trace(tstate->c_tracefunc,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2751 tstate->c_traceobj, f,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2752 PyTrace_RETURN, retval)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2753 Py_XDECREF(retval);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2754 retval = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2755 why = WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2756 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2757 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2758 else if (why == WHY_EXCEPTION) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2759 call_trace_protected(tstate->c_tracefunc,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2760 tstate->c_traceobj, f,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2761 PyTrace_RETURN, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2762 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2763 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2764 if (tstate->c_profilefunc) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2765 if (why == WHY_EXCEPTION)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2766 call_trace_protected(tstate->c_profilefunc,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2767 tstate->c_profileobj, f,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2768 PyTrace_RETURN, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2769 else if (call_trace(tstate->c_profilefunc,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2770 tstate->c_profileobj, f,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2771 PyTrace_RETURN, retval)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2772 Py_XDECREF(retval);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2773 retval = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2774 /* why = WHY_EXCEPTION; */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2775 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2776 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2777 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2778
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2779 /* pop frame */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2780 exit_eval_frame:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2781 Py_LeaveRecursiveCall();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2782 tstate->frame = f->f_back;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2783
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2784 return retval;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2785 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2786
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2787 static void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2788 format_missing(const char *kind, PyCodeObject *co, PyObject *names)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2789 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2790 int err;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2791 Py_ssize_t len = PyList_GET_SIZE(names);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2792 PyObject *name_str, *comma, *tail, *tmp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2793
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2794 assert(PyList_CheckExact(names));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2795 assert(len >= 1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2796 /* Deal with the joys of natural language. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2797 switch (len) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2798 case 1:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2799 name_str = PyList_GET_ITEM(names, 0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2800 Py_INCREF(name_str);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2801 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2802 case 2:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2803 name_str = PyUnicode_FromFormat("%U and %U",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2804 PyList_GET_ITEM(names, len - 2),
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2805 PyList_GET_ITEM(names, len - 1));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2806 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2807 default:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2808 tail = PyUnicode_FromFormat(", %U, and %U",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2809 PyList_GET_ITEM(names, len - 2),
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2810 PyList_GET_ITEM(names, len - 1));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2811 /* Chop off the last two objects in the list. This shouldn't actually
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2812 fail, but we can't be too careful. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2813 err = PyList_SetSlice(names, len - 2, len, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2814 if (err == -1) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2815 Py_DECREF(tail);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2816 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2817 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2818 /* Stitch everything up into a nice comma-separated list. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2819 comma = PyUnicode_FromString(", ");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2820 if (comma == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2821 Py_DECREF(tail);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2822 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2823 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2824 tmp = PyUnicode_Join(comma, names);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2825 Py_DECREF(comma);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2826 if (tmp == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2827 Py_DECREF(tail);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2828 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2829 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2830 name_str = PyUnicode_Concat(tmp, tail);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2831 Py_DECREF(tmp);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2832 Py_DECREF(tail);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2833 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2834 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2835 if (name_str == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2836 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2837 PyErr_Format(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2838 "%U() missing %i required %s argument%s: %U",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2839 co->co_name,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2840 len,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2841 kind,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2842 len == 1 ? "" : "s",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2843 name_str);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2844 Py_DECREF(name_str);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2845 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2846
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2847 static void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2848 missing_arguments(PyCodeObject *co, int missing, int defcount,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2849 PyObject **fastlocals)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2850 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2851 int i, j = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2852 int start, end;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2853 int positional = defcount != -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2854 const char *kind = positional ? "positional" : "keyword-only";
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2855 PyObject *missing_names;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2856
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2857 /* Compute the names of the arguments that are missing. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2858 missing_names = PyList_New(missing);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2859 if (missing_names == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2860 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2861 if (positional) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2862 start = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2863 end = co->co_argcount - defcount;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2864 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2865 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2866 start = co->co_argcount;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2867 end = start + co->co_kwonlyargcount;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2868 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2869 for (i = start; i < end; i++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2870 if (GETLOCAL(i) == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2871 PyObject *raw = PyTuple_GET_ITEM(co->co_varnames, i);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2872 PyObject *name = PyObject_Repr(raw);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2873 if (name == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2874 Py_DECREF(missing_names);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2875 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2876 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2877 PyList_SET_ITEM(missing_names, j++, name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2878 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2879 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2880 assert(j == missing);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2881 format_missing(kind, co, missing_names);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2882 Py_DECREF(missing_names);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2883 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2884
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2885 static void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2886 too_many_positional(PyCodeObject *co, int given, int defcount, PyObject **fastlocals)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2887 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2888 int plural;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2889 int kwonly_given = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2890 int i;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2891 PyObject *sig, *kwonly_sig;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2892
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2893 assert((co->co_flags & CO_VARARGS) == 0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2894 /* Count missing keyword-only args. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2895 for (i = co->co_argcount; i < co->co_argcount + co->co_kwonlyargcount; i++)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2896 if (GETLOCAL(i) != NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2897 kwonly_given++;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2898 if (defcount) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2899 int atleast = co->co_argcount - defcount;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2900 plural = 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2901 sig = PyUnicode_FromFormat("from %d to %d", atleast, co->co_argcount);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2902 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2903 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2904 plural = co->co_argcount != 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2905 sig = PyUnicode_FromFormat("%d", co->co_argcount);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2906 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2907 if (sig == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2908 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2909 if (kwonly_given) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2910 const char *format = " positional argument%s (and %d keyword-only argument%s)";
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2911 kwonly_sig = PyUnicode_FromFormat(format, given != 1 ? "s" : "", kwonly_given,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2912 kwonly_given != 1 ? "s" : "");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2913 if (kwonly_sig == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2914 Py_DECREF(sig);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2915 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2916 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2917 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2918 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2919 /* This will not fail. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2920 kwonly_sig = PyUnicode_FromString("");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2921 assert(kwonly_sig != NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2922 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2923 PyErr_Format(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2924 "%U() takes %U positional argument%s but %d%U %s given",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2925 co->co_name,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2926 sig,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2927 plural ? "s" : "",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2928 given,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2929 kwonly_sig,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2930 given == 1 && !kwonly_given ? "was" : "were");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2931 Py_DECREF(sig);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2932 Py_DECREF(kwonly_sig);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2933 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2934
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2935 /* This is gonna seem *real weird*, but if you put some other code between
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2936 PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2937 the test in the if statements in Misc/gdbinit (pystack and pystackv). */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2938
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2939 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2940 PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2941 PyObject **args, int argcount, PyObject **kws, int kwcount,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2942 PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2943 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2944 PyCodeObject* co = (PyCodeObject*)_co;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2945 register PyFrameObject *f;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2946 register PyObject *retval = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2947 register PyObject **fastlocals, **freevars;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2948 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2949 PyObject *x, *u;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2950 int total_args = co->co_argcount + co->co_kwonlyargcount;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2951 int i;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2952 int n = argcount;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2953 PyObject *kwdict = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2954
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2955 if (globals == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2956 PyErr_SetString(PyExc_SystemError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2957 "PyEval_EvalCodeEx: NULL globals");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2958 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2959 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2960
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2961 assert(tstate != NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2962 assert(globals != NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2963 f = PyFrame_New(tstate, co, globals, locals);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2964 if (f == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2965 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2966
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2967 fastlocals = f->f_localsplus;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2968 freevars = f->f_localsplus + co->co_nlocals;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2969
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2970 /* Parse arguments. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2971 if (co->co_flags & CO_VARKEYWORDS) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2972 kwdict = PyDict_New();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2973 if (kwdict == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2974 goto fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2975 i = total_args;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2976 if (co->co_flags & CO_VARARGS)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2977 i++;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2978 SETLOCAL(i, kwdict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2979 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2980 if (argcount > co->co_argcount)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2981 n = co->co_argcount;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2982 for (i = 0; i < n; i++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2983 x = args[i];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2984 Py_INCREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2985 SETLOCAL(i, x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2986 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2987 if (co->co_flags & CO_VARARGS) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2988 u = PyTuple_New(argcount - n);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2989 if (u == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2990 goto fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2991 SETLOCAL(total_args, u);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2992 for (i = n; i < argcount; i++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2993 x = args[i];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2994 Py_INCREF(x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2995 PyTuple_SET_ITEM(u, i-n, x);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2996 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2997 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2998 for (i = 0; i < kwcount; i++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
2999 PyObject **co_varnames;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3000 PyObject *keyword = kws[2*i];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3001 PyObject *value = kws[2*i + 1];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3002 int j;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3003 if (keyword == NULL || !PyUnicode_Check(keyword)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3004 PyErr_Format(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3005 "%U() keywords must be strings",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3006 co->co_name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3007 goto fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3008 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3009 /* Speed hack: do raw pointer compares. As names are
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3010 normally interned this should almost always hit. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3011 co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3012 for (j = 0; j < total_args; j++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3013 PyObject *nm = co_varnames[j];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3014 if (nm == keyword)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3015 goto kw_found;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3016 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3017 /* Slow fallback, just in case */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3018 for (j = 0; j < total_args; j++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3019 PyObject *nm = co_varnames[j];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3020 int cmp = PyObject_RichCompareBool(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3021 keyword, nm, Py_EQ);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3022 if (cmp > 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3023 goto kw_found;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3024 else if (cmp < 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3025 goto fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3026 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3027 if (j >= total_args && kwdict == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3028 PyErr_Format(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3029 "%U() got an unexpected "
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3030 "keyword argument '%S'",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3031 co->co_name,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3032 keyword);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3033 goto fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3034 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3035 PyDict_SetItem(kwdict, keyword, value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3036 continue;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3037 kw_found:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3038 if (GETLOCAL(j) != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3039 PyErr_Format(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3040 "%U() got multiple "
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3041 "values for argument '%S'",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3042 co->co_name,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3043 keyword);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3044 goto fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3045 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3046 Py_INCREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3047 SETLOCAL(j, value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3048 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3049 if (argcount > co->co_argcount && !(co->co_flags & CO_VARARGS)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3050 too_many_positional(co, argcount, defcount, fastlocals);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3051 goto fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3052 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3053 if (argcount < co->co_argcount) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3054 int m = co->co_argcount - defcount;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3055 int missing = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3056 for (i = argcount; i < m; i++)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3057 if (GETLOCAL(i) == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3058 missing++;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3059 if (missing) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3060 missing_arguments(co, missing, defcount, fastlocals);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3061 goto fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3062 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3063 if (n > m)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3064 i = n - m;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3065 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3066 i = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3067 for (; i < defcount; i++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3068 if (GETLOCAL(m+i) == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3069 PyObject *def = defs[i];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3070 Py_INCREF(def);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3071 SETLOCAL(m+i, def);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3072 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3073 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3074 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3075 if (co->co_kwonlyargcount > 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3076 int missing = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3077 for (i = co->co_argcount; i < total_args; i++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3078 PyObject *name;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3079 if (GETLOCAL(i) != NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3080 continue;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3081 name = PyTuple_GET_ITEM(co->co_varnames, i);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3082 if (kwdefs != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3083 PyObject *def = PyDict_GetItem(kwdefs, name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3084 if (def) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3085 Py_INCREF(def);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3086 SETLOCAL(i, def);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3087 continue;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3088 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3089 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3090 missing++;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3091 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3092 if (missing) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3093 missing_arguments(co, missing, -1, fastlocals);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3094 goto fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3095 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3096 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3097
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3098 /* Allocate and initialize storage for cell vars, and copy free
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3099 vars into frame. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3100 for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3101 PyObject *c;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3102 int arg;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3103 /* Possibly account for the cell variable being an argument. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3104 if (co->co_cell2arg != NULL &&
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3105 (arg = co->co_cell2arg[i]) != CO_CELL_NOT_AN_ARG)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3106 c = PyCell_New(GETLOCAL(arg));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3107 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3108 c = PyCell_New(NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3109 if (c == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3110 goto fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3111 SETLOCAL(co->co_nlocals + i, c);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3112 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3113 for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3114 PyObject *o = PyTuple_GET_ITEM(closure, i);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3115 Py_INCREF(o);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3116 freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3117 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3118
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3119 if (co->co_flags & CO_GENERATOR) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3120 /* Don't need to keep the reference to f_back, it will be set
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3121 * when the generator is resumed. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3122 Py_XDECREF(f->f_back);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3123 f->f_back = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3124
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3125 PCALL(PCALL_GENERATOR);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3126
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3127 /* Create a new generator that owns the ready to run frame
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3128 * and return that as the value. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3129 return PyGen_New(f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3130 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3131
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3132 retval = PyEval_EvalFrameEx(f,0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3133
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3134 fail: /* Jump here from prelude on failure */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3135
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3136 /* decref'ing the frame can cause __del__ methods to get invoked,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3137 which can call back into Python. While we're done with the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3138 current Python frame (f), the associated C stack is still in use,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3139 so recursion_depth must be boosted for the duration.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3140 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3141 assert(tstate != NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3142 ++tstate->recursion_depth;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3143 Py_DECREF(f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3144 --tstate->recursion_depth;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3145 return retval;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3146 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3147
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3148
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3149 static PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3150 special_lookup(PyObject *o, char *meth, PyObject **cache)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3151 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3152 PyObject *res;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3153 res = _PyObject_LookupSpecial(o, meth, cache);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3154 if (res == NULL && !PyErr_Occurred()) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3155 PyErr_SetObject(PyExc_AttributeError, *cache);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3156 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3157 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3158 return res;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3159 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3160
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3161
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3162 /* These 3 functions deal with the exception state of generators. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3163
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3164 static void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3165 save_exc_state(PyThreadState *tstate, PyFrameObject *f)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3166 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3167 PyObject *type, *value, *traceback;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3168 Py_XINCREF(tstate->exc_type);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3169 Py_XINCREF(tstate->exc_value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3170 Py_XINCREF(tstate->exc_traceback);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3171 type = f->f_exc_type;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3172 value = f->f_exc_value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3173 traceback = f->f_exc_traceback;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3174 f->f_exc_type = tstate->exc_type;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3175 f->f_exc_value = tstate->exc_value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3176 f->f_exc_traceback = tstate->exc_traceback;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3177 Py_XDECREF(type);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3178 Py_XDECREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3179 Py_XDECREF(traceback);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3180 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3181
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3182 static void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3183 swap_exc_state(PyThreadState *tstate, PyFrameObject *f)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3184 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3185 PyObject *tmp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3186 tmp = tstate->exc_type;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3187 tstate->exc_type = f->f_exc_type;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3188 f->f_exc_type = tmp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3189 tmp = tstate->exc_value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3190 tstate->exc_value = f->f_exc_value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3191 f->f_exc_value = tmp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3192 tmp = tstate->exc_traceback;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3193 tstate->exc_traceback = f->f_exc_traceback;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3194 f->f_exc_traceback = tmp;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3195 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3196
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3197 static void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3198 restore_and_clear_exc_state(PyThreadState *tstate, PyFrameObject *f)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3199 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3200 PyObject *type, *value, *tb;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3201 type = tstate->exc_type;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3202 value = tstate->exc_value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3203 tb = tstate->exc_traceback;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3204 tstate->exc_type = f->f_exc_type;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3205 tstate->exc_value = f->f_exc_value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3206 tstate->exc_traceback = f->f_exc_traceback;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3207 f->f_exc_type = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3208 f->f_exc_value = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3209 f->f_exc_traceback = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3210 Py_XDECREF(type);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3211 Py_XDECREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3212 Py_XDECREF(tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3213 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3214
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3215
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3216 /* Logic for the raise statement (too complicated for inlining).
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3217 This *consumes* a reference count to each of its arguments. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3218 static enum why_code
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3219 do_raise(PyObject *exc, PyObject *cause)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3220 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3221 PyObject *type = NULL, *value = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3222
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3223 if (exc == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3224 /* Reraise */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3225 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3226 PyObject *tb;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3227 type = tstate->exc_type;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3228 value = tstate->exc_value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3229 tb = tstate->exc_traceback;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3230 if (type == Py_None) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3231 PyErr_SetString(PyExc_RuntimeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3232 "No active exception to reraise");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3233 return WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3234 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3235 Py_XINCREF(type);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3236 Py_XINCREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3237 Py_XINCREF(tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3238 PyErr_Restore(type, value, tb);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3239 return WHY_RERAISE;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3240 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3241
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3242 /* We support the following forms of raise:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3243 raise
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3244 raise <instance>
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3245 raise <type> */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3246
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3247 if (PyExceptionClass_Check(exc)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3248 type = exc;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3249 value = PyObject_CallObject(exc, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3250 if (value == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3251 goto raise_error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3252 if (!PyExceptionInstance_Check(value)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3253 PyErr_Format(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3254 "calling %R should have returned an instance of "
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3255 "BaseException, not %R",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3256 type, Py_TYPE(value));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3257 goto raise_error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3258 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3259 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3260 else if (PyExceptionInstance_Check(exc)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3261 value = exc;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3262 type = PyExceptionInstance_Class(exc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3263 Py_INCREF(type);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3264 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3265 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3266 /* Not something you can raise. You get an exception
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3267 anyway, just not what you specified :-) */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3268 Py_DECREF(exc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3269 PyErr_SetString(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3270 "exceptions must derive from BaseException");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3271 goto raise_error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3272 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3273
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3274 if (cause) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3275 PyObject *fixed_cause;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3276 if (PyExceptionClass_Check(cause)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3277 fixed_cause = PyObject_CallObject(cause, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3278 if (fixed_cause == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3279 goto raise_error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3280 Py_DECREF(cause);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3281 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3282 else if (PyExceptionInstance_Check(cause)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3283 fixed_cause = cause;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3284 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3285 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3286 PyErr_SetString(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3287 "exception causes must derive from "
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3288 "BaseException");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3289 goto raise_error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3290 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3291 PyException_SetCause(value, fixed_cause);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3292 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3293
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3294 PyErr_SetObject(type, value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3295 /* PyErr_SetObject incref's its arguments */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3296 Py_XDECREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3297 Py_XDECREF(type);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3298 return WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3299
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3300 raise_error:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3301 Py_XDECREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3302 Py_XDECREF(type);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3303 Py_XDECREF(cause);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3304 return WHY_EXCEPTION;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3305 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3306
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3307 /* Iterate v argcnt times and store the results on the stack (via decreasing
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3308 sp). Return 1 for success, 0 if error.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3309
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3310 If argcntafter == -1, do a simple unpack. If it is >= 0, do an unpack
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3311 with a variable target.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3312 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3313
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3314 static int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3315 unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3316 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3317 int i = 0, j = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3318 Py_ssize_t ll = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3319 PyObject *it; /* iter(v) */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3320 PyObject *w;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3321 PyObject *l = NULL; /* variable list */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3322
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3323 assert(v != NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3324
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3325 it = PyObject_GetIter(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3326 if (it == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3327 goto Error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3328
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3329 for (; i < argcnt; i++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3330 w = PyIter_Next(it);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3331 if (w == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3332 /* Iterator done, via error or exhaustion. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3333 if (!PyErr_Occurred()) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3334 PyErr_Format(PyExc_ValueError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3335 "need more than %d value%s to unpack",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3336 i, i == 1 ? "" : "s");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3337 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3338 goto Error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3339 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3340 *--sp = w;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3341 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3342
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3343 if (argcntafter == -1) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3344 /* We better have exhausted the iterator now. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3345 w = PyIter_Next(it);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3346 if (w == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3347 if (PyErr_Occurred())
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3348 goto Error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3349 Py_DECREF(it);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3350 return 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3351 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3352 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3353 PyErr_Format(PyExc_ValueError, "too many values to unpack "
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3354 "(expected %d)", argcnt);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3355 goto Error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3356 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3357
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3358 l = PySequence_List(it);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3359 if (l == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3360 goto Error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3361 *--sp = l;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3362 i++;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3363
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3364 ll = PyList_GET_SIZE(l);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3365 if (ll < argcntafter) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3366 PyErr_Format(PyExc_ValueError, "need more than %zd values to unpack",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3367 argcnt + ll);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3368 goto Error;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3369 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3370
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3371 /* Pop the "after-variable" args off the list. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3372 for (j = argcntafter; j > 0; j--, i++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3373 *--sp = PyList_GET_ITEM(l, ll - j);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3374 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3375 /* Resize the list. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3376 Py_SIZE(l) = ll - argcntafter;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3377 Py_DECREF(it);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3378 return 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3379
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3380 Error:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3381 for (; i > 0; i--, sp++)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3382 Py_DECREF(*sp);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3383 Py_XDECREF(it);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3384 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3385 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3386
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3387
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3388 #ifdef LLTRACE
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3389 static int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3390 prtrace(PyObject *v, char *str)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3391 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3392 printf("%s ", str);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3393 if (PyObject_Print(v, stdout, 0) != 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3394 PyErr_Clear(); /* Don't know what else to do */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3395 printf("\n");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3396 return 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3397 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3398 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3399
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3400 static void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3401 call_exc_trace(Py_tracefunc func, PyObject *self, PyFrameObject *f)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3402 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3403 PyObject *type, *value, *traceback, *arg;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3404 int err;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3405 PyErr_Fetch(&type, &value, &traceback);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3406 if (value == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3407 value = Py_None;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3408 Py_INCREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3409 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3410 arg = PyTuple_Pack(3, type, value, traceback);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3411 if (arg == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3412 PyErr_Restore(type, value, traceback);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3413 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3414 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3415 err = call_trace(func, self, f, PyTrace_EXCEPTION, arg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3416 Py_DECREF(arg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3417 if (err == 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3418 PyErr_Restore(type, value, traceback);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3419 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3420 Py_XDECREF(type);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3421 Py_XDECREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3422 Py_XDECREF(traceback);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3423 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3424 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3425
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3426 static int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3427 call_trace_protected(Py_tracefunc func, PyObject *obj, PyFrameObject *frame,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3428 int what, PyObject *arg)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3429 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3430 PyObject *type, *value, *traceback;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3431 int err;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3432 PyErr_Fetch(&type, &value, &traceback);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3433 err = call_trace(func, obj, frame, what, arg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3434 if (err == 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3435 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3436 PyErr_Restore(type, value, traceback);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3437 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3438 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3439 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3440 Py_XDECREF(type);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3441 Py_XDECREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3442 Py_XDECREF(traceback);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3443 return -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3444 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3445 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3446
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3447 static int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3448 call_trace(Py_tracefunc func, PyObject *obj, PyFrameObject *frame,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3449 int what, PyObject *arg)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3450 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3451 register PyThreadState *tstate = frame->f_tstate;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3452 int result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3453 if (tstate->tracing)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3454 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3455 tstate->tracing++;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3456 tstate->use_tracing = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3457 result = func(obj, frame, what, arg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3458 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3459 || (tstate->c_profilefunc != NULL));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3460 tstate->tracing--;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3461 return result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3462 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3463
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3464 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3465 _PyEval_CallTracing(PyObject *func, PyObject *args)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3466 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3467 PyFrameObject *frame = PyEval_GetFrame();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3468 PyThreadState *tstate = frame->f_tstate;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3469 int save_tracing = tstate->tracing;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3470 int save_use_tracing = tstate->use_tracing;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3471 PyObject *result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3472
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3473 tstate->tracing = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3474 tstate->use_tracing = ((tstate->c_tracefunc != NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3475 || (tstate->c_profilefunc != NULL));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3476 result = PyObject_Call(func, args, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3477 tstate->tracing = save_tracing;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3478 tstate->use_tracing = save_use_tracing;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3479 return result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3480 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3481
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3482 /* See Objects/lnotab_notes.txt for a description of how tracing works. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3483 static int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3484 maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3485 PyFrameObject *frame, int *instr_lb, int *instr_ub,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3486 int *instr_prev)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3487 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3488 int result = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3489 int line = frame->f_lineno;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3490
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3491 /* If the last instruction executed isn't in the current
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3492 instruction window, reset the window.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3493 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3494 if (frame->f_lasti < *instr_lb || frame->f_lasti >= *instr_ub) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3495 PyAddrPair bounds;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3496 line = _PyCode_CheckLineNumber(frame->f_code, frame->f_lasti,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3497 &bounds);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3498 *instr_lb = bounds.ap_lower;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3499 *instr_ub = bounds.ap_upper;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3500 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3501 /* If the last instruction falls at the start of a line or if
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3502 it represents a jump backwards, update the frame's line
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3503 number and call the trace function. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3504 if (frame->f_lasti == *instr_lb || frame->f_lasti < *instr_prev) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3505 frame->f_lineno = line;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3506 result = call_trace(func, obj, frame, PyTrace_LINE, Py_None);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3507 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3508 *instr_prev = frame->f_lasti;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3509 return result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3510 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3511
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3512 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3513 PyEval_SetProfile(Py_tracefunc func, PyObject *arg)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3514 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3515 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3516 PyObject *temp = tstate->c_profileobj;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3517 Py_XINCREF(arg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3518 tstate->c_profilefunc = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3519 tstate->c_profileobj = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3520 /* Must make sure that tracing is not ignored if 'temp' is freed */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3521 tstate->use_tracing = tstate->c_tracefunc != NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3522 Py_XDECREF(temp);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3523 tstate->c_profilefunc = func;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3524 tstate->c_profileobj = arg;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3525 /* Flag that tracing or profiling is turned on */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3526 tstate->use_tracing = (func != NULL) || (tstate->c_tracefunc != NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3527 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3528
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3529 void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3530 PyEval_SetTrace(Py_tracefunc func, PyObject *arg)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3531 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3532 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3533 PyObject *temp = tstate->c_traceobj;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3534 _Py_TracingPossible += (func != NULL) - (tstate->c_tracefunc != NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3535 Py_XINCREF(arg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3536 tstate->c_tracefunc = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3537 tstate->c_traceobj = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3538 /* Must make sure that profiling is not ignored if 'temp' is freed */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3539 tstate->use_tracing = tstate->c_profilefunc != NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3540 Py_XDECREF(temp);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3541 tstate->c_tracefunc = func;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3542 tstate->c_traceobj = arg;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3543 /* Flag that tracing or profiling is turned on */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3544 tstate->use_tracing = ((func != NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3545 || (tstate->c_profilefunc != NULL));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3546 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3547
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3548 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3549 PyEval_GetBuiltins(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3550 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3551 PyFrameObject *current_frame = PyEval_GetFrame();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3552 if (current_frame == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3553 return PyThreadState_GET()->interp->builtins;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3554 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3555 return current_frame->f_builtins;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3556 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3557
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3558 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3559 PyEval_GetLocals(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3560 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3561 PyFrameObject *current_frame = PyEval_GetFrame();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3562 if (current_frame == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3563 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3564 PyFrame_FastToLocals(current_frame);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3565 return current_frame->f_locals;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3566 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3567
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3568 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3569 PyEval_GetGlobals(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3570 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3571 PyFrameObject *current_frame = PyEval_GetFrame();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3572 if (current_frame == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3573 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3574 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3575 return current_frame->f_globals;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3576 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3577
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3578 PyFrameObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3579 PyEval_GetFrame(void)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3580 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3581 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3582 return _PyThreadState_GetFrame(tstate);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3583 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3584
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3585 int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3586 PyEval_MergeCompilerFlags(PyCompilerFlags *cf)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3587 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3588 PyFrameObject *current_frame = PyEval_GetFrame();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3589 int result = cf->cf_flags != 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3590
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3591 if (current_frame != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3592 const int codeflags = current_frame->f_code->co_flags;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3593 const int compilerflags = codeflags & PyCF_MASK;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3594 if (compilerflags) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3595 result = 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3596 cf->cf_flags |= compilerflags;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3597 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3598 #if 0 /* future keyword */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3599 if (codeflags & CO_GENERATOR_ALLOWED) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3600 result = 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3601 cf->cf_flags |= CO_GENERATOR_ALLOWED;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3602 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3603 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3604 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3605 return result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3606 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3607
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3608
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3609 /* External interface to call any callable object.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3610 The arg must be a tuple or NULL. The kw must be a dict or NULL. */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3611
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3612 PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3613 PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3614 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3615 PyObject *result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3616
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3617 if (arg == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3618 arg = PyTuple_New(0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3619 if (arg == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3620 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3621 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3622 else if (!PyTuple_Check(arg)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3623 PyErr_SetString(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3624 "argument list must be a tuple");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3625 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3626 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3627 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3628 Py_INCREF(arg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3629
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3630 if (kw != NULL && !PyDict_Check(kw)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3631 PyErr_SetString(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3632 "keyword list must be a dictionary");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3633 Py_DECREF(arg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3634 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3635 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3636
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3637 result = PyObject_Call(func, arg, kw);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3638 Py_DECREF(arg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3639 return result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3640 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3641
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3642 const char *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3643 PyEval_GetFuncName(PyObject *func)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3644 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3645 if (PyMethod_Check(func))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3646 return PyEval_GetFuncName(PyMethod_GET_FUNCTION(func));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3647 else if (PyFunction_Check(func))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3648 return _PyUnicode_AsString(((PyFunctionObject*)func)->func_name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3649 else if (PyCFunction_Check(func))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3650 return ((PyCFunctionObject*)func)->m_ml->ml_name;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3651 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3652 return func->ob_type->tp_name;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3653 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3654
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3655 const char *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3656 PyEval_GetFuncDesc(PyObject *func)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3657 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3658 if (PyMethod_Check(func))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3659 return "()";
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3660 else if (PyFunction_Check(func))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3661 return "()";
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3662 else if (PyCFunction_Check(func))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3663 return "()";
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3664 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3665 return " object";
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3666 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3667
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3668 static void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3669 err_args(PyObject *func, int flags, int nargs)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3670 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3671 if (flags & METH_NOARGS)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3672 PyErr_Format(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3673 "%.200s() takes no arguments (%d given)",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3674 ((PyCFunctionObject *)func)->m_ml->ml_name,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3675 nargs);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3676 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3677 PyErr_Format(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3678 "%.200s() takes exactly one argument (%d given)",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3679 ((PyCFunctionObject *)func)->m_ml->ml_name,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3680 nargs);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3681 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3682
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3683 #define C_TRACE(x, call) \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3684 if (tstate->use_tracing && tstate->c_profilefunc) { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3685 if (call_trace(tstate->c_profilefunc, \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3686 tstate->c_profileobj, \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3687 tstate->frame, PyTrace_C_CALL, \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3688 func)) { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3689 x = NULL; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3690 } \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3691 else { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3692 x = call; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3693 if (tstate->c_profilefunc != NULL) { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3694 if (x == NULL) { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3695 call_trace_protected(tstate->c_profilefunc, \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3696 tstate->c_profileobj, \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3697 tstate->frame, PyTrace_C_EXCEPTION, \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3698 func); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3699 /* XXX should pass (type, value, tb) */ \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3700 } else { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3701 if (call_trace(tstate->c_profilefunc, \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3702 tstate->c_profileobj, \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3703 tstate->frame, PyTrace_C_RETURN, \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3704 func)) { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3705 Py_DECREF(x); \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3706 x = NULL; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3707 } \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3708 } \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3709 } \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3710 } \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3711 } else { \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3712 x = call; \
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3713 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3714
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3715 static PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3716 call_function(PyObject ***pp_stack, int oparg
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3717 #ifdef WITH_TSC
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3718 , uint64* pintr0, uint64* pintr1
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3719 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3720 )
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3721 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3722 int na = oparg & 0xff;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3723 int nk = (oparg>>8) & 0xff;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3724 int n = na + 2 * nk;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3725 PyObject **pfunc = (*pp_stack) - n - 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3726 PyObject *func = *pfunc;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3727 PyObject *x, *w;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3728
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3729 /* Always dispatch PyCFunction first, because these are
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3730 presumed to be the most frequent callable object.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3731 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3732 if (PyCFunction_Check(func) && nk == 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3733 int flags = PyCFunction_GET_FLAGS(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3734 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3735
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3736 PCALL(PCALL_CFUNCTION);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3737 if (flags & (METH_NOARGS | METH_O)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3738 PyCFunction meth = PyCFunction_GET_FUNCTION(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3739 PyObject *self = PyCFunction_GET_SELF(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3740 if (flags & METH_NOARGS && na == 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3741 C_TRACE(x, (*meth)(self,NULL));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3742 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3743 else if (flags & METH_O && na == 1) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3744 PyObject *arg = EXT_POP(*pp_stack);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3745 C_TRACE(x, (*meth)(self,arg));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3746 Py_DECREF(arg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3747 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3748 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3749 err_args(func, flags, na);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3750 x = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3751 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3752 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3753 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3754 PyObject *callargs;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3755 callargs = load_args(pp_stack, na);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3756 READ_TIMESTAMP(*pintr0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3757 C_TRACE(x, PyCFunction_Call(func,callargs,NULL));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3758 READ_TIMESTAMP(*pintr1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3759 Py_XDECREF(callargs);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3760 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3761 } else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3762 if (PyMethod_Check(func) && PyMethod_GET_SELF(func) != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3763 /* optimize access to bound methods */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3764 PyObject *self = PyMethod_GET_SELF(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3765 PCALL(PCALL_METHOD);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3766 PCALL(PCALL_BOUND_METHOD);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3767 Py_INCREF(self);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3768 func = PyMethod_GET_FUNCTION(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3769 Py_INCREF(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3770 Py_DECREF(*pfunc);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3771 *pfunc = self;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3772 na++;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3773 n++;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3774 } else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3775 Py_INCREF(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3776 READ_TIMESTAMP(*pintr0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3777 if (PyFunction_Check(func))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3778 x = fast_function(func, pp_stack, n, na, nk);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3779 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3780 x = do_call(func, pp_stack, na, nk);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3781 READ_TIMESTAMP(*pintr1);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3782 Py_DECREF(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3783 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3784
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3785 /* Clear the stack of the function object. Also removes
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3786 the arguments in case they weren't consumed already
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3787 (fast_function() and err_args() leave them on the stack).
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3788 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3789 while ((*pp_stack) > pfunc) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3790 w = EXT_POP(*pp_stack);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3791 Py_DECREF(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3792 PCALL(PCALL_POP);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3793 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3794 return x;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3795 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3796
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3797 /* The fast_function() function optimize calls for which no argument
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3798 tuple is necessary; the objects are passed directly from the stack.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3799 For the simplest case -- a function that takes only positional
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3800 arguments and is called with only positional arguments -- it
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3801 inlines the most primitive frame setup code from
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3802 PyEval_EvalCodeEx(), which vastly reduces the checks that must be
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3803 done before evaluating the frame.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3804 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3805
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3806 static PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3807 fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3808 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3809 PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3810 PyObject *globals = PyFunction_GET_GLOBALS(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3811 PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3812 PyObject *kwdefs = PyFunction_GET_KW_DEFAULTS(func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3813 PyObject **d = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3814 int nd = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3815
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3816 PCALL(PCALL_FUNCTION);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3817 PCALL(PCALL_FAST_FUNCTION);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3818 if (argdefs == NULL && co->co_argcount == n &&
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3819 co->co_kwonlyargcount == 0 && nk==0 &&
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3820 co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3821 PyFrameObject *f;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3822 PyObject *retval = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3823 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3824 PyObject **fastlocals, **stack;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3825 int i;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3826
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3827 PCALL(PCALL_FASTER_FUNCTION);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3828 assert(globals != NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3829 /* XXX Perhaps we should create a specialized
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3830 PyFrame_New() that doesn't take locals, but does
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3831 take builtins without sanity checking them.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3832 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3833 assert(tstate != NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3834 f = PyFrame_New(tstate, co, globals, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3835 if (f == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3836 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3837
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3838 fastlocals = f->f_localsplus;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3839 stack = (*pp_stack) - n;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3840
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3841 for (i = 0; i < n; i++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3842 Py_INCREF(*stack);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3843 fastlocals[i] = *stack++;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3844 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3845 retval = PyEval_EvalFrameEx(f,0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3846 ++tstate->recursion_depth;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3847 Py_DECREF(f);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3848 --tstate->recursion_depth;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3849 return retval;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3850 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3851 if (argdefs != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3852 d = &PyTuple_GET_ITEM(argdefs, 0);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3853 nd = Py_SIZE(argdefs);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3854 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3855 return PyEval_EvalCodeEx((PyObject*)co, globals,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3856 (PyObject *)NULL, (*pp_stack)-n, na,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3857 (*pp_stack)-2*nk, nk, d, nd, kwdefs,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3858 PyFunction_GET_CLOSURE(func));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3859 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3860
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3861 static PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3862 update_keyword_args(PyObject *orig_kwdict, int nk, PyObject ***pp_stack,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3863 PyObject *func)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3864 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3865 PyObject *kwdict = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3866 if (orig_kwdict == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3867 kwdict = PyDict_New();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3868 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3869 kwdict = PyDict_Copy(orig_kwdict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3870 Py_DECREF(orig_kwdict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3871 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3872 if (kwdict == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3873 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3874 while (--nk >= 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3875 int err;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3876 PyObject *value = EXT_POP(*pp_stack);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3877 PyObject *key = EXT_POP(*pp_stack);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3878 if (PyDict_GetItem(kwdict, key) != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3879 PyErr_Format(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3880 "%.200s%s got multiple values "
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3881 "for keyword argument '%U'",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3882 PyEval_GetFuncName(func),
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3883 PyEval_GetFuncDesc(func),
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3884 key);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3885 Py_DECREF(key);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3886 Py_DECREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3887 Py_DECREF(kwdict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3888 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3889 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3890 err = PyDict_SetItem(kwdict, key, value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3891 Py_DECREF(key);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3892 Py_DECREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3893 if (err) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3894 Py_DECREF(kwdict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3895 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3896 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3897 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3898 return kwdict;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3899 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3900
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3901 static PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3902 update_star_args(int nstack, int nstar, PyObject *stararg,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3903 PyObject ***pp_stack)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3904 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3905 PyObject *callargs, *w;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3906
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3907 callargs = PyTuple_New(nstack + nstar);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3908 if (callargs == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3909 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3910 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3911 if (nstar) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3912 int i;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3913 for (i = 0; i < nstar; i++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3914 PyObject *a = PyTuple_GET_ITEM(stararg, i);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3915 Py_INCREF(a);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3916 PyTuple_SET_ITEM(callargs, nstack + i, a);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3917 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3918 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3919 while (--nstack >= 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3920 w = EXT_POP(*pp_stack);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3921 PyTuple_SET_ITEM(callargs, nstack, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3922 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3923 return callargs;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3924 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3925
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3926 static PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3927 load_args(PyObject ***pp_stack, int na)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3928 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3929 PyObject *args = PyTuple_New(na);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3930 PyObject *w;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3931
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3932 if (args == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3933 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3934 while (--na >= 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3935 w = EXT_POP(*pp_stack);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3936 PyTuple_SET_ITEM(args, na, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3937 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3938 return args;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3939 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3940
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3941 static PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3942 do_call(PyObject *func, PyObject ***pp_stack, int na, int nk)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3943 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3944 PyObject *callargs = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3945 PyObject *kwdict = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3946 PyObject *result = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3947
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3948 if (nk > 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3949 kwdict = update_keyword_args(NULL, nk, pp_stack, func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3950 if (kwdict == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3951 goto call_fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3952 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3953 callargs = load_args(pp_stack, na);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3954 if (callargs == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3955 goto call_fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3956 #ifdef CALL_PROFILE
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3957 /* At this point, we have to look at the type of func to
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3958 update the call stats properly. Do it here so as to avoid
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3959 exposing the call stats machinery outside ceval.c
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3960 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3961 if (PyFunction_Check(func))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3962 PCALL(PCALL_FUNCTION);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3963 else if (PyMethod_Check(func))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3964 PCALL(PCALL_METHOD);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3965 else if (PyType_Check(func))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3966 PCALL(PCALL_TYPE);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3967 else if (PyCFunction_Check(func))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3968 PCALL(PCALL_CFUNCTION);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3969 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3970 PCALL(PCALL_OTHER);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3971 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3972 if (PyCFunction_Check(func)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3973 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3974 C_TRACE(result, PyCFunction_Call(func, callargs, kwdict));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3975 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3976 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3977 result = PyObject_Call(func, callargs, kwdict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3978 call_fail:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3979 Py_XDECREF(callargs);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3980 Py_XDECREF(kwdict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3981 return result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3982 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3983
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3984 static PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3985 ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3986 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3987 int nstar = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3988 PyObject *callargs = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3989 PyObject *stararg = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3990 PyObject *kwdict = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3991 PyObject *result = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3992
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3993 if (flags & CALL_FLAG_KW) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3994 kwdict = EXT_POP(*pp_stack);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3995 if (!PyDict_Check(kwdict)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3996 PyObject *d;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3997 d = PyDict_New();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3998 if (d == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
3999 goto ext_call_fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4000 if (PyDict_Update(d, kwdict) != 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4001 Py_DECREF(d);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4002 /* PyDict_Update raises attribute
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4003 * error (percolated from an attempt
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4004 * to get 'keys' attribute) instead of
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4005 * a type error if its second argument
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4006 * is not a mapping.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4007 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4008 if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4009 PyErr_Format(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4010 "%.200s%.200s argument after ** "
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4011 "must be a mapping, not %.200s",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4012 PyEval_GetFuncName(func),
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4013 PyEval_GetFuncDesc(func),
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4014 kwdict->ob_type->tp_name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4015 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4016 goto ext_call_fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4017 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4018 Py_DECREF(kwdict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4019 kwdict = d;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4020 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4021 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4022 if (flags & CALL_FLAG_VAR) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4023 stararg = EXT_POP(*pp_stack);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4024 if (!PyTuple_Check(stararg)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4025 PyObject *t = NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4026 t = PySequence_Tuple(stararg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4027 if (t == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4028 if (PyErr_ExceptionMatches(PyExc_TypeError)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4029 PyErr_Format(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4030 "%.200s%.200s argument after * "
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4031 "must be a sequence, not %.200s",
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4032 PyEval_GetFuncName(func),
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4033 PyEval_GetFuncDesc(func),
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4034 stararg->ob_type->tp_name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4035 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4036 goto ext_call_fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4037 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4038 Py_DECREF(stararg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4039 stararg = t;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4040 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4041 nstar = PyTuple_GET_SIZE(stararg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4042 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4043 if (nk > 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4044 kwdict = update_keyword_args(kwdict, nk, pp_stack, func);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4045 if (kwdict == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4046 goto ext_call_fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4047 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4048 callargs = update_star_args(na, nstar, stararg, pp_stack);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4049 if (callargs == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4050 goto ext_call_fail;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4051 #ifdef CALL_PROFILE
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4052 /* At this point, we have to look at the type of func to
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4053 update the call stats properly. Do it here so as to avoid
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4054 exposing the call stats machinery outside ceval.c
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4055 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4056 if (PyFunction_Check(func))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4057 PCALL(PCALL_FUNCTION);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4058 else if (PyMethod_Check(func))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4059 PCALL(PCALL_METHOD);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4060 else if (PyType_Check(func))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4061 PCALL(PCALL_TYPE);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4062 else if (PyCFunction_Check(func))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4063 PCALL(PCALL_CFUNCTION);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4064 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4065 PCALL(PCALL_OTHER);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4066 #endif
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4067 if (PyCFunction_Check(func)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4068 PyThreadState *tstate = PyThreadState_GET();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4069 C_TRACE(result, PyCFunction_Call(func, callargs, kwdict));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4070 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4071 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4072 result = PyObject_Call(func, callargs, kwdict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4073 ext_call_fail:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4074 Py_XDECREF(callargs);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4075 Py_XDECREF(kwdict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4076 Py_XDECREF(stararg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4077 return result;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4078 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4079
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4080 /* Extract a slice index from a PyInt or PyLong or an object with the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4081 nb_index slot defined, and store in *pi.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4082 Silently reduce values larger than PY_SSIZE_T_MAX to PY_SSIZE_T_MAX,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4083 and silently boost values less than -PY_SSIZE_T_MAX-1 to -PY_SSIZE_T_MAX-1.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4084 Return 0 on error, 1 on success.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4085 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4086 /* Note: If v is NULL, return success without storing into *pi. This
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4087 is because_PyEval_SliceIndex() is called by apply_slice(), which can be
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4088 called by the SLICE opcode with v and/or w equal to NULL.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4089 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4090 int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4091 _PyEval_SliceIndex(PyObject *v, Py_ssize_t *pi)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4092 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4093 if (v != NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4094 Py_ssize_t x;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4095 if (PyIndex_Check(v)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4096 x = PyNumber_AsSsize_t(v, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4097 if (x == -1 && PyErr_Occurred())
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4098 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4099 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4100 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4101 PyErr_SetString(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4102 "slice indices must be integers or "
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4103 "None or have an __index__ method");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4104 return 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4105 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4106 *pi = x;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4107 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4108 return 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4109 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4110
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4111 #define CANNOT_CATCH_MSG "catching classes that do not inherit from "\
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4112 "BaseException is not allowed"
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4113
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4114 static PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4115 cmp_outcome(int op, register PyObject *v, register PyObject *w)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4116 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4117 int res = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4118 switch (op) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4119 case PyCmp_IS:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4120 res = (v == w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4121 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4122 case PyCmp_IS_NOT:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4123 res = (v != w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4124 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4125 case PyCmp_IN:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4126 res = PySequence_Contains(w, v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4127 if (res < 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4128 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4129 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4130 case PyCmp_NOT_IN:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4131 res = PySequence_Contains(w, v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4132 if (res < 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4133 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4134 res = !res;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4135 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4136 case PyCmp_EXC_MATCH:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4137 if (PyTuple_Check(w)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4138 Py_ssize_t i, length;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4139 length = PyTuple_Size(w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4140 for (i = 0; i < length; i += 1) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4141 PyObject *exc = PyTuple_GET_ITEM(w, i);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4142 if (!PyExceptionClass_Check(exc)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4143 PyErr_SetString(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4144 CANNOT_CATCH_MSG);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4145 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4146 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4147 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4148 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4149 else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4150 if (!PyExceptionClass_Check(w)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4151 PyErr_SetString(PyExc_TypeError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4152 CANNOT_CATCH_MSG);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4153 return NULL;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4154 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4155 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4156 res = PyErr_GivenExceptionMatches(v, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4157 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4158 default:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4159 return PyObject_RichCompare(v, w, op);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4160 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4161 v = res ? Py_True : Py_False;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4162 Py_INCREF(v);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4163 return v;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4164 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4165
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4166 static PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4167 import_from(PyObject *v, PyObject *name)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4168 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4169 PyObject *x;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4170
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4171 x = PyObject_GetAttr(v, name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4172 if (x == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4173 PyErr_Format(PyExc_ImportError, "cannot import name %S", name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4174 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4175 return x;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4176 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4177
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4178 static int
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4179 import_all_from(PyObject *locals, PyObject *v)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4180 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4181 _Py_IDENTIFIER(__all__);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4182 _Py_IDENTIFIER(__dict__);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4183 PyObject *all = _PyObject_GetAttrId(v, &PyId___all__);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4184 PyObject *dict, *name, *value;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4185 int skip_leading_underscores = 0;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4186 int pos, err;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4187
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4188 if (all == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4189 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4190 return -1; /* Unexpected error */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4191 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4192 dict = _PyObject_GetAttrId(v, &PyId___dict__);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4193 if (dict == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4194 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4195 return -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4196 PyErr_SetString(PyExc_ImportError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4197 "from-import-* object has no __dict__ and no __all__");
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4198 return -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4199 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4200 all = PyMapping_Keys(dict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4201 Py_DECREF(dict);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4202 if (all == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4203 return -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4204 skip_leading_underscores = 1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4205 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4206
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4207 for (pos = 0, err = 0; ; pos++) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4208 name = PySequence_GetItem(all, pos);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4209 if (name == NULL) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4210 if (!PyErr_ExceptionMatches(PyExc_IndexError))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4211 err = -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4212 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4213 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4214 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4215 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4216 if (skip_leading_underscores &&
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4217 PyUnicode_Check(name) &&
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4218 PyUnicode_READY(name) != -1 &&
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4219 PyUnicode_READ_CHAR(name, 0) == '_')
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4220 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4221 Py_DECREF(name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4222 continue;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4223 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4224 value = PyObject_GetAttr(v, name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4225 if (value == NULL)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4226 err = -1;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4227 else if (PyDict_CheckExact(locals))
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4228 err = PyDict_SetItem(locals, name, value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4229 else
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4230 err = PyObject_SetItem(locals, name, value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4231 Py_DECREF(name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4232 Py_XDECREF(value);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4233 if (err != 0)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4234 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4235 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4236 Py_DECREF(all);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4237 return err;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4238 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4239
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4240 static void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4241 format_exc_check_arg(PyObject *exc, const char *format_str, PyObject *obj)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4242 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4243 const char *obj_str;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4244
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4245 if (!obj)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4246 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4247
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4248 obj_str = _PyUnicode_AsString(obj);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4249 if (!obj_str)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4250 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4251
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4252 PyErr_Format(exc, format_str, obj_str);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4253 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4254
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4255 static void
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4256 format_exc_unbound(PyCodeObject *co, int oparg)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4257 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4258 PyObject *name;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4259 /* Don't stomp existing exception */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4260 if (PyErr_Occurred())
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4261 return;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4262 if (oparg < PyTuple_GET_SIZE(co->co_cellvars)) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4263 name = PyTuple_GET_ITEM(co->co_cellvars,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4264 oparg);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4265 format_exc_check_arg(
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4266 PyExc_UnboundLocalError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4267 UNBOUNDLOCAL_ERROR_MSG,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4268 name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4269 } else {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4270 name = PyTuple_GET_ITEM(co->co_freevars, oparg -
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4271 PyTuple_GET_SIZE(co->co_cellvars));
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4272 format_exc_check_arg(PyExc_NameError,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4273 UNBOUNDFREE_ERROR_MSG, name);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4274 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4275 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4276
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4277 static PyObject *
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4278 unicode_concatenate(PyObject *v, PyObject *w,
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4279 PyFrameObject *f, unsigned char *next_instr)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4280 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4281 PyObject *res;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4282 if (Py_REFCNT(v) == 2) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4283 /* In the common case, there are 2 references to the value
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4284 * stored in 'variable' when the += is performed: one on the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4285 * value stack (in 'v') and one still stored in the
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4286 * 'variable'. We try to delete the variable now to reduce
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4287 * the refcnt to 1.
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4288 */
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4289 switch (*next_instr) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4290 case STORE_FAST:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4291 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4292 int oparg = PEEKARG();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4293 PyObject **fastlocals = f->f_localsplus;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4294 if (GETLOCAL(oparg) == v)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4295 SETLOCAL(oparg, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4296 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4297 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4298 case STORE_DEREF:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4299 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4300 PyObject **freevars = (f->f_localsplus +
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4301 f->f_code->co_nlocals);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4302 PyObject *c = freevars[PEEKARG()];
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4303 if (PyCell_GET(c) == v)
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4304 PyCell_Set(c, NULL);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4305 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4306 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4307 case STORE_NAME:
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4308 {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4309 PyObject *names = f->f_code->co_names;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4310 PyObject *name = GETITEM(names, PEEKARG());
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4311 PyObject *locals = f->f_locals;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4312 if (PyDict_CheckExact(locals) &&
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4313 PyDict_GetItem(locals, name) == v) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4314 if (PyDict_DelItem(locals, name) != 0) {
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4315 PyErr_Clear();
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4316 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4317 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4318 break;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4319 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4320 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4321 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4322 res = v;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4323 PyUnicode_Append(&res, w);
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4324 return res;
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4325 }
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4326
7f74363f4c82 Added some files for the python port
windel
parents:
diff changeset
4327