mruby-compiler: convert new_and and new_or to always use variable-sized nodes

Remove conditional var_nodes_enabled logic from new_and and new_or functions.
These functions now directly create variable-sized AST nodes using proper
size classes and memory allocation. Also remove unused codegen_and and
codegen_or functions as all code generation now goes through the variable-sized
node handlers gen_and_var and gen_or_var with proper short-circuit evaluation.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-09-04 10:50:44 +09:00
parent b325ad991b
commit b5a4b3a7a7
3 changed files with 1211 additions and 1309 deletions
+30 -72
View File
@@ -3863,45 +3863,6 @@ codegen_if(codegen_scope *s, node *tree, int val)
}
}
static void
codegen_and(codegen_scope *s, node *tree, int val)
{
uint32_t pos;
if (true_always(tree->car)) {
codegen(s, tree->cdr, val);
return;
}
if (false_always(tree->car)) {
codegen(s, tree->car, val);
return;
}
codegen(s, tree->car, VAL);
pop();
pos = genjmp2_0(s, OP_JMPNOT, cursp(), val);
codegen(s, tree->cdr, val);
dispatch(s, pos);
}
static void
codegen_or(codegen_scope *s, node *tree, int val)
{
uint32_t pos;
if (true_always(tree->car)) {
codegen(s, tree->car, val);
return;
}
if (false_always(tree->car)) {
codegen(s, tree->cdr, val);
return;
}
codegen(s, tree->car, VAL);
pop();
pos = genjmp2_0(s, OP_JMPIF, cursp(), val);
codegen(s, tree->cdr, val);
dispatch(s, pos);
}
static void
codegen_self(codegen_scope *s, node *tree, int val)
@@ -5199,43 +5160,47 @@ gen_op_asgn_var(codegen_scope *s, node *varnode, int val)
static void
gen_and_var(codegen_scope *s, node *varnode, int val)
{
struct mrb_ast_and_node *and_n = and_node(varnode);
node *left = AND_NODE_LEFT(and_n);
node *right = AND_NODE_RIGHT(and_n);
struct mrb_ast_and_node *and_n = (struct mrb_ast_and_node*)varnode;
node *left = and_n->left;
node *right = and_n->right;
uint32_t pos;
/* Simplified AND logic - evaluate left, then conditionally right */
if (left) {
codegen(s, left, VAL);
/* For now, just evaluate right too - can be optimized later for short-circuit */
if (right) {
codegen(s, right, val);
}
if (true_always(left)) {
codegen(s, right, val);
return;
}
else if (val) {
genop_1(s, OP_LOADNIL, cursp());
push();
if (false_always(left)) {
codegen(s, left, val);
return;
}
codegen(s, left, VAL);
pop();
pos = genjmp2_0(s, OP_JMPNOT, cursp(), val);
codegen(s, right, val);
dispatch(s, pos);
}
static void
gen_or_var(codegen_scope *s, node *varnode, int val)
{
struct mrb_ast_or_node *or_n = or_node(varnode);
node *left = OR_NODE_LEFT(or_n);
node *right = OR_NODE_RIGHT(or_n);
struct mrb_ast_or_node *or_n = (struct mrb_ast_or_node*)varnode;
node *left = or_n->left;
node *right = or_n->right;
uint32_t pos;
/* Simplified OR logic - evaluate left, then conditionally right */
if (left) {
codegen(s, left, VAL);
/* For now, just evaluate right too - can be optimized later for short-circuit */
if (right) {
codegen(s, right, val);
}
if (true_always(left)) {
codegen(s, left, val);
return;
}
else if (val) {
genop_1(s, OP_LOADNIL, cursp());
push();
if (false_always(left)) {
codegen(s, right, val);
return;
}
codegen(s, left, VAL);
pop();
pos = genjmp2_0(s, OP_JMPIF, cursp(), val);
codegen(s, right, val);
dispatch(s, pos);
}
static void
@@ -6387,13 +6352,6 @@ codegen(codegen_scope *s, node *tree, int val)
codegen_if(s, tree, val);
break;
case NODE_AND:
codegen_and(s, tree, val);
break;
case NODE_OR:
codegen_or(s, tree, val);
break;
case NODE_WHILE_MOD:
case NODE_UNTIL_MOD:
+22 -50
View File
@@ -608,8 +608,6 @@ static node* new_sclass_var(parser_state *p, node *obj, node *body);
static node* new_asgn_var(parser_state *p, node *lhs, node *rhs);
static node* new_masgn_var(parser_state *p, node *lhs, node *rhs);
static node* new_op_asgn_var(parser_state *p, node *lhs, mrb_sym op, node *rhs);
static node* new_and_var(parser_state *p, node *left, node *right);
static node* new_or_var(parser_state *p, node *left, node *right);
/* (:if cond then else) */
static node*
@@ -1119,41 +1117,6 @@ new_op_asgn_var(parser_state *p, node *lhs, mrb_sym op, node *rhs)
}
/* Variable-sized expression node creation */
static node*
new_and_var(parser_state *p, node *left, node *right)
{
size_t total_size = sizeof(struct mrb_ast_and_node);
enum mrb_ast_size_class class = size_to_class(total_size);
struct mrb_ast_and_node *n = (struct mrb_ast_and_node*)parser_alloc_var(p, total_size, class);
init_var_header(&n->header, p, NODE_AND, class);
n->left = left;
n->right = right;
return cons_head((node*)NODE_VARIABLE, (node*)n);
}
static node*
new_or_var(parser_state *p, node *left, node *right)
{
size_t total_size = sizeof(struct mrb_ast_or_node);
enum mrb_ast_size_class class = size_to_class(total_size);
struct mrb_ast_or_node *n = (struct mrb_ast_or_node*)parser_alloc_var(p, total_size, class);
init_var_header(&n->header, p, NODE_OR, class);
n->left = left;
n->right = right;
return cons_head((node*)NODE_VARIABLE, (node*)n);
}
/* Variable-sized literal node creation functions */
/* Variable-sized simple node creation functions */
static node*
@@ -1182,8 +1145,6 @@ new_nil_var(parser_state *p)
return cons_head((node*)NODE_VARIABLE, (node*)n);
}
static node*
new_const_var(parser_state *p, mrb_sym symbol)
{
@@ -1448,10 +1409,17 @@ static node*
new_and(parser_state *p, node *a, node *b)
{
void_expr_error(p, a);
if (p->var_nodes_enabled) {
return new_and_var(p, a, b);
}
return cons_head((node*)NODE_AND, cons(a, b));
size_t total_size = sizeof(struct mrb_ast_and_node);
enum mrb_ast_size_class class = size_to_class(total_size);
struct mrb_ast_and_node *n = (struct mrb_ast_and_node*)parser_alloc_var(p, total_size, class);
init_var_header(&n->header, p, NODE_AND, class);
n->left = a;
n->right = b;
return cons_head((node*)NODE_VARIABLE, (node*)n);
}
/* (:or a b) */
@@ -1459,10 +1427,17 @@ static node*
new_or(parser_state *p, node *a, node *b)
{
void_expr_error(p, a);
if (p->var_nodes_enabled) {
return new_or_var(p, a, b);
}
return cons_head((node*)NODE_OR, cons(a, b));
size_t total_size = sizeof(struct mrb_ast_or_node);
enum mrb_ast_size_class class = size_to_class(total_size);
struct mrb_ast_or_node *n = (struct mrb_ast_or_node*)parser_alloc_var(p, total_size, class);
init_var_header(&n->header, p, NODE_OR, class);
n->left = a;
n->right = b;
return cons_head((node*)NODE_VARIABLE, (node*)n);
}
/* (:array a...) */
@@ -2080,7 +2055,6 @@ new_str(parser_state *p, node *a)
return cons_head((node*)NODE_VARIABLE, (node*)n);
}
/* (:xstr . a) */
static node*
new_xstr(parser_state *p, node *a)
@@ -2093,7 +2067,6 @@ new_xstr(parser_state *p, node *a)
return cons_head((node*)NODE_VARIABLE, (node*)n);
}
/* (:dsym . a) */
static node*
new_dsym(parser_state *p, node *a)
@@ -2106,7 +2079,6 @@ new_dsym(parser_state *p, node *a)
return cons_head((node*)NODE_VARIABLE, (node*)n);
}
/* (:dregx . (list . (flags . encoding))) */
static node*
new_dregx(parser_state *p, node *list, const char *flags, const char *encoding)
File diff suppressed because it is too large Load Diff