ruby-changes:60755
From: Nobuyoshi <ko1@a...>
Date: Mon, 13 Apr 2020 00:02:32 +0900 (JST)
Subject: [ruby-changes:60755] 4c8e3f1241 (master): Make rb_scan_args implementations same
https://git.ruby-lang.org/ruby.git/commit/?id=4c8e3f1241 From 4c8e3f1241e1cc4904e476900bb5309622ba7304 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada <nobu@r...> Date: Sun, 12 Apr 2020 23:29:22 +0900 Subject: Make rb_scan_args implementations same between rb_scan_args_set and rb_scan_args_assign + rb_scan_args_result. diff --git a/class.c b/class.c index cf25ad2..c19de64 100644 --- a/class.c +++ b/class.c @@ -2000,14 +2000,12 @@ rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, V https://github.com/ruby/ruby/blob/trunk/class.c#L2000 struct rb_scan_args_t { int kw_flag; - int f_var; - int f_hash; - int f_block; int n_lead; int n_opt; int n_trail; - int n_mand; - int argi; + bool f_var; + bool f_hash; + bool f_block; }; static void @@ -2045,7 +2043,6 @@ rb_scan_args_parse(int kw_flag, const char *fmt, struct rb_scan_args_t *arg) https://github.com/ruby/ruby/blob/trunk/class.c#L2043 if (*p != '\0') { rb_fatal("bad scan arg format: %s", fmt); } - arg->n_mand = arg->n_lead + arg->n_trail; } static int @@ -2053,29 +2050,38 @@ rb_scan_args_assign(const struct rb_scan_args_t *arg, int argc, const VALUE *con https://github.com/ruby/ruby/blob/trunk/class.c#L2050 { int i, argi = 0; VALUE *var, hash = Qnil; - - if (arg->f_hash && argc > 0) { +#define rb_scan_args_next_param() va_arg(vargs, VALUE *) + const int kw_flag = arg->kw_flag; + const int n_lead = arg->n_lead; + const int n_opt = arg->n_opt; + const int n_trail = arg->n_trail; + const int n_mand = n_lead + n_trail; + const bool f_var = arg->f_var; + const bool f_hash = arg->f_hash; + const bool f_block = arg->f_block; + + if (f_hash && argc > 0) { VALUE last = argv[argc - 1]; - if (rb_scan_args_keyword_p(arg->kw_flag, last)) { + if (rb_scan_args_keyword_p(kw_flag, last)) { hash = rb_hash_dup(last); argc--; } } - if (argc < arg->n_mand) { + if (argc < n_mand) { goto argc_error; } /* capture leading mandatory arguments */ - for (i = arg->n_lead; i-- > 0; ) { - var = va_arg(vargs, VALUE *); + for (i = n_lead; i-- > 0; ) { + var = rb_scan_args_next_param(); if (var) *var = argv[argi]; argi++; } /* capture optional arguments */ - for (i = arg->n_opt; i-- > 0; ) { - var = va_arg(vargs, VALUE *); - if (argi < argc - arg->n_trail) { + for (i = n_opt; i-- > 0; ) { + var = rb_scan_args_next_param(); + if (argi < argc - n_trail) { if (var) *var = argv[argi]; argi++; } @@ -2084,12 +2090,12 @@ rb_scan_args_assign(const struct rb_scan_args_t *arg, int argc, const VALUE *con https://github.com/ruby/ruby/blob/trunk/class.c#L2090 } } /* capture variable length arguments */ - if (arg->f_var) { - int n_var = argc - argi - arg->n_trail; + if (f_var) { + int n_var = argc - argi - n_trail; - var = va_arg(vargs, VALUE *); + var = rb_scan_args_next_param(); if (0 < n_var) { - if (var) *var = rb_ary_new4(n_var, &argv[argi]); + if (var) *var = rb_ary_new_from_values(n_var, &argv[argi]); argi += n_var; } else { @@ -2097,19 +2103,19 @@ rb_scan_args_assign(const struct rb_scan_args_t *arg, int argc, const VALUE *con https://github.com/ruby/ruby/blob/trunk/class.c#L2103 } } /* capture trailing mandatory arguments */ - for (i = arg->n_trail; i-- > 0; ) { - var = va_arg(vargs, VALUE *); + for (i = n_trail; i-- > 0; ) { + var = rb_scan_args_next_param(); if (var) *var = argv[argi]; argi++; } /* capture an option hash - phase 2: assignment */ - if (arg->f_hash) { - var = va_arg(vargs, VALUE *); + if (f_hash) { + var = rb_scan_args_next_param(); if (var) *var = hash; } /* capture iterator block */ - if (arg->f_block) { - var = va_arg(vargs, VALUE *); + if (f_block) { + var = rb_scan_args_next_param(); if (rb_block_given_p()) { *var = rb_block_proc(); } @@ -2124,14 +2130,22 @@ rb_scan_args_assign(const struct rb_scan_args_t *arg, int argc, const VALUE *con https://github.com/ruby/ruby/blob/trunk/class.c#L2130 } return argc; +#undef rb_scan_args_next_param } static int rb_scan_args_result(const struct rb_scan_args_t *const arg, int argc) { if (argc < 0) { - rb_error_arity(-1-argc, arg->n_mand, arg->f_var ? UNLIMITED_ARGUMENTS : arg->n_mand + arg->n_opt); + const int n_lead = arg->n_lead; + const int n_opt = arg->n_opt; + const int n_trail = arg->n_trail; + const int n_mand = n_lead + n_trail; + const bool f_var = arg->f_var; + argc = -argc - 1; + rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt); } + return argc; } diff --git a/include/ruby/3/scan_args.h b/include/ruby/3/scan_args.h index 3944c8b..9bc32fb 100644 --- a/include/ruby/3/scan_args.h +++ b/include/ruby/3/scan_args.h @@ -266,6 +266,7 @@ rb_scan_args_set(int kw_flag, int argc, const VALUE *argv, https://github.com/ruby/ruby/blob/trunk/include/ruby/3/scan_args.h#L266 { int i, argi = 0, vari = 0; VALUE *var, hash = Qnil; +#define rb_scan_args_next_param() vars[vari++] const int n_mand = n_lead + n_trail; if (f_hash && argc > 0) { @@ -282,13 +283,13 @@ rb_scan_args_set(int kw_flag, int argc, const VALUE *argv, https://github.com/ruby/ruby/blob/trunk/include/ruby/3/scan_args.h#L283 /* capture leading mandatory arguments */ for (i = n_lead; i-- > 0; ) { - var = vars[vari++]; + var = rb_scan_args_next_param(); if (var) *var = argv[argi]; argi++; } /* capture optional arguments */ for (i = n_opt; i-- > 0; ) { - var = vars[vari++]; + var = rb_scan_args_next_param(); if (argi < argc - n_trail) { if (var) *var = argv[argi]; argi++; @@ -301,7 +302,7 @@ rb_scan_args_set(int kw_flag, int argc, const VALUE *argv, https://github.com/ruby/ruby/blob/trunk/include/ruby/3/scan_args.h#L302 if (f_var) { int n_var = argc - argi - n_trail; - var = vars[vari++]; + var = rb_scan_args_next_param(); if (0 < n_var) { if (var) *var = rb_ary_new_from_values(n_var, &argv[argi]); argi += n_var; @@ -312,18 +313,18 @@ rb_scan_args_set(int kw_flag, int argc, const VALUE *argv, https://github.com/ruby/ruby/blob/trunk/include/ruby/3/scan_args.h#L313 } /* capture trailing mandatory arguments */ for (i = n_trail; i-- > 0; ) { - var = vars[vari++]; + var = rb_scan_args_next_param(); if (var) *var = argv[argi]; argi++; } /* capture an option hash - phase 2: assignment */ if (f_hash) { - var = vars[vari++]; + var = rb_scan_args_next_param(); if (var) *var = hash; } /* capture iterator block */ if (f_block) { - var = vars[vari++]; + var = rb_scan_args_next_param(); if (rb_block_given_p()) { *var = rb_block_proc(); } @@ -332,12 +333,13 @@ rb_scan_args_set(int kw_flag, int argc, const VALUE *argv, https://github.com/ruby/ruby/blob/trunk/include/ruby/3/scan_args.h#L333 } } - if (argi >= argc) { - return argc; + if (argi < argc) { + argc_error: + rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt); } - argc_error: - rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt); + return argc; +#undef rb_scan_args_next_param } #if ! defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P) -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/