Skip to content

Commit da89f7f

Browse files
committed
Prefer ALLOCV over ALLOCA for unknown size
`ALLOCA` with too large size may result in stack overflow. Incidentally, this suppresses the GCC false maybe-uninitialized warning in `product_each`. Also shrink `struct product_state` when `sizeof(int) < sizeof(VALUE)`.
1 parent 26088dc commit da89f7f

File tree

1 file changed

+11
-3
lines changed

1 file changed

+11
-3
lines changed

enumerator.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3581,9 +3581,9 @@ enum_product_enum_size(VALUE obj, VALUE args, VALUE eobj)
35813581
struct product_state {
35823582
VALUE obj;
35833583
VALUE block;
3584+
int index;
35843585
int argc;
35853586
VALUE *argv;
3586-
int index;
35873587
};
35883588

35893589
static VALUE product_each(VALUE, struct product_state *);
@@ -3622,15 +3622,23 @@ enum_product_run(VALUE obj, VALUE block)
36223622
{
36233623
struct enum_product *ptr = enum_product_ptr(obj);
36243624
int argc = RARRAY_LENINT(ptr->enums);
3625+
if (argc == 0) { /* no need to allocate state.argv */
3626+
rb_funcall(block, id_call, 1, rb_ary_new());
3627+
return obj;
3628+
}
3629+
3630+
VALUE argsbuf = 0;
36253631
struct product_state state = {
36263632
.obj = obj,
36273633
.block = block,
36283634
.index = 0,
36293635
.argc = argc,
3630-
.argv = ALLOCA_N(VALUE, argc),
3636+
.argv = ALLOCV_N(VALUE, argsbuf, argc),
36313637
};
36323638

3633-
return product_each(obj, &state);
3639+
VALUE ret = product_each(obj, &state);
3640+
ALLOCV_END(argsbuf);
3641+
return ret;
36343642
}
36353643

36363644
/*

0 commit comments

Comments
 (0)