From c40802865a756f97ec8ffbd2361864b1fa291d4e Mon Sep 17 00:00:00 2001 From: dearblue Date: Sat, 19 Jun 2021 15:08:09 +0900 Subject: Added `MRB_API` function to get block arguments info. - ` mrb_block_given_p()` -- The name comes from CRuby's `rb_block_given_p ()` At the same time, it applies to `f_instance_eval()` and `f_class_eval()` of `mruby-eval`. --- include/mruby.h | 5 +++++ mrbgems/mruby-eval/src/eval.c | 18 ++++-------------- src/class.c | 11 +++++++++++ 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/include/mruby.h b/include/mruby.h index 04d8c1a53..02be8300f 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -1004,6 +1004,11 @@ MRB_API const mrb_value *mrb_get_argv(mrb_state *mrb); */ MRB_API mrb_value mrb_get_arg1(mrb_state *mrb); +/** + * Check if a block argument is given from mrb_state. + */ +MRB_API mrb_bool mrb_block_given_p(mrb_state *mrb); + /* `strlen` for character string literals (use with caution or `strlen` instead) Adjacent string literals are concatenated in C/C++ in translation phase 6. If `lit` is not one, the compiler will report a syntax error: diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index dc0017e1c..66f4d5283 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -195,12 +195,7 @@ f_eval(mrb_state *mrb, mrb_value self) static mrb_value f_instance_eval(mrb_state *mrb, mrb_value self) { - mrb_value b; - mrb_int argc; const mrb_value *argv; - - mrb_get_args(mrb, "*!&", &argv, &argc, &b); - - if (mrb_nil_p(b)) { + if (!mrb_block_given_p(mrb)) { const char *s; mrb_int len; const char *file = NULL; @@ -217,7 +212,7 @@ f_instance_eval(mrb_state *mrb, mrb_value self) return exec_irep(mrb, self, proc, NULL); } else { - mrb_get_args(mrb, "&", &b); + mrb_get_args(mrb, ""); return mrb_obj_instance_eval(mrb, self); } } @@ -225,12 +220,7 @@ f_instance_eval(mrb_state *mrb, mrb_value self) static mrb_value f_class_eval(mrb_state *mrb, mrb_value self) { - mrb_value b; - mrb_int argc; const mrb_value *argv; - - mrb_get_args(mrb, "*!&", &argv, &argc, &b); - - if (mrb_nil_p(b)) { + if (!mrb_block_given_p(mrb)) { const char *s; mrb_int len; const char *file = NULL; @@ -245,7 +235,7 @@ f_class_eval(mrb_state *mrb, mrb_value self) return exec_irep(mrb, self, proc, NULL); } else { - mrb_get_args(mrb, "&", &b); + mrb_get_args(mrb, ""); return mrb_mod_module_eval(mrb, self); } } diff --git a/src/class.c b/src/class.c index f02e280ef..f9474815e 100644 --- a/src/class.c +++ b/src/class.c @@ -859,6 +859,17 @@ mrb_get_arg1(mrb_state *mrb) return array_argv[0]; } +MRB_API mrb_bool +mrb_block_given_p(mrb_state *mrb) +{ + const mrb_callinfo *ci = mrb->c->ci; + int argc = ci->argc; + int idx = (argc < 0) ? 2 : argc + 1; + mrb_value b = ci->stack[idx]; + + return !mrb_nil_p(b); +} + void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self); /* -- cgit v1.2.3