mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-compiler: migrate NODE_DEF and NODE_SDEF to variable-sized nodes
Complete migration of method definition nodes to variable-sized format: - Convert NODE_DEF and NODE_SDEF from fixed cons-based to variable-sized nodes - Update parser to create variable-sized def/sdef nodes directly - Remove old codegen_def and codegen_sdef functions - Consolidate method setup logic in defn_setup function - Rename lambda_body_ex to lambda_body after removing wrapper layer - Update all method definition code generation to use new node structure This completes the variable-sized node migration for method definitions, improving memory efficiency and enabling more flexible AST handling. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2305,7 +2305,7 @@ search_upvar(codegen_scope *s, mrb_sym id, int *idx)
|
||||
* @return The index of the newly created `mrb_irep` in the parent scope's `reps` array.
|
||||
*/
|
||||
static int
|
||||
lambda_body_ex(codegen_scope *s, node *locals, node *args, node *body, int blk)
|
||||
lambda_body(codegen_scope *s, node *locals, node *args, node *body, int blk)
|
||||
{
|
||||
codegen_scope *parent = s;
|
||||
/* Create a new scope for the lambda/block body. */
|
||||
@@ -2514,18 +2514,6 @@ lambda_body_ex(codegen_scope *s, node *locals, node *args, node *body, int blk)
|
||||
return parent->irep->rlen - 1; /* Return the index of this IREP in the parent's REP list. */
|
||||
}
|
||||
|
||||
static int
|
||||
lambda_body(codegen_scope *s, node *tree, int blk)
|
||||
{
|
||||
/* Extract locals, args, and body from the cons structure */
|
||||
node *locals = tree->car;
|
||||
node *args = tree->cdr ? tree->cdr->car : NULL;
|
||||
node *body = (tree->cdr && tree->cdr->cdr) ? tree->cdr->cdr->car : NULL;
|
||||
|
||||
/* Call the new lambda_body_ex with individual parameters */
|
||||
return lambda_body_ex(s, locals, args, body, blk);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generates code for a new lexical scope, typically for class/module definitions
|
||||
* or the top-level script.
|
||||
@@ -3656,39 +3644,6 @@ codegen_regx(codegen_scope *s, node *tree, int val)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
codegen_def(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
int sym = new_sym(s, node_to_sym(tree->car));
|
||||
int idx = lambda_body(s, tree->cdr, 0);
|
||||
|
||||
genop_1(s, OP_TCLASS, cursp());
|
||||
push();
|
||||
genop_2(s, OP_METHOD, cursp(), idx);
|
||||
push(); pop();
|
||||
pop();
|
||||
genop_2(s, OP_DEF, cursp(), sym);
|
||||
if (val) push();
|
||||
}
|
||||
|
||||
static void
|
||||
codegen_sdef(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
node *recv = tree->car;
|
||||
int sym = new_sym(s, node_to_sym(tree->cdr->car));
|
||||
int idx = lambda_body(s, tree->cdr->cdr, 0);
|
||||
|
||||
codegen(s, recv, VAL);
|
||||
pop();
|
||||
genop_1(s, OP_SCLASS, cursp());
|
||||
push();
|
||||
genop_2(s, OP_METHOD, cursp(), idx);
|
||||
push(); pop();
|
||||
pop();
|
||||
genop_2(s, OP_DEF, cursp(), sym);
|
||||
if (val) push();
|
||||
}
|
||||
|
||||
/* Handle variable-sized node types */
|
||||
static void
|
||||
gen_call_var(codegen_scope *s, node *varnode, int val)
|
||||
@@ -4343,9 +4298,9 @@ gen_def_var(codegen_scope *s, node *varnode, int val)
|
||||
struct mrb_ast_def_node *def_n = def_node(varnode);
|
||||
int sym = new_sym(s, def_n->name);
|
||||
|
||||
/* Call lambda_body_ex directly with individual parameters */
|
||||
/* Call lambda_body directly with individual parameters */
|
||||
/* For NODE_DEF, args should contain the full locals structure from defn_setup */
|
||||
int idx = lambda_body_ex(s, NULL, def_n->args, def_n->body, 0);
|
||||
int idx = lambda_body(s, def_n->locals, def_n->args, def_n->body, 0);
|
||||
|
||||
genop_1(s, OP_TCLASS, cursp());
|
||||
push();
|
||||
@@ -5103,8 +5058,8 @@ gen_block_var(codegen_scope *s, node *varnode, int val)
|
||||
|
||||
struct mrb_ast_block_node *n = block_node(varnode);
|
||||
|
||||
/* Call lambda_body_ex directly with individual parameters */
|
||||
int idx = lambda_body_ex(s, n->locals, n->args, n->body, 1);
|
||||
/* Call lambda_body directly with individual parameters */
|
||||
int idx = lambda_body(s, n->locals, n->args, n->body, 1);
|
||||
genop_2(s, OP_BLOCK, cursp(), idx);
|
||||
push();
|
||||
}
|
||||
@@ -5536,8 +5491,8 @@ gen_lambda_var(codegen_scope *s, node *varnode, int val)
|
||||
|
||||
struct mrb_ast_lambda_node *n = lambda_node(varnode);
|
||||
|
||||
/* Call lambda_body_ex directly with individual parameters */
|
||||
int idx = lambda_body_ex(s, n->locals, n->args, n->body, 1);
|
||||
/* Call lambda_body directly with individual parameters */
|
||||
int idx = lambda_body(s, n->locals, n->args, n->body, 1);
|
||||
genop_2(s, OP_LAMBDA, cursp(), idx);
|
||||
push();
|
||||
}
|
||||
@@ -5716,9 +5671,9 @@ gen_sdef_var(codegen_scope *s, const node *varnode, int val)
|
||||
node *recv = sdef->obj;
|
||||
int sym = new_sym(s, sdef->name);
|
||||
|
||||
/* Call lambda_body_ex directly with individual parameters */
|
||||
/* Call lambda_body directly with individual parameters */
|
||||
/* For NODE_SDEF, args should contain the full locals structure from defs_setup */
|
||||
int idx = lambda_body_ex(s, NULL, sdef->args, sdef->body, 0);
|
||||
int idx = lambda_body(s, sdef->locals, sdef->args, sdef->body, 0);
|
||||
|
||||
codegen(s, recv, VAL);
|
||||
pop();
|
||||
@@ -6104,14 +6059,6 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
codegen_scall(s, tree, val);
|
||||
break;
|
||||
|
||||
case NODE_DEF:
|
||||
codegen_def(s, tree, val);
|
||||
break;
|
||||
|
||||
case NODE_SDEF:
|
||||
codegen_sdef(s, tree, val);
|
||||
break;
|
||||
|
||||
case NODE_VARIABLE:
|
||||
codegen_variable_node(s, tree, val);
|
||||
break;
|
||||
|
||||
@@ -252,11 +252,22 @@ struct mrb_ast_hash_node {
|
||||
struct mrb_ast_def_node {
|
||||
struct mrb_ast_var_header header; /* 8 bytes */
|
||||
mrb_sym name; /* Method name */
|
||||
struct mrb_ast_node *args; /* Arguments node */
|
||||
struct mrb_ast_node *args; /* Method arguments */
|
||||
struct mrb_ast_node *body; /* Method body */
|
||||
struct mrb_ast_node *locals; /* Local Variables */
|
||||
} ;
|
||||
|
||||
/* Variable-sized singleton method definition node */
|
||||
struct mrb_ast_sdef_node {
|
||||
struct mrb_ast_var_header header; /* 8 bytes */
|
||||
mrb_sym name; /* Method name */
|
||||
struct mrb_ast_node *args; /* Method arguments */
|
||||
struct mrb_ast_node *body; /* Method body */
|
||||
struct mrb_ast_node *locals; /* Local Variables */
|
||||
struct mrb_ast_node *obj; /* receiver */
|
||||
};
|
||||
|
||||
/* Variable-sized class definition node */
|
||||
/* variable-sized class definition node */
|
||||
struct mrb_ast_class_node {
|
||||
struct mrb_ast_var_header header; /* 8 bytes */
|
||||
struct mrb_ast_node *name; /* Class name (NODE_CONST or NODE_COLON2) */
|
||||
@@ -906,14 +917,6 @@ struct mrb_ast_postexe_node {
|
||||
struct mrb_ast_node *body;
|
||||
};
|
||||
|
||||
struct mrb_ast_sdef_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
struct mrb_ast_node *obj;
|
||||
mrb_sym name;
|
||||
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_super_node*)(n))
|
||||
#define lambda_node(n) ((struct mrb_ast_lambda_node*)(n))
|
||||
|
||||
@@ -262,20 +262,6 @@ list4_gen(parser_state *p, node *a, node *b, node *c, node *d)
|
||||
}
|
||||
#define list4(a,b,c,d) list4_gen(p, (a),(b),(c),(d))
|
||||
|
||||
static node*
|
||||
list5_gen(parser_state *p, node *a, node *b, node *c, node *d, node *e)
|
||||
{
|
||||
return cons_head(a, cons(b, cons(c, cons(d, cons(e, 0)))));
|
||||
}
|
||||
#define list5(a,b,c,d,e) list5_gen(p, (a),(b),(c),(d),(e))
|
||||
|
||||
static node*
|
||||
list6_gen(parser_state *p, node *a, node *b, node *c, node *d, node *e, node *f)
|
||||
{
|
||||
return cons_head(a, cons(b, cons(c, cons(d, cons(e, cons(f, 0))))));
|
||||
}
|
||||
#define list6(a,b,c,d,e,f) list6_gen(p, (a),(b),(c),(d),(e),(f))
|
||||
|
||||
static node*
|
||||
append_gen(parser_state *p, node *a, node *b)
|
||||
{
|
||||
@@ -605,9 +591,6 @@ new_alias(parser_state *p, mrb_sym a, mrb_sym b)
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)alias_node);
|
||||
}
|
||||
|
||||
/* Forward declarations for variable-sized AST node creation functions */
|
||||
static node* new_def_var(parser_state *p, mrb_sym name, node *args, node *body);
|
||||
|
||||
/* (:if cond then else) */
|
||||
static node*
|
||||
new_if(parser_state *p, node *condition, node *then_body, node *else_body)
|
||||
@@ -853,25 +836,6 @@ new_call_var(parser_state *p, node *receiver, mrb_sym method, node *args, int pa
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Variable-sized method definition node creation */
|
||||
static node*
|
||||
new_def_var(parser_state *p, mrb_sym name, node *args, node *body)
|
||||
{
|
||||
size_t total_size = sizeof(struct mrb_ast_def_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
|
||||
struct mrb_ast_def_node *n = (struct mrb_ast_def_node*)parser_alloc_var(p, total_size, class);
|
||||
|
||||
init_var_header(&n->header, p, NODE_DEF, class);
|
||||
n->name = name;
|
||||
n->args = args;
|
||||
n->body = body;
|
||||
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)n);
|
||||
}
|
||||
|
||||
/* Variable-sized simple node creation functions */
|
||||
|
||||
/* (:fcall self mid args) */
|
||||
static node*
|
||||
new_fcall(parser_state *p, mrb_sym b, node *c)
|
||||
@@ -1357,58 +1321,53 @@ new_module(parser_state *p, node *m, node *b)
|
||||
|
||||
/* (:def m lv (arg . body)) */
|
||||
static node*
|
||||
new_def(parser_state *p, mrb_sym m, node *a, node *b)
|
||||
new_def(parser_state *p, mrb_sym name)
|
||||
{
|
||||
if (p->var_nodes_enabled) {
|
||||
return new_def_var(p, m, a, b);
|
||||
}
|
||||
return list5((node*)NODE_DEF, sym_to_node(m), 0, a, b);
|
||||
size_t total_size = sizeof(struct mrb_ast_def_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
|
||||
struct mrb_ast_def_node *n = (struct mrb_ast_def_node*)parser_alloc_var(p, total_size, class);
|
||||
|
||||
init_var_header(&n->header, p, NODE_DEF, class);
|
||||
n->name = name;
|
||||
n->args = int_to_node(p->cmdarg_stack);
|
||||
n->locals = local_switch(p);
|
||||
n->body = NULL;
|
||||
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)n);
|
||||
}
|
||||
|
||||
static void
|
||||
defn_setup(parser_state *p, node *d, node *a, node *b)
|
||||
{
|
||||
node *n = d->cdr->cdr;
|
||||
struct mrb_ast_def_node *n = def_node(d->cdr);
|
||||
node *locals = n->locals;
|
||||
|
||||
n->car = locals_node(p);
|
||||
p->cmdarg_stack = node_to_int(n->cdr->car);
|
||||
n->cdr->car = a;
|
||||
local_resume(p, n->cdr->cdr->car);
|
||||
n->cdr->cdr->car = b;
|
||||
n->locals = locals_node(p);
|
||||
p->cmdarg_stack = node_to_int(n->args);
|
||||
n->args = a;
|
||||
n->body = b;
|
||||
local_resume(p, locals);
|
||||
}
|
||||
|
||||
/* (:sdef obj m lv (arg . body)) */
|
||||
static node*
|
||||
new_sdef(parser_state *p, node *o, mrb_sym m, node *a, node *b)
|
||||
new_sdef(parser_state *p, node *o, mrb_sym name)
|
||||
{
|
||||
void_expr_error(p, o);
|
||||
if (!p->var_nodes_enabled) {
|
||||
return list6((node*)NODE_SDEF, o, sym_to_node(m), 0, a, b);
|
||||
}
|
||||
|
||||
size_t total_size = sizeof(struct mrb_ast_sdef_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
struct mrb_ast_sdef_node *sdef_node = (struct mrb_ast_sdef_node*)parser_alloc_var(p, total_size, class);
|
||||
init_var_header(&sdef_node->hdr, p, NODE_SDEF, class);
|
||||
init_var_header(&sdef_node->header, p, NODE_SDEF, class);
|
||||
sdef_node->obj = o;
|
||||
sdef_node->name = m;
|
||||
sdef_node->args = a;
|
||||
sdef_node->body = b;
|
||||
sdef_node->name = name;
|
||||
sdef_node->args = int_to_node(p->cmdarg_stack);
|
||||
sdef_node->locals = local_switch(p);
|
||||
sdef_node->body = NULL;
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)sdef_node);
|
||||
}
|
||||
|
||||
static void
|
||||
defs_setup(parser_state *p, node *d, node *a, node *b)
|
||||
{
|
||||
node *n = d->cdr->cdr->cdr;
|
||||
|
||||
n->car = locals_node(p);
|
||||
p->cmdarg_stack = node_to_int(n->cdr->car);
|
||||
n->cdr->car = a;
|
||||
local_resume(p, n->cdr->cdr->car);
|
||||
n->cdr->cdr->car = b;
|
||||
}
|
||||
|
||||
/* (:arg . sym) */
|
||||
static node*
|
||||
new_arg(parser_state *p, mrb_sym sym)
|
||||
@@ -2711,7 +2670,7 @@ command_asgn : lhs '=' command_rhs
|
||||
{
|
||||
$$ = $1;
|
||||
void_expr_error(p, $4);
|
||||
defs_setup(p, $$, $2, $4);
|
||||
defn_setup(p, $$, $2, $4);
|
||||
nvars_unnest(p);
|
||||
p->in_def--;
|
||||
p->in_single--;
|
||||
@@ -2720,7 +2679,7 @@ command_asgn : lhs '=' command_rhs
|
||||
{
|
||||
$$ = $1;
|
||||
void_expr_error(p, $4);
|
||||
defs_setup(p, $$, $2, new_mod_rescue(p, $4, $6));
|
||||
defn_setup(p, $$, $2, new_mod_rescue(p, $4, $6));
|
||||
nvars_unnest(p);
|
||||
p->in_def--;
|
||||
p->in_single--;
|
||||
@@ -2762,7 +2721,7 @@ expr : command_call
|
||||
|
||||
defn_head : keyword_def fname
|
||||
{
|
||||
$$ = new_def(p, $2, int_to_node(p->cmdarg_stack), local_switch(p));
|
||||
$$ = new_def(p, $2);
|
||||
p->cmdarg_stack = 0;
|
||||
p->in_def++;
|
||||
nvars_block(p);
|
||||
@@ -2775,7 +2734,7 @@ defs_head : keyword_def singleton dot_or_colon
|
||||
}
|
||||
fname
|
||||
{
|
||||
$$ = new_sdef(p, $2, $5, int_to_node(p->cmdarg_stack), local_switch(p));
|
||||
$$ = new_sdef(p, $2, $5);
|
||||
p->cmdarg_stack = 0;
|
||||
p->in_def++;
|
||||
p->in_single++;
|
||||
@@ -3342,7 +3301,7 @@ arg : lhs '=' arg_rhs
|
||||
{
|
||||
$$ = $1;
|
||||
void_expr_error(p, $4);
|
||||
defs_setup(p, $$, $2, $4);
|
||||
defn_setup(p, $$, $2, $4);
|
||||
nvars_unnest(p);
|
||||
p->in_def--;
|
||||
p->in_single--;
|
||||
@@ -3351,7 +3310,7 @@ arg : lhs '=' arg_rhs
|
||||
{
|
||||
$$ = $1;
|
||||
void_expr_error(p, $4);
|
||||
defs_setup(p, $$, $2, new_mod_rescue(p, $4, $6));
|
||||
defn_setup(p, $$, $2, new_mod_rescue(p, $4, $6));
|
||||
nvars_unnest(p);
|
||||
p->in_def--;
|
||||
p->in_single--;
|
||||
@@ -3767,7 +3726,7 @@ primary : literal
|
||||
keyword_end
|
||||
{
|
||||
$$ = $1;
|
||||
defs_setup(p, $$, $2, $3);
|
||||
defn_setup(p, $$, $2, $3);
|
||||
nvars_unnest(p);
|
||||
p->in_def--;
|
||||
p->in_single--;
|
||||
|
||||
+1244
-1285
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user