mruby-compiler: implement variable-sized nodes for declarations and definitions

Implements variable-sized AST node support for Group 16 declarations and
definitions including NODE_ALIAS, NODE_POSTEXE, NODE_UNDEF, and NODE_SDEF.
This continues the systematic implementation of memory-efficient variable-
sized nodes across the mruby compiler's AST infrastructure.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-08-29 22:42:44 +09:00
parent 5afa8ea6e9
commit 9b33654d26
4 changed files with 1498 additions and 1298 deletions
+82
View File
@@ -5925,6 +5925,72 @@ gen_ensure_var(codegen_scope *s, const node *varnode, int val)
codegen_ensure(s, &ensure_node_stack, val);
}
// Group 16: Declarations and Definitions
static void
gen_alias_var(codegen_scope *s, const node *varnode, int val)
{
struct mrb_ast_alias_node *alias = alias_node(varnode);
// Create stack-allocated traditional node structure
node alias_node_stack;
alias_node_stack.car = (node*)(intptr_t)alias->new_name;
alias_node_stack.cdr = (node*)(intptr_t)alias->old_name;
codegen_alias(s, &alias_node_stack, val);
}
static void
gen_undef_var(codegen_scope *s, const node *varnode, int val)
{
struct mrb_ast_undef_node *undef = undef_node(varnode);
// Create stack-allocated traditional node structure
node undef_node_stack;
undef_node_stack.car = undef->syms;
undef_node_stack.cdr = NULL;
codegen_undef(s, &undef_node_stack, val);
}
static void
gen_postexe_var(codegen_scope *s, const node *varnode, int val)
{
struct mrb_ast_postexe_node *postexe = postexe_node(varnode);
// Create stack-allocated traditional node structure
node postexe_node_stack;
postexe_node_stack.car = postexe->body;
postexe_node_stack.cdr = NULL;
codegen_postexe(s, &postexe_node_stack, val);
}
static void
gen_sdef_var(codegen_scope *s, const node *varnode, int val)
{
struct mrb_ast_sdef_node *sdef = sdef_node(varnode);
// Extract components and call codegen_sdef logic directly
node *recv = sdef->obj;
mrb_sym method_sym = sdef->name;
node *args_body = sdef->args;
node *body = sdef->body;
int sym = new_sym(s, method_sym);
int idx = lambda_body(s, args_body ? args_body : body, 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();
}
static void
gen_args_tail_var(codegen_scope *s, node *varnode, int val)
{
@@ -6238,6 +6304,22 @@ codegen_variable_node(codegen_scope *s, node *varnode, int val)
gen_ensure_var(s, varnode, val);
return TRUE;
case NODE_ALIAS:
gen_alias_var(s, varnode, val);
return TRUE;
case NODE_UNDEF:
gen_undef_var(s, varnode, val);
return TRUE;
case NODE_POSTEXE:
gen_postexe_var(s, varnode, val);
return TRUE;
case NODE_SDEF:
gen_sdef_var(s, varnode, val);
return TRUE;
default:
return FALSE; /* Not handled, fall through to main codegen */
}
+30
View File
@@ -923,6 +923,32 @@ struct mrb_ast_when_node {
struct mrb_ast_node *next_when;
};
// Group 16: Declarations and Definitions
struct mrb_ast_alias_node {
struct mrb_ast_var_header hdr;
mrb_sym new_name;
mrb_sym old_name;
};
struct mrb_ast_undef_node {
struct mrb_ast_var_header hdr;
struct mrb_ast_node *syms;
};
struct mrb_ast_postexe_node {
struct mrb_ast_var_header hdr;
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_zsuper_node*)(n))
#define lambda_node(n) ((struct mrb_ast_lambda_node*)(n))
@@ -940,6 +966,10 @@ struct mrb_ast_when_node {
#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 alias_node(n) ((struct mrb_ast_alias_node*)(n))
#define undef_node(n) ((struct mrb_ast_undef_node*)(n))
#define postexe_node(n) ((struct mrb_ast_postexe_node*)(n))
#define sdef_node(n) ((struct mrb_ast_sdef_node*)(n))
#define FCALL_NODE_METHOD_NAME(n) (fcall_node(n)->method_name)
#define FCALL_NODE_ARGS(n) (fcall_node(n)->args)
+48 -4
View File
@@ -578,7 +578,18 @@ new_false(parser_state *p)
static node*
new_alias(parser_state *p, mrb_sym a, mrb_sym b)
{
return cons_head((node*)NODE_ALIAS, cons(sym_to_node(a), sym_to_node(b)));
if (!p->var_nodes_enabled) {
return cons_head((node*)NODE_ALIAS, cons(sym_to_node(a), sym_to_node(b)));
}
size_t total_size = sizeof(struct mrb_ast_alias_node);
enum mrb_ast_size_class class = size_to_class(total_size);
struct mrb_ast_alias_node *alias_node = (struct mrb_ast_alias_node*)
parser_alloc_var(p, total_size, class);
init_var_header(&alias_node->hdr, p, NODE_ALIAS, class);
alias_node->new_name = a;
alias_node->old_name = b;
return cons_head((node*)NODE_VARIABLE, (node*)alias_node);
}
/* Forward declaration for variable-sized call node */
@@ -725,7 +736,17 @@ new_case(parser_state *p, node *a, node *b)
static node*
new_postexe(parser_state *p, node *a)
{
return cons_head((node*)NODE_POSTEXE, a);
if (!p->var_nodes_enabled) {
return cons_head((node*)NODE_POSTEXE, a);
}
size_t total_size = sizeof(struct mrb_ast_postexe_node);
enum mrb_ast_size_class class = size_to_class(total_size);
struct mrb_ast_postexe_node *postexe_node = (struct mrb_ast_postexe_node*)
parser_alloc_var(p, total_size, class);
init_var_header(&postexe_node->hdr, p, NODE_POSTEXE, class);
postexe_node->body = a;
return cons_head((node*)NODE_VARIABLE, (node*)postexe_node);
}
/* (:self) */
@@ -1844,7 +1865,17 @@ new_const(parser_state *p, mrb_sym sym)
static node*
new_undef(parser_state *p, mrb_sym sym)
{
return list2((node*)NODE_UNDEF, sym_to_node(sym));
if (!p->var_nodes_enabled) {
return list2((node*)NODE_UNDEF, sym_to_node(sym));
}
size_t total_size = sizeof(struct mrb_ast_undef_node);
enum mrb_ast_size_class class = size_to_class(total_size);
struct mrb_ast_undef_node *undef_node = (struct mrb_ast_undef_node*)
parser_alloc_var(p, total_size, class);
init_var_header(&undef_node->hdr, p, NODE_UNDEF, class);
undef_node->syms = sym_to_node(sym);
return cons_head((node*)NODE_VARIABLE, (node*)undef_node);
}
/* (:class class super body) */
@@ -1906,7 +1937,20 @@ static node*
new_sdef(parser_state *p, node *o, mrb_sym m, node *a, node *b)
{
void_expr_error(p, o);
return list6((node*)NODE_SDEF, o, sym_to_node(m), 0, a, b);
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);
sdef_node->obj = o;
sdef_node->name = m;
sdef_node->args = a;
sdef_node->body = b;
return cons_head((node*)NODE_VARIABLE, (node*)sdef_node);
}
static void
File diff suppressed because it is too large Load Diff