summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1993-10-18 17:06:59 (GMT)
committerGuido van Rossum <guido@python.org>1993-10-18 17:06:59 (GMT)
commitdb3165e6559c6b83373e7fed9cdf4371552a9a8e (patch)
tree97b057363244668ebec6630553a86ad2206e3fd2 /Python/ceval.c
parentcacd9579d48cb1e2acc3536c9701987b118edf8c (diff)
downloadcpython-db3165e6559c6b83373e7fed9cdf4371552a9a8e.zip
cpython-db3165e6559c6b83373e7fed9cdf4371552a9a8e.tar.gz
cpython-db3165e6559c6b83373e7fed9cdf4371552a9a8e.tar.bz2
* bltinmodule.c: removed exec() built-in function.
* Grammar: add exec statement; allow testlist in expr statement. * ceval.c, compile.c, opcode.h: support exec statement; avoid optimizing locals when it is used * fileobject.{c,h}: add getfilename() internal function.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index b8d6de2..071d664 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -35,6 +35,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "opcode.h"
#include "bltinmodule.h"
#include "traceback.h"
+#include "graminit.h"
+#include "pythonrun.h"
/* Turn this on if your compiler chokes on the big switch: */
/* #define CASE_TOO_BIG 1 /**/
@@ -91,6 +93,7 @@ static object *build_class PROTO((object *, object *, object *));
static void locals_2_fast PROTO((frameobject *, int));
static void fast_2_locals PROTO((frameobject *));
static int access_statement PROTO((object *, object *, frameobject *));
+static int exec_statement PROTO((object *, object *, object *));
/* Pointer to current frame, used to link new frames to */
@@ -712,6 +715,22 @@ eval_code(co, globals, locals, owner, arg)
retval = POP();
why = WHY_RETURN;
break;
+
+ case LOAD_GLOBALS:
+ v = f->f_locals;
+ INCREF(v);
+ PUSH(v);
+ break;
+
+ case EXEC_STMT:
+ w = POP();
+ v = POP();
+ u = POP();
+ err = exec_statement(u, v, w);
+ DECREF(u);
+ DECREF(v);
+ DECREF(w);
+ break;
case BUILD_FUNCTION:
v = POP();
@@ -2489,3 +2508,62 @@ access_statement(name, vmode, f)
}
return ret;
}
+
+static int
+exec_statement(prog, globals, locals)
+ object *prog;
+ object *globals;
+ object *locals;
+{
+ char *s;
+ int n;
+
+ if (is_tupleobject(prog) && globals == None && locals == None &&
+ ((n = gettuplesize(prog)) == 2 || n == 3)) {
+ /* Backward compatibility hack */
+ globals = gettupleitem(prog, 1);
+ if (n == 3)
+ locals = gettupleitem(prog, 2);
+ prog = gettupleitem(prog, 0);
+ }
+ if (globals == None) {
+ globals = getglobals();
+ if (locals == None)
+ locals = getlocals();
+ }
+ else if (locals == None)
+ locals = globals;
+ if (!is_stringobject(prog) &&
+ !is_codeobject(prog) &&
+ !is_fileobject(prog)) {
+ err_setstr(TypeError,
+ "exec 1st arg must be string, code or file object");
+ return -1;
+ }
+ if (!is_dictobject(globals) || !is_dictobject(locals)) {
+ err_setstr(TypeError,
+ "exec 2nd/3rd args must be dict or None");
+ return -1;
+ }
+ if (is_codeobject(prog)) {
+ if (eval_code((codeobject *) prog, globals, locals,
+ (object *)NULL, (object *)NULL) == NULL)
+ return -1;
+ return 0;
+ }
+ if (is_fileobject(prog)) {
+ FILE *fp = getfilefile(prog);
+ char *name = getstringvalue(getfilename(prog));
+ if (run_file(fp, name, file_input, globals, locals) == NULL)
+ return -1;
+ return 0;
+ }
+ s = getstringvalue(prog);
+ if (strlen(s) != getstringsize(prog)) {
+ err_setstr(ValueError, "embedded '\\0' in exec string");
+ return -1;
+ }
+ if (run_string(s, file_input, globals, locals) == NULL)
+ return -1;
+ return 0;
+}