Changeset 331 for EcnlProtoTool/trunk/mruby-1.3.0/src/hash.c
- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-1.3.0
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-1.3.0/src/hash.c
r321 r331 5 5 */ 6 6 7 #include "mruby.h"8 #include "mruby/array.h"9 #include "mruby/class.h"10 #include "mruby/hash.h"11 #include "mruby/khash.h"12 #include "mruby/string.h"13 #include "mruby/variable.h"7 #include <mruby.h> 8 #include <mruby/array.h> 9 #include <mruby/class.h> 10 #include <mruby/hash.h> 11 #include <mruby/khash.h> 12 #include <mruby/string.h> 13 #include <mruby/variable.h> 14 14 15 15 /* a function to get hash value of a float number */ … … 92 92 } 93 93 94 typedef struct {95 mrb_value v;96 mrb_int n;97 } mrb_hash_value;98 99 KHASH_DECLARE(ht, mrb_value, mrb_hash_value, TRUE)100 94 KHASH_DEFINE (ht, mrb_value, mrb_hash_value, TRUE, mrb_hash_ht_hash_func, mrb_hash_ht_hash_equal) 101 95 … … 105 99 mrb_hash_ht_key(mrb_state *mrb, mrb_value key) 106 100 { 107 if (mrb_string_p(key) && ! RSTR_FROZEN_P(mrb_str_ptr(key))) {101 if (mrb_string_p(key) && !MRB_FROZEN_P(mrb_str_ptr(key))) { 108 102 key = mrb_str_dup(mrb, key); 109 RSTR_SET_FROZEN_FLAG(mrb_str_ptr(key));103 MRB_SET_FROZEN_FLAG(mrb_str_ptr(key)); 110 104 } 111 105 return key; … … 147 141 148 142 MRB_API mrb_value 149 mrb_hash_new_capa(mrb_state *mrb, int capa)143 mrb_hash_new_capa(mrb_state *mrb, mrb_int capa) 150 144 { 151 145 struct RHash *h; … … 166 160 } 167 161 162 static mrb_value mrb_hash_default(mrb_state *mrb, mrb_value hash); 163 static mrb_value hash_default(mrb_state *mrb, mrb_value hash, mrb_value key); 164 168 165 MRB_API mrb_value 169 166 mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key) … … 171 168 khash_t(ht) *h = RHASH_TBL(hash); 172 169 khiter_t k; 170 mrb_sym mid; 173 171 174 172 if (h) { … … 178 176 } 179 177 180 /* not found */ 181 if (MRB_RHASH_PROCDEFAULT_P(hash)) { 182 return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key); 183 } 184 return RHASH_IFNONE(hash); 178 mid = mrb_intern_lit(mrb, "default"); 179 if (mrb_func_basic_p(mrb, hash, mid, mrb_hash_default)) { 180 return hash_default(mrb, hash, key); 181 } 182 /* xxx mrb_funcall_tailcall(mrb, hash, "default", 1, key); */ 183 return mrb_funcall_argv(mrb, hash, mid, 1, &key); 185 184 } 186 185 … … 234 233 khash_t(ht) *h, *ret_h; 235 234 khiter_t k, ret_k; 235 mrb_value ifnone, vret; 236 236 237 237 h = RHASH_TBL(hash); … … 239 239 ret->ht = kh_init(ht, mrb); 240 240 241 if ( kh_size(h) > 0) {241 if (h && kh_size(h) > 0) { 242 242 ret_h = ret->ht; 243 243 … … 247 247 ret_k = kh_put(ht, mrb, ret_h, KEY(kh_key(h, k))); 248 248 mrb_gc_arena_restore(mrb, ai); 249 kh_val(ret_h, ret_k) = kh_val(h, k); 249 kh_val(ret_h, ret_k).v = kh_val(h, k).v; 250 kh_val(ret_h, ret_k).n = kh_size(ret_h)-1; 250 251 } 251 252 } 252 253 } 253 254 254 return mrb_obj_value(ret); 255 if (MRB_RHASH_DEFAULT_P(hash)) { 256 ret->flags |= MRB_HASH_DEFAULT; 257 } 258 if (MRB_RHASH_PROCDEFAULT_P(hash)) { 259 ret->flags |= MRB_HASH_PROC_DEFAULT; 260 } 261 vret = mrb_obj_value(ret); 262 ifnone = RHASH_IFNONE(hash); 263 if (!mrb_nil_p(ifnone)) { 264 mrb_iv_set(mrb, vret, mrb_intern_lit(mrb, "ifnone"), ifnone); 265 } 266 return vret; 255 267 } 256 268 … … 275 287 mrb_hash_modify(mrb_state *mrb, mrb_value hash) 276 288 { 289 if (MRB_FROZEN_P(mrb_hash_ptr(hash))) { 290 mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen hash"); 291 } 277 292 mrb_hash_tbl(mrb, hash); 278 293 } … … 330 345 ifnone = block; 331 346 } 332 mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone); 347 if (!mrb_nil_p(ifnone)) { 348 RHASH(hash)->flags |= MRB_HASH_DEFAULT; 349 mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone); 350 } 333 351 return hash; 334 352 } … … 357 375 } 358 376 377 static mrb_value 378 hash_default(mrb_state *mrb, mrb_value hash, mrb_value key) 379 { 380 if (MRB_RHASH_DEFAULT_P(hash)) { 381 if (MRB_RHASH_PROCDEFAULT_P(hash)) { 382 return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key); 383 } 384 else { 385 return RHASH_IFNONE(hash); 386 } 387 } 388 return mrb_nil_value(); 389 } 390 359 391 /* 15.2.13.4.5 */ 360 392 /* … … 386 418 387 419 mrb_get_args(mrb, "|o?", &key, &given); 388 if (MRB_RHASH_PROCDEFAULT_P(hash)) { 389 if (!given) return mrb_nil_value(); 390 return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key); 391 } 392 else { 393 return RHASH_IFNONE(hash); 394 } 420 if (MRB_RHASH_DEFAULT_P(hash)) { 421 if (MRB_RHASH_PROCDEFAULT_P(hash)) { 422 if (!given) return mrb_nil_value(); 423 return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key); 424 } 425 else { 426 return RHASH_IFNONE(hash); 427 } 428 } 429 return mrb_nil_value(); 395 430 } 396 431 … … 424 459 mrb_hash_modify(mrb, hash); 425 460 mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone); 426 RHASH(hash)->flags &= ~(MRB_HASH_PROC_DEFAULT); 427 461 RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT; 462 if (!mrb_nil_p(ifnone)) { 463 RHASH(hash)->flags |= MRB_HASH_DEFAULT; 464 } 465 else { 466 RHASH(hash)->flags &= ~MRB_HASH_DEFAULT; 467 } 428 468 return ifnone; 429 469 } … … 475 515 mrb_hash_modify(mrb, hash); 476 516 mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone); 477 RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT; 517 if (!mrb_nil_p(ifnone)) { 518 RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT; 519 RHASH(hash)->flags |= MRB_HASH_DEFAULT; 520 } 521 else { 522 RHASH(hash)->flags &= ~MRB_HASH_DEFAULT; 523 RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT; 524 } 478 525 479 526 return ifnone; … … 530 577 531 578 mrb_get_args(mrb, "o", &key); 579 mrb_hash_modify(mrb, self); 532 580 return mrb_hash_delete_key(mrb, self, key); 533 581 } … … 568 616 } 569 617 570 if (MRB_RHASH_PROCDEFAULT_P(hash)) { 571 return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, mrb_nil_value()); 572 } 573 else { 574 return RHASH_IFNONE(hash); 575 } 618 if (MRB_RHASH_DEFAULT_P(hash)) { 619 if (MRB_RHASH_PROCDEFAULT_P(hash)) { 620 return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, mrb_nil_value()); 621 } 622 else { 623 return RHASH_IFNONE(hash); 624 } 625 } 626 return mrb_nil_value(); 576 627 } 577 628 … … 593 644 khash_t(ht) *h = RHASH_TBL(hash); 594 645 646 mrb_hash_modify(mrb, hash); 595 647 if (h) kh_clear(ht, mrb, h); 596 648 return hash; … … 700 752 khash_t(ht) *h = RHASH_TBL(hash); 701 753 khiter_t k; 754 mrb_int end; 702 755 mrb_value ary; 703 756 mrb_value *p; … … 705 758 if (!h || kh_size(h) == 0) return mrb_ary_new(mrb); 706 759 ary = mrb_ary_new_capa(mrb, kh_size(h)); 707 mrb_ary_set(mrb, ary, kh_size(h)-1, mrb_nil_value()); 760 end = kh_size(h)-1; 761 mrb_ary_set(mrb, ary, end, mrb_nil_value()); 708 762 p = mrb_ary_ptr(ary)->ptr; 709 763 for (k = kh_begin(h); k != kh_end(h); k++) { … … 712 766 mrb_hash_value hv = kh_value(h, k); 713 767 714 p[hv.n] = kv; 768 if (hv.n <= end) { 769 p[hv.n] = kv; 770 } 771 else { 772 p[end] = kv; 773 } 715 774 } 716 775 } … … 731 790 */ 732 791 733 staticmrb_value792 MRB_API mrb_value 734 793 mrb_hash_values(mrb_state *mrb, mrb_value hash) 735 794 {
Note:
See TracChangeset
for help on using the changeset viewer.