summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--dir.c5
-rw-r--r--gc.c16
-rw-r--r--internal.h2
-rw-r--r--vm_insnhelper.c32
5 files changed, 43 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index 134ee661ea..9ea530488c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+Fri Dec 6 17:10:44 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * vm_insnhelper.c (rb_get_kwargs): get keyword argument values from an
+ option hash, not only checking keys.
+
+ * dir.c (dir_initialize): use rb_get_kwargs.
+
+ * gc.c (gc_start_internal): ditto.
+
Fri Dec 6 16:47:45 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* misc/ruby-mode.el (ruby-brace-to-do-end): split single line block.
diff --git a/dir.c b/dir.c
index 99b1caa851..8492ce78d0 100644
--- a/dir.c
+++ b/dir.c
@@ -436,9 +436,8 @@ dir_initialize(int argc, VALUE *argv, VALUE dir)
if (!NIL_P(opt)) {
VALUE enc;
- rb_check_keyword_opthash(opt, keyword_ids, 0, 1);
- enc = rb_hash_aref(opt, ID2SYM(keyword_ids[0]));
- if (!NIL_P(enc)) {
+ rb_get_kwargs(opt, keyword_ids, 0, 1, &enc);
+ if (enc != Qundef && !NIL_P(enc)) {
fsenc = rb_to_encoding(enc);
}
}
diff --git a/gc.c b/gc.c
index e10109b707..d5a708a71a 100644
--- a/gc.c
+++ b/gc.c
@@ -5014,26 +5014,24 @@ gc_start_internal(int argc, VALUE *argv, VALUE self)
rb_objspace_t *objspace = &rb_objspace;
int full_mark = TRUE, immediate_sweep = TRUE;
VALUE opt = Qnil;
- VALUE kwval;
static ID keyword_ids[2];
- static VALUE keyword_syms[2];
rb_scan_args(argc, argv, "0:", &opt);
if (!NIL_P(opt)) {
+ VALUE kwvals[2];
+
if (!keyword_ids[0]) {
keyword_ids[0] = rb_intern("full_mark");
keyword_ids[1] = rb_intern("immediate_sweep");
- keyword_syms[0] = ID2SYM(keyword_ids[0]);
- keyword_syms[1] = ID2SYM(keyword_ids[1]);
}
- rb_check_keyword_opthash(opt, keyword_ids, 0, 2);
+ rb_get_kwargs(opt, keyword_ids, 0, 2, kwvals);
- if ((kwval = rb_hash_lookup2(opt, keyword_syms[0], Qundef)) != Qundef)
- full_mark = RTEST(kwval);
- if ((kwval = rb_hash_lookup2(opt, keyword_syms[1], Qundef)) != Qundef)
- immediate_sweep = RTEST(kwval);
+ if (kwvals[0] != Qundef)
+ full_mark = RTEST(kwvals[0]);
+ if (kwvals[1] != Qundef)
+ immediate_sweep = RTEST(kwvals[1]);
}
garbage_collect(objspace, full_mark, immediate_sweep, GPR_FLAG_METHOD);
diff --git a/internal.h b/internal.h
index 0c9427b202..2b8176c28b 100644
--- a/internal.h
+++ b/internal.h
@@ -775,7 +775,7 @@ VALUE rb_catch_protect(VALUE t, rb_block_call_func *func, VALUE data, int *state
/* vm_insnhelper.c */
VALUE rb_equal_opt(VALUE obj1, VALUE obj2);
-void rb_check_keyword_opthash(VALUE keyword_hash, const ID *table, int required, int optional);
+int rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *);
VALUE rb_extract_keywords(VALUE *orighash);
/* vm_method.c */
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 967c70f360..ffd10c3825 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1113,17 +1113,27 @@ rb_extract_keywords(VALUE *orighash)
return parthash[0];
}
-void
-rb_check_keyword_opthash(VALUE keyword_hash, const ID *table, int required, int optional)
+int
+rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, VALUE *values)
{
int i = 0, j;
VALUE missing = Qnil;
+ if (values) {
+ for (j = 0; j < required + optional; j++) {
+ values[j] = Qundef;
+ }
+ }
if (required) {
for (; i < required; i++) {
VALUE keyword = ID2SYM(table[i]);
- if (keyword_hash && st_lookup(rb_hash_tbl_raw(keyword_hash), (st_data_t)keyword, 0))
- continue;
+ if (keyword_hash) {
+ st_data_t val;
+ if (st_lookup(rb_hash_tbl_raw(keyword_hash), (st_data_t)keyword, &val)) {
+ if (values) values[i] = (VALUE)val;
+ continue;
+ }
+ }
if (NIL_P(missing)) missing = rb_ary_tmp_new(1);
rb_ary_push(missing, keyword);
}
@@ -1133,12 +1143,17 @@ rb_check_keyword_opthash(VALUE keyword_hash, const ID *table, int required, int
}
if (optional && keyword_hash) {
for (j = i, i = 0; i < optional; i++) {
- if (st_lookup(rb_hash_tbl_raw(keyword_hash), ID2SYM(table[required+i]), 0)) j++;
+ st_data_t val;
+ if (st_lookup(rb_hash_tbl_raw(keyword_hash), ID2SYM(table[required+i]), &val)) {
+ if (values) values[required+i] = (VALUE)val;
+ j++;
+ }
}
if (RHASH_SIZE(keyword_hash) > (unsigned int)j) {
unknown_keyword_error(keyword_hash, table, required+optional);
}
}
+ return j;
}
static inline int
@@ -1155,11 +1170,12 @@ vm_callee_setup_keyword_arg(const rb_iseq_t *iseq, int argc, int m, VALUE *orig_
else {
orig_argv[argc-1] = orig_hash;
}
- rb_check_keyword_opthash(keyword_hash, iseq->arg_keyword_table, iseq->arg_keyword_required,
- iseq->arg_keyword_check ? iseq->arg_keywords - iseq->arg_keyword_required : 0);
+ rb_get_kwargs(keyword_hash, iseq->arg_keyword_table, iseq->arg_keyword_required,
+ iseq->arg_keyword_check ? iseq->arg_keywords - iseq->arg_keyword_required : 0,
+ NULL);
}
else if (iseq->arg_keyword_required) {
- rb_check_keyword_opthash(0, iseq->arg_keyword_table, iseq->arg_keyword_required, 0);
+ rb_get_kwargs(0, iseq->arg_keyword_table, iseq->arg_keyword_required, 0, NULL);
}
else {
keyword_hash = rb_hash_new();