• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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