mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
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:
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+1660
-1684
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user