summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2010-12-15 12:46:59 -0500
committerStefan Monnier <monnier@iro.umontreal.ca>2010-12-15 12:46:59 -0500
commita0ee6f2751acba71df443d4d795bb350eb6421dd (patch)
treee4f47d66877b1b00b9ce00a304b509dee840868a /src
parentdefb141157dfa37c33cdcbfa4b29c702a8fc9edf (diff)
Obey lexical-binding in interactive evaluation commands.
* lisp/emacs-lisp/edebug.el (edebug-eval-defun, edebug-eval): * lisp/emacs-lisp/lisp-mode.el (eval-last-sexp-1, eval-defun-1): * lisp/ielm.el (ielm-eval-input): * lisp/simple.el (eval-expression): Use new eval arg to obey lexical-binding. * src/eval.c (Feval): Add `lexical' argument. Adjust callers. (Ffuncall, eval_sub): Avoid goto.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog5
-rw-r--r--src/bytecode.c2
-rw-r--r--src/callint.c2
-rw-r--r--src/doc.c2
-rw-r--r--src/eval.c267
-rw-r--r--src/keyboard.c12
-rw-r--r--src/lisp.h2
-rw-r--r--src/minibuf.c4
8 files changed, 152 insertions, 144 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index c333b6388c..2de6a5ed66 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2010-12-15 Stefan Monnier <monnier@iro.umontreal.ca>
+
+ * eval.c (Feval): Add `lexical' argument. Adjust callers.
+ (Ffuncall, eval_sub): Avoid goto.
+
2010-12-14 Stefan Monnier <monnier@iro.umontreal.ca>
Try and be more careful about propagation of lexical environment.
diff --git a/src/bytecode.c b/src/bytecode.c
index 01fce0577b..eb12b9c496 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -915,7 +915,7 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
Lisp_Object v1;
BEFORE_POTENTIAL_GC ();
v1 = POP;
- TOP = internal_catch (TOP, Feval, v1); /* FIXME: lexbind */
+ TOP = internal_catch (TOP, eval_sub, v1); /* FIXME: lexbind */
AFTER_POTENTIAL_GC ();
break;
}
diff --git a/src/callint.c b/src/callint.c
index 960158029c..5eb65b31cb 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -342,7 +342,7 @@ invoke it. If KEYS is omitted or nil, the return value of
input = specs;
/* Compute the arg values using the user's expression. */
GCPRO2 (input, filter_specs);
- specs = Feval (specs); /* FIXME: lexbind */
+ specs = Feval (specs, Qnil); /* FIXME: lexbind */
UNGCPRO;
if (i != num_input_events || !NILP (record_flag))
{
diff --git a/src/doc.c b/src/doc.c
index b887b3149b..8ae152dca9 100644
--- a/src/doc.c
+++ b/src/doc.c
@@ -490,7 +490,7 @@ aren't strings. */)
}
else if (!STRINGP (tem))
/* Feval protects its argument. */
- tem = Feval (tem);
+ tem = Feval (tem, Qnil);
if (NILP (raw) && STRINGP (tem))
tem = Fsubstitute_command_keys (tem);
diff --git a/src/eval.c b/src/eval.c
index 485ba00c1e..7104a8a839 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2311,12 +2311,14 @@ do_autoload (Lisp_Object fundef, Lisp_Object funname)
}
-DEFUN ("eval", Feval, Seval, 1, 1, 0,
- doc: /* Evaluate FORM and return its value. */)
- (Lisp_Object form)
+DEFUN ("eval", Feval, Seval, 1, 2, 0,
+ doc: /* Evaluate FORM and return its value.
+If LEXICAL is t, evaluate using lexical scoping. */)
+ (Lisp_Object form, Lisp_Object lexical)
{
int count = SPECPDL_INDEX ();
- specbind (Qinternal_interpreter_environment, Qnil);
+ specbind (Qinternal_interpreter_environment,
+ NILP (lexical) ? Qnil : Fcons (Qt, Qnil));
return unbind_to (count, eval_sub (form));
}
@@ -2414,10 +2416,8 @@ eval_sub (Lisp_Object form)
{
backtrace.evalargs = 0;
val = (XSUBR (fun)->function.aUNEVALLED) (args_left);
- goto done;
}
-
- if (XSUBR (fun)->max_args == MANY)
+ else if (XSUBR (fun)->max_args == MANY)
{
/* Pass a vector of evaluated arguments */
Lisp_Object *vals;
@@ -2443,73 +2443,74 @@ eval_sub (Lisp_Object form)
val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals);
UNGCPRO;
SAFE_FREE ();
- goto done;
}
-
- GCPRO3 (args_left, fun, fun);
- gcpro3.var = argvals;
- gcpro3.nvars = 0;
-
- maxargs = XSUBR (fun)->max_args;
- for (i = 0; i < maxargs; args_left = Fcdr (args_left))
+ else
{
- argvals[i] = eval_sub (Fcar (args_left));
- gcpro3.nvars = ++i;
- }
-
- UNGCPRO;
+ GCPRO3 (args_left, fun, fun);
+ gcpro3.var = argvals;
+ gcpro3.nvars = 0;
+
+ maxargs = XSUBR (fun)->max_args;
+ for (i = 0; i < maxargs; args_left = Fcdr (args_left))
+ {
+ argvals[i] = eval_sub (Fcar (args_left));
+ gcpro3.nvars = ++i;
+ }
+
+ UNGCPRO;
- backtrace.args = argvals;
- backtrace.nargs = XINT (numargs);
+ backtrace.args = argvals;
+ backtrace.nargs = XINT (numargs);
- switch (i)
- {
- case 0:
- val = (XSUBR (fun)->function.a0) ();
- goto done;
- case 1:
- val = (XSUBR (fun)->function.a1) (argvals[0]);
- goto done;
- case 2:
- val = (XSUBR (fun)->function.a2) (argvals[0], argvals[1]);
- goto done;
- case 3:
- val = (XSUBR (fun)->function.a3) (argvals[0], argvals[1],
- argvals[2]);
- goto done;
- case 4:
- val = (XSUBR (fun)->function.a4) (argvals[0], argvals[1],
- argvals[2], argvals[3]);
- goto done;
- case 5:
- val = (XSUBR (fun)->function.a5) (argvals[0], argvals[1], argvals[2],
- argvals[3], argvals[4]);
- goto done;
- case 6:
- val = (XSUBR (fun)->function.a6) (argvals[0], argvals[1], argvals[2],
- argvals[3], argvals[4], argvals[5]);
- goto done;
- case 7:
- val = (XSUBR (fun)->function.a7) (argvals[0], argvals[1], argvals[2],
- argvals[3], argvals[4], argvals[5],
- argvals[6]);
- goto done;
-
- case 8:
- val = (XSUBR (fun)->function.a8) (argvals[0], argvals[1], argvals[2],
- argvals[3], argvals[4], argvals[5],
- argvals[6], argvals[7]);
- goto done;
-
- default:
- /* Someone has created a subr that takes more arguments than
- is supported by this code. We need to either rewrite the
- subr to use a different argument protocol, or add more
- cases to this switch. */
- abort ();
+ switch (i)
+ {
+ case 0:
+ val = (XSUBR (fun)->function.a0) ();
+ break;
+ case 1:
+ val = (XSUBR (fun)->function.a1) (argvals[0]);
+ break;
+ case 2:
+ val = (XSUBR (fun)->function.a2) (argvals[0], argvals[1]);
+ break;
+ case 3:
+ val = (XSUBR (fun)->function.a3) (argvals[0], argvals[1],
+ argvals[2]);
+ break;
+ case 4:
+ val = (XSUBR (fun)->function.a4) (argvals[0], argvals[1],
+ argvals[2], argvals[3]);
+ break;
+ case 5:
+ val = (XSUBR (fun)->function.a5) (argvals[0], argvals[1], argvals[2],
+ argvals[3], argvals[4]);
+ break;
+ case 6:
+ val = (XSUBR (fun)->function.a6) (argvals[0], argvals[1], argvals[2],
+ argvals[3], argvals[4], argvals[5]);
+ break;
+ case 7:
+ val = (XSUBR (fun)->function.a7) (argvals[0], argvals[1], argvals[2],
+ argvals[3], argvals[4], argvals[5],
+ argvals[6]);
+
+ break;
+ case 8:
+ val = (XSUBR (fun)->function.a8) (argvals[0], argvals[1], argvals[2],
+ argvals[3], argvals[4], argvals[5],
+ argvals[6], argvals[7]);
+
+ break;
+ default:
+ /* Someone has created a subr that takes more arguments than
+ is supported by this code. We need to either rewrite the
+ subr to use a different argument protocol, or add more
+ cases to this switch. */
+ abort ();
+ }
}
}
- if (FUNVECP (fun))
+ else if (FUNVECP (fun))
val = apply_lambda (fun, original_args);
else
{
@@ -2533,7 +2534,6 @@ eval_sub (Lisp_Object form)
else
xsignal1 (Qinvalid_function, original_fun);
}
- done:
CHECK_CONS_LIST ();
lisp_eval_depth--;
@@ -3109,7 +3109,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
if (SUBRP (fun))
{
- if (numargs < XSUBR (fun)->min_args
+ if (numargs < XSUBR (fun)->min_args
|| (XSUBR (fun)->max_args >= 0 && XSUBR (fun)->max_args < numargs))
{
XSETFASTINT (lisp_numargs, numargs);
@@ -3119,74 +3119,72 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
if (XSUBR (fun)->max_args == UNEVALLED)
xsignal1 (Qinvalid_function, original_fun);
- if (XSUBR (fun)->max_args == MANY)
- {
- val = (XSUBR (fun)->function.aMANY) (numargs, args + 1);
- goto done;
- }
-
- if (XSUBR (fun)->max_args > numargs)
- {
- internal_args = (Lisp_Object *) alloca (XSUBR (fun)->max_args * sizeof (Lisp_Object));
- memcpy (internal_args, args + 1, numargs * sizeof (Lisp_Object));
- for (i = numargs; i < XSUBR (fun)->max_args; i++)
- internal_args[i] = Qnil;
- }
+ else if (XSUBR (fun)->max_args == MANY)
+ val = (XSUBR (fun)->function.aMANY) (numargs, args + 1);
else
- internal_args = args + 1;
- switch (XSUBR (fun)->max_args)
{
- case 0:
- val = (XSUBR (fun)->function.a0) ();
- goto done;
- case 1:
- val = (XSUBR (fun)->function.a1) (internal_args[0]);
- goto done;
- case 2:
- val = (XSUBR (fun)->function.a2) (internal_args[0], internal_args[1]);
- goto done;
- case 3:
- val = (XSUBR (fun)->function.a3) (internal_args[0], internal_args[1],
- internal_args[2]);
- goto done;
- case 4:
- val = (XSUBR (fun)->function.a4) (internal_args[0], internal_args[1],
- internal_args[2], internal_args[3]);
- goto done;
- case 5:
- val = (XSUBR (fun)->function.a5) (internal_args[0], internal_args[1],
- internal_args[2], internal_args[3],
- internal_args[4]);
- goto done;
- case 6:
- val = (XSUBR (fun)->function.a6) (internal_args[0], internal_args[1],
- internal_args[2], internal_args[3],
- internal_args[4], internal_args[5]);
- goto done;
- case 7:
- val = (XSUBR (fun)->function.a7) (internal_args[0], internal_args[1],
- internal_args[2], internal_args[3],
- internal_args[4], internal_args[5],
- internal_args[6]);
- goto done;
-
- case 8:
- val = (XSUBR (fun)->function.a8) (internal_args[0], internal_args[1],
- internal_args[2], internal_args[3],
- internal_args[4], internal_args[5],
- internal_args[6], internal_args[7]);
- goto done;
-
- default:
-
- /* If a subr takes more than 8 arguments without using MANY
- or UNEVALLED, we need to extend this function to support it.
- Until this is done, there is no way to call the function. */
- abort ();
+ if (XSUBR (fun)->max_args > numargs)
+ {
+ internal_args = (Lisp_Object *) alloca (XSUBR (fun)->max_args * sizeof (Lisp_Object));
+ memcpy (internal_args, args + 1, numargs * sizeof (Lisp_Object));
+ for (i = numargs; i < XSUBR (fun)->max_args; i++)
+ internal_args[i] = Qnil;
+ }
+ else
+ internal_args = args + 1;
+ switch (XSUBR (fun)->max_args)
+ {
+ case 0:
+ val = (XSUBR (fun)->function.a0) ();
+ break;
+ case 1:
+ val = (XSUBR (fun)->function.a1) (internal_args[0]);
+ break;
+ case 2:
+ val = (XSUBR (fun)->function.a2) (internal_args[0], internal_args[1]);
+ break;
+ case 3:
+ val = (XSUBR (fun)->function.a3) (internal_args[0], internal_args[1],
+ internal_args[2]);
+ break;
+ case 4:
+ val = (XSUBR (fun)->function.a4) (internal_args[0], internal_args[1],
+ internal_args[2], internal_args[3]);
+ break;
+ case 5:
+ val = (XSUBR (fun)->function.a5) (internal_args[0], internal_args[1],
+ internal_args[2], internal_args[3],
+ internal_args[4]);
+ break;
+ case 6:
+ val = (XSUBR (fun)->function.a6) (internal_args[0], internal_args[1],
+ internal_args[2], internal_args[3],
+ internal_args[4], internal_args[5]);
+ break;
+ case 7:
+ val = (XSUBR (fun)->function.a7) (internal_args[0], internal_args[1],
+ internal_args[2], internal_args[3],
+ internal_args[4], internal_args[5],
+ internal_args[6]);
+ break;
+
+ case 8:
+ val = (XSUBR (fun)->function.a8) (internal_args[0], internal_args[1],
+ internal_args[2], internal_args[3],
+ internal_args[4], internal_args[5],
+ internal_args[6], internal_args[7]);
+ break;
+
+ default:
+
+ /* If a subr takes more than 8 arguments without using MANY
+ or UNEVALLED, we need to extend this function to support it.
+ Until this is done, there is no way to call the function. */
+ abort ();
+ }
}
}
-
- if (FUNVECP (fun))
+ else if (FUNVECP (fun))
val = funcall_lambda (fun, numargs, args + 1);
else
{
@@ -3209,7 +3207,6 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
else
xsignal1 (Qinvalid_function, original_fun);
}
- done:
CHECK_CONS_LIST ();
lisp_eval_depth--;
if (backtrace.debug_on_exit)
diff --git a/src/keyboard.c b/src/keyboard.c
index 1781917064..df69c526f7 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -1327,7 +1327,7 @@ command_loop_2 (Lisp_Object ignore)
Lisp_Object
top_level_2 (void)
{
- return Feval (Vtop_level);
+ return Feval (Vtop_level, Qnil);
}
Lisp_Object
@@ -3255,7 +3255,7 @@ read_char (int commandflag, int nmaps, Lisp_Object *maps, Lisp_Object prev_event
help_form_saved_window_configs);
record_unwind_protect (read_char_help_form_unwind, Qnil);
- tem0 = Feval (Vhelp_form);
+ tem0 = Feval (Vhelp_form, Qnil);
if (STRINGP (tem0))
internal_with_output_to_temp_buffer ("*Help*", print_help, tem0);
@@ -7696,6 +7696,12 @@ menu_item_eval_property_1 (Lisp_Object arg)
return Qnil;
}
+static Lisp_Object
+eval_dyn (Lisp_Object form)
+{
+ return Feval (form, Qnil);
+}
+
/* Evaluate an expression and return the result (or nil if something
went wrong). Used to evaluate dynamic parts of menu items. */
Lisp_Object
@@ -7704,7 +7710,7 @@ menu_item_eval_property (Lisp_Object sexpr)
int count = SPECPDL_INDEX ();
Lisp_Object val;
specbind (Qinhibit_redisplay, Qt);
- val = internal_condition_case_1 (Feval, sexpr, Qerror,
+ val = internal_condition_case_1 (eval_dyn, sexpr, Qerror,
menu_item_eval_property_1);
return unbind_to (count, val);
}
diff --git a/src/lisp.h b/src/lisp.h
index 20b50632c4..db78996be5 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2971,7 +2971,7 @@ extern void xsignal3 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) NO_RET
extern void signal_error (const char *, Lisp_Object) NO_RETURN;
EXFUN (Fautoload, 5);
EXFUN (Fcommandp, 2);
-EXFUN (Feval, 1);
+EXFUN (Feval, 2);
extern Lisp_Object eval_sub (Lisp_Object form);
EXFUN (Fapply, MANY);
EXFUN (Ffuncall, MANY);
diff --git a/src/minibuf.c b/src/minibuf.c
index 409f8a9a9e..9dd32a8bab 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -1026,10 +1026,10 @@ is a string to insert in the minibuffer before reading.
Such arguments are used as in `read-from-minibuffer'.) */)
(Lisp_Object prompt, Lisp_Object initial_contents)
{
- /* FIXME: lexbind. */
return Feval (read_minibuf (Vread_expression_map, initial_contents,
prompt, Qnil, 1, Qread_expression_history,
- make_number (0), Qnil, 0, 0));
+ make_number (0), Qnil, 0, 0),
+ Qnil);
}
/* Functions that use the minibuffer to read various things. */