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.