mruby-compiler: remove redundant fields from call node structure

Remove argc, has_kwargs, has_block, and reserved fields from
mrb_ast_call_node since this information can be determined from the
callargs structure at runtime. Simplify new_call() and call_with_block()
functions to eliminate field analysis during parsing.

Add callargs_empty() helper function to check for empty arguments and
update gen_if_var() to use it instead of accessing removed argc field.

This change reduces memory usage per call node while maintaining full
functionality through runtime analysis of the callargs structure.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-09-26 00:09:09 +09:00
parent b3d501e98c
commit 39cf3038c6
4 changed files with 1604 additions and 1641 deletions
+17 -15
View File
@@ -3427,24 +3427,20 @@ gen_call_var(codegen_scope *s, node *varnode, int val)
}
/* Handle keyword arguments if present */
if (CALL_NODE_HAS_KWARGS(call)) {
if (callargs->keyword_args) {
nk = gen_hash(s, callargs->keyword_args, VAL, 14);
if (nk < 0) {
nk = 15;
}
noop = 1;
if (callargs->keyword_args) {
nk = gen_hash(s, callargs->keyword_args, 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;
}
if (callargs->block_arg) {
codegen(s, callargs->block_arg, VAL);
pop();
blk = 1;
noop = 1;
}
}
@@ -3731,6 +3727,12 @@ gen_array_var(codegen_scope *s, node *varnode, int val)
}
/* Phase 3 Variable Node Codegen Functions */
static mrb_bool
callargs_empty(node *n)
{
if (!n) return TRUE;
return (CALLARGS_NODE_REGULAR(n) == 0 && CALLARGS_NODE_KEYWORDS(n) == 0 && CALLARGS_NODE_BLOCK(n) == 0);
}
static void
gen_if_var(codegen_scope *s, node *varnode, int val)
@@ -3760,7 +3762,7 @@ gen_if_var(codegen_scope *s, node *varnode, int val)
/* Variable-sized NODE_CALL */
struct mrb_ast_call_node *call_n = (struct mrb_ast_call_node*)condition;
mrb_sym sym_nil_p = MRB_SYM_Q_2(s->mrb, nil);
if (call_n->method_name == sym_nil_p && call_n->argc == 0) {
if (call_n->method_name == sym_nil_p && callargs_empty(call_n->args)) {
nil_p = TRUE;
codegen(s, call_n->receiver, VAL);
}
-7
View File
@@ -182,11 +182,7 @@ struct mrb_ast_call_node {
struct mrb_ast_var_header header; /* 8 bytes */
struct mrb_ast_node *receiver; /* Receiver object */
mrb_sym method_name; /* Method name symbol */
uint8_t argc; /* Number of regular arguments */
uint8_t has_kwargs:1; /* Has keyword arguments */
uint8_t has_block:1; /* Has block argument */
uint8_t safe_call:1; /* Safe navigation (&.) */
uint8_t reserved:5; /* Reserved for future flags */
struct mrb_ast_node *args; /* Arguments Information */
};
@@ -400,10 +396,7 @@ struct mrb_ast_super_node {
/* Phase 2 value access macros */
#define CALL_NODE_RECEIVER(n) (call_node(n)->receiver)
#define CALL_NODE_METHOD(n) (call_node(n)->method_name)
#define CALL_NODE_ARGC(n) (call_node(n)->argc)
#define CALL_NODE_ARGS(n) (call_node(n)->args)
#define CALL_NODE_HAS_KWARGS(n) (call_node(n)->has_kwargs)
#define CALL_NODE_HAS_BLOCK(n) (call_node(n)->has_block)
#define CALL_NODE_SAFE(n) (call_node(n)->safe_call)
#define ARRAY_NODE_ELEMENTS(n) (array_node(n)->elements)
+1 -17
View File
@@ -620,26 +620,11 @@ new_self(parser_state *p)
static node*
new_call(parser_state *p, node *receiver, mrb_sym method, node *args, int pass)
{
/* Analyze the arguments to determine structure */
uint8_t has_kwargs = 0;
uint8_t has_block = 0;
if (args) {
/* 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) */ struct mrb_ast_call_node *n = (struct mrb_ast_call_node*)parser_palloc(p, sizeof(struct mrb_ast_call_node));
init_var_header(&n->header, p, NODE_CALL);
n->receiver = receiver;
n->method_name = method;
n->argc = 0; /* argc will be determined at codegen time to handle splats */
n->has_kwargs = has_kwargs;
n->has_block = has_block;
n->safe_call = (pass == 0); /* pass == 0 means safe call (&.) */
n->reserved = 0;
/* Store args pointer directly - no need to unpack and repack */
n->args = args;
@@ -1710,11 +1695,10 @@ call_with_block(parser_state *p, node *a, node *b)
{
struct mrb_ast_call_node *call = call_node(a);
if (call->has_block) {
if (call->args && CALLARGS_NODE_BLOCK(call->args)) {
yyerror(NULL, p, "both block arg and actual block given");
return;
}
call->has_block = 1;
/* Use existing args and add block */
if (call->args) {
File diff suppressed because it is too large Load Diff