From d1e8085a1ef6228eeca483932d6ca5ddf1a34d14 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 10 Nov 2025 23:04:57 +0900 Subject: [PATCH] mruby-binding: add error helper functions to eliminate goto Add badname_error() and caller_error() helper functions to replace goto statements used for error handling. These functions are marked with mrb_noreturn attribute since they call mrb_raise() which never returns. Co-authored-by: Claude --- mrbgems/mruby-binding/src/binding.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/mrbgems/mruby-binding/src/binding.c b/mrbgems/mruby-binding/src/binding.c index 34e089248..d5e3a0424 100644 --- a/mrbgems/mruby-binding/src/binding.c +++ b/mrbgems/mruby-binding/src/binding.c @@ -184,29 +184,34 @@ binding_initialize_copy(mrb_state *mrb, mrb_value binding) return binding; } +static mrb_noreturn void +badname_error(mrb_state *mrb, mrb_sym id) +{ + mrb_raisef(mrb, E_NAME_ERROR, "wrong local variable name %!n for binding", id); +} + static void binding_local_variable_name_check(mrb_state *mrb, mrb_sym id) { if (id == 0) { - badname: - mrb_raisef(mrb, E_NAME_ERROR, "wrong local variable name %!n for binding", id); + badname_error(mrb, id); } mrb_int len; const char *name = mrb_sym_name_len(mrb, id, &len); if (len == 0) { - goto badname; + badname_error(mrb, id); } if (ISASCII(*name) && !(*name == '_' || ISLOWER(*name))) { - goto badname; + badname_error(mrb, id); } len--; name++; for (; len > 0; len--, name++) { if (ISASCII(*name) && !(*name == '_' || ISALNUM(*name))) { - goto badname; + badname_error(mrb, id); } } } @@ -464,6 +469,12 @@ mrb_binding_new(mrb_state *mrb, const struct RProc *proc, mrb_value recv, struct * b = get_binding("hello") * b.eval("param") #=> "hello" */ +static mrb_noreturn void +caller_error(mrb_state *mrb) +{ + mrb_raise(mrb, E_RUNTIME_ERROR, "Cannot create Binding object for non-Ruby caller"); +} + static mrb_value mrb_f_binding(mrb_state *mrb, mrb_value self) { @@ -471,12 +482,11 @@ mrb_f_binding(mrb_state *mrb, mrb_value self) struct REnv *env; if (mrb->c->ci->cci != 0) { - caller_err: - mrb_raise(mrb, E_RUNTIME_ERROR, "Cannot create Binding object for non-Ruby caller"); + caller_error(mrb); } proc = (struct RProc*)mrb_proc_get_caller(mrb, &env); if (!env || MRB_PROC_CFUNC_P(proc)) { - goto caller_err; + caller_error(mrb); } return mrb_binding_new(mrb, proc, self, env); }