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