mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
vm_insnhelper.c: fix many keyword arguments
* vm_insnhelper.c (vm_check_keyword): if the index exceeds the width of unspecified bits, that argument is specified. `unspecified_bits` still be a fixnum if the actual arguments do not exceed the limit, regardless the formal parameters size. [ruby-core:84921] [Bug #14373] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61940 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
828998bcd4
commit
fb839332f3
3 changed files with 11 additions and 5 deletions
|
@ -681,12 +681,13 @@ class TestKeywordArguments < Test::Unit::TestCase
|
|||
def many_kwargs(a0: '', a1: '', a2: '', a3: '', a4: '', a5: '', a6: '', a7: '',
|
||||
b0: '', b1: '', b2: '', b3: '', b4: '', b5: '', b6: '', b7: '',
|
||||
c0: '', c1: '', c2: '', c3: '', c4: '', c5: '', c6: '', c7: '',
|
||||
d0: '', d1: '', d2: '', d3: '', d4: '', d5: '', d6: '', d7: '')
|
||||
d0: '', d1: '', d2: '', d3: '', d4: '', d5: '', d6: '', d7: '',
|
||||
e0: '')
|
||||
[a0, a1, a2, a3, a4, a5, a6, a7,
|
||||
b0, b1, b2, b3, b4, b5, b6, b7,
|
||||
c0, c1, c2, c3, c4, c5, c6, c7,
|
||||
d0, d1, d2, d3, d4, d5, d6, d7,
|
||||
]
|
||||
e0]
|
||||
end
|
||||
|
||||
def test_many_kwargs
|
||||
|
@ -726,5 +727,7 @@ class TestKeywordArguments < Test::Unit::TestCase
|
|||
assert_equal(:ok, many_kwargs(d5: :ok)[i], "#{i}: d5"); i+=1
|
||||
assert_equal(:ok, many_kwargs(d6: :ok)[i], "#{i}: d6"); i+=1
|
||||
assert_equal(:ok, many_kwargs(d7: :ok)[i], "#{i}: d7"); i+=1
|
||||
|
||||
assert_equal(:ok, many_kwargs(e0: :ok)[i], "#{i}: e0"); i+=1
|
||||
end
|
||||
end
|
||||
|
|
|
@ -392,6 +392,8 @@ args_setup_kw_parameters_lookup(const ID key, VALUE *ptr, const VALUE *const pas
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
#define KW_SPECIFIED_BITS_MAX 32 /* TODO: 32 -> Fixnum's max bits */
|
||||
|
||||
static void
|
||||
args_setup_kw_parameters(rb_execution_context_t *const ec, const rb_iseq_t *const iseq,
|
||||
VALUE *const passed_values, const int passed_keyword_len, const VALUE *const passed_keywords,
|
||||
|
@ -427,7 +429,7 @@ args_setup_kw_parameters(rb_execution_context_t *const ec, const rb_iseq_t *cons
|
|||
if (default_values[di] == Qundef) {
|
||||
locals[i] = Qnil;
|
||||
|
||||
if (LIKELY(i < 32)) { /* TODO: 32 -> Fixnum's max bits */
|
||||
if (LIKELY(i < KW_SPECIFIED_BITS_MAX)) {
|
||||
unspecified_bits |= 0x01 << di;
|
||||
}
|
||||
else {
|
||||
|
@ -436,7 +438,7 @@ args_setup_kw_parameters(rb_execution_context_t *const ec, const rb_iseq_t *cons
|
|||
int j;
|
||||
unspecified_bits_value = rb_hash_new();
|
||||
|
||||
for (j=0; j<32; j++) {
|
||||
for (j=0; j<KW_SPECIFIED_BITS_MAX; j++) {
|
||||
if (unspecified_bits & (0x01 << j)) {
|
||||
rb_hash_aset(unspecified_bits_value, INT2FIX(j), Qtrue);
|
||||
}
|
||||
|
|
|
@ -3029,7 +3029,8 @@ vm_check_keyword(lindex_t bits, lindex_t idx, const VALUE *ep)
|
|||
|
||||
if (FIXNUM_P(kw_bits)) {
|
||||
int b = FIX2INT(kw_bits);
|
||||
if (b & (0x01 << idx)) return Qfalse;
|
||||
if ((idx < KW_SPECIFIED_BITS_MAX) && (b & (0x01 << idx)))
|
||||
return Qfalse;
|
||||
}
|
||||
else {
|
||||
VM_ASSERT(RB_TYPE_P(kw_bits, T_HASH));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue