summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/pythonrun.h2
-rw-r--r--Objects/frameobject.c2
-rw-r--r--Python/bltinmodule.c51
-rw-r--r--Python/ceval.c53
-rw-r--r--Python/pythonrun.c45
5 files changed, 117 insertions, 36 deletions
diff --git a/Include/pythonrun.h b/Include/pythonrun.h
index 9441376..6c6117b 100644
--- a/Include/pythonrun.h
+++ b/Include/pythonrun.h
@@ -42,6 +42,8 @@ object *run_file PROTO((FILE *, char *, int, object *, object *));
object *run_err_node PROTO((int, struct _node *, char *, object *, object *));
object *run_node PROTO((struct _node *, char *, object *, object *));
+object *compile_string PROTO((char *, char *, int));
+
void print_error PROTO((void));
void goaway PROTO((int));
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 85c89f6..aa29795 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -38,7 +38,7 @@ static struct memberlist frame_memberlist[] = {
{"f_code", T_OBJECT, OFF(f_code)},
{"f_globals", T_OBJECT, OFF(f_globals)},
{"f_locals", T_OBJECT, OFF(f_locals)},
- {"f_fastlocals",T_OBJECT, OFF(f_fastlocals)},
+/* {"f_fastlocals",T_OBJECT, OFF(f_fastlocals)}, /* XXX Unsafe */
{"f_localmap", T_OBJECT, OFF(f_localmap)},
{"f_lasti", T_INT, OFF(f_lasti)},
{"f_lineno", T_INT, OFF(f_lineno)},
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 8fd12e4..b74b9cc 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -35,6 +35,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "pythonrun.h"
#include "ceval.h"
#include "modsupport.h"
+#include "compile.h"
+#include "eval.h"
static object *
builtin_abs(self, v)
@@ -107,6 +109,29 @@ builtin_coerce(self, args)
}
static object *
+builtin_compile(self, args)
+ object *self;
+ object *args;
+{
+ char *str;
+ char *filename;
+ char *startstr;
+ int start;
+ if (!getargs(args, "(sss)", &str, &filename, &startstr))
+ return NULL;
+ if (strcmp(startstr, "exec") == 0)
+ start = file_input;
+ else if (strcmp(startstr, "eval") == 0)
+ start = eval_input;
+ else {
+ err_setstr(ValueError,
+ "compile() mode must be 'exec' or 'eval'");
+ return NULL;
+ }
+ return compile_string(str, filename, start);
+}
+
+static object *
builtin_dir(self, v)
object *self;
object *v;
@@ -168,23 +193,26 @@ exec_eval(v, start)
char *s;
int n;
if (v != NULL) {
- if (is_stringobject(v))
- str = v;
- else if (is_tupleobject(v) &&
+ if (is_tupleobject(v) &&
((n = gettuplesize(v)) == 2 || n == 3)) {
str = gettupleitem(v, 0);
globals = gettupleitem(v, 1);
if (n == 3)
locals = gettupleitem(v, 2);
}
+ else
+ str = v;
}
- if (str == NULL || !is_stringobject(str) ||
+ if (str == NULL || (!is_stringobject(str) && !is_codeobject(str)) ||
globals != NULL && !is_dictobject(globals) ||
locals != NULL && !is_dictobject(locals)) {
err_setstr(TypeError,
- "exec/eval arguments must be string[,dict[,dict]]");
+ "exec/eval arguments must be (string|code)[,dict[,dict]]");
return NULL;
}
+ if (is_codeobject(str))
+ return eval_code((codeobject *) str, globals, locals,
+ (object *)NULL);
s = getstringvalue(str);
if (strlen(s) != getstringsize(str)) {
err_setstr(ValueError, "embedded '\\0' in string arg");
@@ -306,6 +334,17 @@ builtin_hasattr(self, args)
}
static object *
+builtin_id(self, args)
+ object *self;
+ object *args;
+{
+ object *v;
+ if (!getargs(args, "O", &v))
+ return NULL;
+ return newintobject((long)v);
+}
+
+static object *
builtin_setattr(self, args)
object *self;
object *args;
@@ -713,6 +752,7 @@ static struct methodlist builtin_methods[] = {
{"chr", builtin_chr},
{"cmp", builtin_cmp},
{"coerce", builtin_coerce},
+ {"compile", builtin_compile},
{"dir", builtin_dir},
{"divmod", builtin_divmod},
{"eval", builtin_eval},
@@ -723,6 +763,7 @@ static struct methodlist builtin_methods[] = {
{"hasattr", builtin_hasattr},
{"hash", builtin_hash},
{"hex", builtin_hex},
+ {"id", builtin_id},
{"input", builtin_input},
{"int", builtin_int},
{"len", builtin_len},
diff --git a/Python/ceval.c b/Python/ceval.c
index 45d0a6a..cdd71a8 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -45,6 +45,9 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define CHECKEXC 1 /* Double-check exception checking */
#endif
+#define DEBUG
+
+
/* Forward declarations */
#ifdef LLTRACE
@@ -82,6 +85,7 @@ static object *cmp_outcome PROTO((int, object *, object *));
static int import_from PROTO((object *, object *, object *));
static object *build_class PROTO((object *, object *));
static void locals_2_fast PROTO((frameobject *, int));
+static void fast_2_locals PROTO((frameobject *));
/* Pointer to current frame, used to link new frames to */
@@ -178,6 +182,7 @@ eval_code(co, globals, locals, arg)
object *trace = NULL; /* Trace function or NULL */
object *retval; /* Return value iff why == WHY_RETURN */
char *name; /* Name used by some instructions */
+ int needmerge = 0;
#ifdef LLTRACE
int lltrace = dictlookup(globals, "__lltrace__") != NULL;
#endif
@@ -217,6 +222,18 @@ eval_code(co, globals, locals, arg)
#define POP() BASIC_POP()
#endif
+ if (globals == NULL) {
+ globals = getglobals();
+ if (locals == NULL) {
+ locals = getlocals();
+ needmerge = 1;
+ }
+ }
+ else {
+ if (locals == NULL)
+ locals = globals;
+ }
+
f = newframeobject(
current_frame, /*back*/
co, /*code*/
@@ -1328,11 +1345,17 @@ eval_code(co, globals, locals, arg)
why = WHY_EXCEPTION;
}
}
+
+ if (fastlocals && (f->ob_refcnt > 1 || f->f_locals->ob_refcnt > 2))
+ fast_2_locals(f);
/* Restore previous frame and release the current one */
current_frame = f->f_back;
DECREF(f);
+
+ if (needmerge)
+ locals_2_fast(current_frame, 1);
return retval;
}
@@ -1417,7 +1440,9 @@ call_trace(p_trace, p_newtrace, f, msg, arg)
INCREF(arg);
settupleitem(arglist, 2, arg);
tracing++;
+ fast_2_locals(f);
res = call_object(*p_trace, arglist);
+ locals_2_fast(f, 1);
tracing--;
cleanup:
XDECREF(arglist);
@@ -1447,24 +1472,25 @@ call_trace(p_trace, p_newtrace, f, msg, arg)
}
}
-object *
-getlocals()
-{
- /* Merge f->f_fastlocals into f->f_locals, then return the latter */
+static void
+fast_2_locals(f)
frameobject *f;
+{
+ /* Merge f->f_fastlocals into f->f_locals */
object *locals, *fast, *map;
+ object *error_type, *error_value;
int i;
- f = current_frame;
if (f == NULL)
- return NULL;
+ return;
locals = f->f_locals;
fast = f->f_fastlocals;
map = f->f_localmap;
if (locals == NULL || fast == NULL || map == NULL)
- return locals;
+ return;
if (!is_dictobject(locals) || !is_listobject(fast) ||
!is_dictobject(map))
- return locals;
+ return;
+ err_get(&error_type, &error_value);
i = getdictsize(map);
while (--i >= 0) {
object *key;
@@ -1488,7 +1514,7 @@ getlocals()
err_clear();
}
}
- return locals;
+ err_setval(error_type, error_value);
}
static void
@@ -1539,6 +1565,15 @@ mergelocals()
}
object *
+getlocals()
+{
+ if (current_frame == NULL)
+ return NULL;
+ fast_2_locals(current_frame);
+ return current_frame->f_locals;
+}
+
+object *
getglobals()
{
if (current_frame == NULL)
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index c387c62..98008b4 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -263,7 +263,7 @@ object *
run_string(str, start, globals, locals)
char *str;
int start;
- /*dict*/object *globals, *locals;
+ object *globals, *locals;
{
node *n;
int err;
@@ -276,7 +276,7 @@ run_file(fp, filename, start, globals, locals)
FILE *fp;
char *filename;
int start;
- /*dict*/object *globals, *locals;
+ object *globals, *locals;
{
node *n;
int err;
@@ -289,7 +289,7 @@ run_err_node(err, n, filename, globals, locals)
int err;
node *n;
char *filename;
- /*dict*/object *globals, *locals;
+ object *globals, *locals;
{
if (err != E_DONE) {
err_input(err);
@@ -302,25 +302,9 @@ object *
run_node(n, filename, globals, locals)
node *n;
char *filename;
- /*dict*/object *globals, *locals;
+ object *globals, *locals;
{
- object *res;
- int needmerge = 0;
- if (globals == NULL) {
- globals = getglobals();
- if (locals == NULL) {
- locals = getlocals();
- needmerge = 1;
- }
- }
- else {
- if (locals == NULL)
- locals = globals;
- }
- res = eval_node(n, filename, globals, locals);
- if (needmerge)
- mergelocals();
- return res;
+ return eval_node(n, filename, globals, locals);
}
object *
@@ -341,6 +325,25 @@ eval_node(n, filename, globals, locals)
return v;
}
+object *
+compile_string(str, filename, start)
+ char *str;
+ char *filename;
+ int start;
+{
+ node *n;
+ int err;
+ codeobject *co;
+ err = parse_string(str, start, &n);
+ if (err != E_DONE) {
+ err_input(err);
+ return NULL;
+ }
+ co = compile(n, filename);
+ freetree(n);
+ return (object *)co;
+}
+
/* Simplified interface to parsefile */
int