aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2010-12-12 23:04:15 -0500
committerStefan Monnier2010-12-12 23:04:15 -0500
commitf07a954eeb0930029104402e706165bf89853576 (patch)
tree143d5c5a95904a0559d555ae6fe97eaed7839211 /src
parent2c302df3a13236bfbf8ea1b771d13618fcda8d71 (diff)
downloademacs-f07a954eeb0930029104402e706165bf89853576.tar.gz
emacs-f07a954eeb0930029104402e706165bf89853576.zip
Make the effect of (defvar foo) local.
* src/eval.c (apply_lambda): Make static. Remove eval_flag arg. (Fsetq): Don't check declared_special. (Fdefun, Fdefmacro): Use Ffunction. (Fdefvar): Don't set declared_special for (defvar foo). (FletX): Check locally-special vars. Only do specbind once. (Flet): Check locally-special vars. (Feval): Don't check declared_special. (funcall_lambda): Check locally-special vars. * src/lisp.h (apply_lambda): Remove extern declaration. * src/lread.c (readevalloop): CSE. * lisp/subr.el (with-lexical-binding): Remove.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog14
-rw-r--r--src/eval.c116
-rw-r--r--src/lisp.h1
-rw-r--r--src/lread.c7
4 files changed, 83 insertions, 55 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index e1c0e6e5e9a..6abdf583b00 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,17 @@
12010-12-13 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 Make the effect of (defvar foo) local.
4 * eval.c (apply_lambda): Make static. Remove eval_flag arg.
5 (Fsetq): Don't check declared_special.
6 (Fdefun, Fdefmacro): Use Ffunction.
7 (Fdefvar): Don't set declared_special for (defvar foo).
8 (FletX): Check locally-special vars. Only do specbind once.
9 (Flet): Check locally-special vars.
10 (Feval): Don't check declared_special.
11 (funcall_lambda): Check locally-special vars.
12 * lisp.h (apply_lambda): Remove extern declaration.
13 * lread.c (readevalloop): CSE.
14
12010-07-23 Andreas Schwab <schwab@linux-m68k.org> 152010-07-23 Andreas Schwab <schwab@linux-m68k.org>
2 16
3 * eval.c (funcall_funvec): Replace bcopy by memcpy. 17 * eval.c (funcall_funvec): Replace bcopy by memcpy.
diff --git a/src/eval.c b/src/eval.c
index 574c4ebf361..63ea95513b3 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -81,9 +81,12 @@ Lisp_Object Vrun_hooks;
81Lisp_Object Vautoload_queue; 81Lisp_Object Vautoload_queue;
82 82
83/* When lexical binding is being used, this is non-nil, and contains an 83/* When lexical binding is being used, this is non-nil, and contains an
84 alist of lexically-bound variable, or t, indicating an empty 84 alist of lexically-bound variable, or (t), indicating an empty
85 environment. The lisp name of this variable is 85 environment. The lisp name of this variable is
86 `internal-interpreter-lexical-environment'. */ 86 `internal-interpreter-environment'. Every element of this list
87 can be either a cons (VAR . VAL) specifying a lexical binding,
88 or a single symbol VAR indicating that this variable should use
89 dynamic scoping. */
87 90
88Lisp_Object Vinternal_interpreter_environment; 91Lisp_Object Vinternal_interpreter_environment;
89 92
@@ -175,6 +178,8 @@ int handling_signal;
175 178
176Lisp_Object Vmacro_declaration_function; 179Lisp_Object Vmacro_declaration_function;
177 180
181static Lisp_Object apply_lambda (Lisp_Object fun, Lisp_Object args,
182 Lisp_Object lexenv)
178static Lisp_Object funcall_lambda (Lisp_Object, int, Lisp_Object *, 183static Lisp_Object funcall_lambda (Lisp_Object, int, Lisp_Object *,
179 Lisp_Object); 184 Lisp_Object);
180static void unwind_to_catch (struct catchtag *, Lisp_Object) NO_RETURN; 185static void unwind_to_catch (struct catchtag *, Lisp_Object) NO_RETURN;
@@ -505,10 +510,12 @@ usage: (setq [SYM VAL]...) */)
505 val = Feval (Fcar (Fcdr (args_left))); 510 val = Feval (Fcar (Fcdr (args_left)));
506 sym = Fcar (args_left); 511 sym = Fcar (args_left);
507 512
508 if (!NILP (Vinternal_interpreter_environment) 513 /* Like for Feval, we do not check declared_special here since
514 it's been done when let-binding. */
515 if (!NILP (Vinternal_interpreter_environment) /* Mere optimization! */
509 && SYMBOLP (sym) 516 && SYMBOLP (sym)
510 && !XSYMBOL (sym)->declared_special 517 && !NILP (lex_binding
511 && !NILP (lex_binding = Fassq (sym, Vinternal_interpreter_environment))) 518 = Fassq (sym, Vinternal_interpreter_environment)))
512 XSETCDR (lex_binding, val); /* SYM is lexically bound. */ 519 XSETCDR (lex_binding, val); /* SYM is lexically bound. */
513 else 520 else
514 Fset (sym, val); /* SYM is dynamically bound. */ 521 Fset (sym, val); /* SYM is dynamically bound. */
@@ -667,8 +674,8 @@ usage: (defun NAME ARGLIST [DOCSTRING] BODY...) */)
667 fn_name = Fcar (args); 674 fn_name = Fcar (args);
668 CHECK_SYMBOL (fn_name); 675 CHECK_SYMBOL (fn_name);
669 defn = Fcons (Qlambda, Fcdr (args)); 676 defn = Fcons (Qlambda, Fcdr (args));
670 if (! NILP (Vinternal_interpreter_environment)) 677 if (!NILP (Vinternal_interpreter_environment)) /* Mere optimization! */
671 defn = Fcons (Qclosure, Fcons (Vinternal_interpreter_environment, defn)); 678 defn = Ffunction (Fcons (defn, Qnil));
672 if (!NILP (Vpurify_flag)) 679 if (!NILP (Vpurify_flag))
673 defn = Fpurecopy (defn); 680 defn = Fpurecopy (defn);
674 if (CONSP (XSYMBOL (fn_name)->function) 681 if (CONSP (XSYMBOL (fn_name)->function)
@@ -742,8 +749,8 @@ usage: (defmacro NAME ARGLIST [DOCSTRING] [DECL] BODY...) */)
742 tail = Fcons (lambda_list, Fcons (doc, tail)); 749 tail = Fcons (lambda_list, Fcons (doc, tail));
743 750
744 defn = Fcons (Qlambda, tail); 751 defn = Fcons (Qlambda, tail);
745 if (! NILP (Vinternal_interpreter_environment)) 752 if (!NILP (Vinternal_interpreter_environment)) /* Mere optimization! */
746 defn = Fcons (Qclosure, Fcons (Vinternal_interpreter_environment, defn)); 753 defn = Ffunction (Fcons (defn, Qnil));
747 defn = Fcons (Qmacro, defn); 754 defn = Fcons (Qmacro, defn);
748 755
749 if (!NILP (Vpurify_flag)) 756 if (!NILP (Vpurify_flag))
@@ -888,16 +895,23 @@ usage: (defvar SYMBOL &optional INITVALUE DOCSTRING) */)
888 Fput (sym, Qvariable_documentation, tem); 895 Fput (sym, Qvariable_documentation, tem);
889 } 896 }
890 LOADHIST_ATTACH (sym); 897 LOADHIST_ATTACH (sym);
898
899 if (SYMBOLP (sym))
900 XSYMBOL (sym)->declared_special = 1;
891 } 901 }
902 else if (!NILP (Vinternal_interpreter_environment)
903 && !XSYMBOL (sym)->declared_special)
904 /* A simple (defvar foo) with lexical scoping does "nothing" except
905 declare that var to be dynamically scoped *locally* (i.e. within
906 the current file or let-block). */
907 Vinternal_interpreter_environment =
908 Fcons (sym, Vinternal_interpreter_environment);
892 else 909 else
893 /* Simple (defvar <var>) should not count as a definition at all. 910 /* Simple (defvar <var>) should not count as a definition at all.
894 It could get in the way of other definitions, and unloading this 911 It could get in the way of other definitions, and unloading this
895 package could try to make the variable unbound. */ 912 package could try to make the variable unbound. */
896 ; 913 ;
897 914
898 if (SYMBOLP (sym))
899 XSYMBOL (sym)->declared_special = 1;
900
901 return sym; 915 return sym;
902} 916}
903 917
@@ -1038,12 +1052,21 @@ usage: (let* VARLIST BODY...) */)
1038 val = Feval (Fcar (Fcdr (elt))); 1052 val = Feval (Fcar (Fcdr (elt)));
1039 } 1053 }
1040 1054
1041 if (!NILP (lexenv) && SYMBOLP (var) && !XSYMBOL (var)->declared_special) 1055 if (!NILP (lexenv) && SYMBOLP (var)
1056 && !XSYMBOL (var)->declared_special
1057 && NILP (Fmemq (var, Vinternal_interpreter_environment)))
1042 /* Lexically bind VAR by adding it to the interpreter's binding 1058 /* Lexically bind VAR by adding it to the interpreter's binding
1043 alist. */ 1059 alist. */
1044 { 1060 {
1045 lexenv = Fcons (Fcons (var, val), lexenv); 1061 Lisp_Object newenv
1046 specbind (Qinternal_interpreter_environment, lexenv); 1062 = Fcons (Fcons (var, val), Vinternal_interpreter_environment);
1063 if (EQ (Vinternal_interpreter_environment, lexenv))
1064 /* Save the old lexical environment on the specpdl stack,
1065 but only for the first lexical binding, since we'll never
1066 need to revert to one of the intermediate ones. */
1067 specbind (Qinternal_interpreter_environment, newenv);
1068 else
1069 Vinternal_interpreter_environment = newenv;
1047 } 1070 }
1048 else 1071 else
1049 specbind (var, val); 1072 specbind (var, val);
@@ -1110,7 +1133,9 @@ usage: (let VARLIST BODY...) */)
1110 var = SYMBOLP (elt) ? elt : Fcar (elt); 1133 var = SYMBOLP (elt) ? elt : Fcar (elt);
1111 tem = temps[argnum++]; 1134 tem = temps[argnum++];
1112 1135
1113 if (!NILP (lexenv) && SYMBOLP (var) && !XSYMBOL (var)->declared_special) 1136 if (!NILP (lexenv) && SYMBOLP (var)
1137 && !XSYMBOL (var)->declared_special
1138 && NILP (Fmemq (var, Vinternal_interpreter_environment)))
1114 /* Lexically bind VAR by adding it to the lexenv alist. */ 1139 /* Lexically bind VAR by adding it to the lexenv alist. */
1115 lexenv = Fcons (Fcons (var, tem), lexenv); 1140 lexenv = Fcons (Fcons (var, tem), lexenv);
1116 else 1141 else
@@ -2302,25 +2327,17 @@ DEFUN ("eval", Feval, Seval, 1, 1, 0,
2302 2327
2303 if (SYMBOLP (form)) 2328 if (SYMBOLP (form))
2304 { 2329 {
2305 /* If there's an active lexical environment, and the variable 2330 /* Look up its binding in the lexical environment.
2306 isn't declared special, look up its binding in the lexical 2331 We do not pay attention to the declared_special flag here, since we
2307 environment. */ 2332 already did that when let-binding the variable. */
2308 if (!NILP (Vinternal_interpreter_environment) 2333 Lisp_Object lex_binding
2309 && !XSYMBOL (form)->declared_special) 2334 = !NILP (Vinternal_interpreter_environment) /* Mere optimization! */
2310 { 2335 ? Fassq (form, Vinternal_interpreter_environment)
2311 Lisp_Object lex_binding 2336 : Qnil;
2312 = Fassq (form, Vinternal_interpreter_environment); 2337 if (CONSP (lex_binding))
2313 2338 return XCDR (lex_binding);
2314 /* If we found a lexical binding for FORM, return the value. 2339 else
2315 Otherwise, we just drop through and look for a dynamic 2340 return Fsymbol_value (form);
2316 binding -- the variable isn't declared special, but there's
2317 not much else we can do, and Fsymbol_value will take care
2318 of signaling an error if there is no binding at all. */
2319 if (CONSP (lex_binding))
2320 return XCDR (lex_binding);
2321 }
2322
2323 return Fsymbol_value (form);
2324 } 2341 }
2325 2342
2326 if (!CONSP (form)) 2343 if (!CONSP (form))
@@ -2485,7 +2502,7 @@ DEFUN ("eval", Feval, Seval, 1, 1, 0,
2485 } 2502 }
2486 } 2503 }
2487 if (FUNVECP (fun)) 2504 if (FUNVECP (fun))
2488 val = apply_lambda (fun, original_args, 1, Qnil); 2505 val = apply_lambda (fun, original_args, Qnil);
2489 else 2506 else
2490 { 2507 {
2491 if (EQ (fun, Qunbound)) 2508 if (EQ (fun, Qunbound))
@@ -2503,7 +2520,7 @@ DEFUN ("eval", Feval, Seval, 1, 1, 0,
2503 if (EQ (funcar, Qmacro)) 2520 if (EQ (funcar, Qmacro))
2504 val = Feval (apply1 (Fcdr (fun), original_args)); 2521 val = Feval (apply1 (Fcdr (fun), original_args));
2505 else if (EQ (funcar, Qlambda)) 2522 else if (EQ (funcar, Qlambda))
2506 val = apply_lambda (fun, original_args, 1, 2523 val = apply_lambda (fun, original_args,
2507 /* Only pass down the current lexical environment 2524 /* Only pass down the current lexical environment
2508 if FUN is lexically embedded in FORM. */ 2525 if FUN is lexically embedded in FORM. */
2509 (CONSP (original_fun) 2526 (CONSP (original_fun)
@@ -2513,7 +2530,7 @@ DEFUN ("eval", Feval, Seval, 1, 1, 0,
2513 && CONSP (XCDR (fun)) 2530 && CONSP (XCDR (fun))
2514 && CONSP (XCDR (XCDR (fun))) 2531 && CONSP (XCDR (XCDR (fun)))
2515 && EQ (XCAR (XCDR (XCDR (fun))), Qlambda)) 2532 && EQ (XCAR (XCDR (XCDR (fun))), Qlambda))
2516 val = apply_lambda (XCDR (XCDR (fun)), original_args, 1, 2533 val = apply_lambda (XCDR (XCDR (fun)), original_args,
2517 XCAR (XCDR (fun))); 2534 XCAR (XCDR (fun)));
2518 else 2535 else
2519 xsignal1 (Qinvalid_function, original_fun); 2536 xsignal1 (Qinvalid_function, original_fun);
@@ -3208,9 +3225,8 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
3208 return val; 3225 return val;
3209} 3226}
3210 3227
3211Lisp_Object 3228static Lisp_Object
3212apply_lambda (Lisp_Object fun, Lisp_Object args, int eval_flag, 3229apply_lambda (Lisp_Object fun, Lisp_Object args, Lisp_Object lexenv)
3213 Lisp_Object lexenv)
3214{ 3230{
3215 Lisp_Object args_left; 3231 Lisp_Object args_left;
3216 Lisp_Object numargs; 3232 Lisp_Object numargs;
@@ -3230,18 +3246,15 @@ apply_lambda (Lisp_Object fun, Lisp_Object args, int eval_flag,
3230 for (i = 0; i < XINT (numargs);) 3246 for (i = 0; i < XINT (numargs);)
3231 { 3247 {
3232 tem = Fcar (args_left), args_left = Fcdr (args_left); 3248 tem = Fcar (args_left), args_left = Fcdr (args_left);
3233 if (eval_flag) tem = Feval (tem); 3249 tem = Feval (tem);
3234 arg_vector[i++] = tem; 3250 arg_vector[i++] = tem;
3235 gcpro1.nvars = i; 3251 gcpro1.nvars = i;
3236 } 3252 }
3237 3253
3238 UNGCPRO; 3254 UNGCPRO;
3239 3255
3240 if (eval_flag) 3256 backtrace_list->args = arg_vector;
3241 { 3257 backtrace_list->nargs = i;
3242 backtrace_list->args = arg_vector;
3243 backtrace_list->nargs = i;
3244 }
3245 backtrace_list->evalargs = 0; 3258 backtrace_list->evalargs = 0;
3246 tem = funcall_lambda (fun, XINT (numargs), arg_vector, lexenv); 3259 tem = funcall_lambda (fun, XINT (numargs), arg_vector, lexenv);
3247 3260
@@ -3387,8 +3400,11 @@ funcall_lambda (Lisp_Object fun, int nargs,
3387 val = Qnil; 3400 val = Qnil;
3388 3401
3389 /* Bind the argument. */ 3402 /* Bind the argument. */
3390 if (!NILP (lexenv) 3403 if (!NILP (lexenv) && SYMBOLP (next)
3391 && SYMBOLP (next) && !XSYMBOL (next)->declared_special) 3404 /* FIXME: there's no good reason to allow dynamic-scoping
3405 on function arguments, other than consistency with let. */
3406 && !XSYMBOL (next)->declared_special
3407 && NILP (Fmemq (next, Vinternal_interpreter_environment)))
3392 /* Lexically bind NEXT by adding it to the lexenv alist. */ 3408 /* Lexically bind NEXT by adding it to the lexenv alist. */
3393 lexenv = Fcons (Fcons (next, val), lexenv); 3409 lexenv = Fcons (Fcons (next, val), lexenv);
3394 else 3410 else
diff --git a/src/lisp.h b/src/lisp.h
index 36653e91e4e..aafa3884273 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2985,7 +2985,6 @@ extern Lisp_Object call5 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Li
2985extern Lisp_Object call6 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); 2985extern Lisp_Object call6 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
2986extern Lisp_Object call7 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); 2986extern Lisp_Object call7 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object);
2987EXFUN (Fdo_auto_save, 2); 2987EXFUN (Fdo_auto_save, 2);
2988extern Lisp_Object apply_lambda (Lisp_Object, Lisp_Object, int, Lisp_Object);
2989extern Lisp_Object internal_catch (Lisp_Object, Lisp_Object (*) (Lisp_Object), Lisp_Object); 2988extern Lisp_Object internal_catch (Lisp_Object, Lisp_Object (*) (Lisp_Object), Lisp_Object);
2990extern Lisp_Object internal_lisp_condition_case (Lisp_Object, Lisp_Object, Lisp_Object); 2989extern Lisp_Object internal_lisp_condition_case (Lisp_Object, Lisp_Object, Lisp_Object);
2991extern Lisp_Object internal_condition_case (Lisp_Object (*) (void), Lisp_Object, Lisp_Object (*) (Lisp_Object)); 2990extern Lisp_Object internal_condition_case (Lisp_Object (*) (void), Lisp_Object, Lisp_Object (*) (Lisp_Object));
diff --git a/src/lread.c b/src/lread.c
index 83c94b02e23..d85d146b157 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -1767,10 +1767,9 @@ readevalloop (Lisp_Object readcharfun,
1767 the file's header, or via a buffer-local variable), create an empty 1767 the file's header, or via a buffer-local variable), create an empty
1768 lexical environment, otherwise, turn off lexical binding. */ 1768 lexical environment, otherwise, turn off lexical binding. */
1769 lex_bound = find_symbol_value (Qlexical_binding); 1769 lex_bound = find_symbol_value (Qlexical_binding);
1770 if (NILP (lex_bound) || EQ (lex_bound, Qunbound)) 1770 specbind (Qinternal_interpreter_environment,
1771 specbind (Qinternal_interpreter_environment, Qnil); 1771 NILP (lex_bound) || EQ (lex_bound, Qunbound)
1772 else 1772 ? Qnil : Fcons (Qt, Qnil));
1773 specbind (Qinternal_interpreter_environment, Fcons (Qt, Qnil));
1774 1773
1775 GCPRO4 (sourcename, readfun, start, end); 1774 GCPRO4 (sourcename, readfun, start, end);
1776 1775