summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNARUSE, Yui <naruse@airemix.jp>2022-01-30 19:01:49 +0900
committerNARUSE, Yui <naruse@airemix.jp>2022-01-30 19:01:49 +0900
commit2640161df5cf18d08ec86a0c1b913d4ee99e102a (patch)
tree391cd9a4c88f530009d87a1c1a7347de3a3f87c5
parent20091ccad34904cb5ded13a8787f6662a8e2df68 (diff)
merge revision(s) 5414de4b6e4372af832e338f8eb7a9fe8de17c84: [Backport #18453]
YJIT: Fix SP index with optarg and unordered kwarg Previously when we were calling a method with an optional argument and multiple keywords arguments which weren't in the order the receiver expected we would use the wrong SP index to rearrange them. Fixes Bug #18453 --- bootstraptest/test_yjit.rb | 16 ++++++++++++++++ yjit_codegen.c | 7 +++++-- 2 files changed, 21 insertions(+), 2 deletions(-)
-rw-r--r--bootstraptest/test_yjit.rb16
-rw-r--r--version.h2
-rw-r--r--yjit_codegen.c7
3 files changed, 22 insertions, 3 deletions
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 05947c48ed..30298a820d 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -2280,6 +2280,22 @@ assert_equal '[[1, 2, 3]]', %q{
5.times.map { opt_and_kwargs(1, 2, c: 3) }.uniq
}
+# Bug #18453
+assert_equal '[[1, nil, 2]]', %q{
+ def opt_and_kwargs(a = {}, b: nil, c: nil)
+ [a, b, c]
+ end
+
+ 5.times.map { opt_and_kwargs(1, c: 2) }.uniq
+}
+
+assert_equal '[[{}, nil, 1]]', %q{
+ def opt_and_kwargs(a = {}, b: nil, c: nil)
+ [a, b, c]
+ end
+
+ 5.times.map { opt_and_kwargs(c: 1) }.uniq
+}
# leading and keyword arguments are swapped into the right order
assert_equal '[[1, 2, 3, 4, 5, 6]]', %q{
diff --git a/version.h b/version.h
index 5c32027929..22b61f81e6 100644
--- a/version.h
+++ b/version.h
@@ -11,7 +11,7 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 1
+#define RUBY_PATCHLEVEL 2
#define RUBY_RELEASE_YEAR 2022
#define RUBY_RELEASE_MONTH 1
diff --git a/yjit_codegen.c b/yjit_codegen.c
index 8a547d2ef6..21e4813c19 100644
--- a/yjit_codegen.c
+++ b/yjit_codegen.c
@@ -3671,7 +3671,10 @@ gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r
if (doing_kw_call) {
// Here we're calling a method with keyword arguments and specifying
// keyword arguments at this call site.
- const int lead_num = iseq->body->param.lead_num;
+
+ // Number of positional arguments the callee expects before the first
+ // keyword argument
+ const int args_before_kw = required_num + opt_num;
// This struct represents the metadata about the caller-specified
// keyword arguments.
@@ -3761,7 +3764,7 @@ gen_send_iseq(jitstate_t *jit, ctx_t *ctx, const struct rb_callinfo *ci, const r
if (callee_kwarg == caller_kwargs[swap_idx]) {
// First we're going to generate the code that is going
// to perform the actual swapping at runtime.
- stack_swap(ctx, cb, argc - 1 - swap_idx - lead_num, argc - 1 - kwarg_idx - lead_num, REG1, REG0);
+ stack_swap(ctx, cb, argc - 1 - swap_idx - args_before_kw, argc - 1 - kwarg_idx - args_before_kw, REG1, REG0);
// Next we're going to do some bookkeeping on our end so
// that we know the order that the arguments are