mirror of
https://github.com/python/cpython.git
synced 2025-07-19 01:05:26 +00:00
* 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.
This commit is contained in:
parent
cacd9579d4
commit
db3165e655
9 changed files with 600 additions and 451 deletions
|
@ -232,14 +232,6 @@ builtin_eval(self, v)
|
|||
return exec_eval(v, eval_input);
|
||||
}
|
||||
|
||||
static object *
|
||||
builtin_exec(self, v)
|
||||
object *self;
|
||||
object *v;
|
||||
{
|
||||
return exec_eval(v, file_input);
|
||||
}
|
||||
|
||||
static object *
|
||||
builtin_execfile(self, v)
|
||||
object *self;
|
||||
|
@ -755,7 +747,6 @@ static struct methodlist builtin_methods[] = {
|
|||
{"dir", builtin_dir},
|
||||
{"divmod", builtin_divmod},
|
||||
{"eval", builtin_eval},
|
||||
{"exec", builtin_exec},
|
||||
{"execfile", builtin_execfile},
|
||||
{"float", builtin_float},
|
||||
{"getattr", builtin_getattr},
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1305,7 +1305,7 @@ com_expr_stmt(c, n)
|
|||
struct compiling *c;
|
||||
node *n;
|
||||
{
|
||||
REQ(n, expr_stmt); /* exprlist ('=' exprlist)* */
|
||||
REQ(n, expr_stmt); /* testlist ('=' testlist)* */
|
||||
com_node(c, CHILD(n, NCH(n)-1));
|
||||
if (NCH(n) == 1) {
|
||||
com_addbyte(c, PRINT_EXPR);
|
||||
|
@ -1466,6 +1466,25 @@ com_access_stmt(c, n)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
com_exec_stmt(c, n)
|
||||
struct compiling *c;
|
||||
node *n;
|
||||
{
|
||||
REQ(n, exec_stmt);
|
||||
/* exec_stmt: 'exec' expr ['in' expr [',' expr]] */
|
||||
com_node(c, CHILD(n, 1));
|
||||
if (NCH(n) >= 4)
|
||||
com_node(c, CHILD(n, 3));
|
||||
else
|
||||
com_addoparg(c, LOAD_CONST, com_addconst(c, None));
|
||||
if (NCH(n) >= 6)
|
||||
com_node(c, CHILD(n, 5));
|
||||
else
|
||||
com_addbyte(c, DUP_TOP);
|
||||
com_addbyte(c, EXEC_STMT);
|
||||
}
|
||||
|
||||
static void
|
||||
com_if_stmt(c, n)
|
||||
struct compiling *c;
|
||||
|
@ -1909,6 +1928,9 @@ com_node(c, n)
|
|||
case access_stmt:
|
||||
com_access_stmt(c, n);
|
||||
break;
|
||||
case exec_stmt:
|
||||
com_exec_stmt(c, n);
|
||||
break;
|
||||
case if_stmt:
|
||||
com_if_stmt(c, n);
|
||||
break;
|
||||
|
@ -2183,6 +2205,8 @@ optimize(c)
|
|||
opcode = NEXTOP();
|
||||
if (opcode == STOP_CODE)
|
||||
break;
|
||||
if (opcode == EXEC_STMT)
|
||||
goto end; /* Don't optimize if exec present */
|
||||
if (HAS_ARG(opcode))
|
||||
oparg = NEXTARG();
|
||||
if (opcode == STORE_NAME || opcode == DELETE_NAME ||
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue