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:
Yukihiro "Matz" Matsumoto
2025-08-28 14:47:57 +09:00
parent da8072e00a
commit 47253a0fe4
4 changed files with 1875 additions and 1641 deletions
+77
View File
@@ -5825,6 +5825,62 @@ gen_lambda_var(codegen_scope *s, node *varnode, int val)
codegen_lambda(s, &stack_nodes[0], val);
}
static void
gen_kw_hash_var(codegen_scope *s, node *varnode, int val)
{
struct mrb_ast_kw_hash_node *n = kw_hash_node(varnode);
// Create stack-allocated node structure for traditional codegen
struct mrb_ast_node stack_node;
stack_node.car = (node*)NODE_KW_HASH;
stack_node.cdr = n->args;
codegen_hash(s, &stack_node, val);
}
static void
gen_words_var(codegen_scope *s, node *varnode, int val)
{
struct mrb_ast_words_node *n = words_node(varnode);
// Create stack-allocated node structure for traditional codegen
struct mrb_ast_node stack_node;
stack_node.car = (node*)NODE_WORDS;
stack_node.cdr = n->args;
codegen_words(s, &stack_node, val);
}
static void
gen_symbols_var(codegen_scope *s, node *varnode, int val)
{
struct mrb_ast_symbols_node *n = symbols_node(varnode);
// Create stack-allocated node structure for traditional codegen
struct mrb_ast_node stack_node;
stack_node.car = (node*)NODE_SYMBOLS;
stack_node.cdr = n->args;
codegen_symbols(s, &stack_node, val);
}
static void
gen_splat_var(codegen_scope *s, node *varnode, int val)
{
struct mrb_ast_splat_node *n = splat_node(varnode);
// Create stack-allocated node structure for traditional codegen
struct mrb_ast_node stack_node;
stack_node.car = (node*)NODE_SPLAT;
stack_node.cdr = n->value;
codegen_splat(s, &stack_node, val);
}
static void
gen_block_arg_var(codegen_scope *s, node *varnode, int val)
{
struct mrb_ast_block_arg_node *n = block_arg_node(varnode);
// Create stack-allocated node structure for traditional codegen
struct mrb_ast_node stack_node;
stack_node.car = (node*)NODE_BLOCK_ARG;
stack_node.cdr = n->value;
codegen_block_arg(s, &stack_node, val);
}
static void
gen_args_tail_var(codegen_scope *s, node *varnode, int val)
{
@@ -6105,6 +6161,27 @@ codegen_variable_node(codegen_scope *s, node *varnode, int val)
gen_lambda_var(s, varnode, val);
return TRUE;
case NODE_KW_HASH:
gen_kw_hash_var(s, varnode, val);
return TRUE;
case NODE_WORDS:
gen_words_var(s, varnode, val);
return TRUE;
case NODE_SYMBOLS:
gen_symbols_var(s, varnode, val);
return TRUE;
case NODE_SPLAT:
gen_splat_var(s, varnode, val);
return TRUE;
case NODE_BLOCK_ARG:
gen_block_arg_var(s, varnode, val);
return TRUE;
default:
return FALSE; /* Not handled, fall through to main codegen */
}
+57
View File
@@ -845,14 +845,71 @@ struct mrb_ast_lambda_node {
struct mrb_ast_node *body;
};
// Group 13: Containers and Collections
struct mrb_ast_zarray_node {
struct mrb_ast_var_header hdr;
};
struct mrb_ast_kw_hash_node {
struct mrb_ast_var_header hdr;
struct mrb_ast_node *args;
};
struct mrb_ast_words_node {
struct mrb_ast_var_header hdr;
struct mrb_ast_node *args;
};
struct mrb_ast_symbols_node {
struct mrb_ast_var_header hdr;
struct mrb_ast_node *args;
};
// Group 14: Arguments and Parameters
struct mrb_ast_splat_node {
struct mrb_ast_var_header hdr;
struct mrb_ast_node *value;
};
struct mrb_ast_to_ary_node {
struct mrb_ast_var_header hdr;
struct mrb_ast_node *value;
};
struct mrb_ast_svalue_node {
struct mrb_ast_var_header hdr;
struct mrb_ast_node *value;
};
struct mrb_ast_block_arg_node {
struct mrb_ast_var_header hdr;
struct mrb_ast_node *value;
};
#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))
#define zarray_node(n) ((struct mrb_ast_zarray_node*)(n))
#define kw_hash_node(n) ((struct mrb_ast_kw_hash_node*)(n))
#define words_node(n) ((struct mrb_ast_words_node*)(n))
#define symbols_node(n) ((struct mrb_ast_symbols_node*)(n))
#define splat_node(n) ((struct mrb_ast_splat_node*)(n))
#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 FCALL_NODE_METHOD_NAME(n) (fcall_node(n)->method_name)
#define FCALL_NODE_ARGS(n) (fcall_node(n)->args)
#define LAMBDA_NODE_LOCALS(n) (lambda_node(n)->locals)
#define LAMBDA_NODE_ARGS(n) (lambda_node(n)->args)
#define LAMBDA_NODE_BODY(n) (lambda_node(n)->body)
#define KW_HASH_NODE_ARGS(n) (kw_hash_node(n)->args)
#define WORDS_NODE_ARGS(n) (words_node(n)->args)
#define SYMBOLS_NODE_ARGS(n) (symbols_node(n)->args)
#define SPLAT_NODE_VALUE(n) (splat_node(n)->value)
#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)
#endif /* MRUBY_COMPILER_NODE_H */
+55 -5
View File
@@ -1623,7 +1623,17 @@ static node*
new_splat(parser_state *p, node *a)
{
void_expr_error(p, a);
return cons_head((node*)NODE_SPLAT, a);
if (!p->var_nodes_enabled) {
return cons_head((node*)NODE_SPLAT, a);
}
size_t total_size = sizeof(struct mrb_ast_splat_node);
enum mrb_ast_size_class class = size_to_class(total_size);
struct mrb_ast_splat_node *splat_node = (struct mrb_ast_splat_node*)
parser_alloc_var(p, total_size, class);
init_var_header(&splat_node->hdr, p, NODE_SPLAT, class);
splat_node->value = a;
return cons_head((node*)NODE_VARIABLE, (node*)splat_node);
}
/* (:hash (k . v) (k . v)...) */
@@ -1640,7 +1650,17 @@ new_hash(parser_state *p, node *a)
static node*
new_kw_hash(parser_state *p, node *a)
{
return cons_head((node*)NODE_KW_HASH, a);
if (!p->var_nodes_enabled) {
return cons_head((node*)NODE_KW_HASH, a);
}
size_t total_size = sizeof(struct mrb_ast_kw_hash_node);
enum mrb_ast_size_class class = size_to_class(total_size);
struct mrb_ast_kw_hash_node *kw_hash_node = (struct mrb_ast_kw_hash_node*)
parser_alloc_var(p, total_size, class);
init_var_header(&kw_hash_node->hdr, p, NODE_KW_HASH, class);
kw_hash_node->args = a;
return cons_head((node*)NODE_VARIABLE, (node*)kw_hash_node);
}
/* (:sym . a) */
@@ -1994,7 +2014,17 @@ new_args_dots(parser_state *p, node *m)
static node*
new_block_arg(parser_state *p, node *a)
{
return cons_head((node*)NODE_BLOCK_ARG, a);
if (!p->var_nodes_enabled) {
return cons_head((node*)NODE_BLOCK_ARG, a);
}
size_t total_size = sizeof(struct mrb_ast_block_arg_node);
enum mrb_ast_size_class class = size_to_class(total_size);
struct mrb_ast_block_arg_node *block_arg_node = (struct mrb_ast_block_arg_node*)
parser_alloc_var(p, total_size, class);
init_var_header(&block_arg_node->hdr, p, NODE_BLOCK_ARG, class);
block_arg_node->value = a;
return cons_head((node*)NODE_VARIABLE, (node*)block_arg_node);
}
static node*
@@ -2469,14 +2499,34 @@ new_literal_delim(parser_state *p)
static node*
new_words(parser_state *p, node *a)
{
return cons_head((node*)NODE_WORDS, a);
if (!p->var_nodes_enabled) {
return cons_head((node*)NODE_WORDS, a);
}
size_t total_size = sizeof(struct mrb_ast_words_node);
enum mrb_ast_size_class class = size_to_class(total_size);
struct mrb_ast_words_node *words_node = (struct mrb_ast_words_node*)
parser_alloc_var(p, total_size, class);
init_var_header(&words_node->hdr, p, NODE_WORDS, class);
words_node->args = a;
return cons_head((node*)NODE_VARIABLE, (node*)words_node);
}
/* (:symbols . a) */
static node*
new_symbols(parser_state *p, node *a)
{
return cons_head((node*)NODE_SYMBOLS, a);
if (!p->var_nodes_enabled) {
return cons_head((node*)NODE_SYMBOLS, a);
}
size_t total_size = sizeof(struct mrb_ast_symbols_node);
enum mrb_ast_size_class class = size_to_class(total_size);
struct mrb_ast_symbols_node *symbols_node = (struct mrb_ast_symbols_node*)
parser_alloc_var(p, total_size, class);
init_var_header(&symbols_node->hdr, p, NODE_SYMBOLS, class);
symbols_node->args = a;
return cons_head((node*)NODE_VARIABLE, (node*)symbols_node);
}
/* xxx ----------------------------- */
File diff suppressed because it is too large Load Diff