diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index fa6eb16f3..1b804a4f6 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -3175,8 +3175,12 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) { if (val) { int array_size = 0; + int first = 1; + int slimit = GEN_LIT_ARY_MAX; node *current = tree; + if (cursp() >= slimit) slimit = GEN_VAL_STACK_MAX; + /* Process each segment separated by NODE_LITERAL_DELIM */ while (current) { /* Find the segment boundaries without allocating */ @@ -3213,6 +3217,24 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) /* Only process non-empty segments */ if (!is_empty_segment) { + /* Flush accumulated elements when stack is full */ + if (cursp() >= slimit) { + if (array_size > 0) { + pop_n(array_size); + if (first) { + genop_2(s, OP_ARRAY, cursp(), array_size); + push(); + first = 0; + } + else { + pop(); + genop_2(s, OP_ARYPUSH, cursp(), array_size); + push(); + } + array_size = 0; + } + } + /* Temporarily terminate the segment by saving and clearing the cdr */ node *saved_cdr = NULL; if (segment_prev) { @@ -3243,8 +3265,14 @@ gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) } } - /* Generate the array from pushed elements */ - if (array_size > 0) { + /* Handle remaining elements */ + if (!first) { + if (array_size > 0) { + pop_n(array_size + 1); + genop_2(s, OP_ARYPUSH, cursp(), array_size); + } + } + else if (array_size > 0) { pop_n(array_size); genop_2(s, OP_ARRAY, cursp(), array_size); }