mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Hash: check flags before accessing ifnone; ref #980
This commit is contained in:
@@ -76,7 +76,9 @@ KHASH_DECLARE(ht, mrb_value, mrb_hash_value, TRUE)
|
||||
#define RHASH_PROCDEFAULT(h) RHASH_IFNONE(h)
|
||||
MRB_API struct kh_ht * mrb_hash_tbl(mrb_state *mrb, mrb_value hash);
|
||||
|
||||
#define MRB_HASH_PROC_DEFAULT 256
|
||||
#define MRB_HASH_DEFAULT 1
|
||||
#define MRB_HASH_PROC_DEFAULT 2
|
||||
#define MRB_RHASH_DEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_DEFAULT)
|
||||
#define MRB_RHASH_PROCDEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_PROC_DEFAULT)
|
||||
|
||||
/* GC functions */
|
||||
|
||||
+33
-12
@@ -172,10 +172,13 @@ mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key)
|
||||
}
|
||||
|
||||
/* not found */
|
||||
if (MRB_RHASH_PROCDEFAULT_P(hash)) {
|
||||
return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key);
|
||||
if (MRB_RHASH_DEFAULT_P(hash)) {
|
||||
if (MRB_RHASH_PROCDEFAULT_P(hash)) {
|
||||
return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key);
|
||||
}
|
||||
return RHASH_IFNONE(hash);
|
||||
}
|
||||
return RHASH_IFNONE(hash);
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
MRB_API mrb_value
|
||||
@@ -323,7 +326,10 @@ mrb_hash_init(mrb_state *mrb, mrb_value hash)
|
||||
RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
|
||||
ifnone = block;
|
||||
}
|
||||
mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
|
||||
if (!mrb_nil_p(ifnone)) {
|
||||
RHASH(hash)->flags |= MRB_HASH_DEFAULT;
|
||||
mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
@@ -417,8 +423,13 @@ mrb_hash_set_default(mrb_state *mrb, mrb_value hash)
|
||||
mrb_get_args(mrb, "o", &ifnone);
|
||||
mrb_hash_modify(mrb, hash);
|
||||
mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
|
||||
RHASH(hash)->flags &= ~(MRB_HASH_PROC_DEFAULT);
|
||||
|
||||
RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
|
||||
if (!mrb_nil_p(ifnone)) {
|
||||
RHASH(hash)->flags |= MRB_HASH_DEFAULT;
|
||||
}
|
||||
else {
|
||||
RHASH(hash)->flags &= ~MRB_HASH_DEFAULT;
|
||||
}
|
||||
return ifnone;
|
||||
}
|
||||
|
||||
@@ -468,7 +479,14 @@ mrb_hash_set_default_proc(mrb_state *mrb, mrb_value hash)
|
||||
mrb_get_args(mrb, "o", &ifnone);
|
||||
mrb_hash_modify(mrb, hash);
|
||||
mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
|
||||
RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
|
||||
if (!mrb_nil_p(ifnone)) {
|
||||
RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
|
||||
RHASH(hash)->flags |= MRB_HASH_DEFAULT;
|
||||
}
|
||||
else {
|
||||
RHASH(hash)->flags &= ~MRB_HASH_DEFAULT;
|
||||
RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
|
||||
}
|
||||
|
||||
return ifnone;
|
||||
}
|
||||
@@ -561,12 +579,15 @@ mrb_hash_shift(mrb_state *mrb, mrb_value hash)
|
||||
}
|
||||
}
|
||||
|
||||
if (MRB_RHASH_PROCDEFAULT_P(hash)) {
|
||||
return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, mrb_nil_value());
|
||||
}
|
||||
else {
|
||||
return RHASH_IFNONE(hash);
|
||||
if (MRB_RHASH_DEFAULT_P(hash)) {
|
||||
if (MRB_RHASH_PROCDEFAULT_P(hash)) {
|
||||
return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, mrb_nil_value());
|
||||
}
|
||||
else {
|
||||
return RHASH_IFNONE(hash);
|
||||
}
|
||||
}
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
/* 15.2.13.4.4 */
|
||||
|
||||
Reference in New Issue
Block a user