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