From cf20687ee70c90dd9ab5eff968a8969cc32f2ae5 Mon Sep 17 00:00:00 2001 From: dearblue Date: Fri, 8 May 2026 11:51:25 +0900 Subject: [PATCH] mruby-eval: unify f_instance_eval and f_class_eval Their bodies were nearly identical: same argument parsing, same proc creation, same target-class plumbing. The only differences are which method to delegate to in the block-given case (mrb_obj_instance_eval vs. mrb_mod_module_eval) and which class to use as the target (singleton vs. self-as-class). Extract the shared logic into object_eval(self, class_eval). The two top-level dispatchers become one-line wrappers. Closes #6579, picked from PR by dearblue. Co-authored-by: Claude --- mrbgems/mruby-eval/src/eval.c | 59 ++++++++++++++--------------------- 1 file changed, 24 insertions(+), 35 deletions(-) diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index def92a691..24fee236f 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -322,27 +322,32 @@ f_eval(mrb_state *mrb, mrb_value self) * k.instance_eval { the_secret } #=> "Ssssh! The secret is 99." * k.instance_eval("@secret = 5") #=> 5 */ +static mrb_value +object_eval(mrb_state *mrb, mrb_value self, mrb_bool class_eval) +{ + if (mrb_block_given_p(mrb)) { + mrb_get_args(mrb, ""); + return class_eval ? mrb_mod_module_eval(mrb, self) : mrb_obj_instance_eval(mrb, self); + } + + const char *s; + mrb_int len; + const char *file = NULL; + mrb_int line = 1; + mrb_get_args(mrb, "s|zi", &s, &len, &file, &line); + + struct RClass *c = class_eval ? mrb_class_ptr(self) : mrb_singleton_class_ptr(mrb, self); + struct RProc *proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line); + MRB_PROC_SET_TARGET_CLASS(proc, c); + mrb_assert(!MRB_PROC_CFUNC_P(proc)); + mrb_vm_ci_target_class_set(mrb->c->ci, c); + return eval_irep(mrb, self, proc); +} + static mrb_value f_instance_eval(mrb_state *mrb, mrb_value self) { - if (!mrb_block_given_p(mrb)) { - const char *s; - mrb_int len; - const char *file = NULL; - mrb_int line = 1; - - mrb_get_args(mrb, "s|zi", &s, &len, &file, &line); - struct RClass *c = mrb_singleton_class_ptr(mrb, self); - struct RProc *proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line); - MRB_PROC_SET_TARGET_CLASS(proc, c); - mrb_assert(!MRB_PROC_CFUNC_P(proc)); - mrb_vm_ci_target_class_set(mrb->c->ci, c); - return eval_irep(mrb, self, proc); - } - else { - mrb_get_args(mrb, ""); - return mrb_obj_instance_eval(mrb, self); - } + return object_eval(mrb, self, FALSE); } /* @@ -369,23 +374,7 @@ f_instance_eval(mrb_state *mrb, mrb_value self) static mrb_value f_class_eval(mrb_state *mrb, mrb_value self) { - if (!mrb_block_given_p(mrb)) { - const char *s; - mrb_int len; - const char *file = NULL; - mrb_int line = 1; - - mrb_get_args(mrb, "s|zi", &s, &len, &file, &line); - struct RProc *proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line); - MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(self)); - mrb_assert(!MRB_PROC_CFUNC_P(proc)); - mrb_vm_ci_target_class_set(mrb->c->ci, mrb_class_ptr(self)); - return eval_irep(mrb, self, proc); - } - else { - mrb_get_args(mrb, ""); - return mrb_mod_module_eval(mrb, self); - } + return object_eval(mrb, self, TRUE); } /*