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