Mercurial > cpython-lru_cache-weakref
comparison Python/pythonrun.c @ 36065:ea083efdc96c legacy-trunk
Merge from ast-arena. This reduces the code in Python/ast.c by ~300 lines,
simplifies a lot of error handling code, and fixes many memory leaks.
| author | Neal Norwitz <nnorwitz@gmail.com> |
|---|---|
| date | Sat, 17 Dec 2005 20:54:49 +0000 |
| parents | 72555a967d6a |
| children | 1ff4790b7605 |
comparison
equal
deleted
inserted
replaced
| 36064:fb6e64eb86c0 | 36065:ea083efdc96c |
|---|---|
| 10 #include "parsetok.h" | 10 #include "parsetok.h" |
| 11 #include "errcode.h" | 11 #include "errcode.h" |
| 12 #include "code.h" | 12 #include "code.h" |
| 13 #include "compile.h" | 13 #include "compile.h" |
| 14 #include "symtable.h" | 14 #include "symtable.h" |
| 15 #include "pyarena.h" | |
| 15 #include "ast.h" | 16 #include "ast.h" |
| 16 #include "eval.h" | 17 #include "eval.h" |
| 17 #include "marshal.h" | 18 #include "marshal.h" |
| 18 | 19 |
| 19 #include <signal.h> | 20 #include <signal.h> |
| 34 | 35 |
| 35 /* Forward */ | 36 /* Forward */ |
| 36 static void initmain(void); | 37 static void initmain(void); |
| 37 static void initsite(void); | 38 static void initsite(void); |
| 38 static PyObject *run_err_mod(mod_ty, const char *, PyObject *, PyObject *, | 39 static PyObject *run_err_mod(mod_ty, const char *, PyObject *, PyObject *, |
| 39 PyCompilerFlags *); | 40 PyCompilerFlags *, PyArena *arena); |
| 40 static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *, | 41 static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *, |
| 41 PyCompilerFlags *); | 42 PyCompilerFlags *, PyArena *); |
| 42 static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *, | 43 static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *, |
| 43 PyCompilerFlags *); | 44 PyCompilerFlags *); |
| 44 static void err_input(perrdetail *); | 45 static void err_input(perrdetail *); |
| 45 static void initsigs(void); | 46 static void initsigs(void); |
| 46 static void call_sys_exitfunc(void); | 47 static void call_sys_exitfunc(void); |
| 695 int | 696 int |
| 696 PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags) | 697 PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags) |
| 697 { | 698 { |
| 698 PyObject *m, *d, *v, *w; | 699 PyObject *m, *d, *v, *w; |
| 699 mod_ty mod; | 700 mod_ty mod; |
| 701 PyArena *arena; | |
| 700 char *ps1 = "", *ps2 = ""; | 702 char *ps1 = "", *ps2 = ""; |
| 701 int errcode = 0; | 703 int errcode = 0; |
| 702 | 704 |
| 703 v = PySys_GetObject("ps1"); | 705 v = PySys_GetObject("ps1"); |
| 704 if (v != NULL) { | 706 if (v != NULL) { |
| 714 if (w == NULL) | 716 if (w == NULL) |
| 715 PyErr_Clear(); | 717 PyErr_Clear(); |
| 716 else if (PyString_Check(w)) | 718 else if (PyString_Check(w)) |
| 717 ps2 = PyString_AsString(w); | 719 ps2 = PyString_AsString(w); |
| 718 } | 720 } |
| 721 arena = PyArena_New(); | |
| 719 mod = PyParser_ASTFromFile(fp, filename, | 722 mod = PyParser_ASTFromFile(fp, filename, |
| 720 Py_single_input, ps1, ps2, | 723 Py_single_input, ps1, ps2, |
| 721 flags, &errcode); | 724 flags, &errcode, arena); |
| 722 Py_XDECREF(v); | 725 Py_XDECREF(v); |
| 723 Py_XDECREF(w); | 726 Py_XDECREF(w); |
| 724 if (mod == NULL) { | 727 if (mod == NULL) { |
| 728 PyArena_Free(arena); | |
| 725 if (errcode == E_EOF) { | 729 if (errcode == E_EOF) { |
| 726 PyErr_Clear(); | 730 PyErr_Clear(); |
| 727 return E_EOF; | 731 return E_EOF; |
| 728 } | 732 } |
| 729 PyErr_Print(); | 733 PyErr_Print(); |
| 730 return -1; | 734 return -1; |
| 731 } | 735 } |
| 732 m = PyImport_AddModule("__main__"); | 736 m = PyImport_AddModule("__main__"); |
| 733 if (m == NULL) | 737 if (m == NULL) { |
| 738 PyArena_Free(arena); | |
| 734 return -1; | 739 return -1; |
| 740 } | |
| 735 d = PyModule_GetDict(m); | 741 d = PyModule_GetDict(m); |
| 736 v = run_mod(mod, filename, d, d, flags); | 742 v = run_mod(mod, filename, d, d, flags, arena); |
| 737 free_mod(mod); | 743 PyArena_Free(arena); |
| 738 if (v == NULL) { | 744 if (v == NULL) { |
| 739 PyErr_Print(); | 745 PyErr_Print(); |
| 740 return -1; | 746 return -1; |
| 741 } | 747 } |
| 742 Py_DECREF(v); | 748 Py_DECREF(v); |
| 1153 PyObject * | 1159 PyObject * |
| 1154 PyRun_StringFlags(const char *str, int start, PyObject *globals, | 1160 PyRun_StringFlags(const char *str, int start, PyObject *globals, |
| 1155 PyObject *locals, PyCompilerFlags *flags) | 1161 PyObject *locals, PyCompilerFlags *flags) |
| 1156 { | 1162 { |
| 1157 PyObject *ret; | 1163 PyObject *ret; |
| 1158 mod_ty mod = PyParser_ASTFromString(str, "<string>", start, flags); | 1164 PyArena *arena = PyArena_New(); |
| 1159 ret = run_err_mod(mod, "<string>", globals, locals, flags); | 1165 mod_ty mod = PyParser_ASTFromString(str, "<string>", start, flags, |
| 1160 free_mod(mod); | 1166 arena); |
| 1167 ret = run_err_mod(mod, "<string>", globals, locals, flags, arena); | |
| 1168 PyArena_Free(arena); | |
| 1161 return ret; | 1169 return ret; |
| 1162 } | 1170 } |
| 1163 | 1171 |
| 1164 PyObject * | 1172 PyObject * |
| 1165 PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals, | 1173 PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals, |
| 1166 PyObject *locals, int closeit, PyCompilerFlags *flags) | 1174 PyObject *locals, int closeit, PyCompilerFlags *flags) |
| 1167 { | 1175 { |
| 1168 PyObject *ret; | 1176 PyObject *ret; |
| 1177 PyArena *arena = PyArena_New(); | |
| 1169 mod_ty mod = PyParser_ASTFromFile(fp, filename, start, 0, 0, | 1178 mod_ty mod = PyParser_ASTFromFile(fp, filename, start, 0, 0, |
| 1170 flags, NULL); | 1179 flags, NULL, arena); |
| 1171 if (mod == NULL) | 1180 if (mod == NULL) { |
| 1181 PyArena_Free(arena); | |
| 1172 return NULL; | 1182 return NULL; |
| 1183 } | |
| 1173 if (closeit) | 1184 if (closeit) |
| 1174 fclose(fp); | 1185 fclose(fp); |
| 1175 ret = run_err_mod(mod, filename, globals, locals, flags); | 1186 ret = run_err_mod(mod, filename, globals, locals, flags, arena); |
| 1176 free_mod(mod); | 1187 PyArena_Free(arena); |
| 1177 return ret; | 1188 return ret; |
| 1178 } | 1189 } |
| 1179 | 1190 |
| 1180 static PyObject * | 1191 static PyObject * |
| 1181 run_err_mod(mod_ty mod, const char *filename, PyObject *globals, | 1192 run_err_mod(mod_ty mod, const char *filename, PyObject *globals, |
| 1182 PyObject *locals, PyCompilerFlags *flags) | 1193 PyObject *locals, PyCompilerFlags *flags, PyArena *arena) |
| 1183 { | 1194 { |
| 1184 if (mod == NULL) | 1195 if (mod == NULL) |
| 1185 return NULL; | 1196 return NULL; |
| 1186 return run_mod(mod, filename, globals, locals, flags); | 1197 return run_mod(mod, filename, globals, locals, flags, arena); |
| 1187 } | 1198 } |
| 1188 | 1199 |
| 1189 static PyObject * | 1200 static PyObject * |
| 1190 run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals, | 1201 run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals, |
| 1191 PyCompilerFlags *flags) | 1202 PyCompilerFlags *flags, PyArena *arena) |
| 1192 { | 1203 { |
| 1193 PyCodeObject *co; | 1204 PyCodeObject *co; |
| 1194 PyObject *v; | 1205 PyObject *v; |
| 1195 co = PyAST_Compile(mod, filename, flags); | 1206 co = PyAST_Compile(mod, filename, flags, arena); |
| 1196 if (co == NULL) | 1207 if (co == NULL) |
| 1197 return NULL; | 1208 return NULL; |
| 1198 v = PyEval_EvalCode(co, globals, locals); | 1209 v = PyEval_EvalCode(co, globals, locals); |
| 1199 Py_DECREF(co); | 1210 Py_DECREF(co); |
| 1200 return v; | 1211 return v; |
| 1234 | 1245 |
| 1235 PyObject * | 1246 PyObject * |
| 1236 Py_CompileStringFlags(const char *str, const char *filename, int start, | 1247 Py_CompileStringFlags(const char *str, const char *filename, int start, |
| 1237 PyCompilerFlags *flags) | 1248 PyCompilerFlags *flags) |
| 1238 { | 1249 { |
| 1239 mod_ty mod; | |
| 1240 PyCodeObject *co; | 1250 PyCodeObject *co; |
| 1241 mod = PyParser_ASTFromString(str, filename, start, flags); | 1251 PyArena *arena = PyArena_New(); |
| 1242 if (mod == NULL) | 1252 mod_ty mod = PyParser_ASTFromString(str, filename, start, flags, arena); |
| 1253 if (mod == NULL) { | |
| 1254 PyArena_Free(arena); | |
| 1243 return NULL; | 1255 return NULL; |
| 1244 co = PyAST_Compile(mod, filename, flags); | 1256 } |
| 1245 free_mod(mod); | 1257 co = PyAST_Compile(mod, filename, flags, arena); |
| 1258 PyArena_Free(arena); | |
| 1246 return (PyObject *)co; | 1259 return (PyObject *)co; |
| 1247 } | 1260 } |
| 1248 | 1261 |
| 1249 struct symtable * | 1262 struct symtable * |
| 1250 Py_SymtableString(const char *str, const char *filename, int start) | 1263 Py_SymtableString(const char *str, const char *filename, int start) |
| 1251 { | 1264 { |
| 1252 mod_ty mod; | |
| 1253 struct symtable *st; | 1265 struct symtable *st; |
| 1254 | 1266 PyArena *arena = PyArena_New(); |
| 1255 mod = PyParser_ASTFromString(str, filename, start, NULL); | 1267 mod_ty mod = PyParser_ASTFromString(str, filename, start, NULL, arena); |
| 1256 if (mod == NULL) | 1268 if (mod == NULL) { |
| 1269 PyArena_Free(arena); | |
| 1257 return NULL; | 1270 return NULL; |
| 1271 } | |
| 1258 st = PySymtable_Build(mod, filename, 0); | 1272 st = PySymtable_Build(mod, filename, 0); |
| 1259 free_mod(mod); | 1273 PyArena_Free(arena); |
| 1260 return st; | 1274 return st; |
| 1261 } | 1275 } |
| 1262 | 1276 |
| 1263 /* Preferred access to parser is through AST. */ | 1277 /* Preferred access to parser is through AST. */ |
| 1264 mod_ty | 1278 mod_ty |
| 1265 PyParser_ASTFromString(const char *s, const char *filename, int start, | 1279 PyParser_ASTFromString(const char *s, const char *filename, int start, |
| 1266 PyCompilerFlags *flags) | 1280 PyCompilerFlags *flags, PyArena *arena) |
| 1267 { | 1281 { |
| 1268 node *n; | |
| 1269 mod_ty mod; | 1282 mod_ty mod; |
| 1270 perrdetail err; | 1283 perrdetail err; |
| 1271 n = PyParser_ParseStringFlagsFilename(s, filename, &_PyParser_Grammar, | 1284 node *n = PyParser_ParseStringFlagsFilename(s, filename, |
| 1272 start, &err, | 1285 &_PyParser_Grammar, start, &err, |
| 1273 PARSER_FLAGS(flags)); | 1286 PARSER_FLAGS(flags)); |
| 1274 if (n) { | 1287 if (n) { |
| 1275 mod = PyAST_FromNode(n, flags, filename); | 1288 mod = PyAST_FromNode(n, flags, filename, arena); |
| 1276 PyNode_Free(n); | 1289 PyNode_Free(n); |
| 1277 return mod; | 1290 return mod; |
| 1278 } | 1291 } |
| 1279 else { | 1292 else { |
| 1280 err_input(&err); | 1293 err_input(&err); |
| 1282 } | 1295 } |
| 1283 } | 1296 } |
| 1284 | 1297 |
| 1285 mod_ty | 1298 mod_ty |
| 1286 PyParser_ASTFromFile(FILE *fp, const char *filename, int start, char *ps1, | 1299 PyParser_ASTFromFile(FILE *fp, const char *filename, int start, char *ps1, |
| 1287 char *ps2, PyCompilerFlags *flags, int *errcode) | 1300 char *ps2, PyCompilerFlags *flags, int *errcode, |
| 1288 { | 1301 PyArena *arena) |
| 1289 node *n; | 1302 { |
| 1290 mod_ty mod; | 1303 mod_ty mod; |
| 1291 perrdetail err; | 1304 perrdetail err; |
| 1292 n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar, start, | 1305 node *n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar, |
| 1293 ps1, ps2, &err, PARSER_FLAGS(flags)); | 1306 start, ps1, ps2, &err, PARSER_FLAGS(flags)); |
| 1294 if (n) { | 1307 if (n) { |
| 1295 mod = PyAST_FromNode(n, flags, filename); | 1308 mod = PyAST_FromNode(n, flags, filename, arena); |
| 1296 PyNode_Free(n); | 1309 PyNode_Free(n); |
| 1297 return mod; | 1310 return mod; |
| 1298 } | 1311 } |
| 1299 else { | 1312 else { |
| 1300 err_input(&err); | 1313 err_input(&err); |
| 1307 /* Simplified interface to parsefile -- return node or set exception */ | 1320 /* Simplified interface to parsefile -- return node or set exception */ |
| 1308 | 1321 |
| 1309 node * | 1322 node * |
| 1310 PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags) | 1323 PyParser_SimpleParseFileFlags(FILE *fp, const char *filename, int start, int flags) |
| 1311 { | 1324 { |
| 1312 node *n; | |
| 1313 perrdetail err; | 1325 perrdetail err; |
| 1314 n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar, start, | 1326 node *n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar, |
| 1315 (char *)0, (char *)0, &err, flags); | 1327 start, NULL, NULL, &err, flags); |
| 1316 if (n == NULL) | 1328 if (n == NULL) |
| 1317 err_input(&err); | 1329 err_input(&err); |
| 1318 | 1330 |
| 1319 return n; | 1331 return n; |
| 1320 } | 1332 } |
| 1322 /* Simplified interface to parsestring -- return node or set exception */ | 1334 /* Simplified interface to parsestring -- return node or set exception */ |
| 1323 | 1335 |
| 1324 node * | 1336 node * |
| 1325 PyParser_SimpleParseStringFlags(const char *str, int start, int flags) | 1337 PyParser_SimpleParseStringFlags(const char *str, int start, int flags) |
| 1326 { | 1338 { |
| 1327 node *n; | |
| 1328 perrdetail err; | 1339 perrdetail err; |
| 1329 n = PyParser_ParseStringFlags(str, &_PyParser_Grammar, start, &err, | 1340 node *n = PyParser_ParseStringFlags(str, &_PyParser_Grammar, |
| 1330 flags); | 1341 start, &err, flags); |
| 1331 if (n == NULL) | 1342 if (n == NULL) |
| 1332 err_input(&err); | 1343 err_input(&err); |
| 1333 return n; | 1344 return n; |
| 1334 } | 1345 } |
| 1335 | 1346 |
| 1336 node * | 1347 node * |
| 1337 PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename, | 1348 PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename, |
| 1338 int start, int flags) | 1349 int start, int flags) |
| 1339 { | 1350 { |
| 1340 node *n; | |
| 1341 perrdetail err; | 1351 perrdetail err; |
| 1342 | 1352 node *n = PyParser_ParseStringFlagsFilename(str, filename, |
| 1343 n = PyParser_ParseStringFlagsFilename(str, filename, | 1353 &_PyParser_Grammar, start, &err, flags); |
| 1344 &_PyParser_Grammar, | |
| 1345 start, &err, flags); | |
| 1346 if (n == NULL) | 1354 if (n == NULL) |
| 1347 err_input(&err); | 1355 err_input(&err); |
| 1348 return n; | 1356 return n; |
| 1349 } | 1357 } |
| 1350 | 1358 |
| 1351 node * | 1359 node * |
| 1352 PyParser_SimpleParseStringFilename(const char *str, const char *filename, int start) | 1360 PyParser_SimpleParseStringFilename(const char *str, const char *filename, int start) |
| 1353 { | 1361 { |
| 1354 return PyParser_SimpleParseStringFlagsFilename(str, filename, | 1362 return PyParser_SimpleParseStringFlagsFilename(str, filename, start, 0); |
| 1355 start, 0); | |
| 1356 } | 1363 } |
| 1357 | 1364 |
| 1358 /* May want to move a more generalized form of this to parsetok.c or | 1365 /* May want to move a more generalized form of this to parsetok.c or |
| 1359 even parser modules. */ | 1366 even parser modules. */ |
| 1360 | 1367 |
