summaryrefslogtreecommitdiff
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2024-01-14 11:41:02 -0800
committerGitHub <noreply@github.com>2024-01-14 11:41:02 -0800
commit5c823aa686a5549649df4af86d173bebed2418e1 (patch)
tree7044e21e631b6cb1557ef9aa42ac9b9b4d850898 /vm_insnhelper.c
parent772413245f782f538413a69a270ec75ee8b77f18 (diff)
Support keyword splatting nil
nil is treated similarly to the empty hash in this case, passing no keywords and not calling any conversion methods. Fixes [Bug #20064] Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index d81a121c1f..63567e8f87 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -2668,8 +2668,10 @@ static inline VALUE
vm_caller_setup_keyword_hash(const struct rb_callinfo *ci, VALUE keyword_hash)
{
if (UNLIKELY(!RB_TYPE_P(keyword_hash, T_HASH))) {
- /* Convert a non-hash keyword splat to a new hash */
- keyword_hash = rb_hash_dup(rb_to_hash_type(keyword_hash));
+ if (keyword_hash != Qnil) {
+ /* Convert a non-hash keyword splat to a new hash */
+ keyword_hash = rb_hash_dup(rb_to_hash_type(keyword_hash));
+ }
}
else if (!IS_ARGS_KW_SPLAT_MUT(ci)) {
/* Convert a hash keyword splat to a new hash unless
@@ -2699,7 +2701,7 @@ CALLER_SETUP_ARG(struct rb_control_frame_struct *restrict cfp,
if (vm_caller_setup_arg_splat(cfp, calling, ary, max_args)) return;
// put kw
- if (!RHASH_EMPTY_P(kwh)) {
+ if (kwh != Qnil && !RHASH_EMPTY_P(kwh)) {
if (UNLIKELY(calling->heap_argv)) {
rb_ary_push(calling->heap_argv, kwh);
((struct RHash *)kwh)->basic.flags |= RHASH_PASS_AS_KEYWORDS;
@@ -2770,7 +2772,7 @@ check_keyword:
VM_ASSERT(calling->kw_splat == 1);
VALUE kwh = vm_caller_setup_keyword_hash(ci, cfp->sp[-1]);
- if (RHASH_EMPTY_P(kwh)) {
+ if (kwh == Qnil || RHASH_EMPTY_P(kwh)) {
cfp->sp--;
calling->argc--;
calling->kw_splat = 0;
@@ -3596,7 +3598,7 @@ vm_call_cfunc_only_splat_kw(rb_execution_context_t *ec, rb_control_frame_t *reg_
RB_DEBUG_COUNTER_INC(ccf_cfunc_only_splat_kw);
VALUE keyword_hash = reg_cfp->sp[-1];
- if (RB_TYPE_P(keyword_hash, T_HASH) && RHASH_EMPTY_P(keyword_hash)) {
+ if (keyword_hash == Qnil || (RB_TYPE_P(keyword_hash, T_HASH) && RHASH_EMPTY_P(keyword_hash))) {
return vm_call_cfunc_array_argv(ec, reg_cfp, calling, 1, 0);
}