diff options
| author | K. Handa | 2016-01-03 17:53:43 +0900 |
|---|---|---|
| committer | K. Handa | 2016-01-03 17:53:43 +0900 |
| commit | fb6d826c69939c2d016c1b824d4e9bcb53d9e643 (patch) | |
| tree | b9ce862d6cbe25e740203421984df21e4cbadbf4 /src/eval.c | |
| parent | 536f48e9a2251b9e654ea974bd90ff2f40218753 (diff) | |
| parent | 91917dd58ec5278e555b9c693a830749083e8f89 (diff) | |
| download | emacs-fb6d826c69939c2d016c1b824d4e9bcb53d9e643.tar.gz emacs-fb6d826c69939c2d016c1b824d4e9bcb53d9e643.zip | |
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
Diffstat (limited to 'src/eval.c')
| -rw-r--r-- | src/eval.c | 219 |
1 files changed, 136 insertions, 83 deletions
diff --git a/src/eval.c b/src/eval.c index ac98ca11bd4..bd0cf68369c 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -61,7 +61,7 @@ union specbinding *specpdl_ptr; | |||
| 61 | 61 | ||
| 62 | /* Depth in Lisp evaluations and function calls. */ | 62 | /* Depth in Lisp evaluations and function calls. */ |
| 63 | 63 | ||
| 64 | EMACS_INT lisp_eval_depth; | 64 | static EMACS_INT lisp_eval_depth; |
| 65 | 65 | ||
| 66 | /* The value of num_nonmacro_input_events as of the last time we | 66 | /* The value of num_nonmacro_input_events as of the last time we |
| 67 | started to enter the debugger. If we decide to enter the debugger | 67 | started to enter the debugger. If we decide to enter the debugger |
| @@ -226,9 +226,8 @@ init_eval (void) | |||
| 226 | { /* Put a dummy catcher at top-level so that handlerlist is never NULL. | 226 | { /* Put a dummy catcher at top-level so that handlerlist is never NULL. |
| 227 | This is important since handlerlist->nextfree holds the freelist | 227 | This is important since handlerlist->nextfree holds the freelist |
| 228 | which would otherwise leak every time we unwind back to top-level. */ | 228 | which would otherwise leak every time we unwind back to top-level. */ |
| 229 | struct handler *c; | ||
| 230 | handlerlist = handlerlist_sentinel.nextfree = &handlerlist_sentinel; | 229 | handlerlist = handlerlist_sentinel.nextfree = &handlerlist_sentinel; |
| 231 | PUSH_HANDLER (c, Qunbound, CATCHER); | 230 | struct handler *c = push_handler (Qunbound, CATCHER); |
| 232 | eassert (c == &handlerlist_sentinel); | 231 | eassert (c == &handlerlist_sentinel); |
| 233 | handlerlist_sentinel.nextfree = NULL; | 232 | handlerlist_sentinel.nextfree = NULL; |
| 234 | handlerlist_sentinel.next = NULL; | 233 | handlerlist_sentinel.next = NULL; |
| @@ -488,6 +487,10 @@ usage: (setq [SYM VAL]...) */) | |||
| 488 | if (CONSP (args)) | 487 | if (CONSP (args)) |
| 489 | { | 488 | { |
| 490 | Lisp_Object args_left = args; | 489 | Lisp_Object args_left = args; |
| 490 | Lisp_Object numargs = Flength (args); | ||
| 491 | |||
| 492 | if (XINT (numargs) & 1) | ||
| 493 | xsignal2 (Qwrong_number_of_arguments, Qsetq, numargs); | ||
| 491 | 494 | ||
| 492 | do | 495 | do |
| 493 | { | 496 | { |
| @@ -1059,18 +1062,16 @@ usage: (catch TAG BODY...) */) | |||
| 1059 | This is how catches are done from within C code. */ | 1062 | This is how catches are done from within C code. */ |
| 1060 | 1063 | ||
| 1061 | Lisp_Object | 1064 | Lisp_Object |
| 1062 | internal_catch (Lisp_Object tag, Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) | 1065 | internal_catch (Lisp_Object tag, |
| 1066 | Lisp_Object (*func) (Lisp_Object), Lisp_Object arg) | ||
| 1063 | { | 1067 | { |
| 1064 | /* This structure is made part of the chain `catchlist'. */ | 1068 | /* This structure is made part of the chain `catchlist'. */ |
| 1065 | struct handler *c; | 1069 | struct handler *c = push_handler (tag, CATCHER); |
| 1066 | |||
| 1067 | /* Fill in the components of c, and put it on the list. */ | ||
| 1068 | PUSH_HANDLER (c, tag, CATCHER); | ||
| 1069 | 1070 | ||
| 1070 | /* Call FUNC. */ | 1071 | /* Call FUNC. */ |
| 1071 | if (! sys_setjmp (c->jmp)) | 1072 | if (! sys_setjmp (c->jmp)) |
| 1072 | { | 1073 | { |
| 1073 | Lisp_Object val = (*func) (arg); | 1074 | Lisp_Object val = func (arg); |
| 1074 | clobbered_eassert (handlerlist == c); | 1075 | clobbered_eassert (handlerlist == c); |
| 1075 | handlerlist = handlerlist->next; | 1076 | handlerlist = handlerlist->next; |
| 1076 | return val; | 1077 | return val; |
| @@ -1145,6 +1146,8 @@ Both TAG and VALUE are evalled. */ | |||
| 1145 | if (!NILP (tag)) | 1146 | if (!NILP (tag)) |
| 1146 | for (c = handlerlist; c; c = c->next) | 1147 | for (c = handlerlist; c; c = c->next) |
| 1147 | { | 1148 | { |
| 1149 | if (c->type == CATCHER_ALL) | ||
| 1150 | unwind_to_catch (c, Fcons (tag, value)); | ||
| 1148 | if (c->type == CATCHER && EQ (c->tag_or_ch, tag)) | 1151 | if (c->type == CATCHER && EQ (c->tag_or_ch, tag)) |
| 1149 | unwind_to_catch (c, value); | 1152 | unwind_to_catch (c, value); |
| 1150 | } | 1153 | } |
| @@ -1211,7 +1214,6 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform, | |||
| 1211 | Lisp_Object handlers) | 1214 | Lisp_Object handlers) |
| 1212 | { | 1215 | { |
| 1213 | Lisp_Object val; | 1216 | Lisp_Object val; |
| 1214 | struct handler *c; | ||
| 1215 | struct handler *oldhandlerlist = handlerlist; | 1217 | struct handler *oldhandlerlist = handlerlist; |
| 1216 | int clausenb = 0; | 1218 | int clausenb = 0; |
| 1217 | 1219 | ||
| @@ -1246,7 +1248,7 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform, | |||
| 1246 | Lisp_Object condition = XCAR (clause); | 1248 | Lisp_Object condition = XCAR (clause); |
| 1247 | if (!CONSP (condition)) | 1249 | if (!CONSP (condition)) |
| 1248 | condition = Fcons (condition, Qnil); | 1250 | condition = Fcons (condition, Qnil); |
| 1249 | PUSH_HANDLER (c, condition, CONDITION_CASE); | 1251 | struct handler *c = push_handler (condition, CONDITION_CASE); |
| 1250 | if (sys_setjmp (c->jmp)) | 1252 | if (sys_setjmp (c->jmp)) |
| 1251 | { | 1253 | { |
| 1252 | ptrdiff_t count = SPECPDL_INDEX (); | 1254 | ptrdiff_t count = SPECPDL_INDEX (); |
| @@ -1294,46 +1296,45 @@ Lisp_Object | |||
| 1294 | internal_condition_case (Lisp_Object (*bfun) (void), Lisp_Object handlers, | 1296 | internal_condition_case (Lisp_Object (*bfun) (void), Lisp_Object handlers, |
| 1295 | Lisp_Object (*hfun) (Lisp_Object)) | 1297 | Lisp_Object (*hfun) (Lisp_Object)) |
| 1296 | { | 1298 | { |
| 1297 | Lisp_Object val; | 1299 | struct handler *c = push_handler (handlers, CONDITION_CASE); |
| 1298 | struct handler *c; | ||
| 1299 | |||
| 1300 | PUSH_HANDLER (c, handlers, CONDITION_CASE); | ||
| 1301 | if (sys_setjmp (c->jmp)) | 1300 | if (sys_setjmp (c->jmp)) |
| 1302 | { | 1301 | { |
| 1303 | Lisp_Object val = handlerlist->val; | 1302 | Lisp_Object val = handlerlist->val; |
| 1304 | clobbered_eassert (handlerlist == c); | 1303 | clobbered_eassert (handlerlist == c); |
| 1305 | handlerlist = handlerlist->next; | 1304 | handlerlist = handlerlist->next; |
| 1306 | return (*hfun) (val); | 1305 | return hfun (val); |
| 1306 | } | ||
| 1307 | else | ||
| 1308 | { | ||
| 1309 | Lisp_Object val = bfun (); | ||
| 1310 | clobbered_eassert (handlerlist == c); | ||
| 1311 | handlerlist = handlerlist->next; | ||
| 1312 | return val; | ||
| 1307 | } | 1313 | } |
| 1308 | |||
| 1309 | val = (*bfun) (); | ||
| 1310 | clobbered_eassert (handlerlist == c); | ||
| 1311 | handlerlist = handlerlist->next; | ||
| 1312 | return val; | ||
| 1313 | } | 1314 | } |
| 1314 | 1315 | ||
| 1315 | /* Like internal_condition_case but call BFUN with ARG as its argument. */ | 1316 | /* Like internal_condition_case but call BFUN with ARG as its argument. */ |
| 1316 | 1317 | ||
| 1317 | Lisp_Object | 1318 | Lisp_Object |
| 1318 | internal_condition_case_1 (Lisp_Object (*bfun) (Lisp_Object), Lisp_Object arg, | 1319 | internal_condition_case_1 (Lisp_Object (*bfun) (Lisp_Object), Lisp_Object arg, |
| 1319 | Lisp_Object handlers, Lisp_Object (*hfun) (Lisp_Object)) | 1320 | Lisp_Object handlers, |
| 1321 | Lisp_Object (*hfun) (Lisp_Object)) | ||
| 1320 | { | 1322 | { |
| 1321 | Lisp_Object val; | 1323 | struct handler *c = push_handler (handlers, CONDITION_CASE); |
| 1322 | struct handler *c; | ||
| 1323 | |||
| 1324 | PUSH_HANDLER (c, handlers, CONDITION_CASE); | ||
| 1325 | if (sys_setjmp (c->jmp)) | 1324 | if (sys_setjmp (c->jmp)) |
| 1326 | { | 1325 | { |
| 1327 | Lisp_Object val = handlerlist->val; | 1326 | Lisp_Object val = handlerlist->val; |
| 1328 | clobbered_eassert (handlerlist == c); | 1327 | clobbered_eassert (handlerlist == c); |
| 1329 | handlerlist = handlerlist->next; | 1328 | handlerlist = handlerlist->next; |
| 1330 | return (*hfun) (val); | 1329 | return hfun (val); |
| 1330 | } | ||
| 1331 | else | ||
| 1332 | { | ||
| 1333 | Lisp_Object val = bfun (arg); | ||
| 1334 | clobbered_eassert (handlerlist == c); | ||
| 1335 | handlerlist = handlerlist->next; | ||
| 1336 | return val; | ||
| 1331 | } | 1337 | } |
| 1332 | |||
| 1333 | val = (*bfun) (arg); | ||
| 1334 | clobbered_eassert (handlerlist == c); | ||
| 1335 | handlerlist = handlerlist->next; | ||
| 1336 | return val; | ||
| 1337 | } | 1338 | } |
| 1338 | 1339 | ||
| 1339 | /* Like internal_condition_case_1 but call BFUN with ARG1 and ARG2 as | 1340 | /* Like internal_condition_case_1 but call BFUN with ARG1 and ARG2 as |
| @@ -1346,22 +1347,21 @@ internal_condition_case_2 (Lisp_Object (*bfun) (Lisp_Object, Lisp_Object), | |||
| 1346 | Lisp_Object handlers, | 1347 | Lisp_Object handlers, |
| 1347 | Lisp_Object (*hfun) (Lisp_Object)) | 1348 | Lisp_Object (*hfun) (Lisp_Object)) |
| 1348 | { | 1349 | { |
| 1349 | Lisp_Object val; | 1350 | struct handler *c = push_handler (handlers, CONDITION_CASE); |
| 1350 | struct handler *c; | ||
| 1351 | |||
| 1352 | PUSH_HANDLER (c, handlers, CONDITION_CASE); | ||
| 1353 | if (sys_setjmp (c->jmp)) | 1351 | if (sys_setjmp (c->jmp)) |
| 1354 | { | 1352 | { |
| 1355 | Lisp_Object val = handlerlist->val; | 1353 | Lisp_Object val = handlerlist->val; |
| 1356 | clobbered_eassert (handlerlist == c); | 1354 | clobbered_eassert (handlerlist == c); |
| 1357 | handlerlist = handlerlist->next; | 1355 | handlerlist = handlerlist->next; |
| 1358 | return (*hfun) (val); | 1356 | return hfun (val); |
| 1357 | } | ||
| 1358 | else | ||
| 1359 | { | ||
| 1360 | Lisp_Object val = bfun (arg1, arg2); | ||
| 1361 | clobbered_eassert (handlerlist == c); | ||
| 1362 | handlerlist = handlerlist->next; | ||
| 1363 | return val; | ||
| 1359 | } | 1364 | } |
| 1360 | |||
| 1361 | val = (*bfun) (arg1, arg2); | ||
| 1362 | clobbered_eassert (handlerlist == c); | ||
| 1363 | handlerlist = handlerlist->next; | ||
| 1364 | return val; | ||
| 1365 | } | 1365 | } |
| 1366 | 1366 | ||
| 1367 | /* Like internal_condition_case but call BFUN with NARGS as first, | 1367 | /* Like internal_condition_case but call BFUN with NARGS as first, |
| @@ -1376,22 +1376,57 @@ internal_condition_case_n (Lisp_Object (*bfun) (ptrdiff_t, Lisp_Object *), | |||
| 1376 | ptrdiff_t nargs, | 1376 | ptrdiff_t nargs, |
| 1377 | Lisp_Object *args)) | 1377 | Lisp_Object *args)) |
| 1378 | { | 1378 | { |
| 1379 | Lisp_Object val; | 1379 | struct handler *c = push_handler (handlers, CONDITION_CASE); |
| 1380 | struct handler *c; | ||
| 1381 | |||
| 1382 | PUSH_HANDLER (c, handlers, CONDITION_CASE); | ||
| 1383 | if (sys_setjmp (c->jmp)) | 1380 | if (sys_setjmp (c->jmp)) |
| 1384 | { | 1381 | { |
| 1385 | Lisp_Object val = handlerlist->val; | 1382 | Lisp_Object val = handlerlist->val; |
| 1386 | clobbered_eassert (handlerlist == c); | 1383 | clobbered_eassert (handlerlist == c); |
| 1387 | handlerlist = handlerlist->next; | 1384 | handlerlist = handlerlist->next; |
| 1388 | return (*hfun) (val, nargs, args); | 1385 | return hfun (val, nargs, args); |
| 1386 | } | ||
| 1387 | else | ||
| 1388 | { | ||
| 1389 | Lisp_Object val = bfun (nargs, args); | ||
| 1390 | clobbered_eassert (handlerlist == c); | ||
| 1391 | handlerlist = handlerlist->next; | ||
| 1392 | return val; | ||
| 1389 | } | 1393 | } |
| 1394 | } | ||
| 1390 | 1395 | ||
| 1391 | val = (*bfun) (nargs, args); | 1396 | struct handler * |
| 1392 | clobbered_eassert (handlerlist == c); | 1397 | push_handler (Lisp_Object tag_ch_val, enum handlertype handlertype) |
| 1393 | handlerlist = handlerlist->next; | 1398 | { |
| 1394 | return val; | 1399 | struct handler *c = push_handler_nosignal (tag_ch_val, handlertype); |
| 1400 | if (!c) | ||
| 1401 | memory_full (sizeof *c); | ||
| 1402 | return c; | ||
| 1403 | } | ||
| 1404 | |||
| 1405 | struct handler * | ||
| 1406 | push_handler_nosignal (Lisp_Object tag_ch_val, enum handlertype handlertype) | ||
| 1407 | { | ||
| 1408 | struct handler *c = handlerlist->nextfree; | ||
| 1409 | if (!c) | ||
| 1410 | { | ||
| 1411 | c = malloc (sizeof *c); | ||
| 1412 | if (!c) | ||
| 1413 | return c; | ||
| 1414 | if (profiler_memory_running) | ||
| 1415 | malloc_probe (sizeof *c); | ||
| 1416 | c->nextfree = NULL; | ||
| 1417 | handlerlist->nextfree = c; | ||
| 1418 | } | ||
| 1419 | c->type = handlertype; | ||
| 1420 | c->tag_or_ch = tag_ch_val; | ||
| 1421 | c->val = Qnil; | ||
| 1422 | c->next = handlerlist; | ||
| 1423 | c->lisp_eval_depth = lisp_eval_depth; | ||
| 1424 | c->pdlcount = SPECPDL_INDEX (); | ||
| 1425 | c->poll_suppress_count = poll_suppress_count; | ||
| 1426 | c->interrupt_input_blocked = interrupt_input_blocked; | ||
| 1427 | c->byte_stack = byte_stack_list; | ||
| 1428 | handlerlist = c; | ||
| 1429 | return c; | ||
| 1395 | } | 1430 | } |
| 1396 | 1431 | ||
| 1397 | 1432 | ||
| @@ -2014,6 +2049,10 @@ eval_sub (Lisp_Object form) | |||
| 2014 | Lisp_Object funcar; | 2049 | Lisp_Object funcar; |
| 2015 | ptrdiff_t count; | 2050 | ptrdiff_t count; |
| 2016 | 2051 | ||
| 2052 | /* Declare here, as this array may be accessed by call_debugger near | ||
| 2053 | the end of this function. See Bug#21245. */ | ||
| 2054 | Lisp_Object argvals[8]; | ||
| 2055 | |||
| 2017 | if (SYMBOLP (form)) | 2056 | if (SYMBOLP (form)) |
| 2018 | { | 2057 | { |
| 2019 | /* Look up its binding in the lexical environment. | 2058 | /* Look up its binding in the lexical environment. |
| @@ -2066,13 +2105,8 @@ eval_sub (Lisp_Object form) | |||
| 2066 | 2105 | ||
| 2067 | if (SUBRP (fun)) | 2106 | if (SUBRP (fun)) |
| 2068 | { | 2107 | { |
| 2069 | Lisp_Object numargs; | 2108 | Lisp_Object args_left = original_args; |
| 2070 | Lisp_Object argvals[8]; | 2109 | Lisp_Object numargs = Flength (args_left); |
| 2071 | Lisp_Object args_left; | ||
| 2072 | register int i, maxargs; | ||
| 2073 | |||
| 2074 | args_left = original_args; | ||
| 2075 | numargs = Flength (args_left); | ||
| 2076 | 2110 | ||
| 2077 | check_cons_list (); | 2111 | check_cons_list (); |
| 2078 | 2112 | ||
| @@ -2101,11 +2135,20 @@ eval_sub (Lisp_Object form) | |||
| 2101 | set_backtrace_args (specpdl + count, vals, XINT (numargs)); | 2135 | set_backtrace_args (specpdl + count, vals, XINT (numargs)); |
| 2102 | 2136 | ||
| 2103 | val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals); | 2137 | val = (XSUBR (fun)->function.aMANY) (XINT (numargs), vals); |
| 2138 | |||
| 2139 | check_cons_list (); | ||
| 2140 | lisp_eval_depth--; | ||
| 2141 | /* Do the debug-on-exit now, while VALS still exists. */ | ||
| 2142 | if (backtrace_debug_on_exit (specpdl + count)) | ||
| 2143 | val = call_debugger (list2 (Qexit, val)); | ||
| 2104 | SAFE_FREE (); | 2144 | SAFE_FREE (); |
| 2145 | specpdl_ptr--; | ||
| 2146 | return val; | ||
| 2105 | } | 2147 | } |
| 2106 | else | 2148 | else |
| 2107 | { | 2149 | { |
| 2108 | maxargs = XSUBR (fun)->max_args; | 2150 | int i, maxargs = XSUBR (fun)->max_args; |
| 2151 | |||
| 2109 | for (i = 0; i < maxargs; i++) | 2152 | for (i = 0; i < maxargs; i++) |
| 2110 | { | 2153 | { |
| 2111 | argvals[i] = eval_sub (Fcar (args_left)); | 2154 | argvals[i] = eval_sub (Fcar (args_left)); |
| @@ -2165,7 +2208,7 @@ eval_sub (Lisp_Object form) | |||
| 2165 | } | 2208 | } |
| 2166 | } | 2209 | } |
| 2167 | else if (COMPILEDP (fun)) | 2210 | else if (COMPILEDP (fun)) |
| 2168 | val = apply_lambda (fun, original_args, count); | 2211 | return apply_lambda (fun, original_args, count); |
| 2169 | else | 2212 | else |
| 2170 | { | 2213 | { |
| 2171 | if (NILP (fun)) | 2214 | if (NILP (fun)) |
| @@ -2195,7 +2238,7 @@ eval_sub (Lisp_Object form) | |||
| 2195 | } | 2238 | } |
| 2196 | else if (EQ (funcar, Qlambda) | 2239 | else if (EQ (funcar, Qlambda) |
| 2197 | || EQ (funcar, Qclosure)) | 2240 | || EQ (funcar, Qclosure)) |
| 2198 | val = apply_lambda (fun, original_args, count); | 2241 | return apply_lambda (fun, original_args, count); |
| 2199 | else | 2242 | else |
| 2200 | xsignal1 (Qinvalid_function, original_fun); | 2243 | xsignal1 (Qinvalid_function, original_fun); |
| 2201 | } | 2244 | } |
| @@ -2750,14 +2793,13 @@ apply_lambda (Lisp_Object fun, Lisp_Object args, ptrdiff_t count) | |||
| 2750 | set_backtrace_args (specpdl + count, arg_vector, i); | 2793 | set_backtrace_args (specpdl + count, arg_vector, i); |
| 2751 | tem = funcall_lambda (fun, numargs, arg_vector); | 2794 | tem = funcall_lambda (fun, numargs, arg_vector); |
| 2752 | 2795 | ||
| 2796 | check_cons_list (); | ||
| 2797 | lisp_eval_depth--; | ||
| 2753 | /* Do the debug-on-exit now, while arg_vector still exists. */ | 2798 | /* Do the debug-on-exit now, while arg_vector still exists. */ |
| 2754 | if (backtrace_debug_on_exit (specpdl + count)) | 2799 | if (backtrace_debug_on_exit (specpdl + count)) |
| 2755 | { | 2800 | tem = call_debugger (list2 (Qexit, tem)); |
| 2756 | /* Don't do it again when we return to eval. */ | ||
| 2757 | set_backtrace_debug_on_exit (specpdl + count, false); | ||
| 2758 | tem = call_debugger (list2 (Qexit, tem)); | ||
| 2759 | } | ||
| 2760 | SAFE_FREE (); | 2801 | SAFE_FREE (); |
| 2802 | specpdl_ptr--; | ||
| 2761 | return tem; | 2803 | return tem; |
| 2762 | } | 2804 | } |
| 2763 | 2805 | ||
| @@ -2792,6 +2834,9 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs, | |||
| 2792 | } | 2834 | } |
| 2793 | else if (COMPILEDP (fun)) | 2835 | else if (COMPILEDP (fun)) |
| 2794 | { | 2836 | { |
| 2837 | ptrdiff_t size = ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK; | ||
| 2838 | if (size <= COMPILED_STACK_DEPTH) | ||
| 2839 | xsignal1 (Qinvalid_function, fun); | ||
| 2795 | syms_left = AREF (fun, COMPILED_ARGLIST); | 2840 | syms_left = AREF (fun, COMPILED_ARGLIST); |
| 2796 | if (INTEGERP (syms_left)) | 2841 | if (INTEGERP (syms_left)) |
| 2797 | /* A byte-code object with a non-nil `push args' slot means we | 2842 | /* A byte-code object with a non-nil `push args' slot means we |
| @@ -2889,19 +2934,25 @@ DEFUN ("fetch-bytecode", Ffetch_bytecode, Sfetch_bytecode, | |||
| 2889 | { | 2934 | { |
| 2890 | Lisp_Object tem; | 2935 | Lisp_Object tem; |
| 2891 | 2936 | ||
| 2892 | if (COMPILEDP (object) && CONSP (AREF (object, COMPILED_BYTECODE))) | 2937 | if (COMPILEDP (object)) |
| 2893 | { | 2938 | { |
| 2894 | tem = read_doc_string (AREF (object, COMPILED_BYTECODE)); | 2939 | ptrdiff_t size = ASIZE (object) & PSEUDOVECTOR_SIZE_MASK; |
| 2895 | if (!CONSP (tem)) | 2940 | if (size <= COMPILED_STACK_DEPTH) |
| 2941 | xsignal1 (Qinvalid_function, object); | ||
| 2942 | if (CONSP (AREF (object, COMPILED_BYTECODE))) | ||
| 2896 | { | 2943 | { |
| 2897 | tem = AREF (object, COMPILED_BYTECODE); | 2944 | tem = read_doc_string (AREF (object, COMPILED_BYTECODE)); |
| 2898 | if (CONSP (tem) && STRINGP (XCAR (tem))) | 2945 | if (!CONSP (tem)) |
| 2899 | error ("Invalid byte code in %s", SDATA (XCAR (tem))); | 2946 | { |
| 2900 | else | 2947 | tem = AREF (object, COMPILED_BYTECODE); |
| 2901 | error ("Invalid byte code"); | 2948 | if (CONSP (tem) && STRINGP (XCAR (tem))) |
| 2949 | error ("Invalid byte code in %s", SDATA (XCAR (tem))); | ||
| 2950 | else | ||
| 2951 | error ("Invalid byte code"); | ||
| 2952 | } | ||
| 2953 | ASET (object, COMPILED_BYTECODE, XCAR (tem)); | ||
| 2954 | ASET (object, COMPILED_CONSTANTS, XCDR (tem)); | ||
| 2902 | } | 2955 | } |
| 2903 | ASET (object, COMPILED_BYTECODE, XCAR (tem)); | ||
| 2904 | ASET (object, COMPILED_CONSTANTS, XCDR (tem)); | ||
| 2905 | } | 2956 | } |
| 2906 | return object; | 2957 | return object; |
| 2907 | } | 2958 | } |
| @@ -3145,10 +3196,11 @@ unbind_to (ptrdiff_t count, Lisp_Object value) | |||
| 3145 | { /* If variable has a trivial value (no forwarding), we can | 3196 | { /* If variable has a trivial value (no forwarding), we can |
| 3146 | just set it. No need to check for constant symbols here, | 3197 | just set it. No need to check for constant symbols here, |
| 3147 | since that was already done by specbind. */ | 3198 | since that was already done by specbind. */ |
| 3148 | struct Lisp_Symbol *sym = XSYMBOL (specpdl_symbol (specpdl_ptr)); | 3199 | Lisp_Object sym = specpdl_symbol (specpdl_ptr); |
| 3149 | if (sym->redirect == SYMBOL_PLAINVAL) | 3200 | if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) |
| 3150 | { | 3201 | { |
| 3151 | SET_SYMBOL_VAL (sym, specpdl_old_value (specpdl_ptr)); | 3202 | SET_SYMBOL_VAL (XSYMBOL (sym), |
| 3203 | specpdl_old_value (specpdl_ptr)); | ||
| 3152 | break; | 3204 | break; |
| 3153 | } | 3205 | } |
| 3154 | else | 3206 | else |
| @@ -3357,12 +3409,12 @@ backtrace_eval_unrewind (int distance) | |||
| 3357 | { /* If variable has a trivial value (no forwarding), we can | 3409 | { /* If variable has a trivial value (no forwarding), we can |
| 3358 | just set it. No need to check for constant symbols here, | 3410 | just set it. No need to check for constant symbols here, |
| 3359 | since that was already done by specbind. */ | 3411 | since that was already done by specbind. */ |
| 3360 | struct Lisp_Symbol *sym = XSYMBOL (specpdl_symbol (tmp)); | 3412 | Lisp_Object sym = specpdl_symbol (tmp); |
| 3361 | if (sym->redirect == SYMBOL_PLAINVAL) | 3413 | if (SYMBOLP (sym) && XSYMBOL (sym)->redirect == SYMBOL_PLAINVAL) |
| 3362 | { | 3414 | { |
| 3363 | Lisp_Object old_value = specpdl_old_value (tmp); | 3415 | Lisp_Object old_value = specpdl_old_value (tmp); |
| 3364 | set_specpdl_old_value (tmp, SYMBOL_VAL (sym)); | 3416 | set_specpdl_old_value (tmp, SYMBOL_VAL (XSYMBOL (sym))); |
| 3365 | SET_SYMBOL_VAL (sym, old_value); | 3417 | SET_SYMBOL_VAL (XSYMBOL (sym), old_value); |
| 3366 | break; | 3418 | break; |
| 3367 | } | 3419 | } |
| 3368 | else | 3420 | else |
| @@ -3607,6 +3659,7 @@ To prevent this happening, set `quit-flag' to nil | |||
| 3607 | before making `inhibit-quit' nil. */); | 3659 | before making `inhibit-quit' nil. */); |
| 3608 | Vinhibit_quit = Qnil; | 3660 | Vinhibit_quit = Qnil; |
| 3609 | 3661 | ||
| 3662 | DEFSYM (Qsetq, "setq"); | ||
| 3610 | DEFSYM (Qinhibit_quit, "inhibit-quit"); | 3663 | DEFSYM (Qinhibit_quit, "inhibit-quit"); |
| 3611 | DEFSYM (Qautoload, "autoload"); | 3664 | DEFSYM (Qautoload, "autoload"); |
| 3612 | DEFSYM (Qinhibit_debugger, "inhibit-debugger"); | 3665 | DEFSYM (Qinhibit_debugger, "inhibit-debugger"); |