Bug #7630 ยป proc-keyword-arg.patch
| vm_insnhelper.c | ||
|---|---|---|
|
}
|
||
|
static inline int
|
||
|
vm_callee_setup_keyword_arg(const rb_iseq_t *iseq, int argc, VALUE *orig_argv)
|
||
|
{
|
||
|
VALUE keyword_hash = Qnil;
|
||
|
int i, j;
|
||
|
if (argc > 0) keyword_hash = rb_check_hash_type(orig_argv[argc-1]);
|
||
|
if (!NIL_P(keyword_hash)) {
|
||
|
argc--;
|
||
|
keyword_hash = rb_hash_dup(keyword_hash);
|
||
|
if (iseq->arg_keyword_check) {
|
||
|
for (i = j = 0; i < iseq->arg_keywords; i++) {
|
||
|
if (st_lookup(RHASH_TBL(keyword_hash), ID2SYM(iseq->arg_keyword_table[i]), 0)) j++;
|
||
|
}
|
||
|
if (RHASH_TBL(keyword_hash)->num_entries > (unsigned int) j) {
|
||
|
unknown_keyword_error(iseq, keyword_hash);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
keyword_hash = rb_hash_new();
|
||
|
}
|
||
|
orig_argv[iseq->arg_keyword] = keyword_hash;
|
||
|
return argc;
|
||
|
}
|
||
|
static inline int
|
||
|
vm_callee_setup_arg_complex(rb_thread_t *th, rb_call_info_t *ci, const rb_iseq_t *iseq, VALUE *orig_argv)
|
||
|
{
|
||
|
const int m = iseq->argc;
|
||
| ... | ... | |
|
const int orig_argc = ci->argc;
|
||
|
int argc = orig_argc;
|
||
|
VALUE *argv = orig_argv;
|
||
|
VALUE keyword_hash = Qnil;
|
||
|
rb_num_t opt_pc = 0;
|
||
|
th->mark_stack_len = argc + iseq->arg_size;
|
||
|
/* keyword argument */
|
||
|
if (iseq->arg_keyword != -1) {
|
||
|
int i, j;
|
||
|
if (argc > 0) keyword_hash = rb_check_hash_type(argv[argc-1]);
|
||
|
if (!NIL_P(keyword_hash)) {
|
||
|
argc--;
|
||
|
keyword_hash = rb_hash_dup(keyword_hash);
|
||
|
if (iseq->arg_keyword_check) {
|
||
|
for (i = j = 0; i < iseq->arg_keywords; i++) {
|
||
|
if (st_lookup(RHASH_TBL(keyword_hash), ID2SYM(iseq->arg_keyword_table[i]), 0)) j++;
|
||
|
}
|
||
|
if (RHASH_TBL(keyword_hash)->num_entries > (unsigned int) j) {
|
||
|
unknown_keyword_error(iseq, keyword_hash);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
keyword_hash = rb_hash_new();
|
||
|
}
|
||
|
argc = vm_callee_setup_keyword_arg(iseq, argc, orig_argv);
|
||
|
}
|
||
|
/* mandatory */
|
||
| ... | ... | |
|
argc = 0;
|
||
|
}
|
||
|
/* keyword argument */
|
||
|
if (iseq->arg_keyword != -1) {
|
||
|
orig_argv[iseq->arg_keyword] = keyword_hash;
|
||
|
}
|
||
|
/* block arguments */
|
||
|
if (iseq->arg_block != -1) {
|
||
|
VALUE blockval = Qnil;
|
||
| ... | ... | |
|
th->mark_stack_len = argc;
|
||
|
/* keyword argument */
|
||
|
if (iseq->arg_keyword != -1) {
|
||
|
argc = vm_callee_setup_keyword_arg(iseq, argc, argv);
|
||
|
}
|
||
|
/*
|
||
|
* yield [1, 2]
|
||
|
* => {|a|} => a = [1, 2]
|
||