diff options
| author | Stefan Monnier | 2014-09-22 15:20:45 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2014-09-22 15:20:45 -0400 |
| commit | 9949231fb06aa4a2dfa536e9d5125a81424db3a7 (patch) | |
| tree | a2259e8489127b8685097a20a3fd3d7be222d9fe /src/eval.c | |
| parent | 298dfce8ac018aca6f8f1a38d7199cc28bfaf7fd (diff) | |
| parent | fc5ebc3f497a152132407d57a14cce147d59d29c (diff) | |
| download | emacs-9949231fb06aa4a2dfa536e9d5125a81424db3a7.tar.gz emacs-9949231fb06aa4a2dfa536e9d5125a81424db3a7.zip | |
Merge from emacs-24
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 60 |
1 files changed, 28 insertions, 32 deletions
diff --git a/src/eval.c b/src/eval.c index 5f54c105444..77b1db95397 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -104,7 +104,7 @@ union specbinding *backtrace_next (union specbinding *) EXTERNALLY_VISIBLE; | |||
| 104 | union specbinding *backtrace_top (void) EXTERNALLY_VISIBLE; | 104 | union specbinding *backtrace_top (void) EXTERNALLY_VISIBLE; |
| 105 | 105 | ||
| 106 | static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *); | 106 | static Lisp_Object funcall_lambda (Lisp_Object, ptrdiff_t, Lisp_Object *); |
| 107 | static Lisp_Object apply_lambda (Lisp_Object fun, Lisp_Object args); | 107 | static Lisp_Object apply_lambda (Lisp_Object, Lisp_Object, ptrdiff_t); |
| 108 | 108 | ||
| 109 | static Lisp_Object | 109 | static Lisp_Object |
| 110 | specpdl_symbol (union specbinding *pdl) | 110 | specpdl_symbol (union specbinding *pdl) |
| @@ -172,17 +172,11 @@ backtrace_debug_on_exit (union specbinding *pdl) | |||
| 172 | /* Functions to modify slots of backtrace records. */ | 172 | /* Functions to modify slots of backtrace records. */ |
| 173 | 173 | ||
| 174 | static void | 174 | static void |
| 175 | set_backtrace_args (union specbinding *pdl, Lisp_Object *args) | 175 | set_backtrace_args (union specbinding *pdl, Lisp_Object *args, ptrdiff_t nargs) |
| 176 | { | 176 | { |
| 177 | eassert (pdl->kind == SPECPDL_BACKTRACE); | 177 | eassert (pdl->kind == SPECPDL_BACKTRACE); |
| 178 | pdl->bt.args = args; | 178 | pdl->bt.args = args; |
| 179 | } | 179 | pdl->bt.nargs = nargs; |
| 180 | |||
| 181 | static void | ||
| 182 | set_backtrace_nargs (union specbinding *pdl, ptrdiff_t n) | ||
| 183 | { | ||
| 184 | eassert (pdl->kind == SPECPDL_BACKTRACE); | ||
| 185 | pdl->bt.nargs = n; | ||
| 186 | } | 180 | } |
| 187 | 181 | ||
| 188 | static void | 182 | static void |
| @@ -334,10 +328,10 @@ call_debugger (Lisp_Object arg) | |||
| 334 | } | 328 | } |
| 335 | 329 | ||
| 336 | static void | 330 | static void |
| 337 | do_debug_on_call (Lisp_Object code) | 331 | do_debug_on_call (Lisp_Object code, ptrdiff_t count) |
| 338 | { | 332 | { |
| 339 | debug_on_next_call = 0; | 333 | debug_on_next_call = 0; |
| 340 | set_backtrace_debug_on_exit (specpdl_ptr - 1, true); | 334 | set_backtrace_debug_on_exit (specpdl + count, true); |
| 341 | call_debugger (list1 (code)); | 335 | call_debugger (list1 (code)); |
| 342 | } | 336 | } |
| 343 | 337 | ||
| @@ -2035,9 +2029,11 @@ grow_specpdl (void) | |||
| 2035 | } | 2029 | } |
| 2036 | } | 2030 | } |
| 2037 | 2031 | ||
| 2038 | void | 2032 | ptrdiff_t |
| 2039 | record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs) | 2033 | record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs) |
| 2040 | { | 2034 | { |
| 2035 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 2036 | |||
| 2041 | eassert (nargs >= UNEVALLED); | 2037 | eassert (nargs >= UNEVALLED); |
| 2042 | specpdl_ptr->bt.kind = SPECPDL_BACKTRACE; | 2038 | specpdl_ptr->bt.kind = SPECPDL_BACKTRACE; |
| 2043 | specpdl_ptr->bt.debug_on_exit = false; | 2039 | specpdl_ptr->bt.debug_on_exit = false; |
| @@ -2045,6 +2041,8 @@ record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs) | |||
| 2045 | specpdl_ptr->bt.args = args; | 2041 | specpdl_ptr->bt.args = args; |
| 2046 | specpdl_ptr->bt.nargs = nargs; | 2042 | specpdl_ptr->bt.nargs = nargs; |
| 2047 | grow_specpdl (); | 2043 | grow_specpdl (); |
| 2044 | |||
| 2045 | return count; | ||
| 2048 | } | 2046 | } |
| 2049 | 2047 | ||
| 2050 | /* Eval a sub-expression of the current expression (i.e. in the same | 2048 | /* Eval a sub-expression of the current expression (i.e. in the same |
| @@ -2055,6 +2053,7 @@ eval_sub (Lisp_Object form) | |||
| 2055 | Lisp_Object fun, val, original_fun, original_args; | 2053 | Lisp_Object fun, val, original_fun, original_args; |
| 2056 | Lisp_Object funcar; | 2054 | Lisp_Object funcar; |
| 2057 | struct gcpro gcpro1, gcpro2, gcpro3; | 2055 | struct gcpro gcpro1, gcpro2, gcpro3; |
| 2056 | ptrdiff_t count; | ||
| 2058 | 2057 | ||
| 2059 | if (SYMBOLP (form)) | 2058 | if (SYMBOLP (form)) |
| 2060 | { | 2059 | { |
| @@ -2092,10 +2091,10 @@ eval_sub (Lisp_Object form) | |||
| 2092 | original_args = XCDR (form); | 2091 | original_args = XCDR (form); |
| 2093 | 2092 | ||
| 2094 | /* This also protects them from gc. */ | 2093 | /* This also protects them from gc. */ |
| 2095 | record_in_backtrace (original_fun, &original_args, UNEVALLED); | 2094 | count = record_in_backtrace (original_fun, &original_args, UNEVALLED); |
| 2096 | 2095 | ||
| 2097 | if (debug_on_next_call) | 2096 | if (debug_on_next_call) |
| 2098 | do_debug_on_call (Qt); | 2097 | do_debug_on_call (Qt, count); |
| 2099 | 2098 | ||
| 2100 | /* At this point, only original_fun and original_args | 2099 | /* At this point, only original_fun and original_args |
| 2101 | have values that will be used below. */ | 2100 | have values that will be used below. */ |
| @@ -2147,8 +2146,7 @@ eval_sub (Lisp_Object form) | |||
| 2147 | gcpro3.nvars = argnum; | 2146 | gcpro3.nvars = argnum; |
| 2148 | } | 2147 | } |
| 2149 | 2148 | ||
| 2150 | set_backtrace_args (specpdl_ptr - 1, vals); | 2149 | set_backtrace_args (specpdl + count, vals, XINT (numargs)); |
| 2151 | set_backtrace_nargs (specpdl_ptr - 1, XINT (numargs)); | ||
| 2152 | 2150 | ||
| 2153 | val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals); | 2151 | val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals); |
| 2154 | UNGCPRO; | 2152 | UNGCPRO; |
| @@ -2169,8 +2167,7 @@ eval_sub (Lisp_Object form) | |||
| 2169 | 2167 | ||
| 2170 | UNGCPRO; | 2168 | UNGCPRO; |
| 2171 | 2169 | ||
| 2172 | set_backtrace_args (specpdl_ptr - 1, argvals); | 2170 | set_backtrace_args (specpdl + count, argvals, XINT (numargs)); |
| 2173 | set_backtrace_nargs (specpdl_ptr - 1, XINT (numargs)); | ||
| 2174 | 2171 | ||
| 2175 | switch (i) | 2172 | switch (i) |
| 2176 | { | 2173 | { |
| @@ -2223,7 +2220,7 @@ eval_sub (Lisp_Object form) | |||
| 2223 | } | 2220 | } |
| 2224 | } | 2221 | } |
| 2225 | else if (COMPILEDP (fun)) | 2222 | else if (COMPILEDP (fun)) |
| 2226 | val = apply_lambda (fun, original_args); | 2223 | val = apply_lambda (fun, original_args, count); |
| 2227 | else | 2224 | else |
| 2228 | { | 2225 | { |
| 2229 | if (NILP (fun)) | 2226 | if (NILP (fun)) |
| @@ -2240,7 +2237,7 @@ eval_sub (Lisp_Object form) | |||
| 2240 | } | 2237 | } |
| 2241 | if (EQ (funcar, Qmacro)) | 2238 | if (EQ (funcar, Qmacro)) |
| 2242 | { | 2239 | { |
| 2243 | ptrdiff_t count = SPECPDL_INDEX (); | 2240 | ptrdiff_t count1 = SPECPDL_INDEX (); |
| 2244 | Lisp_Object exp; | 2241 | Lisp_Object exp; |
| 2245 | /* Bind lexical-binding during expansion of the macro, so the | 2242 | /* Bind lexical-binding during expansion of the macro, so the |
| 2246 | macro can know reliably if the code it outputs will be | 2243 | macro can know reliably if the code it outputs will be |
| @@ -2248,19 +2245,19 @@ eval_sub (Lisp_Object form) | |||
| 2248 | specbind (Qlexical_binding, | 2245 | specbind (Qlexical_binding, |
| 2249 | NILP (Vinternal_interpreter_environment) ? Qnil : Qt); | 2246 | NILP (Vinternal_interpreter_environment) ? Qnil : Qt); |
| 2250 | exp = apply1 (Fcdr (fun), original_args); | 2247 | exp = apply1 (Fcdr (fun), original_args); |
| 2251 | unbind_to (count, Qnil); | 2248 | unbind_to (count1, Qnil); |
| 2252 | val = eval_sub (exp); | 2249 | val = eval_sub (exp); |
| 2253 | } | 2250 | } |
| 2254 | else if (EQ (funcar, Qlambda) | 2251 | else if (EQ (funcar, Qlambda) |
| 2255 | || EQ (funcar, Qclosure)) | 2252 | || EQ (funcar, Qclosure)) |
| 2256 | val = apply_lambda (fun, original_args); | 2253 | val = apply_lambda (fun, original_args, count); |
| 2257 | else | 2254 | else |
| 2258 | xsignal1 (Qinvalid_function, original_fun); | 2255 | xsignal1 (Qinvalid_function, original_fun); |
| 2259 | } | 2256 | } |
| 2260 | check_cons_list (); | 2257 | check_cons_list (); |
| 2261 | 2258 | ||
| 2262 | lisp_eval_depth--; | 2259 | lisp_eval_depth--; |
| 2263 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) | 2260 | if (backtrace_debug_on_exit (specpdl + count)) |
| 2264 | val = call_debugger (list2 (Qexit, val)); | 2261 | val = call_debugger (list2 (Qexit, val)); |
| 2265 | specpdl_ptr--; | 2262 | specpdl_ptr--; |
| 2266 | 2263 | ||
| @@ -2657,7 +2654,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2657 | Lisp_Object lisp_numargs; | 2654 | Lisp_Object lisp_numargs; |
| 2658 | Lisp_Object val; | 2655 | Lisp_Object val; |
| 2659 | register Lisp_Object *internal_args; | 2656 | register Lisp_Object *internal_args; |
| 2660 | ptrdiff_t i; | 2657 | ptrdiff_t i, count; |
| 2661 | 2658 | ||
| 2662 | QUIT; | 2659 | QUIT; |
| 2663 | 2660 | ||
| @@ -2670,13 +2667,13 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2670 | } | 2667 | } |
| 2671 | 2668 | ||
| 2672 | /* This also GCPROs them. */ | 2669 | /* This also GCPROs them. */ |
| 2673 | record_in_backtrace (args[0], &args[1], nargs - 1); | 2670 | count = record_in_backtrace (args[0], &args[1], nargs - 1); |
| 2674 | 2671 | ||
| 2675 | /* Call GC after setting up the backtrace, so the latter GCPROs the args. */ | 2672 | /* Call GC after setting up the backtrace, so the latter GCPROs the args. */ |
| 2676 | maybe_gc (); | 2673 | maybe_gc (); |
| 2677 | 2674 | ||
| 2678 | if (debug_on_next_call) | 2675 | if (debug_on_next_call) |
| 2679 | do_debug_on_call (Qlambda); | 2676 | do_debug_on_call (Qlambda, count); |
| 2680 | 2677 | ||
| 2681 | check_cons_list (); | 2678 | check_cons_list (); |
| 2682 | 2679 | ||
| @@ -2796,14 +2793,14 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2796 | } | 2793 | } |
| 2797 | check_cons_list (); | 2794 | check_cons_list (); |
| 2798 | lisp_eval_depth--; | 2795 | lisp_eval_depth--; |
| 2799 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) | 2796 | if (backtrace_debug_on_exit (specpdl + count)) |
| 2800 | val = call_debugger (list2 (Qexit, val)); | 2797 | val = call_debugger (list2 (Qexit, val)); |
| 2801 | specpdl_ptr--; | 2798 | specpdl_ptr--; |
| 2802 | return val; | 2799 | return val; |
| 2803 | } | 2800 | } |
| 2804 | 2801 | ||
| 2805 | static Lisp_Object | 2802 | static Lisp_Object |
| 2806 | apply_lambda (Lisp_Object fun, Lisp_Object args) | 2803 | apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count) |
| 2807 | { | 2804 | { |
| 2808 | Lisp_Object args_left; | 2805 | Lisp_Object args_left; |
| 2809 | ptrdiff_t i; | 2806 | ptrdiff_t i; |
| @@ -2830,15 +2827,14 @@ apply_lambda (Lisp_Object fun, Lisp_Object args) | |||
| 2830 | 2827 | ||
| 2831 | UNGCPRO; | 2828 | UNGCPRO; |
| 2832 | 2829 | ||
| 2833 | set_backtrace_args (specpdl_ptr - 1, arg_vector); | 2830 | set_backtrace_args (specpdl + count, arg_vector, i); |
| 2834 | set_backtrace_nargs (specpdl_ptr - 1, i); | ||
| 2835 | tem = funcall_lambda (fun, numargs, arg_vector); | 2831 | tem = funcall_lambda (fun, numargs, arg_vector); |
| 2836 | 2832 | ||
| 2837 | /* Do the debug-on-exit now, while arg_vector still exists. */ | 2833 | /* Do the debug-on-exit now, while arg_vector still exists. */ |
| 2838 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) | 2834 | if (backtrace_debug_on_exit (specpdl + count)) |
| 2839 | { | 2835 | { |
| 2840 | /* Don't do it again when we return to eval. */ | 2836 | /* Don't do it again when we return to eval. */ |
| 2841 | set_backtrace_debug_on_exit (specpdl_ptr - 1, false); | 2837 | set_backtrace_debug_on_exit (specpdl + count, false); |
| 2842 | tem = call_debugger (list2 (Qexit, tem)); | 2838 | tem = call_debugger (list2 (Qexit, tem)); |
| 2843 | } | 2839 | } |
| 2844 | SAFE_FREE (); | 2840 | SAFE_FREE (); |