proc-keyword-arg.patch

Kazuki Tsujimoto, 12/28/2012 08:47 PM

Download (2.72 KB)

View differences:

vm_insnhelper.c
1065 1065
}
1066 1066

  
1067 1067
static inline int
1068
vm_callee_setup_keyword_arg(const rb_iseq_t *iseq, int argc, VALUE *orig_argv)
1069
{
1070
    VALUE keyword_hash = Qnil;
1071
    int i, j;
1072

  
1073
    if (argc > 0) keyword_hash = rb_check_hash_type(orig_argv[argc-1]);
1074
    if (!NIL_P(keyword_hash)) {
1075
	argc--;
1076
	keyword_hash = rb_hash_dup(keyword_hash);
1077
	if (iseq->arg_keyword_check) {
1078
	    for (i = j = 0; i < iseq->arg_keywords; i++) {
1079
		if (st_lookup(RHASH_TBL(keyword_hash), ID2SYM(iseq->arg_keyword_table[i]), 0)) j++;
1080
	    }
1081
	    if (RHASH_TBL(keyword_hash)->num_entries > (unsigned int) j) {
1082
		unknown_keyword_error(iseq, keyword_hash);
1083
	    }
1084
	}
1085
    }
1086
    else {
1087
	keyword_hash = rb_hash_new();
1088
    }
1089

  
1090
    orig_argv[iseq->arg_keyword] = keyword_hash;
1091

  
1092
    return argc;
1093
}
1094

  
1095
static inline int
1068 1096
vm_callee_setup_arg_complex(rb_thread_t *th, rb_call_info_t *ci, const rb_iseq_t *iseq, VALUE *orig_argv)
1069 1097
{
1070 1098
    const int m = iseq->argc;
......
1074 1102
    const int orig_argc = ci->argc;
1075 1103
    int argc = orig_argc;
1076 1104
    VALUE *argv = orig_argv;
1077
    VALUE keyword_hash = Qnil;
1078 1105
    rb_num_t opt_pc = 0;
1079 1106

  
1080 1107
    th->mark_stack_len = argc + iseq->arg_size;
1081 1108

  
1109
    /* keyword argument */
1082 1110
    if (iseq->arg_keyword != -1) {
1083
	int i, j;
1084
	if (argc > 0) keyword_hash = rb_check_hash_type(argv[argc-1]);
1085
	if (!NIL_P(keyword_hash)) {
1086
	    argc--;
1087
	    keyword_hash = rb_hash_dup(keyword_hash);
1088
	    if (iseq->arg_keyword_check) {
1089
		for (i = j = 0; i < iseq->arg_keywords; i++) {
1090
		    if (st_lookup(RHASH_TBL(keyword_hash), ID2SYM(iseq->arg_keyword_table[i]), 0)) j++;
1091
		}
1092
		if (RHASH_TBL(keyword_hash)->num_entries > (unsigned int) j) {
1093
		    unknown_keyword_error(iseq, keyword_hash);
1094
		}
1095
	    }
1096
	}
1097
	else {
1098
	    keyword_hash = rb_hash_new();
1099
	}
1111
	argc = vm_callee_setup_keyword_arg(iseq, argc, orig_argv);
1100 1112
    }
1101 1113

  
1102 1114
    /* mandatory */
......
1142 1154
	argc = 0;
1143 1155
    }
1144 1156

  
1145
    /* keyword argument */
1146
    if (iseq->arg_keyword != -1) {
1147
	orig_argv[iseq->arg_keyword] = keyword_hash;
1148
    }
1149

  
1150 1157
    /* block arguments */
1151 1158
    if (iseq->arg_block != -1) {
1152 1159
	VALUE blockval = Qnil;
......
2085 2092

  
2086 2093
    th->mark_stack_len = argc;
2087 2094

  
2095
    /* keyword argument */
2096
    if (iseq->arg_keyword != -1) {
2097
	argc = vm_callee_setup_keyword_arg(iseq, argc, argv);
2098
    }
2099

  
2088 2100
    /*
2089 2101
     * yield [1, 2]
2090 2102
     *  => {|a|} => a = [1, 2]