GitHub

@@ -2640,6 +2640,43 @@ gen_values(codegen_scope *s, node *t, int val, int limit)

26402640

while (t) {

26412641

int is_splat = is_splat_node(t->car);

264226422643+

/* Optimization: skip or inline literal splat arrays

2644+

* - Empty splat (`*[]`/`*zarray`): contributes nothing; skip.

2645+

* - Non-empty literal array with no inner splat (`*[a,b]`): inline

2646+

* as normal positional args to avoid building/concatenating arrays.

2647+

*/

2648+

if (is_splat) {

2649+

node *sv = SPLAT_NODE_VALUE(t->car);

2650+

if (sv) {

2651+

enum node_type nt = get_node_type(sv);

2652+

if (nt == NODE_ARRAY) {

2653+

struct mrb_ast_array_node *an = array_node(sv);

2654+

if (ARRAY_NODE_ELEMENTS(an) == NULL) {

2655+

/* empty splat; contributes nothing */

2656+

t = t->cdr;

2657+

continue;

2658+

}

2659+

else if (nosplat(ARRAY_NODE_ELEMENTS(an))) {

2660+

/* Inline non-empty literal array elements as regular args */

2661+

node *e = ARRAY_NODE_ELEMENTS(an);

2662+

while (e) {

2663+

/* Honor evaluation order */

2664+

codegen(s, e->car, val);

2665+

n++;

2666+

e = e->cdr;

2667+

}

2668+

t = t->cdr;

2669+

continue;

2670+

}

2671+

}

2672+

else if (nt == NODE_ZARRAY) {

2673+

/* explicit empty array literal */

2674+

t = t->cdr;

2675+

continue;

2676+

}

2677+

}

2678+

}

2679+26432680

if (is_splat || cursp() >= slimit) { /* flush stack */

26442681

pop_n(n);

26452682

if (first) {

@@ -3630,6 +3667,25 @@ codegen_array(codegen_scope *s, node *varnode, int val)

36303667

struct mrb_ast_node *element = current->car;

36313668

int is_splat = is_splat_node(element);

363236693670+

/* Skip splat of an empty literal array: [*[]] => [] without ARYCAT noise */

3671+

if (is_splat) {

3672+

node *sv = SPLAT_NODE_VALUE(element);

3673+

if (sv) {

3674+

enum node_type nt = get_node_type(sv);

3675+

if (nt == NODE_ARRAY) {

3676+

struct mrb_ast_array_node *an = array_node(sv);

3677+

if (ARRAY_NODE_ELEMENTS(an) == NULL) {

3678+

current = current->cdr;

3679+

continue;

3680+

}

3681+

}

3682+

else if (nt == NODE_ZARRAY) {

3683+

current = current->cdr;

3684+

continue;

3685+

}

3686+

}

3687+

}

3688+36333689

if (is_splat || cursp() >= slimit) { /* flush accumulated elements */

36343690

if (regular_elements > 0) {

36353691

pop_n(regular_elements);

Read the original on github.com ↗