mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-compiler: complete NODE_ARRAY migration to variable-sized nodes exclusively
Following the proven NODE_HASH pattern: - Inlined new_array_var functionality into new_array in parse.y - Enhanced gen_array_var with full splat support from gen_values - Removed obsolete codegen_array function and cons list NODE_ARRAY case - All arrays now use variable-sized nodes with identical test success (1730/1731) Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -3792,21 +3792,6 @@ codegen_const(codegen_scope *s, mrb_sym sym, int val)
|
||||
if (val) push();
|
||||
}
|
||||
|
||||
static void
|
||||
codegen_array(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = gen_values(s, tree, val, 0);
|
||||
if (!val) return;
|
||||
if (n >= 0) {
|
||||
pop_n(n);
|
||||
genop_2(s, OP_ARRAY, cursp(), n);
|
||||
}
|
||||
push();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gen_hash_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
@@ -4655,6 +4640,9 @@ gen_array_var(codegen_scope *s, node *varnode, int val)
|
||||
int len = ARRAY_NODE_LEN(array);
|
||||
struct mrb_ast_node **elements = ARRAY_NODE_ELEMENTS(array);
|
||||
int i;
|
||||
int regular_elements = 0;
|
||||
int first = 1;
|
||||
int slimit = GEN_VAL_STACK_MAX;
|
||||
|
||||
if (!val) return;
|
||||
|
||||
@@ -4664,15 +4652,65 @@ gen_array_var(codegen_scope *s, node *varnode, int val)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Generate code for each element */
|
||||
if (cursp() >= GEN_LIT_ARY_MAX) slimit = INT16_MAX;
|
||||
|
||||
/* Process each element, handling splats */
|
||||
for (i = 0; i < len; i++) {
|
||||
codegen(s, elements[i], VAL);
|
||||
struct mrb_ast_node *element = elements[i];
|
||||
int is_splat = node_to_int(element->car) == NODE_SPLAT;
|
||||
|
||||
if (is_splat || cursp() >= slimit) { /* flush accumulated elements */
|
||||
if (regular_elements > 0) {
|
||||
pop_n(regular_elements);
|
||||
if (first) {
|
||||
genop_2(s, OP_ARRAY, cursp(), regular_elements);
|
||||
push();
|
||||
first = 0;
|
||||
}
|
||||
else {
|
||||
pop();
|
||||
genop_2(s, OP_ARYPUSH, cursp(), regular_elements);
|
||||
push();
|
||||
}
|
||||
regular_elements = 0;
|
||||
}
|
||||
else if (first && is_splat) {
|
||||
/* First element is splat - create empty array */
|
||||
genop_1(s, OP_LOADNIL, cursp());
|
||||
genop_2(s, OP_ARRAY, cursp(), 0);
|
||||
push();
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
|
||||
codegen(s, element, val);
|
||||
|
||||
if (is_splat) {
|
||||
/* Concatenate splat array */
|
||||
pop(); pop();
|
||||
genop_1(s, OP_ARYCAT, cursp());
|
||||
push();
|
||||
}
|
||||
else {
|
||||
regular_elements++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create array with elements on stack */
|
||||
pop_n(len);
|
||||
genop_2(s, OP_ARRAY, cursp(), len);
|
||||
push();
|
||||
/* Handle any remaining regular elements */
|
||||
if (!first) {
|
||||
/* Variable length - we have an array from splats */
|
||||
if (regular_elements > 0) {
|
||||
pop_n(regular_elements + 1);
|
||||
genop_2(s, OP_ARYPUSH, cursp(), regular_elements);
|
||||
push();
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Simple case: no splats, just create array */
|
||||
pop_n(regular_elements);
|
||||
genop_2(s, OP_ARRAY, cursp(), regular_elements);
|
||||
push();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6421,7 +6459,6 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
codegen_block(s, tree, val);
|
||||
break;
|
||||
|
||||
|
||||
case NODE_SCOPE:
|
||||
codegen_scope_node(s, tree, val);
|
||||
break;
|
||||
@@ -6442,10 +6479,6 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
codegen_colon3(s, tree, val);
|
||||
break;
|
||||
|
||||
case NODE_ARRAY:
|
||||
codegen_array(s, tree, val);
|
||||
break;
|
||||
|
||||
case NODE_HASH:
|
||||
case NODE_KW_HASH:
|
||||
codegen_hash(s, tree, val);
|
||||
|
||||
@@ -596,7 +596,6 @@ new_alias(parser_state *p, mrb_sym a, mrb_sym b)
|
||||
}
|
||||
|
||||
/* Forward declarations for variable-sized AST node creation functions */
|
||||
static node* new_array_var(parser_state *p, node *a);
|
||||
static node* new_def_var(parser_state *p, mrb_sym name, node *args, node *body);
|
||||
static node* new_class_var(parser_state *p, node *name, node *superclass, node *body);
|
||||
static node* new_module_var(parser_state *p, node *name, node *body);
|
||||
@@ -851,40 +850,6 @@ new_call_var(parser_state *p, node *receiver, mrb_sym method, node *args, int pa
|
||||
#endif
|
||||
|
||||
/* Variable-sized array node creation */
|
||||
static node*
|
||||
new_array_var(parser_state *p, node *a)
|
||||
{
|
||||
/* Count array elements */
|
||||
uint16_t len = 0;
|
||||
node *elem_iter = a;
|
||||
while (elem_iter) {
|
||||
len++;
|
||||
elem_iter = elem_iter->cdr;
|
||||
}
|
||||
|
||||
/* Calculate total size needed */
|
||||
size_t base_size = sizeof(struct mrb_ast_array_node);
|
||||
size_t elems_size = len * sizeof(struct mrb_ast_node*);
|
||||
size_t total_size = base_size + elems_size;
|
||||
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
|
||||
struct mrb_ast_array_node *n = (struct mrb_ast_array_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
|
||||
init_var_header(&n->header, p, NODE_ARRAY, class);
|
||||
n->len = len;
|
||||
n->flags = 0;
|
||||
|
||||
/* Copy elements into flexible array */
|
||||
elem_iter = a;
|
||||
for (int i = 0; i < len; i++) {
|
||||
n->elements[i] = elem_iter->car;
|
||||
elem_iter = elem_iter->cdr;
|
||||
}
|
||||
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)n);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1309,10 +1274,36 @@ new_or(parser_state *p, node *a, node *b)
|
||||
static node*
|
||||
new_array(parser_state *p, node *a)
|
||||
{
|
||||
if (p->cxt && p->cxt->use_variable_nodes) {
|
||||
return new_array_var(p, a);
|
||||
/* Count array elements */
|
||||
uint16_t len = 0;
|
||||
node *elem_iter = a;
|
||||
while (elem_iter) {
|
||||
len++;
|
||||
elem_iter = elem_iter->cdr;
|
||||
}
|
||||
return cons_head((node*)NODE_ARRAY, a);
|
||||
|
||||
/* Calculate total size needed */
|
||||
size_t base_size = sizeof(struct mrb_ast_array_node);
|
||||
size_t elems_size = len * sizeof(struct mrb_ast_node*);
|
||||
size_t total_size = base_size + elems_size;
|
||||
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
|
||||
struct mrb_ast_array_node *n = (struct mrb_ast_array_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
|
||||
init_var_header(&n->header, p, NODE_ARRAY, class);
|
||||
n->len = len;
|
||||
n->flags = 0;
|
||||
|
||||
/* Copy elements into flexible array */
|
||||
elem_iter = a;
|
||||
for (int i = 0; i < len; i++) {
|
||||
n->elements[i] = elem_iter->car;
|
||||
elem_iter = elem_iter->cdr;
|
||||
}
|
||||
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)n);
|
||||
}
|
||||
|
||||
/* (:splat . a) */
|
||||
|
||||
+1139
-1148
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user