88#include "Python.h"
99#include "pycore_code.h" // _PyCode_HAS_EXECUTORS()
1010#include "pycore_crossinterp.h" // _PyXIData_t
11+ #include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
12+ #include "pycore_function.h" // _PyFunction_VerifyStateless()
1113#include "pycore_interp.h" // _PyInterpreterState_IDIncref()
1214#include "pycore_modsupport.h" // _PyArg_BadArgument()
1315#include "pycore_namespace.h" // _PyNamespace_New()
@@ -374,34 +376,17 @@ check_code_str(PyUnicodeObject *text)
374376 return NULL ;
375377}
376378
377- static const char *
378- check_code_object (PyCodeObject * code )
379+ #ifndef NDEBUG
380+ static int
381+ code_has_args (PyCodeObject * code )
379382{
380383 assert (code != NULL );
381- if (code -> co_argcount > 0
384+ return (code -> co_argcount > 0
382385 || code -> co_posonlyargcount > 0
383386 || 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 ));
404388}
389+ #endif
405390
406391#define RUN_TEXT 1
407392#define RUN_CODE 2
@@ -429,8 +414,10 @@ get_code_str(PyObject *arg, Py_ssize_t *len_p, PyObject **bytes_p, int *flags_p)
429414 flags = RUN_TEXT ;
430415 }
431416 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 ));
434421 flags = RUN_CODE ;
435422
436423 // Serialize the code object.
@@ -949,7 +936,8 @@ Bind the given attributes in the interpreter's __main__ module.");
949936
950937
951938static 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 ,
953941 const char * expected )
954942{
955943 PyUnicodeObject * str = NULL ;
@@ -968,60 +956,53 @@ convert_script_arg(PyObject *arg, const char *fname, const char *displayname,
968956 const char * err = check_code_str (str );
969957 if (err != NULL ) {
970958 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 );
973961 return NULL ;
974962 }
975963
976964 return str ;
977965}
978966
979967static 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 ,
981970 const char * expected )
982971{
983- const char * kind = NULL ;
972+ PyObject * cause ;
984973 PyCodeObject * code = NULL ;
985974 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+ goto chained ;
1003981 }
1004- Py_INCREF (code );
1005- kind = "func" ;
982+ code = (PyCodeObject * )Py_NewRef (codeobj );
1006983 }
1007984 else if (PyCode_Check (arg )) {
985+ if (_PyCode_VerifyStateless (
986+ tstate , (PyCodeObject * )arg , NULL , NULL , NULL ) < 0 ) {
987+ goto chained ;
988+ }
1008989 code = (PyCodeObject * )Py_NewRef (arg );
1009- kind = "code object" ;
1010990 }
1011991 else {
1012992 _PyArg_BadArgument (fname , displayname , expected , arg );
1013993 return NULL ;
1014994 }
1015995
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-
1024996 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 ;
10251006}
10261007
10271008static int
@@ -1057,12 +1038,14 @@ _interp_exec(PyObject *self, PyInterpreterState *interp,
10571038static PyObject *
10581039interp_exec (PyObject * self , PyObject * args , PyObject * kwds )
10591040{
1041+ #define FUNCNAME MODULE_NAME_STR ".exec"
1042+ PyThreadState * tstate = _PyThreadState_GET ();
10601043 static char * kwlist [] = {"id" , "code" , "shared" , "restrict" , NULL };
10611044 PyObject * id , * code ;
10621045 PyObject * shared = NULL ;
10631046 int restricted = 0 ;
10641047 if (!PyArg_ParseTupleAndKeywords (args , kwds ,
1065- "OO|O$p:" MODULE_NAME_STR ".exec" , kwlist ,
1048+ "OO|O$p:" FUNCNAME , kwlist ,
10661049 & id , & code , & shared , & restricted ))
10671050 {
10681051 return NULL ;
@@ -1077,12 +1060,12 @@ interp_exec(PyObject *self, PyObject *args, PyObject *kwds)
10771060
10781061 const char * expected = "a string, a function, or a code object" ;
10791062 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 );
10821065 }
10831066 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 );
10861069 }
10871070 if (code == NULL ) {
10881071 return NULL ;
@@ -1096,6 +1079,7 @@ interp_exec(PyObject *self, PyObject *args, PyObject *kwds)
10961079 return excinfo ;
10971080 }
10981081 Py_RETURN_NONE ;
1082+ #undef FUNCNAME
10991083}
11001084
11011085PyDoc_STRVAR (exec_doc ,
@@ -1118,13 +1102,15 @@ is ignored, including its __globals__ dict.");
11181102static PyObject *
11191103interp_run_string (PyObject * self , PyObject * args , PyObject * kwds )
11201104{
1105+ #define FUNCNAME MODULE_NAME_STR ".run_string"
1106+ PyThreadState * tstate = _PyThreadState_GET ();
11211107 static char * kwlist [] = {"id" , "script" , "shared" , "restrict" , NULL };
11221108 PyObject * id , * script ;
11231109 PyObject * shared = NULL ;
11241110 int restricted = 0 ;
11251111 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 ))
11281114 {
11291115 return NULL ;
11301116 }
@@ -1136,7 +1122,7 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
11361122 return NULL ;
11371123 }
11381124
1139- script = (PyObject * )convert_script_arg (script , MODULE_NAME_STR ".run_string" ,
1125+ script = (PyObject * )convert_script_arg (tstate , script , FUNCNAME ,
11401126 "argument 2" , "a string" );
11411127 if (script == NULL ) {
11421128 return NULL ;
@@ -1150,6 +1136,7 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
11501136 return excinfo ;
11511137 }
11521138 Py_RETURN_NONE ;
1139+ #undef FUNCNAME
11531140}
11541141
11551142PyDoc_STRVAR (run_string_doc ,
@@ -1162,13 +1149,15 @@ Execute the provided string in the identified interpreter.\n\
11621149static PyObject *
11631150interp_run_func (PyObject * self , PyObject * args , PyObject * kwds )
11641151{
1152+ #define FUNCNAME MODULE_NAME_STR ".run_func"
1153+ PyThreadState * tstate = _PyThreadState_GET ();
11651154 static char * kwlist [] = {"id" , "func" , "shared" , "restrict" , NULL };
11661155 PyObject * id , * func ;
11671156 PyObject * shared = NULL ;
11681157 int restricted = 0 ;
11691158 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 ))
11721161 {
11731162 return NULL ;
11741163 }
@@ -1180,7 +1169,7 @@ interp_run_func(PyObject *self, PyObject *args, PyObject *kwds)
11801169 return NULL ;
11811170 }
11821171
1183- PyCodeObject * code = convert_code_arg (func , MODULE_NAME_STR ".exec" ,
1172+ PyCodeObject * code = convert_code_arg (tstate , func , FUNCNAME ,
11841173 "argument 2" ,
11851174 "a function or a code object" );
11861175 if (code == NULL ) {
@@ -1195,6 +1184,7 @@ interp_run_func(PyObject *self, PyObject *args, PyObject *kwds)
11951184 return excinfo ;
11961185 }
11971186 Py_RETURN_NONE ;
1187+ #undef FUNCNAME
11981188}
11991189
12001190PyDoc_STRVAR (run_func_doc ,
@@ -1209,14 +1199,16 @@ are not supported. Methods and other callables are not supported either.\n\
12091199static PyObject *
12101200interp_call (PyObject * self , PyObject * args , PyObject * kwds )
12111201{
1202+ #define FUNCNAME MODULE_NAME_STR ".call"
1203+ PyThreadState * tstate = _PyThreadState_GET ();
12121204 static char * kwlist [] = {"id" , "callable" , "args" , "kwargs" ,
12131205 "restrict" , NULL };
12141206 PyObject * id , * callable ;
12151207 PyObject * args_obj = NULL ;
12161208 PyObject * kwargs_obj = NULL ;
12171209 int restricted = 0 ;
12181210 if (!PyArg_ParseTupleAndKeywords (args , kwds ,
1219- "OO|OO$p:" MODULE_NAME_STR ".call" , kwlist ,
1211+ "OO|OO$p:" FUNCNAME , kwlist ,
12201212 & id , & callable , & args_obj , & kwargs_obj ,
12211213 & restricted ))
12221214 {
@@ -1231,15 +1223,15 @@ interp_call(PyObject *self, PyObject *args, PyObject *kwds)
12311223 }
12321224
12331225 if (args_obj != NULL ) {
1234- PyErr_SetString ( PyExc_ValueError , "got unexpected args" );
1226+ _PyErr_SetString ( tstate , PyExc_ValueError , "got unexpected args" );
12351227 return NULL ;
12361228 }
12371229 if (kwargs_obj != NULL ) {
1238- PyErr_SetString ( PyExc_ValueError , "got unexpected kwargs" );
1230+ _PyErr_SetString ( tstate , PyExc_ValueError , "got unexpected kwargs" );
12391231 return NULL ;
12401232 }
12411233
1242- PyObject * code = (PyObject * )convert_code_arg (callable , MODULE_NAME_STR ".call" ,
1234+ PyObject * code = (PyObject * )convert_code_arg (tstate , callable , FUNCNAME ,
12431235 "argument 2" , "a function" );
12441236 if (code == NULL ) {
12451237 return NULL ;
@@ -1253,6 +1245,7 @@ interp_call(PyObject *self, PyObject *args, PyObject *kwds)
12531245 return excinfo ;
12541246 }
12551247 Py_RETURN_NONE ;
1248+ #undef FUNCNAME
12561249}
12571250
12581251PyDoc_STRVAR (call_doc ,
0 commit comments