Skip to content

Commit b425870

Browse files
committed
fix #6098, crash on stack overflow splicing big argument lists
still slow as hell and still a bad idea, but at least it doesn't segfault
1 parent 8fde67c commit b425870

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

src/builtins.c

+19-11
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,9 @@ JL_CALLABLE(jl_f_apply)
266266
jl_tuple_len(args[1]));
267267
}
268268
}
269+
jl_value_t *argarr = NULL;
270+
JL_GC_PUSH1(&argarr);
271+
jl_value_t *result;
269272
jl_value_t **newargs;
270273
size_t n=0, i, j;
271274
for(i=1; i < nargs; i++) {
@@ -285,15 +288,27 @@ JL_CALLABLE(jl_f_apply)
285288
JL_TYPECHK(apply, tuple, args[i]);
286289
}
287290
}
288-
goto fancy_apply;
291+
argarr = jl_apply(jl_append_any_func, &args[1], nargs-1);
292+
assert(jl_typeis(argarr, jl_array_any_type));
293+
result = jl_apply((jl_function_t*)args[0], jl_cell_data(argarr), jl_array_len(argarr));
294+
JL_GC_POP();
295+
return result;
289296
}
290297
}
291-
newargs = (jl_value_t**)alloca(n * sizeof(jl_value_t*));
298+
if (n > 64000) {
299+
// put arguments on the heap if there are too many
300+
argarr = (jl_value_t*)jl_alloc_cell_1d(n);
301+
newargs = jl_cell_data(argarr);
302+
}
303+
else {
304+
newargs = (jl_value_t**)alloca(n * sizeof(jl_value_t*));
305+
}
292306
n = 0;
293307
for(i=1; i < nargs; i++) {
294308
if (jl_is_tuple(args[i])) {
295309
jl_tuple_t *t = (jl_tuple_t*)args[i];
296-
for(j=0; j < jl_tuple_len(t); j++)
310+
size_t al = jl_tuple_len(t);
311+
for(j=0; j < al; j++)
297312
newargs[n++] = jl_tupleref(t, j);
298313
}
299314
else {
@@ -302,14 +317,7 @@ JL_CALLABLE(jl_f_apply)
302317
newargs[n++] = jl_cellref(args[i], j);
303318
}
304319
}
305-
return jl_apply((jl_function_t*)args[0], newargs, n);
306-
307-
fancy_apply: ;
308-
jl_value_t *argarr = jl_apply(jl_append_any_func, &args[1], nargs-1);
309-
JL_GC_PUSH1(&argarr);
310-
assert(jl_typeis(argarr, jl_array_any_type));
311-
jl_value_t *result = jl_apply((jl_function_t*)args[0],
312-
jl_cell_data(argarr), jl_array_len(argarr));
320+
result = jl_apply((jl_function_t*)args[0], newargs, n);
313321
JL_GC_POP();
314322
return result;
315323
}

0 commit comments

Comments
 (0)