From 62cf0dc17a5851a7100de7e662925698c12b6484 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 12 Mar 2026 12:12:25 +0900 Subject: [PATCH] codegen.c: chunk %w() and %i() literals to reduce register pressure Apply the same chunking strategy used for regular array literals to %w() and %i() literal arrays in gen_literal_array(). Fixes #6740. Co-authored-by: Claude --- mrbgems/mruby-compiler/core/codegen.c | 32 +++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) 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); }