mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-compiler: simplify callargs to use direct pointer casting
Replace variable-sized NODE_VARIABLE wrapper with fixed-size struct allocation, following the same pattern as new_args(). This eliminates the need for NODE_VARIABLE checking and uses direct casting instead. Changes: - Remove mrb_ast_var_header from callargs struct - Use parser_palloc instead of parser_alloc_var for fixed-size allocation - Update all access points to use direct casting: (struct mrb_ast_callargs*) - Remove unnecessary backward compatibility code for newly introduced NODE_CALLARGS Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -3470,33 +3470,36 @@ gen_call_var(codegen_scope *s, node *varnode, int val)
|
||||
}
|
||||
|
||||
/* Generate arguments - use gen_values to properly handle splat */
|
||||
if (args && args->car) {
|
||||
n = gen_values(s, args->car, VAL, 14);
|
||||
if (n < 0) { /* variable length (contains splat) */
|
||||
n = 15;
|
||||
push();
|
||||
noop = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle keyword arguments if present */
|
||||
if (CALL_NODE_HAS_KWARGS(call)) {
|
||||
if (args && args->cdr && args->cdr->car) {
|
||||
nk = gen_hash(s, args->cdr->car->cdr, VAL, 14);
|
||||
if (nk < 0) {
|
||||
nk = 15;
|
||||
if (args) {
|
||||
struct mrb_ast_callargs *callargs = (struct mrb_ast_callargs*)args;
|
||||
if (callargs->regular_args) {
|
||||
n = gen_values(s, callargs->regular_args, VAL, 14);
|
||||
if (n < 0) { /* variable length (contains splat) */
|
||||
n = 15;
|
||||
push();
|
||||
noop = 1;
|
||||
}
|
||||
noop = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle block if present */
|
||||
if (CALL_NODE_HAS_BLOCK(call)) {
|
||||
if (args && args->cdr && args->cdr->cdr) {
|
||||
codegen(s, args->cdr->cdr, VAL);
|
||||
pop();
|
||||
blk = 1;
|
||||
noop = 1;
|
||||
/* Handle keyword arguments if present */
|
||||
if (CALL_NODE_HAS_KWARGS(call)) {
|
||||
if (callargs->keyword_args) {
|
||||
nk = gen_hash(s, callargs->keyword_args->cdr, VAL, 14);
|
||||
if (nk < 0) {
|
||||
nk = 15;
|
||||
}
|
||||
noop = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle block if present */
|
||||
if (CALL_NODE_HAS_BLOCK(call)) {
|
||||
if (callargs->block_arg) {
|
||||
codegen(s, callargs->block_arg, VAL);
|
||||
pop();
|
||||
blk = 1;
|
||||
noop = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3609,44 +3612,47 @@ gen_call_assign_var(codegen_scope *s, node *varnode, node *rhs, int sp, int val)
|
||||
}
|
||||
|
||||
/* Generate arguments from original call */
|
||||
if (args && args->car) {
|
||||
node *regular_args = args->car;
|
||||
node *arg_iter = regular_args;
|
||||
while (arg_iter) {
|
||||
codegen(s, arg_iter->car, VAL);
|
||||
n++;
|
||||
arg_iter = arg_iter->cdr;
|
||||
if (args) {
|
||||
struct mrb_ast_callargs *callargs = (struct mrb_ast_callargs*)args;
|
||||
if (callargs->regular_args) {
|
||||
node *regular_args = callargs->regular_args;
|
||||
node *arg_iter = regular_args;
|
||||
while (arg_iter) {
|
||||
codegen(s, arg_iter->car, VAL);
|
||||
n++;
|
||||
arg_iter = arg_iter->cdr;
|
||||
}
|
||||
if (n > 13) { /* leave room for rhs */
|
||||
pop_n(n);
|
||||
genop_2(s, OP_ARRAY, cursp(), n);
|
||||
push();
|
||||
n = 15;
|
||||
noop = 1;
|
||||
}
|
||||
}
|
||||
if (n > 13) { /* leave room for rhs */
|
||||
pop_n(n);
|
||||
genop_2(s, OP_ARRAY, cursp(), n);
|
||||
|
||||
/* Handle keyword arguments if present */
|
||||
if (callargs->keyword_args) {
|
||||
node *kwargs = callargs->keyword_args;
|
||||
if (n == 13 || n == 14) {
|
||||
pop_n(n);
|
||||
genop_2(s, OP_ARRAY, cursp(), n);
|
||||
push();
|
||||
n = 15;
|
||||
}
|
||||
gen_hash(s, kwargs->cdr, VAL, 0);
|
||||
if (n < 14) {
|
||||
n++;
|
||||
}
|
||||
else {
|
||||
pop_n(2);
|
||||
genop_2(s, OP_ARYPUSH, cursp(), 1);
|
||||
}
|
||||
push();
|
||||
n = 15;
|
||||
noop = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle keyword arguments if present */
|
||||
if (args && args->cdr && args->cdr->car) {
|
||||
node *kwargs = args->cdr->car;
|
||||
if (n == 13 || n == 14) {
|
||||
pop_n(n);
|
||||
genop_2(s, OP_ARRAY, cursp(), n);
|
||||
push();
|
||||
n = 15;
|
||||
}
|
||||
gen_hash(s, kwargs->cdr, VAL, 0);
|
||||
if (n < 14) {
|
||||
n++;
|
||||
}
|
||||
else {
|
||||
pop_n(2);
|
||||
genop_2(s, OP_ARYPUSH, cursp(), 1);
|
||||
}
|
||||
push();
|
||||
noop = 1;
|
||||
}
|
||||
|
||||
/* Generate rhs (the assigned value) */
|
||||
if (rhs) {
|
||||
codegen(s, rhs, VAL);
|
||||
@@ -4696,15 +4702,16 @@ gen_yield_var(codegen_scope *s, node *varnode, int val)
|
||||
if (lv > 0xf) codegen_error(s, "too deep nesting");
|
||||
push();
|
||||
if (args) {
|
||||
if (args->car) {
|
||||
n = gen_values(s, args->car, VAL, 14);
|
||||
struct mrb_ast_callargs *callargs = (struct mrb_ast_callargs*)args;
|
||||
if (callargs->regular_args) {
|
||||
n = gen_values(s, callargs->regular_args, VAL, 14);
|
||||
if (n < 0) {
|
||||
n = sendv = 1;
|
||||
push();
|
||||
}
|
||||
}
|
||||
if (args->cdr->car) {
|
||||
nk = gen_hash(s, args->cdr->car->cdr, VAL, 14);
|
||||
if (callargs->keyword_args) {
|
||||
nk = gen_hash(s, callargs->keyword_args->cdr, VAL, 14);
|
||||
if (nk < 0) {
|
||||
nk = 15;
|
||||
}
|
||||
@@ -4735,31 +4742,36 @@ gen_super_var(codegen_scope *s, node *varnode, int val)
|
||||
if (!s2) break;
|
||||
}
|
||||
if (tree) {
|
||||
node *args = tree->car;
|
||||
if (args) {
|
||||
st = n = gen_values(s, args, VAL, 14);
|
||||
if (n < 0) {
|
||||
st = 1; n = 15;
|
||||
/* Handle callargs structure - direct casting like new_args() */
|
||||
struct mrb_ast_callargs *callargs = (struct mrb_ast_callargs*)tree;
|
||||
|
||||
/* Regular arguments */
|
||||
if (callargs->regular_args) {
|
||||
st = n = gen_values(s, callargs->regular_args, VAL, 14);
|
||||
if (n < 0) {
|
||||
st = 1; n = 15;
|
||||
push();
|
||||
}
|
||||
}
|
||||
|
||||
/* Keyword arguments */
|
||||
if (callargs->keyword_args) {
|
||||
nk = gen_hash(s, callargs->keyword_args->cdr, VAL, 14);
|
||||
if (nk < 0) {st++; nk = 15;}
|
||||
else st += nk*2;
|
||||
n |= nk<<4;
|
||||
}
|
||||
|
||||
/* Block arguments */
|
||||
if (callargs->block_arg) {
|
||||
codegen(s, callargs->block_arg, VAL);
|
||||
}
|
||||
else if (s2) gen_blkmove(s, s2->ainfo, lv);
|
||||
else {
|
||||
genop_1(s, OP_LOADNIL, cursp());
|
||||
push();
|
||||
}
|
||||
}
|
||||
/* keyword arguments */
|
||||
if (tree->cdr->car) {
|
||||
nk = gen_hash(s, tree->cdr->car->cdr, VAL, 14);
|
||||
if (nk < 0) {st++; nk = 15;}
|
||||
else st += nk*2;
|
||||
n |= nk<<4;
|
||||
}
|
||||
/* block arguments */
|
||||
if (tree->cdr->cdr) {
|
||||
codegen(s, tree->cdr->cdr, VAL);
|
||||
}
|
||||
else if (s2) gen_blkmove(s, s2->ainfo, lv);
|
||||
else {
|
||||
genop_1(s, OP_LOADNIL, cursp());
|
||||
push();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (s2) gen_blkmove(s, s2->ainfo, lv);
|
||||
else {
|
||||
@@ -5373,16 +5385,22 @@ gen_zsuper_var(codegen_scope *s, node *varnode, int val)
|
||||
n |= CALL_MAXARGS<<4;
|
||||
push();
|
||||
}
|
||||
/* block argument - tree here is args, so check tree->cdr->cdr */
|
||||
if (tree && tree->cdr && tree->cdr->cdr) {
|
||||
push();
|
||||
codegen(s, tree->cdr->cdr, VAL);
|
||||
/* block argument - tree here is args, so check for block */
|
||||
if (tree) {
|
||||
struct mrb_ast_callargs *callargs = (struct mrb_ast_callargs*)tree;
|
||||
if (callargs->block_arg) {
|
||||
push();
|
||||
codegen(s, callargs->block_arg, VAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* block argument */
|
||||
if (tree && tree->cdr && tree->cdr->cdr) {
|
||||
codegen(s, tree->cdr->cdr, VAL);
|
||||
if (tree) {
|
||||
struct mrb_ast_callargs *callargs = (struct mrb_ast_callargs*)tree;
|
||||
if (callargs->block_arg) {
|
||||
codegen(s, callargs->block_arg, VAL);
|
||||
}
|
||||
}
|
||||
else if (s2) {
|
||||
gen_blkmove(s, 0, lv);
|
||||
|
||||
@@ -60,6 +60,7 @@ enum node_type {
|
||||
NODE_XSTR,
|
||||
NODE_REGX,
|
||||
NODE_DREGX,
|
||||
NODE_CALLARGS,
|
||||
NODE_KW_ARG,
|
||||
NODE_KW_REST_ARGS,
|
||||
NODE_SPLAT,
|
||||
@@ -620,9 +621,17 @@ struct mrb_ast_args {
|
||||
mrb_sym block_arg; /* Block argument symbol (0 = none) */
|
||||
};
|
||||
|
||||
/* Call arguments structure - replaces cons-based new_callargs */
|
||||
struct mrb_ast_callargs {
|
||||
struct mrb_ast_node *regular_args; /* Cons list of regular arguments (preserves splat compatibility) */
|
||||
struct mrb_ast_node *keyword_args; /* Keyword arguments hash node */
|
||||
struct mrb_ast_node *block_arg; /* Block argument node */
|
||||
};
|
||||
|
||||
/* Advanced node casting macros */
|
||||
#define rescue_node(n) ((struct mrb_ast_rescue_node*)(n))
|
||||
#define block_node(n) ((struct mrb_ast_block_node*)(n))
|
||||
#define callargs_node(n) ((struct mrb_ast_callargs*)(n))
|
||||
|
||||
/* Advanced node value access macros */
|
||||
#define RESCUE_NODE_BODY(n) (rescue_node(n)->body)
|
||||
@@ -643,6 +652,10 @@ struct mrb_ast_args {
|
||||
#define ARGS_TAIL_NODE_KWREST(n) (args_tail_node(n)->kwrest)
|
||||
#define ARGS_TAIL_NODE_BLOCK(n) (args_tail_node(n)->block)
|
||||
|
||||
#define CALLARGS_NODE_REGULAR(n) (callargs_node(n)->regular_args)
|
||||
#define CALLARGS_NODE_KEYWORDS(n) (callargs_node(n)->keyword_args)
|
||||
#define CALLARGS_NODE_BLOCK(n) (callargs_node(n)->block_arg)
|
||||
|
||||
// Group 8: Control Flow Statements
|
||||
struct mrb_ast_break_node {
|
||||
struct mrb_ast_var_header hdr;
|
||||
|
||||
@@ -728,13 +728,10 @@ new_call(parser_state *p, node *receiver, mrb_sym method, node *args, int pass)
|
||||
uint8_t has_block = 0;
|
||||
|
||||
if (args) {
|
||||
/* Check for kwargs and block */
|
||||
if (args->cdr) {
|
||||
has_kwargs = (args->cdr->car != NULL);
|
||||
if (args->cdr->cdr) {
|
||||
has_block = (args->cdr->cdr != NULL);
|
||||
}
|
||||
}
|
||||
/* Handle callargs structure - direct casting like new_args() */
|
||||
struct mrb_ast_callargs *callargs = (struct mrb_ast_callargs*)args;
|
||||
has_kwargs = (callargs->keyword_args != NULL);
|
||||
has_block = (callargs->block_arg != NULL);
|
||||
}
|
||||
|
||||
/* Calculate size needed (fixed size now) */
|
||||
@@ -770,7 +767,16 @@ new_fcall(parser_state *p, mrb_sym b, node *c)
|
||||
static node*
|
||||
new_callargs(parser_state *p, node *a, node *b, node *c)
|
||||
{
|
||||
return cons_head(a, cons(b, c));
|
||||
/* Allocate struct mrb_ast_callargs (fixed size, like new_args) */
|
||||
struct mrb_ast_callargs *callargs = (struct mrb_ast_callargs*)parser_palloc(p, sizeof(struct mrb_ast_callargs));
|
||||
|
||||
/* Initialize members directly */
|
||||
callargs->regular_args = a; /* Cons list of regular arguments (preserves splat compatibility) */
|
||||
callargs->keyword_args = b; /* Keyword arguments hash node */
|
||||
callargs->block_arg = c; /* Block argument node */
|
||||
|
||||
/* Return direct cast to node (like new_args) */
|
||||
return (node*)callargs;
|
||||
}
|
||||
|
||||
/* (:super . c) */
|
||||
@@ -804,8 +810,12 @@ new_zsuper(parser_state *p)
|
||||
static node*
|
||||
new_yield(parser_state *p, node *c)
|
||||
{
|
||||
if (c && c->cdr && c->cdr->cdr) {
|
||||
yyerror(NULL, p, "both block arg and actual block given");
|
||||
/* Handle callargs structure - direct casting like new_args() */
|
||||
if (c) {
|
||||
struct mrb_ast_callargs *callargs = (struct mrb_ast_callargs*)c;
|
||||
if (callargs->block_arg) {
|
||||
yyerror(NULL, p, "both block arg and actual block given");
|
||||
}
|
||||
}
|
||||
|
||||
size_t total_size = sizeof(struct mrb_ast_yield_node);
|
||||
@@ -1920,10 +1930,12 @@ static void
|
||||
args_with_block(parser_state *p, node *a, node *b)
|
||||
{
|
||||
if (b) {
|
||||
if (a->cdr && a->cdr->cdr) {
|
||||
/* Handle callargs structure - direct casting like new_args() */
|
||||
struct mrb_ast_callargs *callargs = (struct mrb_ast_callargs*)a;
|
||||
if (callargs->block_arg) {
|
||||
yyerror(NULL, p, "both block arg and actual block given");
|
||||
}
|
||||
a->cdr->cdr = b;
|
||||
callargs->block_arg = b;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2044,13 +2056,15 @@ cond(node *n)
|
||||
static node*
|
||||
ret_args(parser_state *p, node *n)
|
||||
{
|
||||
if (n->cdr->cdr) {
|
||||
/* Handle callargs structure - direct casting like new_args() */
|
||||
struct mrb_ast_callargs *callargs = (struct mrb_ast_callargs*)n;
|
||||
if (callargs->block_arg) {
|
||||
yyerror(NULL, p, "block argument should not be given");
|
||||
return NULL;
|
||||
}
|
||||
if (!n->car) return NULL;
|
||||
if (!n->car->cdr) return n->car->car;
|
||||
return new_array(p, n->car);
|
||||
if (!callargs->regular_args) return NULL;
|
||||
if (!callargs->regular_args->cdr) return callargs->regular_args->car;
|
||||
return new_array(p, callargs->regular_args);
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+1137
-1123
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user