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:
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 ----------------------------- */
|
||||
|
||||
+1686
-1636
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user