mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-compiler: add no_return_value context flag for script optimization
when running scripts via mruby -e or file, return values are unused. this adds a no_return_value flag to skip generating unnecessary code. for parallel assignment like a,b = 1,2: - before: 18 bytes, 5 registers, creates temporary array - after: 5 bytes, 3 registers, direct register assignment, no RETURN the flag is set only for the main program, not for libraries loaded with -r option. eval() and mirb continue returning values correctly. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,7 @@ typedef struct mrb_ccontext {
|
||||
mrb_bool keep_lv:1;
|
||||
mrb_bool no_optimize:1;
|
||||
mrb_bool no_ext_ops:1;
|
||||
mrb_bool no_return_value:1;
|
||||
const struct RProc *upper;
|
||||
|
||||
size_t parser_nerr;
|
||||
@@ -125,6 +126,7 @@ struct mrb_parser_state {
|
||||
mrb_bool no_optimize:1;
|
||||
mrb_bool capture_errors:1;
|
||||
mrb_bool no_ext_ops:1;
|
||||
mrb_bool no_return_value:1;
|
||||
const struct RProc *upper;
|
||||
struct mrb_parser_message error_buffer[10];
|
||||
struct mrb_parser_message warn_buffer[10];
|
||||
|
||||
@@ -345,6 +345,7 @@ main(int argc, char **argv)
|
||||
|
||||
/* set program filename */
|
||||
mrb_ccontext_filename(mrb, c, cmdline);
|
||||
c->no_return_value = TRUE; /* main program doesn't need return value */
|
||||
|
||||
/* Load program */
|
||||
if (args.mrbfile || mrb_extension_p(cmdline)) {
|
||||
|
||||
@@ -2603,14 +2603,25 @@ scope_body(codegen_scope *s, node *locals, node *body, int val)
|
||||
codegen_scope *scope = scope_new(s->mrb, s, locals);
|
||||
|
||||
/* Generate code for the body of the scope. */
|
||||
codegen(scope, body, VAL);
|
||||
/* Ensure the scope returns the value of its last expression. */
|
||||
gen_return(scope, OP_RETURN, scope->sp-1);
|
||||
codegen(scope, body, val);
|
||||
|
||||
/* If this is the outermost scope (e.g., top-level script), add OP_STOP. */
|
||||
if (!s->iseq) { /* s->iseq would be NULL for the initial dummy scope. */
|
||||
if (val) {
|
||||
gen_return(scope, OP_RETURN, scope->sp-1);
|
||||
}
|
||||
/* skip RETURN when no_return_value; STOP will terminate VM */
|
||||
genop_0(scope, OP_STOP);
|
||||
}
|
||||
else {
|
||||
/* Ensure the scope returns the value of its last expression. */
|
||||
if (val) {
|
||||
gen_return(scope, OP_RETURN, scope->sp-1);
|
||||
}
|
||||
else {
|
||||
gen_return(scope, OP_RETURN, 0); /* return nil */
|
||||
}
|
||||
}
|
||||
|
||||
/* Finalize the IREP for this scope. */
|
||||
scope_finish(scope);
|
||||
@@ -6120,7 +6131,7 @@ codegen_scope_node(codegen_scope *s, const node *varnode, int val)
|
||||
struct mrb_ast_scope_node *scope = scope_node(varnode);
|
||||
|
||||
/* Pass locals and body directly to scope_body() */
|
||||
scope_body(s, scope->locals, scope->body, NOVAL);
|
||||
scope_body(s, scope->locals, scope->body, val);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -6937,5 +6948,5 @@ generate_code(mrb_state *mrb, parser_state *p, int val)
|
||||
MRB_API struct RProc*
|
||||
mrb_generate_code(mrb_state *mrb, parser_state *p)
|
||||
{
|
||||
return generate_code(mrb, p, VAL);
|
||||
return generate_code(mrb, p, p->no_return_value ? NOVAL : VAL);
|
||||
}
|
||||
|
||||
@@ -7459,6 +7459,7 @@ parser_init_cxt(parser_state *p, mrb_ccontext *cxt)
|
||||
p->capture_errors = cxt->capture_errors;
|
||||
p->no_optimize = cxt->no_optimize;
|
||||
p->no_ext_ops = cxt->no_ext_ops;
|
||||
p->no_return_value = cxt->no_return_value;
|
||||
p->upper = cxt->upper;
|
||||
if (cxt->partial_hook) {
|
||||
p->cxt = cxt;
|
||||
|
||||
+3828
-3890
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user