1
2 #define _PY_INTERPRETER
3
4 #include "Python.h"
5 #include "pycore_frame.h"
6 #include "pycore_function.h"
7 #include "pycore_global_objects.h"
8 #include "pycore_compile.h" // _PyCompile_GetUnaryIntrinsicName, etc
9 #include "pycore_intrinsics.h" // INTRINSIC_PRINT
10 #include "pycore_pyerrors.h" // _PyErr_SetString()
11 #include "pycore_runtime.h" // _Py_ID()
12 #include "pycore_sysmodule.h" // _PySys_GetAttr()
13 #include "pycore_typevarobject.h" // _Py_make_typevar()
14
15
16 /******** Unary functions ********/
17
18 static PyObject *
no_intrinsic1(PyThreadState * tstate,PyObject * unused)19 no_intrinsic1(PyThreadState* tstate, PyObject *unused)
20 {
21 _PyErr_SetString(tstate, PyExc_SystemError, "invalid intrinsic function");
22 return NULL;
23 }
24
25 static PyObject *
print_expr(PyThreadState * tstate,PyObject * value)26 print_expr(PyThreadState* tstate, PyObject *value)
27 {
28 PyObject *hook = _PySys_GetAttr(tstate, &_Py_ID(displayhook));
29 // Can't use ERROR_IF here.
30 if (hook == NULL) {
31 _PyErr_SetString(tstate, PyExc_RuntimeError,
32 "lost sys.displayhook");
33 return NULL;
34 }
35 return PyObject_CallOneArg(hook, value);
36 }
37
38 static int
import_all_from(PyThreadState * tstate,PyObject * locals,PyObject * v)39 import_all_from(PyThreadState *tstate, PyObject *locals, PyObject *v)
40 {
41 PyObject *all, *dict, *name, *value;
42 int skip_leading_underscores = 0;
43 int pos, err;
44
45 if (PyObject_GetOptionalAttr(v, &_Py_ID(__all__), &all) < 0) {
46 return -1; /* Unexpected error */
47 }
48 if (all == NULL) {
49 if (PyObject_GetOptionalAttr(v, &_Py_ID(__dict__), &dict) < 0) {
50 return -1;
51 }
52 if (dict == NULL) {
53 _PyErr_SetString(tstate, PyExc_ImportError,
54 "from-import-* object has no __dict__ and no __all__");
55 return -1;
56 }
57 all = PyMapping_Keys(dict);
58 Py_DECREF(dict);
59 if (all == NULL)
60 return -1;
61 skip_leading_underscores = 1;
62 }
63
64 for (pos = 0, err = 0; ; pos++) {
65 name = PySequence_GetItem(all, pos);
66 if (name == NULL) {
67 if (!_PyErr_ExceptionMatches(tstate, PyExc_IndexError)) {
68 err = -1;
69 }
70 else {
71 _PyErr_Clear(tstate);
72 }
73 break;
74 }
75 if (!PyUnicode_Check(name)) {
76 PyObject *modname = PyObject_GetAttr(v, &_Py_ID(__name__));
77 if (modname == NULL) {
78 Py_DECREF(name);
79 err = -1;
80 break;
81 }
82 if (!PyUnicode_Check(modname)) {
83 _PyErr_Format(tstate, PyExc_TypeError,
84 "module __name__ must be a string, not %.100s",
85 Py_TYPE(modname)->tp_name);
86 }
87 else {
88 _PyErr_Format(tstate, PyExc_TypeError,
89 "%s in %U.%s must be str, not %.100s",
90 skip_leading_underscores ? "Key" : "Item",
91 modname,
92 skip_leading_underscores ? "__dict__" : "__all__",
93 Py_TYPE(name)->tp_name);
94 }
95 Py_DECREF(modname);
96 Py_DECREF(name);
97 err = -1;
98 break;
99 }
100 if (skip_leading_underscores) {
101 if (PyUnicode_READ_CHAR(name, 0) == '_') {
102 Py_DECREF(name);
103 continue;
104 }
105 }
106 value = PyObject_GetAttr(v, name);
107 if (value == NULL)
108 err = -1;
109 else if (PyDict_CheckExact(locals))
110 err = PyDict_SetItem(locals, name, value);
111 else
112 err = PyObject_SetItem(locals, name, value);
113 Py_DECREF(name);
114 Py_XDECREF(value);
115 if (err < 0)
116 break;
117 }
118 Py_DECREF(all);
119 return err;
120 }
121
122 static PyObject *
import_star(PyThreadState * tstate,PyObject * from)123 import_star(PyThreadState* tstate, PyObject *from)
124 {
125 _PyInterpreterFrame *frame = tstate->current_frame;
126
127 PyObject *locals = _PyFrame_GetLocals(frame);
128 if (locals == NULL) {
129 _PyErr_SetString(tstate, PyExc_SystemError,
130 "no locals found during 'import *'");
131 return NULL;
132 }
133 int err = import_all_from(tstate, locals, from);
134 Py_DECREF(locals);
135 if (err < 0) {
136 return NULL;
137 }
138 Py_RETURN_NONE;
139 }
140
141 static PyObject *
stopiteration_error(PyThreadState * tstate,PyObject * exc)142 stopiteration_error(PyThreadState* tstate, PyObject *exc)
143 {
144 _PyInterpreterFrame *frame = tstate->current_frame;
145 assert(frame->owner == FRAME_OWNED_BY_GENERATOR);
146 assert(PyExceptionInstance_Check(exc));
147 const char *msg = NULL;
148 if (PyErr_GivenExceptionMatches(exc, PyExc_StopIteration)) {
149 msg = "generator raised StopIteration";
150 if (_PyFrame_GetCode(frame)->co_flags & CO_ASYNC_GENERATOR) {
151 msg = "async generator raised StopIteration";
152 }
153 else if (_PyFrame_GetCode(frame)->co_flags & CO_COROUTINE) {
154 msg = "coroutine raised StopIteration";
155 }
156 }
157 else if ((_PyFrame_GetCode(frame)->co_flags & CO_ASYNC_GENERATOR) &&
158 PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration))
159 {
160 /* code in `gen` raised a StopAsyncIteration error:
161 raise a RuntimeError.
162 */
163 msg = "async generator raised StopAsyncIteration";
164 }
165 if (msg != NULL) {
166 PyObject *message = _PyUnicode_FromASCII(msg, strlen(msg));
167 if (message == NULL) {
168 return NULL;
169 }
170 PyObject *error = PyObject_CallOneArg(PyExc_RuntimeError, message);
171 if (error == NULL) {
172 Py_DECREF(message);
173 return NULL;
174 }
175 assert(PyExceptionInstance_Check(error));
176 PyException_SetCause(error, Py_NewRef(exc));
177 // Steal exc reference, rather than Py_NewRef+Py_DECREF
178 PyException_SetContext(error, Py_NewRef(exc));
179 Py_DECREF(message);
180 return error;
181 }
182 return Py_NewRef(exc);
183 }
184
185 static PyObject *
unary_pos(PyThreadState * unused,PyObject * value)186 unary_pos(PyThreadState* unused, PyObject *value)
187 {
188 return PyNumber_Positive(value);
189 }
190
191 static PyObject *
list_to_tuple(PyThreadState * unused,PyObject * v)192 list_to_tuple(PyThreadState* unused, PyObject *v)
193 {
194 assert(PyList_Check(v));
195 return _PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v));
196 }
197
198 static PyObject *
make_typevar(PyThreadState * Py_UNUSED (ignored),PyObject * v)199 make_typevar(PyThreadState* Py_UNUSED(ignored), PyObject *v)
200 {
201 assert(PyUnicode_Check(v));
202 return _Py_make_typevar(v, NULL, NULL);
203 }
204
205
206 #define INTRINSIC_FUNC_ENTRY(N, F) \
207 [N] = {F, #N},
208
209 const intrinsic_func1_info
210 _PyIntrinsics_UnaryFunctions[] = {
211 INTRINSIC_FUNC_ENTRY(INTRINSIC_1_INVALID, no_intrinsic1)
212 INTRINSIC_FUNC_ENTRY(INTRINSIC_PRINT, print_expr)
213 INTRINSIC_FUNC_ENTRY(INTRINSIC_IMPORT_STAR, import_star)
214 INTRINSIC_FUNC_ENTRY(INTRINSIC_STOPITERATION_ERROR, stopiteration_error)
215 INTRINSIC_FUNC_ENTRY(INTRINSIC_ASYNC_GEN_WRAP, _PyAsyncGenValueWrapperNew)
216 INTRINSIC_FUNC_ENTRY(INTRINSIC_UNARY_POSITIVE, unary_pos)
217 INTRINSIC_FUNC_ENTRY(INTRINSIC_LIST_TO_TUPLE, list_to_tuple)
218 INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVAR, make_typevar)
219 INTRINSIC_FUNC_ENTRY(INTRINSIC_PARAMSPEC, _Py_make_paramspec)
220 INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVARTUPLE, _Py_make_typevartuple)
221 INTRINSIC_FUNC_ENTRY(INTRINSIC_SUBSCRIPT_GENERIC, _Py_subscript_generic)
222 INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEALIAS, _Py_make_typealias)
223 };
224
225
226 /******** Binary functions ********/
227
228 static PyObject *
no_intrinsic2(PyThreadState * tstate,PyObject * unused1,PyObject * unused2)229 no_intrinsic2(PyThreadState* tstate, PyObject *unused1, PyObject *unused2)
230 {
231 _PyErr_SetString(tstate, PyExc_SystemError, "invalid intrinsic function");
232 return NULL;
233 }
234
235 static PyObject *
prep_reraise_star(PyThreadState * unused,PyObject * orig,PyObject * excs)236 prep_reraise_star(PyThreadState* unused, PyObject *orig, PyObject *excs)
237 {
238 assert(PyList_Check(excs));
239 return _PyExc_PrepReraiseStar(orig, excs);
240 }
241
242 static PyObject *
make_typevar_with_bound(PyThreadState * Py_UNUSED (ignored),PyObject * name,PyObject * evaluate_bound)243 make_typevar_with_bound(PyThreadState* Py_UNUSED(ignored), PyObject *name,
244 PyObject *evaluate_bound)
245 {
246 assert(PyUnicode_Check(name));
247 return _Py_make_typevar(name, evaluate_bound, NULL);
248 }
249
250 static PyObject *
make_typevar_with_constraints(PyThreadState * Py_UNUSED (ignored),PyObject * name,PyObject * evaluate_constraints)251 make_typevar_with_constraints(PyThreadState* Py_UNUSED(ignored), PyObject *name,
252 PyObject *evaluate_constraints)
253 {
254 assert(PyUnicode_Check(name));
255 return _Py_make_typevar(name, NULL, evaluate_constraints);
256 }
257
258 const intrinsic_func2_info
259 _PyIntrinsics_BinaryFunctions[] = {
260 INTRINSIC_FUNC_ENTRY(INTRINSIC_2_INVALID, no_intrinsic2)
261 INTRINSIC_FUNC_ENTRY(INTRINSIC_PREP_RERAISE_STAR, prep_reraise_star)
262 INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVAR_WITH_BOUND, make_typevar_with_bound)
263 INTRINSIC_FUNC_ENTRY(INTRINSIC_TYPEVAR_WITH_CONSTRAINTS, make_typevar_with_constraints)
264 INTRINSIC_FUNC_ENTRY(INTRINSIC_SET_FUNCTION_TYPE_PARAMS, _Py_set_function_type_params)
265 INTRINSIC_FUNC_ENTRY(INTRINSIC_SET_TYPEPARAM_DEFAULT, _Py_set_typeparam_default)
266 };
267
268 #undef INTRINSIC_FUNC_ENTRY
269
270 PyObject*
_PyCompile_GetUnaryIntrinsicName(int index)271 _PyCompile_GetUnaryIntrinsicName(int index)
272 {
273 if (index < 0 || index > MAX_INTRINSIC_1) {
274 return NULL;
275 }
276 return PyUnicode_FromString(_PyIntrinsics_UnaryFunctions[index].name);
277 }
278
279 PyObject*
_PyCompile_GetBinaryIntrinsicName(int index)280 _PyCompile_GetBinaryIntrinsicName(int index)
281 {
282 if (index < 0 || index > MAX_INTRINSIC_2) {
283 return NULL;
284 }
285 return PyUnicode_FromString(_PyIntrinsics_BinaryFunctions[index].name);
286 }
287