mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-compiler: implement variable-sized nodes for function calls and special forms
Implements variable-sized nodes for function calls and special forms (NODE_FCALL, NODE_ZSUPER, NODE_LAMBDA) with optimized memory allocation. These nodes now use compact variable-sized structures instead of fixed-size headers, reducing AST memory usage. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -5781,6 +5781,50 @@ gen_defined_var(codegen_scope *s, node *varnode, int val)
|
||||
}
|
||||
}
|
||||
|
||||
// Group 12: Function Calls and Special Forms
|
||||
static void
|
||||
gen_fcall_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_fcall_node *n = fcall_node(varnode);
|
||||
// Create a stack-allocated node structure for traditional codegen
|
||||
struct mrb_ast_node stack_nodes[3];
|
||||
stack_nodes[0].car = NULL; // no receiver (self)
|
||||
stack_nodes[0].cdr = &stack_nodes[1];
|
||||
stack_nodes[1].car = (node*)(intptr_t)n->method_name; // method name as int
|
||||
stack_nodes[1].cdr = &stack_nodes[2];
|
||||
stack_nodes[2].car = n->args;
|
||||
stack_nodes[2].cdr = NULL;
|
||||
gen_call(s, &stack_nodes[0], val, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_zsuper_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
(void)varnode; // suppress unused warning
|
||||
// Create a simple stack structure
|
||||
struct mrb_ast_node stack_node;
|
||||
stack_node.car = (node*)NODE_ZSUPER;
|
||||
stack_node.cdr = NULL;
|
||||
codegen_zsuper(s, &stack_node, val);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_lambda_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_lambda_node *n = lambda_node(varnode);
|
||||
// Create stack-allocated node structure for traditional codegen
|
||||
struct mrb_ast_node stack_nodes[4];
|
||||
stack_nodes[0].car = (node*)NODE_LAMBDA;
|
||||
stack_nodes[0].cdr = &stack_nodes[1];
|
||||
stack_nodes[1].car = n->locals;
|
||||
stack_nodes[1].cdr = &stack_nodes[2];
|
||||
stack_nodes[2].car = n->args;
|
||||
stack_nodes[2].cdr = &stack_nodes[3];
|
||||
stack_nodes[3].car = n->body;
|
||||
stack_nodes[3].cdr = NULL;
|
||||
codegen_lambda(s, &stack_nodes[0], val);
|
||||
}
|
||||
|
||||
static void
|
||||
gen_args_tail_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
@@ -6049,6 +6093,18 @@ codegen_variable_node(codegen_scope *s, node *varnode, int val)
|
||||
gen_defined_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_FCALL:
|
||||
gen_fcall_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_ZSUPER:
|
||||
gen_zsuper_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
case NODE_LAMBDA:
|
||||
gen_lambda_var(s, varnode, val);
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE; /* Not handled, fall through to main codegen */
|
||||
}
|
||||
|
||||
@@ -827,4 +827,32 @@ struct mrb_ast_defined_node {
|
||||
#define COLON3_NODE_NAME(n) (colon3_node(n)->name)
|
||||
#define DEFINED_NODE_EXPR(n) (defined_node(n)->expr)
|
||||
|
||||
// Group 12: Function Calls and Special Forms
|
||||
struct mrb_ast_fcall_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
mrb_sym method_name;
|
||||
struct mrb_ast_node *args;
|
||||
};
|
||||
|
||||
struct mrb_ast_zsuper_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
};
|
||||
|
||||
struct mrb_ast_lambda_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *locals;
|
||||
struct mrb_ast_node *args;
|
||||
struct mrb_ast_node *body;
|
||||
};
|
||||
|
||||
#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 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)
|
||||
|
||||
#endif /* MRUBY_COMPILER_NODE_H */
|
||||
|
||||
@@ -1392,8 +1392,19 @@ new_args_tail_var(parser_state *p, node *keywords, node *kwrest, mrb_sym block)
|
||||
static node*
|
||||
new_fcall(parser_state *p, mrb_sym b, node *c)
|
||||
{
|
||||
node *n = list4((node*)NODE_FCALL, 0, sym_to_node(b), c);
|
||||
return n;
|
||||
if (!p->var_nodes_enabled) {
|
||||
node *n = list4((node*)NODE_FCALL, 0, sym_to_node(b), c);
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t total_size = sizeof(struct mrb_ast_fcall_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
struct mrb_ast_fcall_node *fcall_node = (struct mrb_ast_fcall_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
init_var_header(&fcall_node->hdr, p, NODE_FCALL, class);
|
||||
fcall_node->method_name = b;
|
||||
fcall_node->args = c;
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)fcall_node);
|
||||
}
|
||||
|
||||
/* (a b . c) */
|
||||
@@ -1417,7 +1428,16 @@ new_super(parser_state *p, node *c)
|
||||
static node*
|
||||
new_zsuper(parser_state *p)
|
||||
{
|
||||
return cons_head((node*)NODE_ZSUPER, 0);
|
||||
if (!p->var_nodes_enabled) {
|
||||
return cons_head((node*)NODE_ZSUPER, 0);
|
||||
}
|
||||
|
||||
size_t total_size = sizeof(struct mrb_ast_zsuper_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
struct mrb_ast_zsuper_node *zsuper_node = (struct mrb_ast_zsuper_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
init_var_header(&zsuper_node->hdr, p, NODE_ZSUPER, class);
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)zsuper_node);
|
||||
}
|
||||
|
||||
/* (:yield . c) */
|
||||
@@ -2023,7 +2043,19 @@ static node*
|
||||
new_lambda(parser_state *p, node *a, node *b)
|
||||
{
|
||||
a = setup_numparams(p, a);
|
||||
return list4((node*)NODE_LAMBDA, locals_node(p), a, b);
|
||||
if (!p->var_nodes_enabled) {
|
||||
return list4((node*)NODE_LAMBDA, locals_node(p), a, b);
|
||||
}
|
||||
|
||||
size_t total_size = sizeof(struct mrb_ast_lambda_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
struct mrb_ast_lambda_node *lambda_node = (struct mrb_ast_lambda_node*)
|
||||
parser_alloc_var(p, total_size, class);
|
||||
init_var_header(&lambda_node->hdr, p, NODE_LAMBDA, class);
|
||||
lambda_node->locals = locals_node(p);
|
||||
lambda_node->args = a;
|
||||
lambda_node->body = b;
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)lambda_node);
|
||||
}
|
||||
|
||||
/* (:asgn lhs rhs) */
|
||||
|
||||
+1886
-1854
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user