mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-compiler: remove cons-list support for NODE_BREAK, NODE_NEXT, NODE_REDO, NODE_RETRY
These node types always generate variable-sized nodes, so the cons-list codegen support is no longer needed. This change: codegen.c: - Moves logic from codegen_break/next/redo/retry into gen_*_var functions - Removes cons-list switch cases for these four node types - Removes the now-unused codegen_break/next/redo/retry functions parse.y: - Updates call_with_block to handle NODE_BREAK and NODE_NEXT through NODE_VARIABLE case instead of cons-list cases - Removes the now-unused cons-list cases for these node types All control flow functionality remains identical, but the code path is simplified since these nodes exclusively use variable-sized structures. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -4177,73 +4177,6 @@ codegen_undef(codegen_scope *s, node *tree, int val)
|
||||
gen_load_nil(s, val);
|
||||
}
|
||||
|
||||
static void
|
||||
codegen_break(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
loop_break(s, tree);
|
||||
if (!val) return;
|
||||
push();
|
||||
}
|
||||
|
||||
static void
|
||||
codegen_next(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
if (!s->loop) {
|
||||
raise_error(s, "unexpected next");
|
||||
}
|
||||
else if (s->loop->type == LOOP_NORMAL) {
|
||||
codegen(s, tree, NOVAL);
|
||||
genjmp(s, OP_JMPUW, s->loop->pc0);
|
||||
}
|
||||
else {
|
||||
if (tree) {
|
||||
codegen(s, tree, VAL);
|
||||
pop();
|
||||
}
|
||||
else {
|
||||
genop_1(s, OP_LOADNIL, cursp());
|
||||
}
|
||||
gen_return(s, OP_RETURN, cursp());
|
||||
}
|
||||
if (!val) return;
|
||||
push();
|
||||
}
|
||||
|
||||
static void
|
||||
codegen_redo(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
for (const struct loopinfo *lp = s->loop; ; lp = lp->prev) {
|
||||
if (!lp) {
|
||||
raise_error(s, "unexpected redo");
|
||||
break;
|
||||
}
|
||||
if (lp->type != LOOP_BEGIN && lp->type != LOOP_RESCUE) {
|
||||
genjmp(s, OP_JMPUW, lp->pc1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!val) return;
|
||||
push();
|
||||
}
|
||||
|
||||
static void
|
||||
codegen_retry(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
const struct loopinfo *lp = s->loop;
|
||||
|
||||
while (lp && lp->type != LOOP_RESCUE) {
|
||||
lp = lp->prev;
|
||||
}
|
||||
if (!lp) {
|
||||
raise_error(s, "unexpected retry");
|
||||
}
|
||||
else {
|
||||
genjmp(s, OP_JMPUW, lp->pc0);
|
||||
}
|
||||
if (!val) return;
|
||||
push();
|
||||
}
|
||||
|
||||
static void
|
||||
codegen_back_ref(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
@@ -5532,26 +5465,69 @@ static void
|
||||
gen_break_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_break_node *n = (struct mrb_ast_break_node*)varnode;
|
||||
codegen_break(s, n->value, val);
|
||||
loop_break(s, n->value);
|
||||
if (!val) return;
|
||||
push();
|
||||
}
|
||||
|
||||
static void
|
||||
gen_next_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_next_node *n = (struct mrb_ast_next_node*)varnode;
|
||||
codegen_next(s, n->value, val);
|
||||
if (!s->loop) {
|
||||
raise_error(s, "unexpected next");
|
||||
}
|
||||
else if (s->loop->type == LOOP_NORMAL) {
|
||||
codegen(s, n->value, NOVAL);
|
||||
genjmp(s, OP_JMPUW, s->loop->pc0);
|
||||
}
|
||||
else {
|
||||
if (n->value) {
|
||||
codegen(s, n->value, VAL);
|
||||
pop();
|
||||
}
|
||||
else {
|
||||
genop_1(s, OP_LOADNIL, cursp());
|
||||
}
|
||||
gen_return(s, OP_RETURN, cursp());
|
||||
}
|
||||
if (!val) return;
|
||||
push();
|
||||
}
|
||||
|
||||
static void
|
||||
gen_redo_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
codegen_redo(s, NULL, val);
|
||||
for (const struct loopinfo *lp = s->loop; ; lp = lp->prev) {
|
||||
if (!lp) {
|
||||
raise_error(s, "unexpected redo");
|
||||
break;
|
||||
}
|
||||
if (lp->type != LOOP_BEGIN && lp->type != LOOP_RESCUE) {
|
||||
genjmp(s, OP_JMPUW, lp->pc1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!val) return;
|
||||
push();
|
||||
}
|
||||
|
||||
static void
|
||||
gen_retry_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
codegen_retry(s, NULL, val);
|
||||
const struct loopinfo *lp = s->loop;
|
||||
|
||||
while (lp && lp->type != LOOP_RESCUE) {
|
||||
lp = lp->prev;
|
||||
}
|
||||
if (!lp) {
|
||||
raise_error(s, "unexpected retry");
|
||||
}
|
||||
else {
|
||||
genjmp(s, OP_JMPUW, lp->pc0);
|
||||
}
|
||||
if (!val) return;
|
||||
push();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -6399,22 +6375,6 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
codegen_op_asgn(s, tree, val);
|
||||
break;
|
||||
|
||||
case NODE_BREAK:
|
||||
codegen_break(s, tree, val);
|
||||
break;
|
||||
|
||||
case NODE_NEXT:
|
||||
codegen_next(s, tree, val);
|
||||
break;
|
||||
|
||||
case NODE_REDO:
|
||||
codegen_redo(s, tree, val);
|
||||
break;
|
||||
|
||||
case NODE_RETRY:
|
||||
codegen_retry(s, tree, val);
|
||||
break;
|
||||
|
||||
case NODE_LVAR:
|
||||
codegen_lvar(s, node_to_sym(tree), val);
|
||||
break;
|
||||
|
||||
@@ -2185,6 +2185,20 @@ call_with_block(parser_state *p, node *a, node *b)
|
||||
call_with_block(p, return_n->args, b);
|
||||
return;
|
||||
}
|
||||
else if (var_type == NODE_BREAK) {
|
||||
/* Variable-sized break nodes - recursively call with value */
|
||||
struct mrb_ast_break_node *break_n = (struct mrb_ast_break_node*)a->cdr;
|
||||
if (break_n->value == NULL) return;
|
||||
call_with_block(p, break_n->value, b);
|
||||
return;
|
||||
}
|
||||
else if (var_type == NODE_NEXT) {
|
||||
/* Variable-sized next nodes - recursively call with value */
|
||||
struct mrb_ast_next_node *next_n = (struct mrb_ast_next_node*)a->cdr;
|
||||
if (next_n->value == NULL) return;
|
||||
call_with_block(p, next_n->value, b);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* For other variable-sized nodes, fall through to default */
|
||||
break;
|
||||
@@ -2196,11 +2210,6 @@ call_with_block(parser_state *p, node *a, node *b)
|
||||
if (!n->car) n->car = new_callargs(p, 0, 0, b);
|
||||
else args_with_block(p, n->car, b);
|
||||
break;
|
||||
case NODE_BREAK:
|
||||
case NODE_NEXT:
|
||||
if (a->cdr == NULL) return;
|
||||
call_with_block(p, a->cdr, b);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
+1272
-1263
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user