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,50 @@ 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 ;
975+ if (_PyFunction_VerifyStateless (tstate , arg ) < 0 ) {
976+ goto chained ;
990977 }
991978 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 ;
1003- }
1004979 Py_INCREF (code );
1005- kind = "func" ;
1006980 }
1007981 else if (PyCode_Check (arg )) {
982+ if (_PyCode_VerifyStateless (
983+ tstate , (PyCodeObject * )arg , NULL , NULL , NULL ) < 0 ) {
984+ goto chained ;
985+ }
1008986 code = (PyCodeObject * )Py_NewRef (arg );
1009- kind = "code object" ;
1010987 }
1011988 else {
1012989 _PyArg_BadArgument (fname , displayname , expected , arg );
1013990 return NULL ;
1014991 }
1015992
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-
1024993 return code ;
994+
995+ chained :
996+ cause = _PyErr_GetRaisedException (tstate );
997+ assert (cause != NULL );
998+ _PyArg_BadArgument (fname , displayname , expected , arg );
999+ PyObject * exc = _PyErr_GetRaisedException (tstate );
1000+ PyException_SetCause (exc , cause );
1001+ _PyErr_SetRaisedException (tstate , exc );
1002+ return NULL ;
10251003}
10261004
10271005static int
@@ -1057,12 +1035,14 @@ _interp_exec(PyObject *self, PyInterpreterState *interp,
10571035static PyObject *
10581036interp_exec (PyObject * self , PyObject * args , PyObject * kwds )
10591037{
1038+ #define FUNCNAME MODULE_NAME_STR ".exec"
1039+ PyThreadState * tstate = _PyThreadState_GET ();
10601040 static char * kwlist [] = {"id" , "code" , "shared" , "restrict" , NULL };
10611041 PyObject * id , * code ;
10621042 PyObject * shared = NULL ;
10631043 int restricted = 0 ;
10641044 if (!PyArg_ParseTupleAndKeywords (args , kwds ,
1065- "OO|O$p:" MODULE_NAME_STR ".exec" , kwlist ,
1045+ "OO|O$p:" FUNCNAME , kwlist ,
10661046 & id , & code , & shared , & restricted ))
10671047 {
10681048 return NULL ;
@@ -1077,12 +1057,12 @@ interp_exec(PyObject *self, PyObject *args, PyObject *kwds)
10771057
10781058 const char * expected = "a string, a function, or a code object" ;
10791059 if (PyUnicode_Check (code )) {
1080- code = (PyObject * )convert_script_arg (code , MODULE_NAME_STR ".exec" ,
1081- "argument 2" , expected );
1060+ code = (PyObject * )convert_script_arg (tstate , code , FUNCNAME ,
1061+ "argument 2" , expected );
10821062 }
10831063 else {
1084- code = (PyObject * )convert_code_arg (code , MODULE_NAME_STR ".exec" ,
1085- "argument 2" , expected );
1064+ code = (PyObject * )convert_code_arg (tstate , code , FUNCNAME ,
1065+ "argument 2" , expected );
10861066 }
10871067 if (code == NULL ) {
10881068 return NULL ;
@@ -1096,6 +1076,7 @@ interp_exec(PyObject *self, PyObject *args, PyObject *kwds)
10961076 return excinfo ;
10971077 }
10981078 Py_RETURN_NONE ;
1079+ #undef FUNCNAME
10991080}
11001081
11011082PyDoc_STRVAR (exec_doc ,
@@ -1118,13 +1099,15 @@ is ignored, including its __globals__ dict.");
11181099static PyObject *
11191100interp_run_string (PyObject * self , PyObject * args , PyObject * kwds )
11201101{
1102+ #define FUNCNAME MODULE_NAME_STR ".run_string"
1103+ PyThreadState * tstate = _PyThreadState_GET ();
11211104 static char * kwlist [] = {"id" , "script" , "shared" , "restrict" , NULL };
11221105 PyObject * id , * script ;
11231106 PyObject * shared = NULL ;
11241107 int restricted = 0 ;
11251108 if (!PyArg_ParseTupleAndKeywords (args , kwds ,
1126- "OU|O$p:" MODULE_NAME_STR ".run_string" ,
1127- kwlist , & id , & script , & shared , & restricted ))
1109+ "OU|O$p:" FUNCNAME , kwlist ,
1110+ & id , & script , & shared , & restricted ))
11281111 {
11291112 return NULL ;
11301113 }
@@ -1136,7 +1119,7 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
11361119 return NULL ;
11371120 }
11381121
1139- script = (PyObject * )convert_script_arg (script , MODULE_NAME_STR ".run_string" ,
1122+ script = (PyObject * )convert_script_arg (tstate , script , FUNCNAME ,
11401123 "argument 2" , "a string" );
11411124 if (script == NULL ) {
11421125 return NULL ;
@@ -1150,6 +1133,7 @@ interp_run_string(PyObject *self, PyObject *args, PyObject *kwds)
11501133 return excinfo ;
11511134 }
11521135 Py_RETURN_NONE ;
1136+ #undef FUNCNAME
11531137}
11541138
11551139PyDoc_STRVAR (run_string_doc ,
@@ -1162,13 +1146,15 @@ Execute the provided string in the identified interpreter.\n\
11621146static PyObject *
11631147interp_run_func (PyObject * self , PyObject * args , PyObject * kwds )
11641148{
1149+ #define FUNCNAME MODULE_NAME_STR ".run_func"
1150+ PyThreadState * tstate = _PyThreadState_GET ();
11651151 static char * kwlist [] = {"id" , "func" , "shared" , "restrict" , NULL };
11661152 PyObject * id , * func ;
11671153 PyObject * shared = NULL ;
11681154 int restricted = 0 ;
11691155 if (!PyArg_ParseTupleAndKeywords (args , kwds ,
1170- "OO|O$p:" MODULE_NAME_STR ".run_func" ,
1171- kwlist , & id , & func , & shared , & restricted ))
1156+ "OO|O$p:" FUNCNAME , kwlist ,
1157+ & id , & func , & shared , & restricted ))
11721158 {
11731159 return NULL ;
11741160 }
@@ -1180,7 +1166,7 @@ interp_run_func(PyObject *self, PyObject *args, PyObject *kwds)
11801166 return NULL ;
11811167 }
11821168
1183- PyCodeObject * code = convert_code_arg (func , MODULE_NAME_STR ".exec" ,
1169+ PyCodeObject * code = convert_code_arg (tstate , func , FUNCNAME ,
11841170 "argument 2" ,
11851171 "a function or a code object" );
11861172 if (code == NULL ) {
@@ -1195,6 +1181,7 @@ interp_run_func(PyObject *self, PyObject *args, PyObject *kwds)
11951181 return excinfo ;
11961182 }
11971183 Py_RETURN_NONE ;
1184+ #undef FUNCNAME
11981185}
11991186
12001187PyDoc_STRVAR (run_func_doc ,
@@ -1209,14 +1196,16 @@ are not supported. Methods and other callables are not supported either.\n\
12091196static PyObject *
12101197interp_call (PyObject * self , PyObject * args , PyObject * kwds )
12111198{
1199+ #define FUNCNAME MODULE_NAME_STR ".call"
1200+ PyThreadState * tstate = _PyThreadState_GET ();
12121201 static char * kwlist [] = {"id" , "callable" , "args" , "kwargs" ,
12131202 "restrict" , NULL };
12141203 PyObject * id , * callable ;
12151204 PyObject * args_obj = NULL ;
12161205 PyObject * kwargs_obj = NULL ;
12171206 int restricted = 0 ;
12181207 if (!PyArg_ParseTupleAndKeywords (args , kwds ,
1219- "OO|OO$p:" MODULE_NAME_STR ".call" , kwlist ,
1208+ "OO|OO$p:" FUNCNAME , kwlist ,
12201209 & id , & callable , & args_obj , & kwargs_obj ,
12211210 & restricted ))
12221211 {
@@ -1231,15 +1220,15 @@ interp_call(PyObject *self, PyObject *args, PyObject *kwds)
12311220 }
12321221
12331222 if (args_obj != NULL ) {
1234- PyErr_SetString ( PyExc_ValueError , "got unexpected args" );
1223+ _PyErr_SetString ( tstate , PyExc_ValueError , "got unexpected args" );
12351224 return NULL ;
12361225 }
12371226 if (kwargs_obj != NULL ) {
1238- PyErr_SetString ( PyExc_ValueError , "got unexpected kwargs" );
1227+ _PyErr_SetString ( tstate , PyExc_ValueError , "got unexpected kwargs" );
12391228 return NULL ;
12401229 }
12411230
1242- PyObject * code = (PyObject * )convert_code_arg (callable , MODULE_NAME_STR ".call" ,
1231+ PyObject * code = (PyObject * )convert_code_arg (tstate , callable , FUNCNAME ,
12431232 "argument 2" , "a function" );
12441233 if (code == NULL ) {
12451234 return NULL ;
@@ -1253,6 +1242,7 @@ interp_call(PyObject *self, PyObject *args, PyObject *kwds)
12531242 return excinfo ;
12541243 }
12551244 Py_RETURN_NONE ;
1245+ #undef FUNCNAME
12561246}
12571247
12581248PyDoc_STRVAR (call_doc ,
0 commit comments