summaryrefslogtreecommitdiff
path: root/thread.c
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2019-10-04 12:51:57 -0700
committerJeremy Evans <code@jeremyevans.net>2020-01-02 18:40:45 -0800
commitbeae6cbf0fd8b6619e5212552de98022d4c4d4d4 (patch)
treea926f619ed39569df4e93ec31157acdb78796379 /thread.c
parent8ba261c7546e3cd12ff6870bb41dd0a0bee32ba8 (diff)
Fully separate positional arguments and keyword arguments
This removes the warnings added in 2.7, and changes the behavior so that a final positional hash is not treated as keywords or vice-versa. To handle the arg_setup_block splat case correctly with keyword arguments, we need to check if we are taking a keyword hash. That case didn't have a test, but it affects real-world code, so add a test for it. This removes rb_empty_keyword_given_p() and related code, as that is not needed in Ruby 3. The empty keyword case is the same as the no keyword case in Ruby 3. This changes rb_scan_args to implement keyword argument separation for C functions when the : character is used. For backwards compatibility, it returns a duped hash. This is a bad idea for performance, but not duping the hash breaks at least Enumerator::ArithmeticSequence#inspect. Instead of having RB_PASS_CALLED_KEYWORDS be a number, simplify the code by just making it be rb_keyword_given_p().
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/2794
Diffstat (limited to 'thread.c')
-rw-r--r--thread.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/thread.c b/thread.c
index 16f3e1ffed..4faf04c1ce 100644
--- a/thread.c
+++ b/thread.c
@@ -681,7 +681,6 @@ thread_do_start(rb_thread_t *th)
if (th->invoke_type == thread_invoke_type_proc) {
VALUE args = th->invoke_arg.proc.args;
int args_len = (int)RARRAY_LEN(args);
- int kw_splat = th->invoke_arg.proc.kw_splat;
const VALUE *args_ptr;
VALUE procval = th->invoke_arg.proc.proc;
rb_proc_t *proc;
@@ -704,10 +703,11 @@ thread_do_start(rb_thread_t *th)
args_ptr = RARRAY_CONST_PTR(args);
}
- rb_adjust_argv_kw_splat(&args_len, &args_ptr, &kw_splat);
+ vm_check_ints_blocking(th->ec);
th->value = rb_vm_invoke_proc(th->ec, proc,
args_len, args_ptr,
- kw_splat, VM_BLOCK_HANDLER_NONE);
+ th->invoke_arg.proc.kw_splat,
+ VM_BLOCK_HANDLER_NONE);
EXEC_EVENT_HOOK(th->ec, RUBY_EVENT_THREAD_END, th->self, 0, 0, 0, Qundef);
}
@@ -856,9 +856,7 @@ thread_create_core(VALUE thval, VALUE args, VALUE (*fn)(void *))
th->invoke_type = thread_invoke_type_proc;
th->invoke_arg.proc.proc = rb_block_proc();
th->invoke_arg.proc.args = args;
- th->invoke_arg.proc.kw_splat = rb_empty_keyword_given_p() ?
- RB_PASS_EMPTY_KEYWORDS :
- rb_keyword_given_p();
+ th->invoke_arg.proc.kw_splat = rb_keyword_given_p();
}
th->priority = current_th->priority;