mruby-compiler: remove codegen_stmts and inline logic into gen_stmts_var

Complete NODE_STMTS migration by removing unused codegen_stmts function
and inlining statement traversal logic directly into gen_stmts_var.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-09-09 13:03:19 +09:00
parent f4fe87c11e
commit 624b92d0db
4 changed files with 1158 additions and 1120 deletions
+44 -20
View File
@@ -3578,18 +3578,6 @@ codegen_masgn(codegen_scope *s, node *tree, int val)
}
}
static void
codegen_stmts(codegen_scope *s, node *tree, int val)
{
if (val && !tree) {
gen_load_nil(s, 1);
}
while (tree) {
codegen(s, tree->car, tree->cdr ? NOVAL : val);
tree = tree->cdr;
}
}
static void
codegen_lambda(codegen_scope *s, node *tree, int val)
{
@@ -4881,6 +4869,9 @@ gen_def_var(codegen_scope *s, node *varnode, int val)
}
/* Helper function for generating class/module/singleton class body */
/* Forward declaration */
static mrb_bool is_empty_stmts(node *stmt_node);
static void
gen_class_body(codegen_scope *s, node *body, int val)
{
@@ -4892,7 +4883,7 @@ gen_class_body(codegen_scope *s, node *body, int val)
node *body_stmts = body->cdr;
/* Check for empty body case */
if (node_to_int(body_stmts->car) == NODE_STMTS && body_stmts->cdr == NULL) {
if (is_empty_stmts(body_stmts)) {
genop_1(s, OP_LOADNIL, cursp());
}
else {
@@ -5876,9 +5867,7 @@ gen_ensure_var(codegen_scope *s, node *varnode, int val)
node *body = ensure->body;
node *ensure_clause = ensure->ensure_clause;
if (!ensure_clause ||
(node_to_int(ensure_clause->car) == NODE_STMTS &&
ensure_clause->cdr)) {
if (!ensure_clause || !is_empty_stmts(ensure_clause)) {
int catch_entry, begin, end, target;
int idx;
@@ -5901,6 +5890,41 @@ gen_ensure_var(codegen_scope *s, node *varnode, int val)
}
}
static void
gen_stmts_var(codegen_scope *s, node *varnode, int val)
{
struct mrb_ast_stmts_node *stmts = stmts_node(varnode);
node *tree = STMTS_NODE_STMTS(stmts);
if (val && !tree) {
gen_load_nil(s, 1);
}
while (tree) {
codegen(s, tree->car, tree->cdr ? NOVAL : val);
tree = tree->cdr;
}
}
static mrb_bool
is_empty_stmts(node *stmt_node)
{
if (!stmt_node) return TRUE;
if (node_to_int(stmt_node->car) == NODE_VARIABLE) {
/* Variable-sized NODE_STMTS with internal cons-list */
if (NODE_TYPE(stmt_node) == NODE_STMTS) {
struct mrb_ast_stmts_node *stmts = stmts_node(NODE_VAR_NODE_PTR(stmt_node));
return STMTS_NODE_STMTS(stmts) == NULL;
}
}
else if (node_to_int(stmt_node->car) == NODE_STMTS) {
/* Traditional cons-list NODE_STMTS */
return stmt_node->cdr == NULL;
}
return FALSE;
}
// Group 16: Declarations and Definitions
static void
@@ -6275,6 +6299,10 @@ codegen_variable_node(codegen_scope *s, node *varnode, int val)
gen_ensure_var(s, varnode, val);
return TRUE;
case NODE_STMTS:
gen_stmts_var(s, varnode, val);
return TRUE;
case NODE_ALIAS:
gen_alias_var(s, varnode, val);
return TRUE;
@@ -6334,10 +6362,6 @@ codegen(codegen_scope *s, node *tree, int val)
s->lineno = head->lineno;
tree = tree->cdr;
switch (nt) {
case NODE_STMTS:
codegen_stmts(s, tree, val);
break;
case NODE_LAMBDA:
codegen_lambda(s, tree, val);
break;
+6
View File
@@ -870,6 +870,11 @@ struct mrb_ast_ensure_node {
struct mrb_ast_node *ensure_clause;
};
struct mrb_ast_stmts_node {
struct mrb_ast_var_header hdr;
struct mrb_ast_node *stmts; /* Cons-list of statements */
};
struct mrb_ast_iter_node {
struct mrb_ast_var_header hdr;
struct mrb_ast_node *vars;
@@ -924,6 +929,7 @@ struct mrb_ast_sdef_node {
#define scope_node(n) ((struct mrb_ast_scope_node*)(n))
#define begin_node(n) ((struct mrb_ast_begin_node*)(n))
#define ensure_node(n) ((struct mrb_ast_ensure_node*)(n))
#define stmts_node(n) ((struct mrb_ast_stmts_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))
+14 -10
View File
@@ -492,16 +492,18 @@ new_scope(parser_state *p, node *body)
static node*
new_stmts(parser_state *p, node *body)
{
if (body) {
/* If body is already a NODE_STMTS, just return it directly */
if (node_to_type(body->car) == NODE_STMTS) {
return body;
}
return list2((node*)NODE_STMTS, body);
}
return cons_head((node*)NODE_STMTS, 0);
size_t total_size = sizeof(struct mrb_ast_stmts_node);
enum mrb_ast_size_class class = size_to_class(total_size);
struct mrb_ast_stmts_node *n = (struct mrb_ast_stmts_node*)parser_alloc_var(p, total_size, class);
init_var_header(&n->hdr, p, NODE_STMTS, class);
n->stmts = body ? list1(body) : 0; /* Wrap single statement in cons-list */
return cons_head((node*)NODE_VARIABLE, (node*)n);
}
/* (:begin body) - Always use variable-sized nodes */
static node*
new_begin(parser_state *p, node *body)
@@ -2668,7 +2670,9 @@ stmts : none
}
| stmts terms stmt
{
$$ = push($1, newline_node($3));
/* Update the cons-list inside the existing variable-sized node */
STMTS_NODE_STMTS($1->cdr) = push(STMTS_NODE_STMTS($1->cdr), newline_node($3));
$$ = $1;
}
| error stmt
{
@@ -7652,7 +7656,7 @@ mrb_parser_new(mrb_state *mrb)
p->var_alloc_counts[i] = 0;
}
p->var_total_allocated = 0;
p->var_nodes_enabled = TRUE; /* Enable variable-sized nodes by default */
p->var_nodes_enabled = TRUE;
return p;
}
File diff suppressed because it is too large Load Diff