diff options
author | Jeremy Evans <code@jeremyevans.net> | 2024-01-14 11:41:02 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-14 11:41:02 -0800 |
commit | 5c823aa686a5549649df4af86d173bebed2418e1 (patch) | |
tree | 7044e21e631b6cb1557ef9aa42ac9b9b4d850898 /vm_insnhelper.c | |
parent | 772413245f782f538413a69a270ec75ee8b77f18 (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.c | 12 |
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); } |