mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-compiler: convert new_yield to always use variable-sized nodes
- Remove conditional var_nodes_enabled logic from new_yield - Delete unused new_yield_var function and forward declaration - Move NODE_YIELD handling to NODE_VARIABLE branch in call_with_block - Remove traditional NODE_YIELD case from main codegen function - Inline codegen_yield logic directly into gen_yield_var This completes the modernization of yield node handling to exclusively use variable-sized nodes throughout the compiler pipeline. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -4791,47 +4791,6 @@ codegen_block_arg(codegen_scope *s, node *tree, int val)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
codegen_yield(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
codegen_scope *s2 = s;
|
||||
int lv = 0, ainfo = -1;
|
||||
int n = 0, nk = 0, sendv = 0;
|
||||
|
||||
while (!s2->mscope) {
|
||||
lv++;
|
||||
s2 = s2->prev;
|
||||
if (!s2) break;
|
||||
}
|
||||
if (s2) {
|
||||
ainfo = (int)s2->ainfo;
|
||||
}
|
||||
if (ainfo < 0) codegen_error(s, "invalid yield (SyntaxError)");
|
||||
if (lv > 0xf) codegen_error(s, "too deep nesting");
|
||||
push();
|
||||
if (tree) {
|
||||
if (tree->car) {
|
||||
n = gen_values(s, tree->car, VAL, 14);
|
||||
if (n < 0) {
|
||||
n = sendv = 1;
|
||||
push();
|
||||
}
|
||||
}
|
||||
if (tree->cdr->car) {
|
||||
nk = gen_hash(s, tree->cdr->car->cdr, VAL, 14);
|
||||
if (nk < 0) {
|
||||
nk = 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
push();pop(); /* space for a block */
|
||||
pop_n(n + (nk == 15 ? 1 : nk * 2) + 1);
|
||||
genop_2S(s, OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf));
|
||||
if (sendv) n = CALL_MAXARGS;
|
||||
genop_3(s, OP_SEND, cursp(), new_sym(s, MRB_SYM_2(s->mrb, call)), n|(nk<<4));
|
||||
if (val) push();
|
||||
}
|
||||
|
||||
/* Handle variable-sized node types */
|
||||
static void
|
||||
gen_call_var(codegen_scope *s, node *varnode, int val)
|
||||
@@ -5317,9 +5276,42 @@ gen_yield_var(codegen_scope *s, node *varnode, int val)
|
||||
{
|
||||
struct mrb_ast_yield_node *yield_n = yield_node(varnode);
|
||||
node *args = YIELD_NODE_ARGS(yield_n);
|
||||
codegen_scope *s2 = s;
|
||||
int lv = 0, ainfo = -1;
|
||||
int n = 0, nk = 0, sendv = 0;
|
||||
|
||||
/* Use traditional yield codegen logic */
|
||||
codegen_yield(s, args, val);
|
||||
while (!s2->mscope) {
|
||||
lv++;
|
||||
s2 = s2->prev;
|
||||
if (!s2) break;
|
||||
}
|
||||
if (s2) {
|
||||
ainfo = (int)s2->ainfo;
|
||||
}
|
||||
if (ainfo < 0) codegen_error(s, "invalid yield (SyntaxError)");
|
||||
if (lv > 0xf) codegen_error(s, "too deep nesting");
|
||||
push();
|
||||
if (args) {
|
||||
if (args->car) {
|
||||
n = gen_values(s, args->car, VAL, 14);
|
||||
if (n < 0) {
|
||||
n = sendv = 1;
|
||||
push();
|
||||
}
|
||||
}
|
||||
if (args->cdr->car) {
|
||||
nk = gen_hash(s, args->cdr->car->cdr, VAL, 14);
|
||||
if (nk < 0) {
|
||||
nk = 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
push();pop(); /* space for a block */
|
||||
pop_n(n + (nk == 15 ? 1 : nk * 2) + 1);
|
||||
genop_2S(s, OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf));
|
||||
if (sendv) n = CALL_MAXARGS;
|
||||
genop_3(s, OP_SEND, cursp(), new_sym(s, MRB_SYM_2(s->mrb, call)), n|(nk<<4));
|
||||
if (val) push();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -6473,15 +6465,10 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
codegen_op_asgn(s, tree, val);
|
||||
break;
|
||||
|
||||
|
||||
case NODE_RETURN:
|
||||
codegen_return(s, tree, val);
|
||||
break;
|
||||
|
||||
case NODE_YIELD:
|
||||
codegen_yield(s, tree, val);
|
||||
break;
|
||||
|
||||
case NODE_BREAK:
|
||||
codegen_break(s, tree, val);
|
||||
break;
|
||||
|
||||
@@ -611,7 +611,6 @@ 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);
|
||||
static node* new_return_var(parser_state *p, node *args);
|
||||
static node* new_yield_var(parser_state *p, node *args);
|
||||
static node* new_float_var(parser_state *p, const char *value);
|
||||
|
||||
/* (:if cond then else) */
|
||||
@@ -1166,19 +1165,6 @@ new_return_var(parser_state *p, node *args)
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)n);
|
||||
}
|
||||
|
||||
static node*
|
||||
new_yield_var(parser_state *p, node *args)
|
||||
{
|
||||
size_t total_size = sizeof(struct mrb_ast_yield_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
|
||||
struct mrb_ast_yield_node *n = (struct mrb_ast_yield_node*)parser_alloc_var(p, total_size, class);
|
||||
|
||||
init_var_header(&n->header, p, NODE_YIELD, class);
|
||||
n->args = args;
|
||||
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)n);
|
||||
}
|
||||
|
||||
/* Variable-sized literal node creation functions */
|
||||
|
||||
@@ -1351,10 +1337,15 @@ new_yield(parser_state *p, node *c)
|
||||
yyerror(NULL, p, "both block arg and actual block given");
|
||||
}
|
||||
|
||||
if (p->var_nodes_enabled) {
|
||||
return new_yield_var(p, c);
|
||||
}
|
||||
return cons_head((node*)NODE_YIELD, c);
|
||||
size_t total_size = sizeof(struct mrb_ast_yield_node);
|
||||
enum mrb_ast_size_class class = size_to_class(total_size);
|
||||
|
||||
struct mrb_ast_yield_node *n = (struct mrb_ast_yield_node*)parser_alloc_var(p, total_size, class);
|
||||
|
||||
init_var_header(&n->header, p, NODE_YIELD, class);
|
||||
n->args = c;
|
||||
|
||||
return cons_head((node*)NODE_VARIABLE, (node*)n);
|
||||
}
|
||||
|
||||
/* (:return . c) */
|
||||
@@ -2323,6 +2314,11 @@ call_with_block(parser_state *p, node *a, node *b)
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (var_type == NODE_YIELD) {
|
||||
/* Variable-sized yield nodes should generate an error when given a block */
|
||||
yyerror(NULL, p, "block given to yield");
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* For other variable-sized nodes, fall through to default */
|
||||
break;
|
||||
@@ -4270,12 +4266,7 @@ do_block : keyword_do_block
|
||||
|
||||
block_call : command do_block
|
||||
{
|
||||
if (node_to_type($1->car) == NODE_YIELD) {
|
||||
yyerror(&@1, p, "block given to yield");
|
||||
}
|
||||
else {
|
||||
call_with_block(p, $1, $2);
|
||||
}
|
||||
call_with_block(p, $1, $2);
|
||||
$$ = $1;
|
||||
}
|
||||
| block_call call_op2 operation2 opt_paren_args
|
||||
|
||||
+1110
-1119
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user