From 32d7ddac3b997352eb6f0f4a81590d9c937b4576 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 13 Jun 2026 04:23:56 +0000 Subject: [PATCH] mruby-exit: fix SystemExit#status inaccessible from Ruby MRB_SYM(status) stores the exit status under the plain `status` symbol, which is invisible to Ruby's ivar machinery. Switch both the write site in mruby_exit.c and the read macro MRB_EXC_EXIT_STATUS in error.h to MRB_IVSYM(status) so the value is stored under `@status` and C callers remain consistent. Also add SystemExit#status accessor in mrblib to match CRuby behaviour. https://claude.ai/code/session_018JRpuKQBupCU8iNrvdtrmv --- include/mruby/error.h | 2 +- mrbgems/mruby-exit/mrblib/mruby-exit.rb | 5 +++++ mrbgems/mruby-exit/src/mruby_exit.c | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 mrbgems/mruby-exit/mrblib/mruby-exit.rb diff --git a/include/mruby/error.h b/include/mruby/error.h index dbe4bf7584..cc84e309c0 100644 --- a/include/mruby/error.h +++ b/include/mruby/error.h @@ -26,7 +26,7 @@ struct RException { #define MRB_EXC_EXIT 65536 #define MRB_EXC_EXIT_P(e) ((e)->flags & MRB_EXC_EXIT) /* retrieve status value from exc; need and */ -#define MRB_EXC_EXIT_STATUS(mrb,e) ((int)mrb_as_int((mrb),mrb_obj_iv_get((mrb),(e),MRB_SYM(status)))) +#define MRB_EXC_EXIT_STATUS(mrb,e) ((int)mrb_as_int((mrb),mrb_obj_iv_get((mrb),(e),MRB_IVSYM(status)))) /* exit with SystemExit status */ #define MRB_EXC_CHECK_EXIT(mrb,e) do {if (MRB_EXC_EXIT_P(e)) exit(MRB_EXC_EXIT_STATUS((mrb),(e)));} while (0) diff --git a/mrbgems/mruby-exit/mrblib/mruby-exit.rb b/mrbgems/mruby-exit/mrblib/mruby-exit.rb new file mode 100644 index 0000000000..477582ba83 --- /dev/null +++ b/mrbgems/mruby-exit/mrblib/mruby-exit.rb @@ -0,0 +1,5 @@ +class SystemExit + def status + @status + end +end diff --git a/mrbgems/mruby-exit/src/mruby_exit.c b/mrbgems/mruby-exit/src/mruby_exit.c index 13da43201e..1ba0fea660 100644 --- a/mrbgems/mruby-exit/src/mruby_exit.c +++ b/mrbgems/mruby-exit/src/mruby_exit.c @@ -44,7 +44,7 @@ f_exit(mrb_state *mrb, mrb_value self) mrb_value exc = mrb_obj_new(mrb, mrb_exc_get_id(mrb, MRB_SYM(SystemExit)), 0, NULL); struct RException *e = mrb_exc_ptr(exc); e->flags |= MRB_EXC_EXIT; - mrb_iv_set(mrb, exc, MRB_SYM(status), mrb_int_value(mrb, (mrb_int)status)); + mrb_iv_set(mrb, exc, MRB_IVSYM(status), mrb_int_value(mrb, (mrb_int)status)); mrb_exc_raise(mrb, exc); /* not reached */ return mrb_nil_value();