Mercurial > emacs
comparison src/eval.c @ 109929:64970e6695e8
Avoid stack overflow in let, eval, and apply (Bug#6214).
* eval.c (Flet, Feval, Fapply, apply_lambda): Use SAFE_ALLOCA (Bug#6214).
author | Chong Yidong <cyd@stupidchicken.com> |
---|---|
date | Tue, 17 Aug 2010 12:34:28 -0400 |
parents | 1d1d5d9bd884 |
children | 7daea44c7bcc |
comparison
equal
deleted
inserted
replaced
109928:b476f3b6d93c | 109929:64970e6695e8 |
---|---|
1026 Lisp_Object *temps, tem; | 1026 Lisp_Object *temps, tem; |
1027 register Lisp_Object elt, varlist; | 1027 register Lisp_Object elt, varlist; |
1028 int count = SPECPDL_INDEX (); | 1028 int count = SPECPDL_INDEX (); |
1029 register int argnum; | 1029 register int argnum; |
1030 struct gcpro gcpro1, gcpro2; | 1030 struct gcpro gcpro1, gcpro2; |
1031 USE_SAFE_ALLOCA; | |
1031 | 1032 |
1032 varlist = Fcar (args); | 1033 varlist = Fcar (args); |
1033 | 1034 |
1034 /* Make space to hold the values to give the bound variables */ | 1035 /* Make space to hold the values to give the bound variables */ |
1035 elt = Flength (varlist); | 1036 elt = Flength (varlist); |
1036 temps = (Lisp_Object *) alloca (XFASTINT (elt) * sizeof (Lisp_Object)); | 1037 SAFE_ALLOCA (temps, Lisp_Object *, XFASTINT (elt) * sizeof (Lisp_Object)); |
1037 | 1038 |
1038 /* Compute the values and store them in `temps' */ | 1039 /* Compute the values and store them in `temps' */ |
1039 | 1040 |
1040 GCPRO2 (args, *temps); | 1041 GCPRO2 (args, *temps); |
1041 gcpro2.nvars = 0; | 1042 gcpro2.nvars = 0; |
1064 else | 1065 else |
1065 specbind (Fcar (elt), tem); | 1066 specbind (Fcar (elt), tem); |
1066 } | 1067 } |
1067 | 1068 |
1068 elt = Fprogn (Fcdr (args)); | 1069 elt = Fprogn (Fcdr (args)); |
1070 SAFE_FREE (); | |
1069 return unbind_to (count, elt); | 1071 return unbind_to (count, elt); |
1070 } | 1072 } |
1071 | 1073 |
1072 DEFUN ("while", Fwhile, Swhile, 1, UNEVALLED, 0, | 1074 DEFUN ("while", Fwhile, Swhile, 1, UNEVALLED, 0, |
1073 doc: /* If TEST yields non-nil, eval BODY... and repeat. | 1075 doc: /* If TEST yields non-nil, eval BODY... and repeat. |
2297 if (XSUBR (fun)->max_args == MANY) | 2299 if (XSUBR (fun)->max_args == MANY) |
2298 { | 2300 { |
2299 /* Pass a vector of evaluated arguments */ | 2301 /* Pass a vector of evaluated arguments */ |
2300 Lisp_Object *vals; | 2302 Lisp_Object *vals; |
2301 register int argnum = 0; | 2303 register int argnum = 0; |
2302 | 2304 USE_SAFE_ALLOCA; |
2303 vals = (Lisp_Object *) alloca (XINT (numargs) * sizeof (Lisp_Object)); | 2305 |
2306 SAFE_ALLOCA (vals, Lisp_Object *, | |
2307 XINT (numargs) * sizeof (Lisp_Object)); | |
2304 | 2308 |
2305 GCPRO3 (args_left, fun, fun); | 2309 GCPRO3 (args_left, fun, fun); |
2306 gcpro3.var = vals; | 2310 gcpro3.var = vals; |
2307 gcpro3.nvars = 0; | 2311 gcpro3.nvars = 0; |
2308 | 2312 |
2316 backtrace.args = vals; | 2320 backtrace.args = vals; |
2317 backtrace.nargs = XINT (numargs); | 2321 backtrace.nargs = XINT (numargs); |
2318 | 2322 |
2319 val = (*XSUBR (fun)->function) (XINT (numargs), vals); | 2323 val = (*XSUBR (fun)->function) (XINT (numargs), vals); |
2320 UNGCPRO; | 2324 UNGCPRO; |
2325 SAFE_FREE (); | |
2321 goto done; | 2326 goto done; |
2322 } | 2327 } |
2323 | 2328 |
2324 GCPRO3 (args_left, fun, fun); | 2329 GCPRO3 (args_left, fun, fun); |
2325 gcpro3.var = argvals; | 2330 gcpro3.var = argvals; |
2428 Lisp_Object *args; | 2433 Lisp_Object *args; |
2429 { | 2434 { |
2430 register int i, numargs; | 2435 register int i, numargs; |
2431 register Lisp_Object spread_arg; | 2436 register Lisp_Object spread_arg; |
2432 register Lisp_Object *funcall_args; | 2437 register Lisp_Object *funcall_args; |
2433 Lisp_Object fun; | 2438 Lisp_Object fun, retval; |
2434 struct gcpro gcpro1; | 2439 struct gcpro gcpro1; |
2440 USE_SAFE_ALLOCA; | |
2435 | 2441 |
2436 fun = args [0]; | 2442 fun = args [0]; |
2437 funcall_args = 0; | 2443 funcall_args = 0; |
2438 spread_arg = args [nargs - 1]; | 2444 spread_arg = args [nargs - 1]; |
2439 CHECK_LIST (spread_arg); | 2445 CHECK_LIST (spread_arg); |
2468 goto funcall; /* Let funcall get the error */ | 2474 goto funcall; /* Let funcall get the error */ |
2469 else if (XSUBR (fun)->max_args > numargs) | 2475 else if (XSUBR (fun)->max_args > numargs) |
2470 { | 2476 { |
2471 /* Avoid making funcall cons up a yet another new vector of arguments | 2477 /* Avoid making funcall cons up a yet another new vector of arguments |
2472 by explicitly supplying nil's for optional values */ | 2478 by explicitly supplying nil's for optional values */ |
2473 funcall_args = (Lisp_Object *) alloca ((1 + XSUBR (fun)->max_args) | 2479 SAFE_ALLOCA (funcall_args, Lisp_Object *, |
2474 * sizeof (Lisp_Object)); | 2480 (1 + XSUBR (fun)->max_args) * sizeof (Lisp_Object)); |
2475 for (i = numargs; i < XSUBR (fun)->max_args;) | 2481 for (i = numargs; i < XSUBR (fun)->max_args;) |
2476 funcall_args[++i] = Qnil; | 2482 funcall_args[++i] = Qnil; |
2477 GCPRO1 (*funcall_args); | 2483 GCPRO1 (*funcall_args); |
2478 gcpro1.nvars = 1 + XSUBR (fun)->max_args; | 2484 gcpro1.nvars = 1 + XSUBR (fun)->max_args; |
2479 } | 2485 } |
2481 funcall: | 2487 funcall: |
2482 /* We add 1 to numargs because funcall_args includes the | 2488 /* We add 1 to numargs because funcall_args includes the |
2483 function itself as well as its arguments. */ | 2489 function itself as well as its arguments. */ |
2484 if (!funcall_args) | 2490 if (!funcall_args) |
2485 { | 2491 { |
2486 funcall_args = (Lisp_Object *) alloca ((1 + numargs) | 2492 SAFE_ALLOCA (funcall_args, Lisp_Object *, |
2487 * sizeof (Lisp_Object)); | 2493 (1 + numargs) * sizeof (Lisp_Object)); |
2488 GCPRO1 (*funcall_args); | 2494 GCPRO1 (*funcall_args); |
2489 gcpro1.nvars = 1 + numargs; | 2495 gcpro1.nvars = 1 + numargs; |
2490 } | 2496 } |
2491 | 2497 |
2492 bcopy (args, funcall_args, nargs * sizeof (Lisp_Object)); | 2498 bcopy (args, funcall_args, nargs * sizeof (Lisp_Object)); |
2498 funcall_args [i++] = XCAR (spread_arg); | 2504 funcall_args [i++] = XCAR (spread_arg); |
2499 spread_arg = XCDR (spread_arg); | 2505 spread_arg = XCDR (spread_arg); |
2500 } | 2506 } |
2501 | 2507 |
2502 /* By convention, the caller needs to gcpro Ffuncall's args. */ | 2508 /* By convention, the caller needs to gcpro Ffuncall's args. */ |
2503 RETURN_UNGCPRO (Ffuncall (gcpro1.nvars, funcall_args)); | 2509 retval = Ffuncall (gcpro1.nvars, funcall_args); |
2510 UNGCPRO; | |
2511 SAFE_FREE (); | |
2512 | |
2513 return retval; | |
2504 } | 2514 } |
2505 | 2515 |
2506 /* Run hook variables in various ways. */ | 2516 /* Run hook variables in various ways. */ |
2507 | 2517 |
2508 enum run_hooks_condition {to_completion, until_success, until_failure}; | 2518 enum run_hooks_condition {to_completion, until_success, until_failure}; |
3106 Lisp_Object numargs; | 3116 Lisp_Object numargs; |
3107 register Lisp_Object *arg_vector; | 3117 register Lisp_Object *arg_vector; |
3108 struct gcpro gcpro1, gcpro2, gcpro3; | 3118 struct gcpro gcpro1, gcpro2, gcpro3; |
3109 register int i; | 3119 register int i; |
3110 register Lisp_Object tem; | 3120 register Lisp_Object tem; |
3121 USE_SAFE_ALLOCA; | |
3111 | 3122 |
3112 numargs = Flength (args); | 3123 numargs = Flength (args); |
3113 arg_vector = (Lisp_Object *) alloca (XINT (numargs) * sizeof (Lisp_Object)); | 3124 SAFE_ALLOCA (arg_vector, Lisp_Object *, |
3125 XINT (numargs) * sizeof (Lisp_Object)); | |
3114 args_left = args; | 3126 args_left = args; |
3115 | 3127 |
3116 GCPRO3 (*arg_vector, args_left, fun); | 3128 GCPRO3 (*arg_vector, args_left, fun); |
3117 gcpro1.nvars = 0; | 3129 gcpro1.nvars = 0; |
3118 | 3130 |
3137 /* Do the debug-on-exit now, while arg_vector still exists. */ | 3149 /* Do the debug-on-exit now, while arg_vector still exists. */ |
3138 if (backtrace_list->debug_on_exit) | 3150 if (backtrace_list->debug_on_exit) |
3139 tem = call_debugger (Fcons (Qexit, Fcons (tem, Qnil))); | 3151 tem = call_debugger (Fcons (Qexit, Fcons (tem, Qnil))); |
3140 /* Don't do it again when we return to eval. */ | 3152 /* Don't do it again when we return to eval. */ |
3141 backtrace_list->debug_on_exit = 0; | 3153 backtrace_list->debug_on_exit = 0; |
3154 SAFE_FREE (); | |
3142 return tem; | 3155 return tem; |
3143 } | 3156 } |
3144 | 3157 |
3145 /* Apply a Lisp function FUN to the NARGS evaluated arguments in ARG_VECTOR | 3158 /* Apply a Lisp function FUN to the NARGS evaluated arguments in ARG_VECTOR |
3146 and return the result of evaluation. | 3159 and return the result of evaluation. |