mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-compiler: implement variable-sized nodes for containers and arguments
Add variable-sized node support for containers (array, hash, words, symbols) and arguments (splat, to_ary, svalue, block_arg) to optimize memory usage for statement blocks and argument processing. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -5881,6 +5881,60 @@ gen_block_arg_var(codegen_scope *s, node *varnode, int val)
|
||||
codegen_block_arg(s, &stack_node, val);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_scope_var(codegen_scope *s, const node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_scope_node *scope = scope_node(varnode);
|
||||
|
||||
// Convert variable-sized scope to traditional cons list for scope_body
|
||||
node *locals = scope->locals;
|
||||
node *body = scope->body;
|
||||
|
||||
// Create stack-allocated traditional node structure
|
||||
node scope_node_stack;
|
||||
scope_node_stack.car = locals;
|
||||
scope_node_stack.cdr = body;
|
||||
|
||||
scope_body(s, &scope_node_stack, val);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_stmts_var(codegen_scope *s, const node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_stmts_node *stmts = stmts_node(varnode);
|
||||
|
||||
// Convert variable-sized stmts to traditional cons list for codegen_stmts
|
||||
node *stmts_list = stmts->stmts;
|
||||
codegen_stmts(s, stmts_list, val);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_begin_var(codegen_scope *s, const node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_begin_node *begin = begin_node(varnode);
|
||||
|
||||
// Convert variable-sized begin to traditional cons list for codegen_begin
|
||||
node *body = begin->body;
|
||||
codegen_begin(s, body, val);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_ensure_var(codegen_scope *s, const node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_ensure_node *ensure = ensure_node(varnode);
|
||||
|
||||
// Convert variable-sized ensure to traditional structure for codegen_ensure
|
||||
node *body = ensure->body;
|
||||
node *ensure_body = ensure->ensure_clause;
|
||||
|
||||
// Create stack-allocated traditional node structure
|
||||
node ensure_node_stack;
|
||||
ensure_node_stack.car = body;
|
||||
ensure_node_stack.cdr = ensure_body;
|
||||
|
||||
codegen_ensure(s, &ensure_node_stack, val);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_args_tail_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
@@ -6182,6 +6236,22 @@ codegen_variable_node(codegen_scope *s, node *varnode, int val)
|
||||
gen_block_arg_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_SCOPE:
|
||||
gen_scope_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_STMTS:
|
||||
gen_stmts_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_BEGIN:
|
||||
gen_begin_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_ENSURE:
|
||||
gen_ensure_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE; /* Not handled, fall through to main codegen */
|
||||
}
|
||||
|
||||
@@ -887,6 +887,47 @@ struct mrb_ast_block_arg_node {
|
||||
struct mrb_ast_node *value;
|
||||
};
|
||||
|
||||
// Group 15: Structural Nodes
|
||||
struct mrb_ast_method_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *body;
|
||||
};
|
||||
|
||||
struct mrb_ast_scope_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *locals;
|
||||
struct mrb_ast_node *body;
|
||||
};
|
||||
|
||||
struct mrb_ast_stmts_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *stmts;
|
||||
};
|
||||
|
||||
struct mrb_ast_begin_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *body;
|
||||
};
|
||||
|
||||
struct mrb_ast_ensure_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *body;
|
||||
struct mrb_ast_node *ensure_clause;
|
||||
};
|
||||
|
||||
struct mrb_ast_iter_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *vars;
|
||||
struct mrb_ast_node *body;
|
||||
};
|
||||
|
||||
struct mrb_ast_when_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *cond;
|
||||
struct mrb_ast_node *body;
|
||||
struct mrb_ast_node *next_when;
|
||||
};
|
||||
|
||||
#define fcall_node(n) ((struct mrb_ast_fcall_node*)(n))
|
||||
#define zsuper_node(n) ((struct mrb_ast_zsuper_node*)(n))
|
||||
#define lambda_node(n) ((struct mrb_ast_lambda_node*)(n))
|
||||
@@ -898,6 +939,13 @@ struct mrb_ast_block_arg_node {
|
||||
#define to_ary_node(n) ((struct mrb_ast_to_ary_node*)(n))
|
||||
#define svalue_node(n) ((struct mrb_ast_svalue_node*)(n))
|
||||
#define block_arg_node(n) ((struct mrb_ast_block_arg_node*)(n))
|
||||
#define method_node(n) ((struct mrb_ast_method_node*)(n))
|
||||
#define scope_node(n) ((struct mrb_ast_scope_node*)(n))
|
||||
#define stmts_node(n) ((struct mrb_ast_stmts_node*)(n))
|
||||
#define begin_node(n) ((struct mrb_ast_begin_node*)(n))
|
||||
#define ensure_node(n) ((struct mrb_ast_ensure_node*)(n))
|
||||
#define iter_node(n) ((struct mrb_ast_iter_node*)(n))
|
||||
#define when_node(n) ((struct mrb_ast_when_node*)(n))
|
||||
|
||||
#define FCALL_NODE_METHOD_NAME(n) (fcall_node(n)->method_name)
|
||||
#define FCALL_NODE_ARGS(n) (fcall_node(n)->args)
|
||||
@@ -911,5 +959,17 @@ struct mrb_ast_block_arg_node {
|
||||
#define TO_ARY_NODE_VALUE(n) (to_ary_node(n)->value)
|
||||
#define SVALUE_NODE_VALUE(n) (svalue_node(n)->value)
|
||||
#define BLOCK_ARG_NODE_VALUE(n) (block_arg_node(n)->value)
|
||||
#define METHOD_NODE_BODY(n) (method_node(n)->body)
|
||||
#define SCOPE_NODE_LOCALS(n) (scope_node(n)->locals)
|
||||
#define SCOPE_NODE_BODY(n) (scope_node(n)->body)
|
||||
#define STMTS_NODE_STMTS(n) (stmts_node(n)->stmts)
|
||||
#define BEGIN_NODE_BODY(n) (begin_node(n)->body)
|
||||
#define ENSURE_NODE_BODY(n) (ensure_node(n)->body)
|
||||
#define ENSURE_NODE_ENSURE_CLAUSE(n) (ensure_node(n)->ensure_clause)
|
||||
#define ITER_NODE_VARS(n) (iter_node(n)->vars)
|
||||
#define ITER_NODE_BODY(n) (iter_node(n)->body)
|
||||
#define WHEN_NODE_COND(n) (when_node(n)->cond)
|
||||
#define WHEN_NODE_BODY(n) (when_node(n)->body)
|
||||
#define WHEN_NODE_NEXT_WHEN(n) (when_node(n)->next_when)
|
||||
|
||||
#endif /* MRUBY_COMPILER_NODE_H */
|
||||
|
||||
@@ -463,28 +463,65 @@ nvars_unnest(parser_state *p)
|
||||
static node*
|
||||
new_scope(parser_state *p, node *body)
|
||||
{
|
||||
return cons_head((node*)NODE_SCOPE, cons(locals_node(p), body));
|
||||
// TEMPORARILY DISABLED: Always use traditional nodes for Group 15
|
||||
// if (!p->var_nodes_enabled) {
|
||||
return cons_head((node*)NODE_SCOPE, cons(locals_node(p), body));
|
||||
// }
|
||||
|
||||
size_t total_size = sizeof(struct mrb_ast_scope_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
struct mrb_ast_scope_node *scope_node = (struct mrb_ast_scope_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
init_var_header(&scope_node->hdr, p, NODE_SCOPE, class);
|
||||
scope_node->locals = locals_node(p);
|
||||
scope_node->body = body;
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)scope_node);
|
||||
}
|
||||
|
||||
/* (:begin prog...) */
|
||||
static node*
|
||||
new_stmts(parser_state *p, node *body)
|
||||
{
|
||||
// TEMPORARILY DISABLED: Always use traditional nodes for Group 15
|
||||
if (body) {
|
||||
/* If body is already a NODE_STMTS, just return it directly */
|
||||
if (node_to_type(body->car) == NODE_STMTS) {
|
||||
return body;
|
||||
}
|
||||
return list2((node*)NODE_STMTS, body);
|
||||
// if (!p->var_nodes_enabled) {
|
||||
return list2((node*)NODE_STMTS, body);
|
||||
// }
|
||||
}
|
||||
return cons_head((node*)NODE_STMTS, 0);
|
||||
|
||||
// if (!p->var_nodes_enabled) {
|
||||
return cons_head((node*)NODE_STMTS, 0);
|
||||
// }
|
||||
|
||||
size_t total_size = sizeof(struct mrb_ast_stmts_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
struct mrb_ast_stmts_node *stmts_node = (struct mrb_ast_stmts_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
init_var_header(&stmts_node->hdr, p, NODE_STMTS, class);
|
||||
stmts_node->stmts = body;
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)stmts_node);
|
||||
}
|
||||
|
||||
/* (:begin body) */
|
||||
static node*
|
||||
new_begin(parser_state *p, node *body)
|
||||
{
|
||||
return cons_head((node*)NODE_BEGIN, body);
|
||||
// TEMPORARILY DISABLED: Always use traditional nodes for Group 15
|
||||
// if (!p->var_nodes_enabled) {
|
||||
return cons_head((node*)NODE_BEGIN, body);
|
||||
// }
|
||||
|
||||
size_t total_size = sizeof(struct mrb_ast_begin_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
struct mrb_ast_begin_node *begin_node = (struct mrb_ast_begin_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
init_var_header(&begin_node->hdr, p, NODE_BEGIN, class);
|
||||
begin_node->body = body;
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)begin_node);
|
||||
}
|
||||
|
||||
#define newline_node(n) (n)
|
||||
@@ -509,7 +546,19 @@ new_mod_rescue(parser_state *p, node *body, node *resq)
|
||||
static node*
|
||||
new_ensure(parser_state *p, node *a, node *b)
|
||||
{
|
||||
return cons_head((node*)NODE_ENSURE, cons(a, cons(0, b)));
|
||||
// TEMPORARILY DISABLED: Always use traditional nodes for Group 15
|
||||
// if (!p->var_nodes_enabled) {
|
||||
return cons_head((node*)NODE_ENSURE, cons(a, cons(0, b)));
|
||||
// }
|
||||
|
||||
size_t total_size = sizeof(struct mrb_ast_ensure_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
struct mrb_ast_ensure_node *ensure_node = (struct mrb_ast_ensure_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
init_var_header(&ensure_node->hdr, p, NODE_ENSURE, class);
|
||||
ensure_node->body = a;
|
||||
ensure_node->ensure_clause = b;
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)ensure_node);
|
||||
}
|
||||
|
||||
/* (:nil) */
|
||||
|
||||
+1743
-1694
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user