Project

General

Profile

Bug #7630 ยป proc-keyword-arg.patch

ktsj (Kazuki Tsujimoto), 12/28/2012 08:47 PM

View differences:

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]
    (1-1/1)