mruby-compiler: simplify mrb_ast_array_node from flat array to cons list

Replace complex flat array packing with simple cons-list storage to reduce
memory overhead and code complexity. This continues the compiler simplification
work by reverting array nodes to the original memory-efficient approach.

- Remove len/flags fields from mrb_ast_array_node structure
- Eliminate complex two-pass processing (count + copy) in new_array()
- Replace array indexing with cons-list iteration in gen_array_var()
- Reduce parser code from 30+ lines to 4 lines for array creation
- Maintain full functionality with zero test regressions

Following the same successful pattern used for mrb_ast_case_node upgrade,
this change proves that flat array packing provides no memory benefit
since cons lists aren't recycled, while adding unnecessary complexity.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-09-21 15:53:21 +09:00
parent 4a04f7d4eb
commit f50936e8bd
4 changed files with 1674 additions and 1724 deletions
+8 -7
View File
@@ -3707,16 +3707,14 @@ static void
gen_array_var(codegen_scope *s, node *varnode, int val)
{
struct mrb_ast_array_node *array = array_node(varnode);
int len = ARRAY_NODE_LEN(array);
struct mrb_ast_node **elements = ARRAY_NODE_ELEMENTS(array);
int i;
node *elements = ARRAY_NODE_ELEMENTS(array);
int regular_elements = 0;
int first = 1;
int slimit = GEN_VAL_STACK_MAX;
if (!val) return;
if (len == 0) {
if (!elements) {
genop_2(s, OP_ARRAY, cursp(), 0);
push();
return;
@@ -3724,9 +3722,10 @@ gen_array_var(codegen_scope *s, node *varnode, int val)
if (cursp() >= GEN_LIT_ARY_MAX) slimit = INT16_MAX;
/* Process each element, handling splats */
for (i = 0; i < len; i++) {
struct mrb_ast_node *element = elements[i];
/* Process each element using cons-list iteration, handling splats */
node *current = elements;
while (current) {
struct mrb_ast_node *element = current->car;
int is_splat = is_splat_node(element);
if (is_splat || cursp() >= slimit) { /* flush accumulated elements */
@@ -3764,6 +3763,8 @@ gen_array_var(codegen_scope *s, node *varnode, int val)
else {
regular_elements++;
}
current = current->cdr;
}
/* Handle any remaining regular elements */
+3 -6
View File
@@ -219,12 +219,10 @@ struct mrb_ast_call_node {
struct mrb_ast_node *args; /* Arguments Information */
};
/* Variable-sized array node with inline element storage */
/* Variable-sized array node - revert to original cons list approach */
struct mrb_ast_array_node {
struct mrb_ast_var_header header; /* 8 bytes */
uint16_t len; /* Number of elements */
uint16_t flags; /* Array-specific flags */
struct mrb_ast_node *elements[]; /* Flexible array for elements */
struct mrb_ast_var_header header; /* 8 bytes */
struct mrb_ast_node *elements; /* Original elements list */
};
/* Variable-sized hash node with inline key-value storage */
@@ -447,7 +445,6 @@ struct mrb_ast_super_node {
#define CALL_NODE_HAS_BLOCK(n) (call_node(n)->has_block)
#define CALL_NODE_SAFE(n) (call_node(n)->safe_call)
#define ARRAY_NODE_LEN(n) (array_node(n)->len)
#define ARRAY_NODE_ELEMENTS(n) (array_node(n)->elements)
#define HASH_NODE_LEN(n) (hash_node(n)->len)
+3 -27
View File
@@ -989,34 +989,10 @@ new_or(parser_state *p, node *a, node *b)
static node*
new_array(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;
}
struct mrb_ast_array_node *n = (struct mrb_ast_array_node*)parser_alloc_var(p, sizeof(struct mrb_ast_array_node), SIZE_CLASS_MEDIUM);
/* 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 size_class = size_to_class(total_size);
struct mrb_ast_array_node *n = (struct mrb_ast_array_node*)
parser_alloc_var(p, total_size, size_class);
init_var_header(&n->header, p, NODE_ARRAY, size_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;
}
init_var_header(&n->header, p, NODE_ARRAY, SIZE_CLASS_MEDIUM);
n->elements = a;
return cons_head((node*)NODE_VARIABLE, (node*)n);
}
File diff suppressed because it is too large Load Diff