8
8
#include "Python.h"
9
9
#include "pycore_code.h" // _PyCode_HAS_EXECUTORS()
10
10
#include "pycore_crossinterp.h" // _PyXIData_t
11
+ #include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
12
+ #include "pycore_function.h" // _PyFunction_VerifyStateless()
11
13
#include "pycore_interp.h" // _PyInterpreterState_IDIncref()
12
14
#include "pycore_modsupport.h" // _PyArg_BadArgument()
13
15
#include "pycore_namespace.h" // _PyNamespace_New()
@@ -374,34 +376,17 @@ check_code_str(PyUnicodeObject *text)
374
376
return NULL ;
375
377
}
376
378
377
- static const char *
378
- check_code_object (PyCodeObject * code )
379
+ #ifndef NDEBUG
380
+ static int
381
+ code_has_args (PyCodeObject * code )
379
382
{
380
383
assert (code != NULL );
381
- if (code -> co_argcount > 0
384
+ return (code -> co_argcount > 0
382
385
|| code -> co_posonlyargcount > 0
383
386
|| code -> co_kwonlyargcount > 0
384
- || code -> co_flags & (CO_VARARGS |CO_VARKEYWORDS ))
385
- {
386
- return "arguments not supported" ;
387
- }
388
- if (code -> co_ncellvars > 0 ) {
389
- return "closures not supported" ;
390
- }
391
- // We trust that no code objects under co_consts have unbound cell vars.
392
-
393
- if (_PyCode_HAS_EXECUTORS (code )|| _PyCode_HAS_INSTRUMENTATION (code )) {
394
- return "only basic functions are supported" ;
395
- }
396
- if (code -> _co_monitoring != NULL ) {
397
- return "only basic functions are supported" ;
398
- }
399
- if (code -> co_extra != NULL ) {
400
- return "only basic functions are supported" ;
401
- }
402
-
403
- return NULL ;
387
+ || code -> co_flags & (CO_VARARGS |CO_VARKEYWORDS ));
404
388
}
389
+ #endif
405
390
406
391
#define RUN_TEXT 1
407
392
#define RUN_CODE 2
@@ -429,8 +414,10 @@ get_code_str(PyObject *arg, Py_ssize_t *len_p, PyObject **bytes_p, int *flags_p)
429
414
flags = RUN_TEXT ;
430
415
}
431
416
else {
432
- assert (PyCode_Check (arg )
433
- && (check_code_object ((PyCodeObject * )arg )== NULL ));
417
+ assert (PyCode_Check (arg ));
418
+ assert (_PyCode_VerifyStateless (
419
+ PyThreadState_Get (), (PyCodeObject * )arg ,NULL ,NULL ,NULL )== 0 );
420
+ assert (!code_has_args ((PyCodeObject * )arg ));
434
421
flags = RUN_CODE ;
435
422
436
423
// Serialize the code object.
@@ -949,7 +936,8 @@ Bind the given attributes in the interpreter's __main__ module.");
949
936
950
937
951
938
static PyUnicodeObject *
952
- convert_script_arg (PyObject * arg ,const char * fname ,const char * displayname ,
939
+ convert_script_arg (PyThreadState * tstate ,
940
+ PyObject * arg ,const char * fname ,const char * displayname ,
953
941
const char * expected )
954
942
{
955
943
PyUnicodeObject * str = NULL ;
@@ -968,60 +956,53 @@ convert_script_arg(PyObject *arg, const char *fname, const char *displayname,
968
956
const char * err = check_code_str (str );
969
957
if (err != NULL ) {
970
958
Py_DECREF (str );
971
- PyErr_Format ( PyExc_ValueError ,
972
- "%.200s(): bad script text (%s)" ,fname ,err );
959
+ _PyErr_Format ( tstate , PyExc_ValueError ,
960
+ "%.200s(): bad script text (%s)" ,fname ,err );
973
961
return NULL ;
974
962
}
975
963
976
964
return str ;
977
965
}
978
966
979
967
static PyCodeObject *
980
- convert_code_arg (PyObject * arg ,const char * fname ,const char * displayname ,
968
+ convert_code_arg (PyThreadState * tstate ,
969
+ PyObject * arg ,const char * fname ,const char * displayname ,
981
970
const char * expected )
982
971
{
983
- const char * kind = NULL ;
972
+ PyObject * cause ;
984
973
PyCodeObject * code = NULL ;
985
974
if (PyFunction_Check (arg )) {
986
- if (PyFunction_GetClosure (arg )!= NULL ) {
987
- PyErr_Format (PyExc_ValueError ,
988
- "%.200s(): closures not supported" ,fname );
989
- return NULL ;
990
- }
991
- code = (PyCodeObject * )PyFunction_GetCode (arg );
992
- if (code == NULL ) {
993
- if (PyErr_Occurred ()) {
994
- // This chains.
995
- PyErr_Format (PyExc_ValueError ,
996
- "%.200s(): bad func" ,fname );
997
- }
998
- else {
999
- PyErr_Format (PyExc_ValueError ,
1000
- "%.200s(): func.__code__ missing" ,fname );
1001
- }
1002
- return NULL ;
975
+ // For now we allow globals, so we can't use
976
+ // _PyFunction_VerifyStateless().
977
+ PyObject * codeobj = PyFunction_GetCode (arg );
978
+ if (_PyCode_VerifyStateless (
979
+ tstate , (PyCodeObject * )codeobj ,NULL ,NULL ,NULL )< 0 ) {
980
+ gotochained ;
1003
981
}
1004
- Py_INCREF (code );
1005
- kind = "func" ;
982
+ code = (PyCodeObject * )Py_NewRef (codeobj );
1006
983
}
1007
984
else if (PyCode_Check (arg )) {
985
+ if (_PyCode_VerifyStateless (
986
+ tstate , (PyCodeObject * )arg ,NULL ,NULL ,NULL )< 0 ) {
987
+ gotochained ;
988
+ }
1008
989
code = (PyCodeObject * )Py_NewRef (arg );
1009
- kind = "code object" ;
1010
990
}
1011
991
else {
1012
992
_PyArg_BadArgument (fname ,displayname ,expected ,arg );
1013
993
return NULL ;
1014
994
}
1015
995
1016
- const char * err = check_code_object (code );
1017
- if (err != NULL ) {
1018
- Py_DECREF (code );
1019
- PyErr_Format (PyExc_ValueError ,
1020
- "%.200s(): bad %s (%s)" ,fname ,kind ,err );
1021
- return NULL ;
1022
- }
1023
-
1024
996
return code ;
997
+
998
+ chained :
999
+ cause = _PyErr_GetRaisedException (tstate );
1000
+ assert (cause != NULL );
1001
+ _PyArg_BadArgument (fname ,displayname ,expected ,arg );
1002
+ PyObject * exc = _PyErr_GetRaisedException (tstate );
1003
+ PyException_SetCause (exc ,cause );
1004
+ _PyErr_SetRaisedException (tstate ,exc );
1005
+ return NULL ;
1025
1006
}
1026
1007
1027
1008
static int
@@ -1057,12 +1038,14 @@ _interp_exec(PyObject *self, PyInterpreterState *interp,
1057
1038
static PyObject *
1058
1039
interp_exec (PyObject * self ,PyObject * args ,PyObject * kwds )
1059
1040
{
1041
+ #define FUNCNAME MODULE_NAME_STR ".exec"
1042
+ PyThreadState * tstate = _PyThreadState_GET ();
1060
1043
static char * kwlist []= {"id" ,"code" ,"shared" ,"restrict" ,NULL };
1061
1044
PyObject * id ,* code ;
1062
1045
PyObject * shared = NULL ;
1063
1046
int restricted = 0 ;
1064
1047
if (!PyArg_ParseTupleAndKeywords (args ,kwds ,
1065
- "OO|O$p:" MODULE_NAME_STR ".exec" ,kwlist ,
1048
+ "OO|O$p:" FUNCNAME ,kwlist ,
1066
1049
& id ,& code ,& shared ,& restricted ))
1067
1050
{
1068
1051
return NULL ;
@@ -1077,12 +1060,12 @@ interp_exec(PyObject *self, PyObject *args, PyObject *kwds)
1077
1060
1078
1061
const char * expected = "a string, a function, or a code object" ;
1079
1062
if (PyUnicode_Check (code )) {
1080
- code = (PyObject * )convert_script_arg (code ,MODULE_NAME_STR ".exec" ,
1081
- "argument 2" ,expected );
1063
+ code = (PyObject * )convert_script_arg (tstate , code ,FUNCNAME ,
1064
+ "argument 2" ,expected );
1082
1065
}
1083
1066
else {
1084
- code = (PyObject * )convert_code_arg (code ,MODULE_NAME_STR ".exec" ,
1085
- "argument 2" ,expected );
1067
+ code = (PyObject * )convert_code_arg (tstate , code ,FUNCNAME ,
1068
+ "argument 2" ,expected );
1086
1069
}
1087
1070
if (code == NULL ) {
1088
1071
return NULL ;
@@ -1096,6 +1079,7 @@ interp_exec(PyObject *self, PyObject *args, PyObject *kwds)
1096
1079
return excinfo ;
1097
1080
}
1098
1081
Py_RETURN_NONE ;
1082
+ #undef FUNCNAME
1099
1083
}
1100
1084
1101
1085
PyDoc_STRVAR (exec_doc ,
@@ -1118,13 +1102,15 @@ is ignored, including its __globals__ dict.");
1118
1102
static PyObject *
1119
1103
interp_run_string (PyObject * self ,PyObject * args ,PyObject * kwds )
1120
1104
{
1105
+ #define FUNCNAME MODULE_NAME_STR ".run_string"
1106
+ PyThreadState * tstate = _PyThreadState_GET ();
1121
1107
static char * kwlist []= {"id" ,"script" ,"shared" ,"restrict" ,NULL };
1122
1108
PyObject * id ,* script ;
1123
1109
PyObject * shared = NULL ;
1124
1110
int restricted = 0 ;
1125
1111
if (!PyArg_ParseTupleAndKeywords (args ,kwds ,
1126
- "OU|O$p:" MODULE_NAME_STR ".run_string" ,
1127
- kwlist , & id ,& script ,& shared ,& restricted ))
1112
+ "OU|O$p:" FUNCNAME , kwlist ,
1113
+ & id ,& script ,& shared ,& restricted ))
1128
1114
{
1129
1115
return NULL ;
1130
1116
}
@@ -1136,7 +1122,7 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
1136
1122
return NULL ;
1137
1123
}
1138
1124
1139
- script = (PyObject * )convert_script_arg (script ,MODULE_NAME_STR ".run_string" ,
1125
+ script = (PyObject * )convert_script_arg (tstate , script ,FUNCNAME ,
1140
1126
"argument 2" ,"a string" );
1141
1127
if (script == NULL ) {
1142
1128
return NULL ;
@@ -1150,6 +1136,7 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
1150
1136
return excinfo ;
1151
1137
}
1152
1138
Py_RETURN_NONE ;
1139
+ #undef FUNCNAME
1153
1140
}
1154
1141
1155
1142
PyDoc_STRVAR (run_string_doc ,
@@ -1162,13 +1149,15 @@ Execute the provided string in the identified interpreter.\n\
1162
1149
static PyObject *
1163
1150
interp_run_func (PyObject * self ,PyObject * args ,PyObject * kwds )
1164
1151
{
1152
+ #define FUNCNAME MODULE_NAME_STR ".run_func"
1153
+ PyThreadState * tstate = _PyThreadState_GET ();
1165
1154
static char * kwlist []= {"id" ,"func" ,"shared" ,"restrict" ,NULL };
1166
1155
PyObject * id ,* func ;
1167
1156
PyObject * shared = NULL ;
1168
1157
int restricted = 0 ;
1169
1158
if (!PyArg_ParseTupleAndKeywords (args ,kwds ,
1170
- "OO|O$p:" MODULE_NAME_STR ".run_func" ,
1171
- kwlist , & id ,& func ,& shared ,& restricted ))
1159
+ "OO|O$p:" FUNCNAME , kwlist ,
1160
+ & id ,& func ,& shared ,& restricted ))
1172
1161
{
1173
1162
return NULL ;
1174
1163
}
@@ -1180,7 +1169,7 @@ interp_run_func(PyObject *self, PyObject *args, PyObject *kwds)
1180
1169
return NULL ;
1181
1170
}
1182
1171
1183
- PyCodeObject * code = convert_code_arg (func ,MODULE_NAME_STR ".exec" ,
1172
+ PyCodeObject * code = convert_code_arg (tstate , func ,FUNCNAME ,
1184
1173
"argument 2" ,
1185
1174
"a function or a code object" );
1186
1175
if (code == NULL ) {
@@ -1195,6 +1184,7 @@ interp_run_func(PyObject *self, PyObject *args, PyObject *kwds)
1195
1184
return excinfo ;
1196
1185
}
1197
1186
Py_RETURN_NONE ;
1187
+ #undef FUNCNAME
1198
1188
}
1199
1189
1200
1190
PyDoc_STRVAR (run_func_doc ,
@@ -1209,14 +1199,16 @@ are not supported. Methods and other callables are not supported either.\n\
1209
1199
static PyObject *
1210
1200
interp_call (PyObject * self ,PyObject * args ,PyObject * kwds )
1211
1201
{
1202
+ #define FUNCNAME MODULE_NAME_STR ".call"
1203
+ PyThreadState * tstate = _PyThreadState_GET ();
1212
1204
static char * kwlist []= {"id" ,"callable" ,"args" ,"kwargs" ,
1213
1205
"restrict" ,NULL };
1214
1206
PyObject * id ,* callable ;
1215
1207
PyObject * args_obj = NULL ;
1216
1208
PyObject * kwargs_obj = NULL ;
1217
1209
int restricted = 0 ;
1218
1210
if (!PyArg_ParseTupleAndKeywords (args ,kwds ,
1219
- "OO|OO$p:" MODULE_NAME_STR ".call" ,kwlist ,
1211
+ "OO|OO$p:" FUNCNAME ,kwlist ,
1220
1212
& id ,& callable ,& args_obj ,& kwargs_obj ,
1221
1213
& restricted ))
1222
1214
{
@@ -1231,15 +1223,15 @@ interp_call(PyObject *self, PyObject *args, PyObject *kwds)
1231
1223
}
1232
1224
1233
1225
if (args_obj != NULL ) {
1234
- PyErr_SetString ( PyExc_ValueError ,"got unexpected args" );
1226
+ _PyErr_SetString ( tstate , PyExc_ValueError ,"got unexpected args" );
1235
1227
return NULL ;
1236
1228
}
1237
1229
if (kwargs_obj != NULL ) {
1238
- PyErr_SetString ( PyExc_ValueError ,"got unexpected kwargs" );
1230
+ _PyErr_SetString ( tstate , PyExc_ValueError ,"got unexpected kwargs" );
1239
1231
return NULL ;
1240
1232
}
1241
1233
1242
- PyObject * code = (PyObject * )convert_code_arg (callable ,MODULE_NAME_STR ".call" ,
1234
+ PyObject * code = (PyObject * )convert_code_arg (tstate , callable ,FUNCNAME ,
1243
1235
"argument 2" ,"a function" );
1244
1236
if (code == NULL ) {
1245
1237
return NULL ;
@@ -1253,6 +1245,7 @@ interp_call(PyObject *self, PyObject *args, PyObject *kwds)
1253
1245
return excinfo ;
1254
1246
}
1255
1247
Py_RETURN_NONE ;
1248
+ #undef FUNCNAME
1256
1249
}
1257
1250
1258
1251
PyDoc_STRVAR (call_doc ,