diff options
| author | Joakim Verona | 2013-07-20 01:44:36 +0200 |
|---|---|---|
| committer | Joakim Verona | 2013-07-20 01:44:36 +0200 |
| commit | 759dbb1aebe68fb392f7ed53eba4b460ae6b83be (patch) | |
| tree | 1becc0cc6d676589eb274cb2c457e4256e908010 /src/eval.c | |
| parent | 6c1769c85ecb61b40a1f9a3b56b61cdd6c1f8992 (diff) | |
| parent | 3f5bef16fab0ba83cb2298f8137fec831af1aec4 (diff) | |
| download | emacs-759dbb1aebe68fb392f7ed53eba4b460ae6b83be.tar.gz emacs-759dbb1aebe68fb392f7ed53eba4b460ae6b83be.zip | |
Merge branch 'trunk' into xwidget
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 133 |
1 files changed, 105 insertions, 28 deletions
diff --git a/src/eval.c b/src/eval.c index 0e231bdb285..23834cb54f6 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -152,13 +152,6 @@ specpdl_arg (union specbinding *pdl) | |||
| 152 | return pdl->unwind.arg; | 152 | return pdl->unwind.arg; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static specbinding_func | ||
| 156 | specpdl_func (union specbinding *pdl) | ||
| 157 | { | ||
| 158 | eassert (pdl->kind == SPECPDL_UNWIND); | ||
| 159 | return pdl->unwind.func; | ||
| 160 | } | ||
| 161 | |||
| 162 | Lisp_Object | 155 | Lisp_Object |
| 163 | backtrace_function (union specbinding *pdl) | 156 | backtrace_function (union specbinding *pdl) |
| 164 | { | 157 | { |
| @@ -267,12 +260,11 @@ init_eval (void) | |||
| 267 | 260 | ||
| 268 | /* Unwind-protect function used by call_debugger. */ | 261 | /* Unwind-protect function used by call_debugger. */ |
| 269 | 262 | ||
| 270 | static Lisp_Object | 263 | static void |
| 271 | restore_stack_limits (Lisp_Object data) | 264 | restore_stack_limits (Lisp_Object data) |
| 272 | { | 265 | { |
| 273 | max_specpdl_size = XINT (XCAR (data)); | 266 | max_specpdl_size = XINT (XCAR (data)); |
| 274 | max_lisp_eval_depth = XINT (XCDR (data)); | 267 | max_lisp_eval_depth = XINT (XCDR (data)); |
| 275 | return Qnil; | ||
| 276 | } | 268 | } |
| 277 | 269 | ||
| 278 | /* Call the Lisp debugger, giving it argument ARG. */ | 270 | /* Call the Lisp debugger, giving it argument ARG. */ |
| @@ -338,7 +330,7 @@ do_debug_on_call (Lisp_Object code) | |||
| 338 | { | 330 | { |
| 339 | debug_on_next_call = 0; | 331 | debug_on_next_call = 0; |
| 340 | set_backtrace_debug_on_exit (specpdl_ptr - 1, true); | 332 | set_backtrace_debug_on_exit (specpdl_ptr - 1, true); |
| 341 | call_debugger (Fcons (code, Qnil)); | 333 | call_debugger (list1 (code)); |
| 342 | } | 334 | } |
| 343 | 335 | ||
| 344 | /* NOTE!!! Every function that can call EVAL must protect its args | 336 | /* NOTE!!! Every function that can call EVAL must protect its args |
| @@ -450,23 +442,32 @@ usage: (cond CLAUSES...) */) | |||
| 450 | DEFUN ("progn", Fprogn, Sprogn, 0, UNEVALLED, 0, | 442 | DEFUN ("progn", Fprogn, Sprogn, 0, UNEVALLED, 0, |
| 451 | doc: /* Eval BODY forms sequentially and return value of last one. | 443 | doc: /* Eval BODY forms sequentially and return value of last one. |
| 452 | usage: (progn BODY...) */) | 444 | usage: (progn BODY...) */) |
| 453 | (Lisp_Object args) | 445 | (Lisp_Object body) |
| 454 | { | 446 | { |
| 455 | register Lisp_Object val = Qnil; | 447 | Lisp_Object val = Qnil; |
| 456 | struct gcpro gcpro1; | 448 | struct gcpro gcpro1; |
| 457 | 449 | ||
| 458 | GCPRO1 (args); | 450 | GCPRO1 (body); |
| 459 | 451 | ||
| 460 | while (CONSP (args)) | 452 | while (CONSP (body)) |
| 461 | { | 453 | { |
| 462 | val = eval_sub (XCAR (args)); | 454 | val = eval_sub (XCAR (body)); |
| 463 | args = XCDR (args); | 455 | body = XCDR (body); |
| 464 | } | 456 | } |
| 465 | 457 | ||
| 466 | UNGCPRO; | 458 | UNGCPRO; |
| 467 | return val; | 459 | return val; |
| 468 | } | 460 | } |
| 469 | 461 | ||
| 462 | /* Evaluate BODY sequentually, discarding its value. Suitable for | ||
| 463 | record_unwind_protect. */ | ||
| 464 | |||
| 465 | void | ||
| 466 | unwind_body (Lisp_Object body) | ||
| 467 | { | ||
| 468 | Fprogn (body); | ||
| 469 | } | ||
| 470 | |||
| 470 | DEFUN ("prog1", Fprog1, Sprog1, 1, UNEVALLED, 0, | 471 | DEFUN ("prog1", Fprog1, Sprog1, 1, UNEVALLED, 0, |
| 471 | doc: /* Eval FIRST and BODY sequentially; return value from FIRST. | 472 | doc: /* Eval FIRST and BODY sequentially; return value from FIRST. |
| 472 | The value of FIRST is saved during the evaluation of the remaining args, | 473 | The value of FIRST is saved during the evaluation of the remaining args, |
| @@ -1149,7 +1150,7 @@ usage: (unwind-protect BODYFORM UNWINDFORMS...) */) | |||
| 1149 | Lisp_Object val; | 1150 | Lisp_Object val; |
| 1150 | ptrdiff_t count = SPECPDL_INDEX (); | 1151 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1151 | 1152 | ||
| 1152 | record_unwind_protect (Fprogn, Fcdr (args)); | 1153 | record_unwind_protect (unwind_body, Fcdr (args)); |
| 1153 | val = eval_sub (Fcar (args)); | 1154 | val = eval_sub (Fcar (args)); |
| 1154 | return unbind_to (count, val); | 1155 | return unbind_to (count, val); |
| 1155 | } | 1156 | } |
| @@ -1611,7 +1612,7 @@ signal_error (const char *s, Lisp_Object arg) | |||
| 1611 | } | 1612 | } |
| 1612 | 1613 | ||
| 1613 | if (!NILP (hare)) | 1614 | if (!NILP (hare)) |
| 1614 | arg = Fcons (arg, Qnil); /* Make it a list. */ | 1615 | arg = list1 (arg); |
| 1615 | 1616 | ||
| 1616 | xsignal (Qerror, Fcons (build_string (s), arg)); | 1617 | xsignal (Qerror, Fcons (build_string (s), arg)); |
| 1617 | } | 1618 | } |
| @@ -1703,7 +1704,7 @@ maybe_call_debugger (Lisp_Object conditions, Lisp_Object sig, Lisp_Object data) | |||
| 1703 | /* RMS: What's this for? */ | 1704 | /* RMS: What's this for? */ |
| 1704 | && when_entered_debugger < num_nonmacro_input_events) | 1705 | && when_entered_debugger < num_nonmacro_input_events) |
| 1705 | { | 1706 | { |
| 1706 | call_debugger (Fcons (Qerror, Fcons (combined_data, Qnil))); | 1707 | call_debugger (list2 (Qerror, combined_data)); |
| 1707 | return 1; | 1708 | return 1; |
| 1708 | } | 1709 | } |
| 1709 | 1710 | ||
| @@ -1890,10 +1891,10 @@ this does nothing and returns nil. */) | |||
| 1890 | Qnil); | 1891 | Qnil); |
| 1891 | } | 1892 | } |
| 1892 | 1893 | ||
| 1893 | Lisp_Object | 1894 | void |
| 1894 | un_autoload (Lisp_Object oldqueue) | 1895 | un_autoload (Lisp_Object oldqueue) |
| 1895 | { | 1896 | { |
| 1896 | register Lisp_Object queue, first, second; | 1897 | Lisp_Object queue, first, second; |
| 1897 | 1898 | ||
| 1898 | /* Queue to unwind is current value of Vautoload_queue. | 1899 | /* Queue to unwind is current value of Vautoload_queue. |
| 1899 | oldqueue is the shadowed value to leave in Vautoload_queue. */ | 1900 | oldqueue is the shadowed value to leave in Vautoload_queue. */ |
| @@ -1910,7 +1911,6 @@ un_autoload (Lisp_Object oldqueue) | |||
| 1910 | Ffset (first, second); | 1911 | Ffset (first, second); |
| 1911 | queue = XCDR (queue); | 1912 | queue = XCDR (queue); |
| 1912 | } | 1913 | } |
| 1913 | return Qnil; | ||
| 1914 | } | 1914 | } |
| 1915 | 1915 | ||
| 1916 | /* Load an autoloaded function. | 1916 | /* Load an autoloaded function. |
| @@ -1992,7 +1992,7 @@ If LEXICAL is t, evaluate using lexical scoping. */) | |||
| 1992 | { | 1992 | { |
| 1993 | ptrdiff_t count = SPECPDL_INDEX (); | 1993 | ptrdiff_t count = SPECPDL_INDEX (); |
| 1994 | specbind (Qinternal_interpreter_environment, | 1994 | specbind (Qinternal_interpreter_environment, |
| 1995 | CONSP (lexical) || NILP (lexical) ? lexical : Fcons (Qt, Qnil)); | 1995 | CONSP (lexical) || NILP (lexical) ? lexical : list1 (Qt)); |
| 1996 | return unbind_to (count, eval_sub (form)); | 1996 | return unbind_to (count, eval_sub (form)); |
| 1997 | } | 1997 | } |
| 1998 | 1998 | ||
| @@ -2257,7 +2257,7 @@ eval_sub (Lisp_Object form) | |||
| 2257 | 2257 | ||
| 2258 | lisp_eval_depth--; | 2258 | lisp_eval_depth--; |
| 2259 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) | 2259 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) |
| 2260 | val = call_debugger (Fcons (Qexit, Fcons (val, Qnil))); | 2260 | val = call_debugger (list2 (Qexit, val)); |
| 2261 | specpdl_ptr--; | 2261 | specpdl_ptr--; |
| 2262 | 2262 | ||
| 2263 | return val; | 2263 | return val; |
| @@ -2878,7 +2878,7 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */) | |||
| 2878 | check_cons_list (); | 2878 | check_cons_list (); |
| 2879 | lisp_eval_depth--; | 2879 | lisp_eval_depth--; |
| 2880 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) | 2880 | if (backtrace_debug_on_exit (specpdl_ptr - 1)) |
| 2881 | val = call_debugger (Fcons (Qexit, Fcons (val, Qnil))); | 2881 | val = call_debugger (list2 (Qexit, val)); |
| 2882 | specpdl_ptr--; | 2882 | specpdl_ptr--; |
| 2883 | return val; | 2883 | return val; |
| 2884 | } | 2884 | } |
| @@ -2920,7 +2920,7 @@ apply_lambda (Lisp_Object fun, Lisp_Object args) | |||
| 2920 | { | 2920 | { |
| 2921 | /* Don't do it again when we return to eval. */ | 2921 | /* Don't do it again when we return to eval. */ |
| 2922 | set_backtrace_debug_on_exit (specpdl_ptr - 1, false); | 2922 | set_backtrace_debug_on_exit (specpdl_ptr - 1, false); |
| 2923 | tem = call_debugger (Fcons (Qexit, Fcons (tem, Qnil))); | 2923 | tem = call_debugger (list2 (Qexit, tem)); |
| 2924 | } | 2924 | } |
| 2925 | SAFE_FREE (); | 2925 | SAFE_FREE (); |
| 2926 | return tem; | 2926 | return tem; |
| @@ -3190,8 +3190,10 @@ specbind (Lisp_Object symbol, Lisp_Object value) | |||
| 3190 | } | 3190 | } |
| 3191 | } | 3191 | } |
| 3192 | 3192 | ||
| 3193 | /* Push unwind-protect entries of various types. */ | ||
| 3194 | |||
| 3193 | void | 3195 | void |
| 3194 | record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg) | 3196 | record_unwind_protect (void (*function) (Lisp_Object), Lisp_Object arg) |
| 3195 | { | 3197 | { |
| 3196 | specpdl_ptr->unwind.kind = SPECPDL_UNWIND; | 3198 | specpdl_ptr->unwind.kind = SPECPDL_UNWIND; |
| 3197 | specpdl_ptr->unwind.func = function; | 3199 | specpdl_ptr->unwind.func = function; |
| @@ -3199,6 +3201,72 @@ record_unwind_protect (Lisp_Object (*function) (Lisp_Object), Lisp_Object arg) | |||
| 3199 | grow_specpdl (); | 3201 | grow_specpdl (); |
| 3200 | } | 3202 | } |
| 3201 | 3203 | ||
| 3204 | void | ||
| 3205 | record_unwind_protect_ptr (void (*function) (void *), void *arg) | ||
| 3206 | { | ||
| 3207 | specpdl_ptr->unwind_ptr.kind = SPECPDL_UNWIND_PTR; | ||
| 3208 | specpdl_ptr->unwind_ptr.func = function; | ||
| 3209 | specpdl_ptr->unwind_ptr.arg = arg; | ||
| 3210 | grow_specpdl (); | ||
| 3211 | } | ||
| 3212 | |||
| 3213 | void | ||
| 3214 | record_unwind_protect_int (void (*function) (int), int arg) | ||
| 3215 | { | ||
| 3216 | specpdl_ptr->unwind_int.kind = SPECPDL_UNWIND_INT; | ||
| 3217 | specpdl_ptr->unwind_int.func = function; | ||
| 3218 | specpdl_ptr->unwind_int.arg = arg; | ||
| 3219 | grow_specpdl (); | ||
| 3220 | } | ||
| 3221 | |||
| 3222 | void | ||
| 3223 | record_unwind_protect_void (void (*function) (void)) | ||
| 3224 | { | ||
| 3225 | specpdl_ptr->unwind_void.kind = SPECPDL_UNWIND_VOID; | ||
| 3226 | specpdl_ptr->unwind_void.func = function; | ||
| 3227 | grow_specpdl (); | ||
| 3228 | } | ||
| 3229 | |||
| 3230 | static void | ||
| 3231 | do_nothing (void) | ||
| 3232 | {} | ||
| 3233 | |||
| 3234 | /* Push an unwind-protect entry that does nothing, so that | ||
| 3235 | set_unwind_protect_ptr can overwrite it later. */ | ||
| 3236 | |||
| 3237 | void | ||
| 3238 | record_unwind_protect_nothing (void) | ||
| 3239 | { | ||
| 3240 | record_unwind_protect_void (do_nothing); | ||
| 3241 | } | ||
| 3242 | |||
| 3243 | /* Clear the unwind-protect entry COUNT, so that it does nothing. | ||
| 3244 | It need not be at the top of the stack. */ | ||
| 3245 | |||
| 3246 | void | ||
| 3247 | clear_unwind_protect (ptrdiff_t count) | ||
| 3248 | { | ||
| 3249 | union specbinding *p = specpdl + count; | ||
| 3250 | p->unwind_void.kind = SPECPDL_UNWIND_VOID; | ||
| 3251 | p->unwind_void.func = do_nothing; | ||
| 3252 | } | ||
| 3253 | |||
| 3254 | /* Set the unwind-protect entry COUNT so that it invokes FUNC (ARG). | ||
| 3255 | It need not be at the top of the stack. Discard the entry's | ||
| 3256 | previous value without invoking it. */ | ||
| 3257 | |||
| 3258 | void | ||
| 3259 | set_unwind_protect_ptr (ptrdiff_t count, void (*func) (void *), void *arg) | ||
| 3260 | { | ||
| 3261 | union specbinding *p = specpdl + count; | ||
| 3262 | p->unwind_ptr.kind = SPECPDL_UNWIND_PTR; | ||
| 3263 | p->unwind_ptr.func = func; | ||
| 3264 | p->unwind_ptr.arg = arg; | ||
| 3265 | } | ||
| 3266 | |||
| 3267 | /* Pop and execute entries from the unwind-protect stack until the | ||
| 3268 | depth COUNT is reached. Return VALUE. */ | ||
| 3269 | |||
| 3202 | Lisp_Object | 3270 | Lisp_Object |
| 3203 | unbind_to (ptrdiff_t count, Lisp_Object value) | 3271 | unbind_to (ptrdiff_t count, Lisp_Object value) |
| 3204 | { | 3272 | { |
| @@ -3220,7 +3288,16 @@ unbind_to (ptrdiff_t count, Lisp_Object value) | |||
| 3220 | switch (specpdl_ptr->kind) | 3288 | switch (specpdl_ptr->kind) |
| 3221 | { | 3289 | { |
| 3222 | case SPECPDL_UNWIND: | 3290 | case SPECPDL_UNWIND: |
| 3223 | specpdl_func (specpdl_ptr) (specpdl_arg (specpdl_ptr)); | 3291 | specpdl_ptr->unwind.func (specpdl_ptr->unwind.arg); |
| 3292 | break; | ||
| 3293 | case SPECPDL_UNWIND_PTR: | ||
| 3294 | specpdl_ptr->unwind_ptr.func (specpdl_ptr->unwind_ptr.arg); | ||
| 3295 | break; | ||
| 3296 | case SPECPDL_UNWIND_INT: | ||
| 3297 | specpdl_ptr->unwind_int.func (specpdl_ptr->unwind_int.arg); | ||
| 3298 | break; | ||
| 3299 | case SPECPDL_UNWIND_VOID: | ||
| 3300 | specpdl_ptr->unwind_void.func (); | ||
| 3224 | break; | 3301 | break; |
| 3225 | case SPECPDL_LET: | 3302 | case SPECPDL_LET: |
| 3226 | /* If variable has a trivial value (no forwarding), we can | 3303 | /* If variable has a trivial value (no forwarding), we can |