Ruby  2.7.1p83(2020-03-31revisiona0c7c23c9cec0d0ffcba012279cd652d28ad5bf3)
hash.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  hash.c -
4 
5  $Author$
6  created at: Mon Nov 22 18:51:18 JST 1993
7 
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9  Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
10  Copyright (C) 2000 Information-technology Promotion Agency, Japan
11 
12 **********************************************************************/
13 
14 #include "ruby/encoding.h"
15 #include "ruby/st.h"
16 #include "ruby/util.h"
17 #include "internal.h"
18 #include <errno.h>
19 #include "probes.h"
20 #include "id.h"
21 #include "symbol.h"
22 #include "debug_counter.h"
23 #include "transient_heap.h"
24 #include "ruby_assert.h"
25 #ifdef __APPLE__
26 # ifdef HAVE_CRT_EXTERNS_H
27 # include <crt_externs.h>
28 # else
29 # include "missing/crt_externs.h"
30 # endif
31 #endif
32 
33 #ifndef HASH_DEBUG
34 #define HASH_DEBUG 0
35 #endif
36 
37 #if HASH_DEBUG
38 #include "gc.h"
39 #endif
40 
41 #define HAS_EXTRA_STATES(hash, klass) ( \
42  ((klass = has_extra_methods(rb_obj_class(hash))) != 0) || \
43  FL_TEST((hash), FL_EXIVAR|RHASH_PROC_DEFAULT) || \
44  !NIL_P(RHASH_IFNONE(hash)))
45 
46 #define SET_DEFAULT(hash, ifnone) ( \
47  FL_UNSET_RAW(hash, RHASH_PROC_DEFAULT), \
48  RHASH_SET_IFNONE(hash, ifnone))
49 
50 #define SET_PROC_DEFAULT(hash, proc) set_proc_default(hash, proc)
51 
52 #define COPY_DEFAULT(hash, hash2) copy_default(RHASH(hash), RHASH(hash2))
53 
54 static inline void
55 copy_default(struct RHash *hash, const struct RHash *hash2)
56 {
57  hash->basic.flags &= ~RHASH_PROC_DEFAULT;
58  hash->basic.flags |= hash2->basic.flags & RHASH_PROC_DEFAULT;
59  RHASH_SET_IFNONE(hash, RHASH_IFNONE(hash2));
60 }
61 
62 static VALUE
63 has_extra_methods(VALUE klass)
64 {
65  const VALUE base = rb_cHash;
66  VALUE c = klass;
67  while (c != base) {
68  if (rb_class_has_methods(c)) return klass;
69  c = RCLASS_SUPER(c);
70  }
71  return 0;
72 }
73 
74 static VALUE rb_hash_s_try_convert(VALUE, VALUE);
75 
76 /*
77  * Hash WB strategy:
78  * 1. Check mutate st_* functions
79  * * st_insert()
80  * * st_insert2()
81  * * st_update()
82  * * st_add_direct()
83  * 2. Insert WBs
84  */
85 
86 VALUE
88 {
89  return rb_obj_freeze(hash);
90 }
91 
93 
94 static VALUE envtbl;
95 static ID id_hash, id_yield, id_default, id_flatten_bang;
96 static ID id_hash_iter_lev;
97 
98 VALUE
100 {
101  RB_OBJ_WRITE(hash, (&RHASH(hash)->ifnone), ifnone);
102  return hash;
103 }
104 
105 static int
106 rb_any_cmp(VALUE a, VALUE b)
107 {
108  if (a == b) return 0;
109  if (RB_TYPE_P(a, T_STRING) && RBASIC(a)->klass == rb_cString &&
110  RB_TYPE_P(b, T_STRING) && RBASIC(b)->klass == rb_cString) {
111  return rb_str_hash_cmp(a, b);
112  }
113  if (a == Qundef || b == Qundef) return -1;
114  if (SYMBOL_P(a) && SYMBOL_P(b)) {
115  return a != b;
116  }
117 
118  return !rb_eql(a, b);
119 }
120 
121 static VALUE
122 hash_recursive(VALUE obj, VALUE arg, int recurse)
123 {
124  if (recurse) return INT2FIX(0);
125  return rb_funcallv(obj, id_hash, 0, 0);
126 }
127 
128 VALUE
130 {
131  VALUE hval = rb_exec_recursive_outer(hash_recursive, obj, 0);
132 
133  while (!FIXNUM_P(hval)) {
134  if (RB_TYPE_P(hval, T_BIGNUM)) {
135  int sign;
136  unsigned long ul;
137  sign = rb_integer_pack(hval, &ul, 1, sizeof(ul), 0,
139  ul &= (1UL << (sizeof(long)*CHAR_BIT-1)) - 1;
140  if (sign < 0)
141  return LONG2FIX(-(long)ul);
142  return LONG2FIX((long)ul);
143  }
144  hval = rb_to_int(hval);
145  }
146  return hval;
147 }
148 
149 static long rb_objid_hash(st_index_t index);
150 
151 static st_index_t
152 dbl_to_index(double d)
153 {
154  union {double d; st_index_t i;} u;
155  u.d = d;
156  return u.i;
157 }
158 
159 long
161 {
162  /* normalize -0.0 to 0.0 */
163  if (d == 0.0) d = 0.0;
164 #if SIZEOF_INT == SIZEOF_VOIDP
165  return rb_memhash(&d, sizeof(d));
166 #else
167  return rb_objid_hash(dbl_to_index(d));
168 #endif
169 }
170 
171 static inline long
172 any_hash(VALUE a, st_index_t (*other_func)(VALUE))
173 {
174  VALUE hval;
175  st_index_t hnum;
176 
177  if (SPECIAL_CONST_P(a)) {
178  if (STATIC_SYM_P(a)) {
179  hnum = a >> (RUBY_SPECIAL_SHIFT + ID_SCOPE_SHIFT);
180  hnum = rb_hash_start(hnum);
181  goto out;
182  }
183  else if (FLONUM_P(a)) {
184  /* prevent pathological behavior: [Bug #10761] */
185  goto flt;
186  }
187  hnum = rb_objid_hash((st_index_t)a);
188  }
189  else if (BUILTIN_TYPE(a) == T_STRING) {
190  hnum = rb_str_hash(a);
191  }
192  else if (BUILTIN_TYPE(a) == T_SYMBOL) {
193  hnum = RSYMBOL(a)->hashval;
194  }
195  else if (BUILTIN_TYPE(a) == T_BIGNUM) {
196  hval = rb_big_hash(a);
197  hnum = FIX2LONG(hval);
198  }
199  else if (BUILTIN_TYPE(a) == T_FLOAT) {
200  flt:
201  hnum = rb_dbl_long_hash(rb_float_value(a));
202  }
203  else {
204  hnum = other_func(a);
205  }
206  out:
207 #if SIZEOF_LONG < SIZEOF_ST_INDEX_T
208  if (hnum > 0)
209  hnum &= (unsigned long)-1 >> 2;
210  else
211  hnum |= ~((unsigned long)-1 >> 2);
212 #else
213  hnum <<= 1;
214  hnum = RSHIFT(hnum, 1);
215 #endif
216  return (long)hnum;
217 }
218 
219 static st_index_t
220 obj_any_hash(VALUE obj)
221 {
222  obj = rb_hash(obj);
223  return FIX2LONG(obj);
224 }
225 
226 static st_index_t
227 rb_any_hash(VALUE a)
228 {
229  return any_hash(a, obj_any_hash);
230 }
231 
232 /* Here is a hash function for 64-bit key. It is about 5 times faster
233  (2 times faster when uint128 type is absent) on Haswell than
234  tailored Spooky or City hash function can be. */
235 
236 /* Here we two primes with random bit generation. */
237 static const uint64_t prime1 = ((uint64_t)0x2e0bb864 << 32) | 0xe9ea7df5;
238 static const uint32_t prime2 = 0x830fcab9;
239 
240 
241 static inline uint64_t
242 mult_and_mix(uint64_t m1, uint64_t m2)
243 {
244 #if defined HAVE_UINT128_T
245  uint128_t r = (uint128_t) m1 * (uint128_t) m2;
246  return (uint64_t) (r >> 64) ^ (uint64_t) r;
247 #else
248  uint64_t hm1 = m1 >> 32, hm2 = m2 >> 32;
249  uint64_t lm1 = m1, lm2 = m2;
250  uint64_t v64_128 = hm1 * hm2;
251  uint64_t v32_96 = hm1 * lm2 + lm1 * hm2;
252  uint64_t v1_32 = lm1 * lm2;
253 
254  return (v64_128 + (v32_96 >> 32)) ^ ((v32_96 << 32) + v1_32);
255 #endif
256 }
257 
258 static inline uint64_t
259 key64_hash(uint64_t key, uint32_t seed)
260 {
261  return mult_and_mix(key + seed, prime1);
262 }
263 
264 /* Should cast down the result for each purpose */
265 #define st_index_hash(index) key64_hash(rb_hash_start(index), prime2)
266 
267 static long
268 rb_objid_hash(st_index_t index)
269 {
270  return (long)st_index_hash(index);
271 }
272 
273 static st_index_t
274 objid_hash(VALUE obj)
275 {
277  if (!FIXNUM_P(object_id))
279 
280 #if SIZEOF_LONG == SIZEOF_VOIDP
282 #elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
284 #endif
285 }
286 
290 VALUE
292 {
293  long hnum = any_hash(obj, objid_hash);
294  return ST2FIX(hnum);
295 }
296 
297 static const struct st_hash_type objhash = {
298  rb_any_cmp,
299  rb_any_hash,
300 };
301 
302 #define rb_ident_cmp st_numcmp
303 
304 static st_index_t
305 rb_ident_hash(st_data_t n)
306 {
307 #ifdef USE_FLONUM /* RUBY */
308  /*
309  * - flonum (on 64-bit) is pathologically bad, mix the actual
310  * float value in, but do not use the float value as-is since
311  * many integers get interpreted as 2.0 or -2.0 [Bug #10761]
312  */
313  if (FLONUM_P(n)) {
314  n ^= dbl_to_index(rb_float_value(n));
315  }
316 #endif
317 
319 }
320 
321 #define identhash rb_hashtype_ident
323  rb_ident_cmp,
324  rb_ident_hash,
325 };
326 
328 
329 /*
330  * RHASH_AR_TABLE_P(h):
331  * * as.ar == NULL or
332  * as.ar points ar_table.
333  * * as.ar is allocated by transient heap or xmalloc.
334  *
335  * !RHASH_AR_TABLE_P(h):
336  * * as.st points st_table.
337  */
338 
339 #define RHASH_AR_TABLE_MAX_BOUND RHASH_AR_TABLE_MAX_SIZE
340 
341 #define RHASH_AR_TABLE_REF(hash, n) (&RHASH_AR_TABLE(hash)->pairs[n])
342 #define RHASH_AR_CLEARED_HINT 0xff
343 
344 typedef struct ar_table_pair_struct {
347 } ar_table_pair;
348 
349 typedef struct ar_table_struct {
350  /* 64bit CPU: 8B * 2 * 8 = 128B */
352 } ar_table;
353 
354 size_t
356 {
357  return sizeof(ar_table);
358 }
359 
360 static inline st_hash_t
361 ar_do_hash(st_data_t key)
362 {
363  return (st_hash_t)rb_any_hash(key);
364 }
365 
366 static inline ar_hint_t
367 ar_do_hash_hint(st_hash_t hash_value)
368 {
369  return (ar_hint_t)hash_value;
370 }
371 
372 static inline ar_hint_t
373 ar_hint(VALUE hash, unsigned int index)
374 {
375  return RHASH(hash)->ar_hint.ary[index];
376 }
377 
378 static inline void
379 ar_hint_set_hint(VALUE hash, unsigned int index, ar_hint_t hint)
380 {
381  RHASH(hash)->ar_hint.ary[index] = hint;
382 }
383 
384 static inline void
385 ar_hint_set(VALUE hash, unsigned int index, st_hash_t hash_value)
386 {
387  ar_hint_set_hint(hash, index, ar_do_hash_hint(hash_value));
388 }
389 
390 static inline void
391 ar_clear_entry(VALUE hash, unsigned int index)
392 {
393  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, index);
394  pair->key = Qundef;
395  ar_hint_set_hint(hash, index, RHASH_AR_CLEARED_HINT);
396 }
397 
398 static inline int
399 ar_cleared_entry(VALUE hash, unsigned int index)
400 {
401  if (ar_hint(hash, index) == RHASH_AR_CLEARED_HINT) {
402  /* RHASH_AR_CLEARED_HINT is only a hint, not mean cleared entry,
403  * so you need to check key == Qundef
404  */
405  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, index);
406  return pair->key == Qundef;
407  }
408  else {
409  return FALSE;
410  }
411 }
412 
413 static inline void
414 ar_set_entry(VALUE hash, unsigned int index, st_data_t key, st_data_t val, st_hash_t hash_value)
415 {
416  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, index);
417  pair->key = key;
418  pair->val = val;
419  ar_hint_set(hash, index, hash_value);
420 }
421 
422 #define RHASH_AR_TABLE_SIZE(h) (HASH_ASSERT(RHASH_AR_TABLE_P(h)), \
423  RHASH_AR_TABLE_SIZE_RAW(h))
424 
425 #define RHASH_AR_TABLE_BOUND_RAW(h) \
426  ((unsigned int)((RBASIC(h)->flags >> RHASH_AR_TABLE_BOUND_SHIFT) & \
427  (RHASH_AR_TABLE_BOUND_MASK >> RHASH_AR_TABLE_BOUND_SHIFT)))
428 
429 #define RHASH_AR_TABLE_BOUND(h) (HASH_ASSERT(RHASH_AR_TABLE_P(h)), \
430  RHASH_AR_TABLE_BOUND_RAW(h))
431 
432 #define RHASH_ST_TABLE_SET(h, s) rb_hash_st_table_set(h, s)
433 #define RHASH_TYPE(hash) (RHASH_AR_TABLE_P(hash) ? &objhash : RHASH_ST_TABLE(hash)->type)
434 
435 #define HASH_ASSERT(expr) RUBY_ASSERT_MESG_WHEN(HASH_DEBUG, expr, #expr)
436 
437 #if HASH_DEBUG
438 #define hash_verify(hash) hash_verify_(hash, __FILE__, __LINE__)
439 
440 void
441 rb_hash_dump(VALUE hash)
442 {
443  rb_obj_info_dump(hash);
444 
445  if (RHASH_AR_TABLE_P(hash)) {
446  unsigned i, n = 0, bound = RHASH_AR_TABLE_BOUND(hash);
447 
448  fprintf(stderr, " size:%u bound:%u\n",
450 
451  for (i=0; i<bound; i++) {
452  st_data_t k, v;
453 
454  if (!ar_cleared_entry(hash, i)) {
455  char b1[0x100], b2[0x100];
456  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
457  k = pair->key;
458  v = pair->val;
459  fprintf(stderr, " %d key:%s val:%s hint:%02x\n", i,
460  rb_raw_obj_info(b1, 0x100, k),
461  rb_raw_obj_info(b2, 0x100, v),
462  ar_hint(hash, i));
463  n++;
464  }
465  else {
466  fprintf(stderr, " %d empty\n", i);
467  }
468  }
469  }
470 }
471 
472 static VALUE
473 hash_verify_(VALUE hash, const char *file, int line)
474 {
475  HASH_ASSERT(RB_TYPE_P(hash, T_HASH));
476 
477  if (RHASH_AR_TABLE_P(hash)) {
478  unsigned i, n = 0, bound = RHASH_AR_TABLE_BOUND(hash);
479 
480  for (i=0; i<bound; i++) {
481  st_data_t k, v;
482  if (!ar_cleared_entry(hash, i)) {
483  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
484  k = pair->key;
485  v = pair->val;
486  HASH_ASSERT(k != Qundef);
487  HASH_ASSERT(v != Qundef);
488  n++;
489  }
490  }
491  if (n != RHASH_AR_TABLE_SIZE(hash)) {
492  rb_bug("n:%u, RHASH_AR_TABLE_SIZE:%u", n, RHASH_AR_TABLE_SIZE(hash));
493  }
494  }
495  else {
496  HASH_ASSERT(RHASH_ST_TABLE(hash) != NULL);
499  }
500 
501  if (RHASH_TRANSIENT_P(hash)) {
502  volatile st_data_t MAYBE_UNUSED(key) = RHASH_AR_TABLE_REF(hash, 0)->key; /* read */
503  HASH_ASSERT(RHASH_AR_TABLE(hash) != NULL);
505  }
506  return hash;
507 }
508 
509 #else
510 #define hash_verify(h) ((void)0)
511 #endif
512 
513 static inline int
514 RHASH_TABLE_NULL_P(VALUE hash)
515 {
516  if (RHASH(hash)->as.ar == NULL) {
518  return TRUE;
519  }
520  else {
521  return FALSE;
522  }
523 }
524 
525 static inline int
526 RHASH_TABLE_EMPTY_P(VALUE hash)
527 {
528  return RHASH_SIZE(hash) == 0;
529 }
530 
531 int
533 {
534  if (FL_TEST_RAW((hash), RHASH_ST_TABLE_FLAG)) {
535  HASH_ASSERT(RHASH(hash)->as.st != NULL);
536  return FALSE;
537  }
538  else {
539  return TRUE;
540  }
541 }
542 
543 ar_table *
545 {
547  return RHASH(hash)->as.ar;
548 }
549 
550 st_table *
552 {
554  return RHASH(hash)->as.st;
555 }
556 
557 void
559 {
560  HASH_ASSERT(st != NULL);
562  RHASH(hash)->as.st = st;
563 }
564 
565 static void
566 hash_ar_table_set(VALUE hash, ar_table *ar)
567 {
569  HASH_ASSERT((RHASH_TRANSIENT_P(hash) && ar == NULL) ? FALSE : TRUE);
570  RHASH(hash)->as.ar = ar;
571  hash_verify(hash);
572 }
573 
574 #define RHASH_SET_ST_FLAG(h) FL_SET_RAW(h, RHASH_ST_TABLE_FLAG)
575 #define RHASH_UNSET_ST_FLAG(h) FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG)
576 
577 static inline void
578 RHASH_AR_TABLE_BOUND_SET(VALUE h, st_index_t n)
579 {
582 
583  RBASIC(h)->flags &= ~RHASH_AR_TABLE_BOUND_MASK;
584  RBASIC(h)->flags |= n << RHASH_AR_TABLE_BOUND_SHIFT;
585 }
586 
587 static inline void
588 RHASH_AR_TABLE_SIZE_SET(VALUE h, st_index_t n)
589 {
592 
593  RBASIC(h)->flags &= ~RHASH_AR_TABLE_SIZE_MASK;
594  RBASIC(h)->flags |= n << RHASH_AR_TABLE_SIZE_SHIFT;
595 }
596 
597 static inline void
598 HASH_AR_TABLE_SIZE_ADD(VALUE h, st_index_t n)
599 {
601 
602  RHASH_AR_TABLE_SIZE_SET(h, RHASH_AR_TABLE_SIZE(h) + n);
603 
604  hash_verify(h);
605 }
606 
607 #define RHASH_AR_TABLE_SIZE_INC(h) HASH_AR_TABLE_SIZE_ADD(h, 1)
608 
609 static inline void
610 RHASH_AR_TABLE_SIZE_DEC(VALUE h)
611 {
613  int new_size = RHASH_AR_TABLE_SIZE(h) - 1;
614 
615  if (new_size != 0) {
616  RHASH_AR_TABLE_SIZE_SET(h, new_size);
617  }
618  else {
619  RHASH_AR_TABLE_SIZE_SET(h, 0);
620  RHASH_AR_TABLE_BOUND_SET(h, 0);
621  }
622  hash_verify(h);
623 }
624 
625 static inline void
626 RHASH_AR_TABLE_CLEAR(VALUE h)
627 {
628  RBASIC(h)->flags &= ~RHASH_AR_TABLE_SIZE_MASK;
629  RBASIC(h)->flags &= ~RHASH_AR_TABLE_BOUND_MASK;
630 
631  hash_ar_table_set(h, NULL);
632 }
633 
634 static ar_table*
635 ar_alloc_table(VALUE hash)
636 {
637  ar_table *tab = (ar_table*)rb_transient_heap_alloc(hash, sizeof(ar_table));
638 
639  if (tab != NULL) {
641  }
642  else {
644  tab = (ar_table*)ruby_xmalloc(sizeof(ar_table));
645  }
646 
647  RHASH_AR_TABLE_SIZE_SET(hash, 0);
648  RHASH_AR_TABLE_BOUND_SET(hash, 0);
649  hash_ar_table_set(hash, tab);
650 
651  return tab;
652 }
653 
654 NOINLINE(static int ar_equal(VALUE x, VALUE y));
655 
656 static int
657 ar_equal(VALUE x, VALUE y)
658 {
659  return rb_any_cmp(x, y) == 0;
660 }
661 
662 static unsigned
663 ar_find_entry_hint(VALUE hash, ar_hint_t hint, st_data_t key)
664 {
665  unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
666  const ar_hint_t *hints = RHASH(hash)->ar_hint.ary;
667 
668  /* if table is NULL, then bound also should be 0 */
669 
670  for (i = 0; i < bound; i++) {
671  if (hints[i] == hint) {
672  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
673  if (ar_equal(key, pair->key)) {
674  RB_DEBUG_COUNTER_INC(artable_hint_hit);
675  return i;
676  }
677  else {
678 #if 0
679  static int pid;
680  static char fname[256];
681  static FILE *fp;
682 
683  if (pid != getpid()) {
684  snprintf(fname, sizeof(fname), "/tmp/ruby-armiss.%d", pid = getpid());
685  if ((fp = fopen(fname, "w")) == NULL) rb_bug("fopen");
686  }
687 
688  st_hash_t h1 = ar_do_hash(key);
689  st_hash_t h2 = ar_do_hash(pair->key);
690 
691  fprintf(fp, "miss: hash_eq:%d hints[%d]:%02x hint:%02x\n"
692  " key :%016lx %s\n"
693  " pair->key:%016lx %s\n",
694  h1 == h2, i, hints[i], hint,
695  h1, rb_obj_info(key), h2, rb_obj_info(pair->key));
696 #endif
697  RB_DEBUG_COUNTER_INC(artable_hint_miss);
698  }
699  }
700  }
701  RB_DEBUG_COUNTER_INC(artable_hint_notfound);
703 }
704 
705 static unsigned
706 ar_find_entry(VALUE hash, st_hash_t hash_value, st_data_t key)
707 {
708  ar_hint_t hint = ar_do_hash_hint(hash_value);
709  return ar_find_entry_hint(hash, hint, key);
710 }
711 
712 static inline void
713 ar_free_and_clear_table(VALUE hash)
714 {
715  ar_table *tab = RHASH_AR_TABLE(hash);
716 
717  if (tab) {
718  if (RHASH_TRANSIENT_P(hash)) {
720  }
721  else {
722  ruby_xfree(RHASH_AR_TABLE(hash));
723  }
724  RHASH_AR_TABLE_CLEAR(hash);
725  }
726  HASH_ASSERT(RHASH_AR_TABLE_SIZE(hash) == 0);
727  HASH_ASSERT(RHASH_AR_TABLE_BOUND(hash) == 0);
728  HASH_ASSERT(RHASH_TRANSIENT_P(hash) == 0);
729 }
730 
731 static void
732 ar_try_convert_table(VALUE hash)
733 {
734  if (!RHASH_AR_TABLE_P(hash)) return;
735 
736  const unsigned size = RHASH_AR_TABLE_SIZE(hash);
737 
738  st_table *new_tab;
739  st_index_t i;
740 
742  return;
743  }
744 
745  new_tab = st_init_table_with_size(&objhash, size * 2);
746 
747  for (i = 0; i < RHASH_AR_TABLE_MAX_BOUND; i++) {
748  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
749  st_add_direct(new_tab, pair->key, pair->val);
750  }
751  ar_free_and_clear_table(hash);
752  RHASH_ST_TABLE_SET(hash, new_tab);
753  return;
754 }
755 
756 static st_table *
757 ar_force_convert_table(VALUE hash, const char *file, int line)
758 {
759  st_table *new_tab;
760 
761  if (RHASH_ST_TABLE_P(hash)) {
762  return RHASH_ST_TABLE(hash);
763  }
764 
765  if (RHASH_AR_TABLE(hash)) {
766  unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
767 
768 #if RHASH_CONVERT_TABLE_DEBUG
769  rb_obj_info_dump(hash);
770  fprintf(stderr, "force_convert: %s:%d\n", file, line);
771  RB_DEBUG_COUNTER_INC(obj_hash_force_convert);
772 #endif
773 
774  new_tab = st_init_table_with_size(&objhash, RHASH_AR_TABLE_SIZE(hash));
775 
776  for (i = 0; i < bound; i++) {
777  if (ar_cleared_entry(hash, i)) continue;
778 
779  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
780  st_add_direct(new_tab, pair->key, pair->val);
781  }
782  ar_free_and_clear_table(hash);
783  }
784  else {
785  new_tab = st_init_table(&objhash);
786  }
787  RHASH_ST_TABLE_SET(hash, new_tab);
788 
789  return new_tab;
790 }
791 
792 static ar_table *
793 hash_ar_table(VALUE hash)
794 {
795  if (RHASH_TABLE_NULL_P(hash)) {
796  ar_alloc_table(hash);
797  }
798  return RHASH_AR_TABLE(hash);
799 }
800 
801 static int
802 ar_compact_table(VALUE hash)
803 {
804  const unsigned bound = RHASH_AR_TABLE_BOUND(hash);
805  const unsigned size = RHASH_AR_TABLE_SIZE(hash);
806 
807  if (size == bound) {
808  return size;
809  }
810  else {
811  unsigned i, j=0;
812  ar_table_pair *pairs = RHASH_AR_TABLE(hash)->pairs;
813 
814  for (i=0; i<bound; i++) {
815  if (ar_cleared_entry(hash, i)) {
816  if (j <= i) j = i+1;
817  for (; j<bound; j++) {
818  if (!ar_cleared_entry(hash, j)) {
819  pairs[i] = pairs[j];
820  ar_hint_set_hint(hash, i, (st_hash_t)ar_hint(hash, j));
821  ar_clear_entry(hash, j);
822  j++;
823  goto found;
824  }
825  }
826  /* non-empty is not found */
827  goto done;
828  found:;
829  }
830  }
831  done:
832  HASH_ASSERT(i<=bound);
833 
834  RHASH_AR_TABLE_BOUND_SET(hash, size);
835  hash_verify(hash);
836  return size;
837  }
838 }
839 
840 static int
841 ar_add_direct_with_hash(VALUE hash, st_data_t key, st_data_t val, st_hash_t hash_value)
842 {
843  unsigned bin = RHASH_AR_TABLE_BOUND(hash);
844 
846  return 1;
847  }
848  else {
850  bin = ar_compact_table(hash);
851  hash_ar_table(hash);
852  }
854 
855  ar_set_entry(hash, bin, key, val, hash_value);
856  RHASH_AR_TABLE_BOUND_SET(hash, bin+1);
858  return 0;
859  }
860 }
861 
862 static int
863 ar_general_foreach(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
864 {
865  if (RHASH_AR_TABLE_SIZE(hash) > 0) {
866  unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
867 
868  for (i = 0; i < bound; i++) {
869  if (ar_cleared_entry(hash, i)) continue;
870 
871  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
872  enum st_retval retval = (*func)(pair->key, pair->val, arg, 0);
873  /* pair may be not valid here because of theap */
874 
875  switch (retval) {
876  case ST_CONTINUE:
877  break;
878  case ST_CHECK:
879  case ST_STOP:
880  return 0;
881  case ST_REPLACE:
882  if (replace) {
883  VALUE key = pair->key;
884  VALUE val = pair->val;
885  retval = (*replace)(&key, &val, arg, TRUE);
886 
887  // TODO: pair should be same as pair before.
888  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
889  pair->key = key;
890  pair->val = val;
891  }
892  break;
893  case ST_DELETE:
894  ar_clear_entry(hash, i);
895  RHASH_AR_TABLE_SIZE_DEC(hash);
896  break;
897  }
898  }
899  }
900  return 0;
901 }
902 
903 static int
904 ar_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
905 {
906  return ar_general_foreach(hash, func, replace, arg);
907 }
908 
909 struct functor {
912 };
913 
914 static int
915 apply_functor(st_data_t k, st_data_t v, st_data_t d, int _)
916 {
917  const struct functor *f = (void *)d;
918  return f->func(k, v, f->arg);
919 }
920 
921 static int
922 ar_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg)
923 {
924  const struct functor f = { func, arg };
925  return ar_general_foreach(hash, apply_functor, NULL, (st_data_t)&f);
926 }
927 
928 static int
929 ar_foreach_check(VALUE hash, st_foreach_check_callback_func *func, st_data_t arg,
930  st_data_t never)
931 {
932  if (RHASH_AR_TABLE_SIZE(hash) > 0) {
933  unsigned i, ret = 0, bound = RHASH_AR_TABLE_BOUND(hash);
934  enum st_retval retval;
935  st_data_t key;
936  ar_table_pair *pair;
937  ar_hint_t hint;
938 
939  for (i = 0; i < bound; i++) {
940  if (ar_cleared_entry(hash, i)) continue;
941 
942  pair = RHASH_AR_TABLE_REF(hash, i);
943  key = pair->key;
944  hint = ar_hint(hash, i);
945 
946  retval = (*func)(key, pair->val, arg, 0);
947  hash_verify(hash);
948 
949  switch (retval) {
950  case ST_CHECK: {
951  pair = RHASH_AR_TABLE_REF(hash, i);
952  if (pair->key == never) break;
953  ret = ar_find_entry_hint(hash, hint, key);
954  if (ret == RHASH_AR_TABLE_MAX_BOUND) {
955  retval = (*func)(0, 0, arg, 1);
956  return 2;
957  }
958  }
959  case ST_CONTINUE:
960  break;
961  case ST_STOP:
962  case ST_REPLACE:
963  return 0;
964  case ST_DELETE: {
965  if (!ar_cleared_entry(hash, i)) {
966  ar_clear_entry(hash, i);
967  RHASH_AR_TABLE_SIZE_DEC(hash);
968  }
969  break;
970  }
971  }
972  }
973  }
974  return 0;
975 }
976 
977 static int
978 ar_update(VALUE hash, st_data_t key,
980 {
981  int retval, existing;
982  unsigned bin = RHASH_AR_TABLE_MAX_BOUND;
983  st_data_t value = 0, old_key;
984  st_hash_t hash_value = ar_do_hash(key);
985 
986  if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
987  // `#hash` changes ar_table -> st_table
988  return -1;
989  }
990 
991  if (RHASH_AR_TABLE_SIZE(hash) > 0) {
992  bin = ar_find_entry(hash, hash_value, key);
993  existing = (bin != RHASH_AR_TABLE_MAX_BOUND) ? TRUE : FALSE;
994  }
995  else {
996  hash_ar_table(hash); /* allocate ltbl if needed */
997  existing = FALSE;
998  }
999 
1000  if (existing) {
1001  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, bin);
1002  key = pair->key;
1003  value = pair->val;
1004  }
1005  old_key = key;
1006  retval = (*func)(&key, &value, arg, existing);
1007  /* pair can be invalid here because of theap */
1008 
1009  switch (retval) {
1010  case ST_CONTINUE:
1011  if (!existing) {
1012  if (ar_add_direct_with_hash(hash, key, value, hash_value)) {
1013  return -1;
1014  }
1015  }
1016  else {
1017  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, bin);
1018  if (old_key != key) {
1019  pair->key = key;
1020  }
1021  pair->val = value;
1022  }
1023  break;
1024  case ST_DELETE:
1025  if (existing) {
1026  ar_clear_entry(hash, bin);
1027  RHASH_AR_TABLE_SIZE_DEC(hash);
1028  }
1029  break;
1030  }
1031  return existing;
1032 }
1033 
1034 static int
1035 ar_insert(VALUE hash, st_data_t key, st_data_t value)
1036 {
1037  unsigned bin = RHASH_AR_TABLE_BOUND(hash);
1038  st_hash_t hash_value = ar_do_hash(key);
1039 
1040  if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
1041  // `#hash` changes ar_table -> st_table
1042  return -1;
1043  }
1044 
1045  hash_ar_table(hash); /* prepare ltbl */
1046 
1047  bin = ar_find_entry(hash, hash_value, key);
1048  if (bin == RHASH_AR_TABLE_MAX_BOUND) {
1050  return -1;
1051  }
1052  else if (bin >= RHASH_AR_TABLE_MAX_BOUND) {
1053  bin = ar_compact_table(hash);
1054  hash_ar_table(hash);
1055  }
1057 
1058  ar_set_entry(hash, bin, key, value, hash_value);
1059  RHASH_AR_TABLE_BOUND_SET(hash, bin+1);
1061  return 0;
1062  }
1063  else {
1064  RHASH_AR_TABLE_REF(hash, bin)->val = value;
1065  return 1;
1066  }
1067 }
1068 
1069 static int
1070 ar_lookup(VALUE hash, st_data_t key, st_data_t *value)
1071 {
1072  if (RHASH_AR_TABLE_SIZE(hash) == 0) {
1073  return 0;
1074  }
1075  else {
1076  st_hash_t hash_value = ar_do_hash(key);
1077  if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
1078  // `#hash` changes ar_table -> st_table
1079  return st_lookup(RHASH_ST_TABLE(hash), key, value);
1080  }
1081  unsigned bin = ar_find_entry(hash, hash_value, key);
1082 
1083  if (bin == RHASH_AR_TABLE_MAX_BOUND) {
1084  return 0;
1085  }
1086  else {
1088  if (value != NULL) {
1089  *value = RHASH_AR_TABLE_REF(hash, bin)->val;
1090  }
1091  return 1;
1092  }
1093  }
1094 }
1095 
1096 static int
1097 ar_delete(VALUE hash, st_data_t *key, st_data_t *value)
1098 {
1099  unsigned bin;
1100  st_hash_t hash_value = ar_do_hash(*key);
1101 
1102  if (UNLIKELY(!RHASH_AR_TABLE_P(hash))) {
1103  // `#hash` changes ar_table -> st_table
1104  return st_delete(RHASH_ST_TABLE(hash), key, value);
1105  }
1106 
1107  bin = ar_find_entry(hash, hash_value, *key);
1108 
1109  if (bin == RHASH_AR_TABLE_MAX_BOUND) {
1110  if (value != 0) *value = 0;
1111  return 0;
1112  }
1113  else {
1114  if (value != 0) {
1115  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, bin);
1116  *value = pair->val;
1117  }
1118  ar_clear_entry(hash, bin);
1119  RHASH_AR_TABLE_SIZE_DEC(hash);
1120  return 1;
1121  }
1122 }
1123 
1124 static int
1125 ar_shift(VALUE hash, st_data_t *key, st_data_t *value)
1126 {
1127  if (RHASH_AR_TABLE_SIZE(hash) > 0) {
1128  unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
1129 
1130  for (i = 0; i < bound; i++) {
1131  if (!ar_cleared_entry(hash, i)) {
1132  ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
1133  if (value != 0) *value = pair->val;
1134  *key = pair->key;
1135  ar_clear_entry(hash, i);
1136  RHASH_AR_TABLE_SIZE_DEC(hash);
1137  return 1;
1138  }
1139  }
1140  }
1141  if (value != NULL) *value = 0;
1142  return 0;
1143 }
1144 
1145 static long
1146 ar_keys(VALUE hash, st_data_t *keys, st_index_t size)
1147 {
1148  unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
1149  st_data_t *keys_start = keys, *keys_end = keys + size;
1150 
1151  for (i = 0; i < bound; i++) {
1152  if (keys == keys_end) {
1153  break;
1154  }
1155  else {
1156  if (!ar_cleared_entry(hash, i)) {
1157  *keys++ = RHASH_AR_TABLE_REF(hash, i)->key;
1158  }
1159  }
1160  }
1161 
1162  return keys - keys_start;
1163 }
1164 
1165 static long
1166 ar_values(VALUE hash, st_data_t *values, st_index_t size)
1167 {
1168  unsigned i, bound = RHASH_AR_TABLE_BOUND(hash);
1169  st_data_t *values_start = values, *values_end = values + size;
1170 
1171  for (i = 0; i < bound; i++) {
1172  if (values == values_end) {
1173  break;
1174  }
1175  else {
1176  if (!ar_cleared_entry(hash, i)) {
1177  *values++ = RHASH_AR_TABLE_REF(hash, i)->val;
1178  }
1179  }
1180  }
1181 
1182  return values - values_start;
1183 }
1184 
1185 static ar_table*
1186 ar_copy(VALUE hash1, VALUE hash2)
1187 {
1188  ar_table *old_tab = RHASH_AR_TABLE(hash2);
1189 
1190  if (old_tab != NULL) {
1191  ar_table *new_tab = RHASH_AR_TABLE(hash1);
1192  if (new_tab == NULL) {
1193  new_tab = (ar_table*) rb_transient_heap_alloc(hash1, sizeof(ar_table));
1194  if (new_tab != NULL) {
1195  RHASH_SET_TRANSIENT_FLAG(hash1);
1196  }
1197  else {
1199  new_tab = (ar_table*)ruby_xmalloc(sizeof(ar_table));
1200  }
1201  }
1202  *new_tab = *old_tab;
1203  RHASH(hash1)->ar_hint.word = RHASH(hash2)->ar_hint.word;
1204  RHASH_AR_TABLE_BOUND_SET(hash1, RHASH_AR_TABLE_BOUND(hash2));
1205  RHASH_AR_TABLE_SIZE_SET(hash1, RHASH_AR_TABLE_SIZE(hash2));
1206  hash_ar_table_set(hash1, new_tab);
1207 
1209  return new_tab;
1210  }
1211  else {
1212  RHASH_AR_TABLE_BOUND_SET(hash1, RHASH_AR_TABLE_BOUND(hash2));
1213  RHASH_AR_TABLE_SIZE_SET(hash1, RHASH_AR_TABLE_SIZE(hash2));
1214 
1215  if (RHASH_TRANSIENT_P(hash1)) {
1217  }
1218  else if (RHASH_AR_TABLE(hash1)) {
1219  ruby_xfree(RHASH_AR_TABLE(hash1));
1220  }
1221 
1222  hash_ar_table_set(hash1, NULL);
1223 
1225  return old_tab;
1226  }
1227 }
1228 
1229 static void
1230 ar_clear(VALUE hash)
1231 {
1232  if (RHASH_AR_TABLE(hash) != NULL) {
1233  RHASH_AR_TABLE_SIZE_SET(hash, 0);
1234  RHASH_AR_TABLE_BOUND_SET(hash, 0);
1235  }
1236  else {
1237  HASH_ASSERT(RHASH_AR_TABLE_SIZE(hash) == 0);
1238  HASH_ASSERT(RHASH_AR_TABLE_BOUND(hash) == 0);
1239  }
1240 }
1241 
1242 #if USE_TRANSIENT_HEAP
1243 void
1245 {
1246  if (RHASH_TRANSIENT_P(hash)) {
1247  ar_table *new_tab;
1248  ar_table *old_tab = RHASH_AR_TABLE(hash);
1249 
1250  if (UNLIKELY(old_tab == NULL)) {
1251  rb_gc_force_recycle(hash);
1252  return;
1253  }
1254  HASH_ASSERT(old_tab != NULL);
1255  if (promote) {
1256  promote:
1257  new_tab = ruby_xmalloc(sizeof(ar_table));
1259  }
1260  else {
1261  new_tab = rb_transient_heap_alloc(hash, sizeof(ar_table));
1262  if (new_tab == NULL) goto promote;
1263  }
1264  *new_tab = *old_tab;
1265  hash_ar_table_set(hash, new_tab);
1266  }
1267  hash_verify(hash);
1268 }
1269 #endif
1270 
1272 
1277 };
1278 
1279 static int
1280 foreach_safe_i(st_data_t key, st_data_t value, st_data_t args, int error)
1281 {
1282  int status;
1283  struct foreach_safe_arg *arg = (void *)args;
1284 
1285  if (error) return ST_STOP;
1286  status = (*arg->func)(key, value, arg->arg);
1287  if (status == ST_CONTINUE) {
1288  return ST_CHECK;
1289  }
1290  return status;
1291 }
1292 
1293 void
1295 {
1296  struct foreach_safe_arg arg;
1297 
1298  arg.tbl = table;
1299  arg.func = (st_foreach_func *)func;
1300  arg.arg = a;
1301  if (st_foreach_check(table, foreach_safe_i, (st_data_t)&arg, 0)) {
1302  rb_raise(rb_eRuntimeError, "hash modified during iteration");
1303  }
1304 }
1305 
1307 
1308 struct hash_foreach_arg {
1312 };
1313 
1314 static int
1315 hash_ar_foreach_iter(st_data_t key, st_data_t value, st_data_t argp, int error)
1316 {
1317  struct hash_foreach_arg *arg = (struct hash_foreach_arg *)argp;
1318  int status;
1319 
1320  if (error) return ST_STOP;
1321  status = (*arg->func)((VALUE)key, (VALUE)value, arg->arg);
1322  /* TODO: rehash check? rb_raise(rb_eRuntimeError, "rehash occurred during iteration"); */
1323 
1324  switch (status) {
1325  case ST_DELETE:
1326  return ST_DELETE;
1327  case ST_CONTINUE:
1328  break;
1329  case ST_STOP:
1330  return ST_STOP;
1331  }
1332  return ST_CHECK;
1333 }
1334 
1335 static int
1336 hash_foreach_iter(st_data_t key, st_data_t value, st_data_t argp, int error)
1337 {
1338  struct hash_foreach_arg *arg = (struct hash_foreach_arg *)argp;
1339  int status;
1340  st_table *tbl;
1341 
1342  if (error) return ST_STOP;
1343  tbl = RHASH_ST_TABLE(arg->hash);
1344  status = (*arg->func)((VALUE)key, (VALUE)value, arg->arg);
1345  if (RHASH_ST_TABLE(arg->hash) != tbl) {
1346  rb_raise(rb_eRuntimeError, "rehash occurred during iteration");
1347  }
1348  switch (status) {
1349  case ST_DELETE:
1350  return ST_DELETE;
1351  case ST_CONTINUE:
1352  break;
1353  case ST_STOP:
1354  return ST_STOP;
1355  }
1356  return ST_CHECK;
1357 }
1358 
1359 static int
1360 iter_lev_in_ivar(VALUE hash)
1361 {
1362  VALUE levval = rb_ivar_get(hash, id_hash_iter_lev);
1363  HASH_ASSERT(FIXNUM_P(levval));
1364  return FIX2INT(levval);
1365 }
1366 
1367 void rb_ivar_set_internal(VALUE obj, ID id, VALUE val);
1368 
1369 static void
1370 iter_lev_in_ivar_set(VALUE hash, int lev)
1371 {
1372  rb_ivar_set_internal(hash, id_hash_iter_lev, INT2FIX(lev));
1373 }
1374 
1375 static int
1376 iter_lev_in_flags(VALUE hash)
1377 {
1378  unsigned int u = (unsigned int)((RBASIC(hash)->flags >> RHASH_LEV_SHIFT) & RHASH_LEV_MAX);
1379  return (int)u;
1380 }
1381 
1382 static int
1384 {
1385  int lev = iter_lev_in_flags(hash);
1386 
1387  if (lev == RHASH_LEV_MAX) {
1388  return iter_lev_in_ivar(hash);
1389  }
1390  else {
1391  return lev;
1392  }
1393 }
1394 
1395 static void
1396 hash_iter_lev_inc(VALUE hash)
1397 {
1398  int lev = iter_lev_in_flags(hash);
1399  if (lev == RHASH_LEV_MAX) {
1400  lev = iter_lev_in_ivar(hash);
1401  iter_lev_in_ivar_set(hash, lev+1);
1402  }
1403  else {
1404  lev += 1;
1405  RBASIC(hash)->flags = ((RBASIC(hash)->flags & ~RHASH_LEV_MASK) | (lev << RHASH_LEV_SHIFT));
1406  if (lev == RHASH_LEV_MAX) {
1407  iter_lev_in_ivar_set(hash, lev);
1408  }
1409  }
1410 }
1411 
1412 static void
1413 hash_iter_lev_dec(VALUE hash)
1414 {
1415  int lev = iter_lev_in_flags(hash);
1416  if (lev == RHASH_LEV_MAX) {
1417  lev = iter_lev_in_ivar(hash);
1418  HASH_ASSERT(lev > 0);
1419  iter_lev_in_ivar_set(hash, lev-1);
1420  }
1421  else {
1422  HASH_ASSERT(lev > 0);
1423  RBASIC(hash)->flags = ((RBASIC(hash)->flags & ~RHASH_LEV_MASK) | ((lev-1) << RHASH_LEV_SHIFT));
1424  }
1425 }
1426 
1427 static VALUE
1428 hash_foreach_ensure_rollback(VALUE hash)
1429 {
1430  hash_iter_lev_inc(hash);
1431  return 0;
1432 }
1433 
1434 static VALUE
1435 hash_foreach_ensure(VALUE hash)
1436 {
1437  hash_iter_lev_dec(hash);
1438  return 0;
1439 }
1440 
1441 int
1443 {
1444  if (RHASH_AR_TABLE_P(hash)) {
1445  return ar_foreach(hash, func, arg);
1446  }
1447  else {
1448  return st_foreach(RHASH_ST_TABLE(hash), func, arg);
1449  }
1450 }
1451 
1452 int
1454 {
1455  if (RHASH_AR_TABLE_P(hash)) {
1456  return ar_foreach_with_replace(hash, func, replace, arg);
1457  }
1458  else {
1459  return st_foreach_with_replace(RHASH_ST_TABLE(hash), func, replace, arg);
1460  }
1461 }
1462 
1463 static VALUE
1464 hash_foreach_call(VALUE arg)
1465 {
1466  VALUE hash = ((struct hash_foreach_arg *)arg)->hash;
1467  int ret = 0;
1468  if (RHASH_AR_TABLE_P(hash)) {
1469  ret = ar_foreach_check(hash, hash_ar_foreach_iter,
1471  }
1472  else if (RHASH_ST_TABLE_P(hash)) {
1473  ret = st_foreach_check(RHASH_ST_TABLE(hash), hash_foreach_iter,
1475  }
1476  if (ret) {
1477  rb_raise(rb_eRuntimeError, "ret: %d, hash modified during iteration", ret);
1478  }
1479  return Qnil;
1480 }
1481 
1482 void
1484 {
1485  struct hash_foreach_arg arg;
1486 
1487  if (RHASH_TABLE_EMPTY_P(hash))
1488  return;
1489  hash_iter_lev_inc(hash);
1490  arg.hash = hash;
1491  arg.func = (rb_foreach_func *)func;
1492  arg.arg = farg;
1493  rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
1494  hash_verify(hash);
1495 }
1496 
1497 static VALUE
1498 hash_alloc_flags(VALUE klass, VALUE flags, VALUE ifnone)
1499 {
1500  const VALUE wb = (RGENGC_WB_PROTECTED_HASH ? FL_WB_PROTECTED : 0);
1501  NEWOBJ_OF(hash, struct RHash, klass, T_HASH | wb | flags);
1502 
1503  RHASH_SET_IFNONE((VALUE)hash, ifnone);
1504 
1505  return (VALUE)hash;
1506 }
1507 
1508 static VALUE
1509 hash_alloc(VALUE klass)
1510 {
1511  return hash_alloc_flags(klass, 0, Qnil);
1512 }
1513 
1514 static VALUE
1515 empty_hash_alloc(VALUE klass)
1516 {
1517  RUBY_DTRACE_CREATE_HOOK(HASH, 0);
1518 
1519  return hash_alloc(klass);
1520 }
1521 
1522 VALUE
1524 {
1525  return hash_alloc(rb_cHash);
1526 }
1527 
1530 {
1531  VALUE ret = rb_hash_new();
1532  if (size == 0) {
1533  /* do nothing */
1534  }
1535  else if (size <= RHASH_AR_TABLE_MAX_SIZE) {
1536  ar_alloc_table(ret);
1537  }
1538  else {
1540  }
1541  return ret;
1542 }
1543 
1544 static VALUE
1545 hash_dup(VALUE hash, VALUE klass, VALUE flags)
1546 {
1547  VALUE ret = hash_alloc_flags(klass, flags,
1548  RHASH_IFNONE(hash));
1549  if (!RHASH_EMPTY_P(hash)) {
1550  if (RHASH_AR_TABLE_P(hash))
1551  ar_copy(ret, hash);
1552  else if (RHASH_ST_TABLE_P(hash))
1554  }
1555  return ret;
1556 }
1557 
1558 VALUE
1560 {
1561  const VALUE flags = RBASIC(hash)->flags;
1562  VALUE ret = hash_dup(hash, rb_obj_class(hash),
1563  flags & (FL_EXIVAR|RHASH_PROC_DEFAULT));
1564  if (flags & FL_EXIVAR)
1565  rb_copy_generic_ivar(ret, hash);
1566  return ret;
1567 }
1568 
1571 {
1572  VALUE ret = hash_dup(hash, rb_cHash, 0);
1573  return ret;
1574 }
1575 
1576 static void
1577 rb_hash_modify_check(VALUE hash)
1578 {
1580 }
1581 
1583 #if RHASH_CONVERT_TABLE_DEBUG
1584 rb_hash_tbl_raw(VALUE hash, const char *file, int line)
1585 {
1586  return ar_force_convert_table(hash, file, line);
1587 }
1588 #else
1590 {
1591  return ar_force_convert_table(hash, NULL, 0);
1592 }
1593 #endif
1594 
1595 struct st_table *
1596 rb_hash_tbl(VALUE hash, const char *file, int line)
1597 {
1598  OBJ_WB_UNPROTECT(hash);
1599  return RHASH_TBL_RAW(hash);
1600 }
1601 
1602 static void
1603 rb_hash_modify(VALUE hash)
1604 {
1605  rb_hash_modify_check(hash);
1606 }
1607 
1608 NORETURN(static void no_new_key(void));
1609 static void
1610 no_new_key(void)
1611 {
1612  rb_raise(rb_eRuntimeError, "can't add a new key into hash during iteration");
1613 }
1614 
1618 };
1619 
1620 #define NOINSERT_UPDATE_CALLBACK(func) \
1621 static int \
1622 func##_noinsert(st_data_t *key, st_data_t *val, st_data_t arg, int existing) \
1623 { \
1624  if (!existing) no_new_key(); \
1625  return func(key, val, (struct update_arg *)arg, existing); \
1626 } \
1627  \
1628 static int \
1629 func##_insert(st_data_t *key, st_data_t *val, st_data_t arg, int existing) \
1630 { \
1631  return func(key, val, (struct update_arg *)arg, existing); \
1632 }
1633 
1634 struct update_arg {
1641 };
1642 
1644 
1645 int
1647 {
1648  if (RHASH_AR_TABLE_P(hash)) {
1649  int result = ar_update(hash, (st_data_t)key, func, arg);
1650  if (result == -1) {
1651  ar_try_convert_table(hash);
1652  }
1653  else {
1654  return result;
1655  }
1656  }
1657 
1658  return st_update(RHASH_ST_TABLE(hash), (st_data_t)key, func, arg);
1659 }
1660 
1661 static int
1662 tbl_update(VALUE hash, VALUE key, tbl_update_func func, st_data_t optional_arg)
1663 {
1664  struct update_arg arg;
1665  int result;
1666 
1667  arg.arg = optional_arg;
1668  arg.hash = hash;
1669  arg.new_key = 0;
1670  arg.old_key = Qundef;
1671  arg.new_value = 0;
1672  arg.old_value = Qundef;
1673 
1674  result = rb_hash_stlike_update(hash, key, func, (st_data_t)&arg);
1675 
1676  /* write barrier */
1677  if (arg.new_key) RB_OBJ_WRITTEN(hash, arg.old_key, arg.new_key);
1678  if (arg.new_value) RB_OBJ_WRITTEN(hash, arg.old_value, arg.new_value);
1679 
1680  return result;
1681 }
1682 
1683 #define UPDATE_CALLBACK(iter_lev, func) ((iter_lev) > 0 ? func##_noinsert : func##_insert)
1684 
1685 #define RHASH_UPDATE_ITER(h, iter_lev, key, func, a) do { \
1686  tbl_update((h), (key), UPDATE_CALLBACK((iter_lev), func), (st_data_t)(a)); \
1687 } while (0)
1688 
1689 #define RHASH_UPDATE(hash, key, func, arg) \
1690  RHASH_UPDATE_ITER(hash, RHASH_ITER_LEV(hash), key, func, arg)
1691 
1692 static void
1693 set_proc_default(VALUE hash, VALUE proc)
1694 {
1695  if (rb_proc_lambda_p(proc)) {
1696  int n = rb_proc_arity(proc);
1697 
1698  if (n != 2 && (n >= 0 || n < -3)) {
1699  if (n < 0) n = -n-1;
1700  rb_raise(rb_eTypeError, "default_proc takes two arguments (2 for %d)", n);
1701  }
1702  }
1703 
1705  RHASH_SET_IFNONE(hash, proc);
1706 }
1707 
1708 /*
1709  * call-seq:
1710  * Hash.new -> new_hash
1711  * Hash.new(obj) -> new_hash
1712  * Hash.new {|hash, key| block } -> new_hash
1713  *
1714  * Returns a new, empty hash. If this hash is subsequently accessed by
1715  * a key that doesn't correspond to a hash entry, the value returned
1716  * depends on the style of <code>new</code> used to create the hash. In
1717  * the first form, the access returns <code>nil</code>. If
1718  * <i>obj</i> is specified, this single object will be used for
1719  * all <em>default values</em>. If a block is specified, it will be
1720  * called with the hash object and the key, and should return the
1721  * default value. It is the block's responsibility to store the value
1722  * in the hash if required.
1723  *
1724  * h = Hash.new("Go Fish")
1725  * h["a"] = 100
1726  * h["b"] = 200
1727  * h["a"] #=> 100
1728  * h["c"] #=> "Go Fish"
1729  * # The following alters the single default object
1730  * h["c"].upcase! #=> "GO FISH"
1731  * h["d"] #=> "GO FISH"
1732  * h.keys #=> ["a", "b"]
1733  *
1734  * # While this creates a new default object each time
1735  * h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
1736  * h["c"] #=> "Go Fish: c"
1737  * h["c"].upcase! #=> "GO FISH: C"
1738  * h["d"] #=> "Go Fish: d"
1739  * h.keys #=> ["c", "d"]
1740  *
1741  */
1742 
1743 static VALUE
1744 rb_hash_initialize(int argc, VALUE *argv, VALUE hash)
1745 {
1746  VALUE ifnone;
1747 
1748  rb_hash_modify(hash);
1749  if (rb_block_given_p()) {
1750  rb_check_arity(argc, 0, 0);
1751  ifnone = rb_block_proc();
1752  SET_PROC_DEFAULT(hash, ifnone);
1753  }
1754  else {
1755  rb_check_arity(argc, 0, 1);
1756  ifnone = argc == 0 ? Qnil : argv[0];
1757  RHASH_SET_IFNONE(hash, ifnone);
1758  }
1759 
1760  return hash;
1761 }
1762 
1763 /*
1764  * call-seq:
1765  * Hash[ key, value, ... ] -> new_hash
1766  * Hash[ [ [key, value], ... ] ] -> new_hash
1767  * Hash[ object ] -> new_hash
1768  *
1769  * Creates a new hash populated with the given objects.
1770  *
1771  * Similar to the literal <code>{ _key_ => _value_, ... }</code>. In the first
1772  * form, keys and values occur in pairs, so there must be an even number of
1773  * arguments.
1774  *
1775  * The second and third form take a single argument which is either an array
1776  * of key-value pairs or an object convertible to a hash.
1777  *
1778  * Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}
1779  * Hash[ [ ["a", 100], ["b", 200] ] ] #=> {"a"=>100, "b"=>200}
1780  * Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200}
1781  */
1782 
1783 static VALUE
1784 rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
1785 {
1786  VALUE hash, tmp;
1787 
1788  if (argc == 1) {
1789  tmp = rb_hash_s_try_convert(Qnil, argv[0]);
1790  if (!NIL_P(tmp)) {
1791  hash = hash_alloc(klass);
1792  if (RHASH_AR_TABLE_P(tmp)) {
1793  ar_copy(hash, tmp);
1794  }
1795  else {
1797  }
1798  return hash;
1799  }
1800 
1801  tmp = rb_check_array_type(argv[0]);
1802  if (!NIL_P(tmp)) {
1803  long i;
1804 
1805  hash = hash_alloc(klass);
1806  for (i = 0; i < RARRAY_LEN(tmp); ++i) {
1807  VALUE e = RARRAY_AREF(tmp, i);
1809  VALUE key, val = Qnil;
1810 
1811  if (NIL_P(v)) {
1812  rb_raise(rb_eArgError, "wrong element type %s at %ld (expected array)",
1813  rb_builtin_class_name(e), i);
1814  }
1815  switch (RARRAY_LEN(v)) {
1816  default:
1817  rb_raise(rb_eArgError, "invalid number of elements (%ld for 1..2)",
1818  RARRAY_LEN(v));
1819  case 2:
1820  val = RARRAY_AREF(v, 1);
1821  case 1:
1822  key = RARRAY_AREF(v, 0);
1823  rb_hash_aset(hash, key, val);
1824  }
1825  }
1826  return hash;
1827  }
1828  }
1829  if (argc % 2 != 0) {
1830  rb_raise(rb_eArgError, "odd number of arguments for Hash");
1831  }
1832 
1833  hash = hash_alloc(klass);
1835  hash_verify(hash);
1836  return hash;
1837 }
1838 
1839 VALUE
1841 {
1842  return rb_convert_type_with_id(hash, T_HASH, "Hash", idTo_hash);
1843 }
1844 #define to_hash rb_to_hash_type
1845 
1846 VALUE
1848 {
1850 }
1851 
1852 /*
1853  * call-seq:
1854  * Hash.try_convert(obj) -> hash or nil
1855  *
1856  * Try to convert <i>obj</i> into a hash, using to_hash method.
1857  * Returns converted hash or nil if <i>obj</i> cannot be converted
1858  * for any reason.
1859  *
1860  * Hash.try_convert({1=>2}) # => {1=>2}
1861  * Hash.try_convert("1=>2") # => nil
1862  */
1863 static VALUE
1864 rb_hash_s_try_convert(VALUE dummy, VALUE hash)
1865 {
1866  return rb_check_hash_type(hash);
1867 }
1868 
1869 /*
1870  * call-seq:
1871  * Hash.ruby2_keywords_hash?(hash) -> true or false
1872  *
1873  * Checks if a given hash is flagged by Module#ruby2_keywords (or
1874  * Proc#ruby2_keywords).
1875  * This method is not for casual use; debugging, researching, and
1876  * some truly necessary cases like serialization of arguments.
1877  *
1878  * ruby2_keywords def foo(*args)
1879  * Hash.ruby2_keywords_hash?(args.last)
1880  * end
1881  * foo(k: 1) #=> true
1882  * foo({k: 1}) #=> false
1883  */
1884 static VALUE
1885 rb_hash_s_ruby2_keywords_hash_p(VALUE dummy, VALUE hash)
1886 {
1888  return (RHASH(hash)->basic.flags & RHASH_PASS_AS_KEYWORDS) ? Qtrue : Qfalse;
1889 }
1890 
1891 /*
1892  * call-seq:
1893  * Hash.ruby2_keywords_hash(hash) -> hash
1894  *
1895  * Duplicates a given hash and adds a ruby2_keywords flag.
1896  * This method is not for casual use; debugging, researching, and
1897  * some truly necessary cases like deserialization of arguments.
1898  *
1899  * h = {k: 1}
1900  * h = Hash.ruby2_keywords_hash(h)
1901  * def foo(k: 42)
1902  * k
1903  * end
1904  * foo(*[h]) #=> 1 with neither a warning or an error
1905  */
1906 static VALUE
1907 rb_hash_s_ruby2_keywords_hash(VALUE dummy, VALUE hash)
1908 {
1910  hash = rb_hash_dup(hash);
1911  RHASH(hash)->basic.flags |= RHASH_PASS_AS_KEYWORDS;
1912  return hash;
1913 }
1914 
1915 struct rehash_arg {
1918 };
1919 
1920 static int
1921 rb_hash_rehash_i(VALUE key, VALUE value, VALUE arg)
1922 {
1923  if (RHASH_AR_TABLE_P(arg)) {
1924  ar_insert(arg, (st_data_t)key, (st_data_t)value);
1925  }
1926  else {
1928  }
1929  return ST_CONTINUE;
1930 }
1931 
1932 /*
1933  * call-seq:
1934  * hsh.rehash -> hsh
1935  *
1936  * Rebuilds the hash based on the current hash values for each key. If
1937  * values of key objects have changed since they were inserted, this
1938  * method will reindex <i>hsh</i>. If Hash#rehash is
1939  * called while an iterator is traversing the hash, a
1940  * RuntimeError will be raised in the iterator.
1941  *
1942  * a = [ "a", "b" ]
1943  * c = [ "c", "d" ]
1944  * h = { a => 100, c => 300 }
1945  * h[a] #=> 100
1946  * a[0] = "z"
1947  * h[a] #=> nil
1948  * h.rehash #=> {["z", "b"]=>100, ["c", "d"]=>300}
1949  * h[a] #=> 100
1950  */
1951 
1952 VALUE
1954 {
1955  VALUE tmp;
1956  st_table *tbl;
1957 
1958  if (RHASH_ITER_LEV(hash) > 0) {
1959  rb_raise(rb_eRuntimeError, "rehash during iteration");
1960  }
1961  rb_hash_modify_check(hash);
1962  if (RHASH_AR_TABLE_P(hash)) {
1963  tmp = hash_alloc(0);
1964  ar_alloc_table(tmp);
1965  rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
1966  ar_free_and_clear_table(hash);
1967  ar_copy(hash, tmp);
1968  ar_free_and_clear_table(tmp);
1969  }
1970  else if (RHASH_ST_TABLE_P(hash)) {
1971  st_table *old_tab = RHASH_ST_TABLE(hash);
1972  tmp = hash_alloc(0);
1973  tbl = st_init_table_with_size(old_tab->type, old_tab->num_entries);
1974  RHASH_ST_TABLE_SET(tmp, tbl);
1975  rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
1976  st_free_table(old_tab);
1977  RHASH_ST_TABLE_SET(hash, tbl);
1978  RHASH_ST_CLEAR(tmp);
1979  }
1980  hash_verify(hash);
1981  return hash;
1982 }
1983 
1984 VALUE
1986 {
1987  if (rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
1988  VALUE ifnone = RHASH_IFNONE(hash);
1989  if (!FL_TEST(hash, RHASH_PROC_DEFAULT)) return ifnone;
1990  if (key == Qundef) return Qnil;
1991  return rb_funcall(ifnone, id_yield, 2, hash, key);
1992  }
1993  else {
1994  return rb_funcall(hash, id_default, 1, key);
1995  }
1996 }
1997 
1998 static inline int
1999 hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval)
2000 {
2001  hash_verify(hash);
2002 
2003  if (RHASH_AR_TABLE_P(hash)) {
2004  return ar_lookup(hash, key, pval);
2005  }
2006  else {
2007  return st_lookup(RHASH_ST_TABLE(hash), key, pval);
2008  }
2009 }
2010 
2013 {
2014  return hash_stlike_lookup(hash, key, pval);
2015 }
2016 
2017 /*
2018  * call-seq:
2019  * hsh[key] -> value
2020  *
2021  * Element Reference---Retrieves the <i>value</i> object corresponding
2022  * to the <i>key</i> object. If not found, returns the default value (see
2023  * Hash::new for details).
2024  *
2025  * h = { "a" => 100, "b" => 200 }
2026  * h["a"] #=> 100
2027  * h["c"] #=> nil
2028  *
2029  */
2030 
2031 VALUE
2033 {
2034  st_data_t val;
2035 
2036  if (hash_stlike_lookup(hash, key, &val)) {
2037  return (VALUE)val;
2038  }
2039  else {
2040  return rb_hash_default_value(hash, key);
2041  }
2042 }
2043 
2044 VALUE
2046 {
2047  st_data_t val;
2048 
2049  if (hash_stlike_lookup(hash, key, &val)) {
2050  return (VALUE)val;
2051  }
2052  else {
2053  return def; /* without Hash#default */
2054  }
2055 }
2056 
2057 VALUE
2059 {
2060  return rb_hash_lookup2(hash, key, Qnil);
2061 }
2062 
2063 /*
2064  * call-seq:
2065  * hsh.fetch(key [, default] ) -> obj
2066  * hsh.fetch(key) {| key | block } -> obj
2067  *
2068  * Returns a value from the hash for the given key. If the key can't be
2069  * found, there are several options: With no other arguments, it will
2070  * raise a KeyError exception; if <i>default</i> is given,
2071  * then that will be returned; if the optional code block is specified,
2072  * then that will be run and its result returned.
2073  *
2074  * h = { "a" => 100, "b" => 200 }
2075  * h.fetch("a") #=> 100
2076  * h.fetch("z", "go fish") #=> "go fish"
2077  * h.fetch("z") { |el| "go fish, #{el}"} #=> "go fish, z"
2078  *
2079  * The following example shows that an exception is raised if the key
2080  * is not found and a default value is not supplied.
2081  *
2082  * h = { "a" => 100, "b" => 200 }
2083  * h.fetch("z")
2084  *
2085  * <em>produces:</em>
2086  *
2087  * prog.rb:2:in `fetch': key not found (KeyError)
2088  * from prog.rb:2
2089  *
2090  */
2091 
2092 static VALUE
2093 rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash)
2094 {
2095  VALUE key;
2096  st_data_t val;
2097  long block_given;
2098 
2099  rb_check_arity(argc, 1, 2);
2100  key = argv[0];
2101 
2102  block_given = rb_block_given_p();
2103  if (block_given && argc == 2) {
2104  rb_warn("block supersedes default value argument");
2105  }
2106 
2107  if (hash_stlike_lookup(hash, key, &val)) {
2108  return (VALUE)val;
2109  }
2110  else {
2111  if (block_given) {
2112  return rb_yield(key);
2113  }
2114  else if (argc == 1) {
2115  VALUE desc = rb_protect(rb_inspect, key, 0);
2116  if (NIL_P(desc)) {
2117  desc = rb_any_to_s(key);
2118  }
2119  desc = rb_str_ellipsize(desc, 65);
2120  rb_key_err_raise(rb_sprintf("key not found: %"PRIsVALUE, desc), hash, key);
2121  }
2122  else {
2123  return argv[1];
2124  }
2125  }
2126 }
2127 
2128 VALUE
2130 {
2131  return rb_hash_fetch_m(1, &key, hash);
2132 }
2133 
2134 /*
2135  * call-seq:
2136  * hsh.default(key=nil) -> obj
2137  *
2138  * Returns the default value, the value that would be returned by
2139  * <i>hsh</i>[<i>key</i>] if <i>key</i> did not exist in <i>hsh</i>.
2140  * See also Hash::new and Hash#default=.
2141  *
2142  * h = Hash.new #=> {}
2143  * h.default #=> nil
2144  * h.default(2) #=> nil
2145  *
2146  * h = Hash.new("cat") #=> {}
2147  * h.default #=> "cat"
2148  * h.default(2) #=> "cat"
2149  *
2150  * h = Hash.new {|h,k| h[k] = k.to_i*10} #=> {}
2151  * h.default #=> nil
2152  * h.default(2) #=> 20
2153  */
2154 
2155 static VALUE
2156 rb_hash_default(int argc, VALUE *argv, VALUE hash)
2157 {
2158  VALUE args[2], ifnone;
2159 
2160  rb_check_arity(argc, 0, 1);
2161  ifnone = RHASH_IFNONE(hash);
2162  if (FL_TEST(hash, RHASH_PROC_DEFAULT)) {
2163  if (argc == 0) return Qnil;
2164  args[0] = hash;
2165  args[1] = argv[0];
2166  return rb_funcallv(ifnone, id_yield, 2, args);
2167  }
2168  return ifnone;
2169 }
2170 
2171 /*
2172  * call-seq:
2173  * hsh.default = obj -> obj
2174  *
2175  * Sets the default value, the value returned for a key that does not
2176  * exist in the hash. It is not possible to set the default to a
2177  * Proc that will be executed on each key lookup.
2178  *
2179  * h = { "a" => 100, "b" => 200 }
2180  * h.default = "Go fish"
2181  * h["a"] #=> 100
2182  * h["z"] #=> "Go fish"
2183  * # This doesn't do what you might hope...
2184  * h.default = proc do |hash, key|
2185  * hash[key] = key + key
2186  * end
2187  * h[2] #=> #<Proc:0x401b3948@-:6>
2188  * h["cat"] #=> #<Proc:0x401b3948@-:6>
2189  */
2190 
2191 static VALUE
2192 rb_hash_set_default(VALUE hash, VALUE ifnone)
2193 {
2194  rb_hash_modify_check(hash);
2195  SET_DEFAULT(hash, ifnone);
2196  return ifnone;
2197 }
2198 
2199 /*
2200  * call-seq:
2201  * hsh.default_proc -> anObject
2202  *
2203  * If Hash::new was invoked with a block, return that
2204  * block, otherwise return <code>nil</code>.
2205  *
2206  * h = Hash.new {|h,k| h[k] = k*k } #=> {}
2207  * p = h.default_proc #=> #<Proc:0x401b3d08@-:1>
2208  * a = [] #=> []
2209  * p.call(a, 2)
2210  * a #=> [nil, nil, 4]
2211  */
2212 
2213 
2214 static VALUE
2215 rb_hash_default_proc(VALUE hash)
2216 {
2217  if (FL_TEST(hash, RHASH_PROC_DEFAULT)) {
2218  return RHASH_IFNONE(hash);
2219  }
2220  return Qnil;
2221 }
2222 
2223 /*
2224  * call-seq:
2225  * hsh.default_proc = proc_obj or nil
2226  *
2227  * Sets the default proc to be executed on each failed key lookup.
2228  *
2229  * h.default_proc = proc do |hash, key|
2230  * hash[key] = key + key
2231  * end
2232  * h[2] #=> 4
2233  * h["cat"] #=> "catcat"
2234  */
2235 
2236 VALUE
2238 {
2239  VALUE b;
2240 
2241  rb_hash_modify_check(hash);
2242  if (NIL_P(proc)) {
2243  SET_DEFAULT(hash, proc);
2244  return proc;
2245  }
2246  b = rb_check_convert_type_with_id(proc, T_DATA, "Proc", idTo_proc);
2247  if (NIL_P(b) || !rb_obj_is_proc(b)) {
2249  "wrong default_proc type %s (expected Proc)",
2250  rb_obj_classname(proc));
2251  }
2252  proc = b;
2253  SET_PROC_DEFAULT(hash, proc);
2254  return proc;
2255 }
2256 
2257 static int
2258 key_i(VALUE key, VALUE value, VALUE arg)
2259 {
2260  VALUE *args = (VALUE *)arg;
2261 
2262  if (rb_equal(value, args[0])) {
2263  args[1] = key;
2264  return ST_STOP;
2265  }
2266  return ST_CONTINUE;
2267 }
2268 
2269 /*
2270  * call-seq:
2271  * hsh.key(value) -> key
2272  *
2273  * Returns the key of an occurrence of a given value. If the value is
2274  * not found, returns <code>nil</code>.
2275  *
2276  * h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 }
2277  * h.key(200) #=> "b"
2278  * h.key(300) #=> "c"
2279  * h.key(999) #=> nil
2280  *
2281  */
2282 
2283 static VALUE
2284 rb_hash_key(VALUE hash, VALUE value)
2285 {
2286  VALUE args[2];
2287 
2288  args[0] = value;
2289  args[1] = Qnil;
2290 
2291  rb_hash_foreach(hash, key_i, (VALUE)args);
2292 
2293  return args[1];
2294 }
2295 
2296 /* :nodoc: */
2297 static VALUE
2298 rb_hash_index(VALUE hash, VALUE value)
2299 {
2300  rb_warn_deprecated("Hash#index", "Hash#key");
2301  return rb_hash_key(hash, value);
2302 }
2303 
2304 int
2306 {
2307  if (RHASH_AR_TABLE_P(hash)) {
2308  return ar_delete(hash, pkey, pval);
2309  }
2310  else {
2311  return st_delete(RHASH_ST_TABLE(hash), pkey, pval);
2312  }
2313 }
2314 
2315 /*
2316  * delete a specified entry a given key.
2317  * if there is the corresponding entry, return a value of the entry.
2318  * if there is no corresponding entry, return Qundef.
2319  */
2320 VALUE
2322 {
2323  st_data_t ktmp = (st_data_t)key, val;
2324 
2325  if (rb_hash_stlike_delete(hash, &ktmp, &val)) {
2326  return (VALUE)val;
2327  }
2328  else {
2329  return Qundef;
2330  }
2331 }
2332 
2333 /*
2334  * delete a specified entry by a given key.
2335  * if there is the corresponding entry, return a value of the entry.
2336  * if there is no corresponding entry, return Qnil.
2337  */
2338 VALUE
2340 {
2341  VALUE deleted_value = rb_hash_delete_entry(hash, key);
2342 
2343  if (deleted_value != Qundef) { /* likely pass */
2344  return deleted_value;
2345  }
2346  else {
2347  return Qnil;
2348  }
2349 }
2350 
2351 /*
2352  * call-seq:
2353  * hsh.delete(key) -> value
2354  * hsh.delete(key) {| key | block } -> value
2355  *
2356  * Deletes the key-value pair and returns the value from <i>hsh</i> whose
2357  * key is equal to <i>key</i>. If the key is not found, it returns
2358  * <em>nil</em>. If the optional code block is given and the
2359  * key is not found, pass in the key and return the result of
2360  * <i>block</i>.
2361  *
2362  * h = { "a" => 100, "b" => 200 }
2363  * h.delete("a") #=> 100
2364  * h.delete("z") #=> nil
2365  * h.delete("z") { |el| "#{el} not found" } #=> "z not found"
2366  *
2367  */
2368 
2369 static VALUE
2370 rb_hash_delete_m(VALUE hash, VALUE key)
2371 {
2372  VALUE val;
2373 
2374  rb_hash_modify_check(hash);
2375  val = rb_hash_delete_entry(hash, key);
2376 
2377  if (val != Qundef) {
2378  return val;
2379  }
2380  else {
2381  if (rb_block_given_p()) {
2382  return rb_yield(key);
2383  }
2384  else {
2385  return Qnil;
2386  }
2387  }
2388 }
2389 
2390 struct shift_var {
2393 };
2394 
2395 static int
2396 shift_i_safe(VALUE key, VALUE value, VALUE arg)
2397 {
2398  struct shift_var *var = (struct shift_var *)arg;
2399 
2400  var->key = key;
2401  var->val = value;
2402  return ST_STOP;
2403 }
2404 
2405 /*
2406  * call-seq:
2407  * hsh.shift -> anArray or obj
2408  *
2409  * Removes a key-value pair from <i>hsh</i> and returns it as the
2410  * two-item array <code>[</code> <i>key, value</i> <code>]</code>, or
2411  * the hash's default value if the hash is empty.
2412  *
2413  * h = { 1 => "a", 2 => "b", 3 => "c" }
2414  * h.shift #=> [1, "a"]
2415  * h #=> {2=>"b", 3=>"c"}
2416  */
2417 
2418 static VALUE
2419 rb_hash_shift(VALUE hash)
2420 {
2421  struct shift_var var;
2422 
2423  rb_hash_modify_check(hash);
2424  if (RHASH_AR_TABLE_P(hash)) {
2425  var.key = Qundef;
2426  if (RHASH_ITER_LEV(hash) == 0) {
2427  if (ar_shift(hash, &var.key, &var.val)) {
2428  return rb_assoc_new(var.key, var.val);
2429  }
2430  }
2431  else {
2432  rb_hash_foreach(hash, shift_i_safe, (VALUE)&var);
2433  if (var.key != Qundef) {
2434  rb_hash_delete_entry(hash, var.key);
2435  return rb_assoc_new(var.key, var.val);
2436  }
2437  }
2438  }
2439  if (RHASH_ST_TABLE_P(hash)) {
2440  var.key = Qundef;
2441  if (RHASH_ITER_LEV(hash) == 0) {
2442  if (st_shift(RHASH_ST_TABLE(hash), &var.key, &var.val)) {
2443  return rb_assoc_new(var.key, var.val);
2444  }
2445  }
2446  else {
2447  rb_hash_foreach(hash, shift_i_safe, (VALUE)&var);
2448  if (var.key != Qundef) {
2449  rb_hash_delete_entry(hash, var.key);
2450  return rb_assoc_new(var.key, var.val);
2451  }
2452  }
2453  }
2454  return rb_hash_default_value(hash, Qnil);
2455 }
2456 
2457 static int
2458 delete_if_i(VALUE key, VALUE value, VALUE hash)
2459 {
2460  if (RTEST(rb_yield_values(2, key, value))) {
2461  return ST_DELETE;
2462  }
2463  return ST_CONTINUE;
2464 }
2465 
2466 static VALUE
2467 hash_enum_size(VALUE hash, VALUE args, VALUE eobj)
2468 {
2469  return rb_hash_size(hash);
2470 }
2471 
2472 /*
2473  * call-seq:
2474  * hsh.delete_if {| key, value | block } -> hsh
2475  * hsh.delete_if -> an_enumerator
2476  *
2477  * Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
2478  * evaluates to <code>true</code>.
2479  *
2480  * If no block is given, an enumerator is returned instead.
2481  *
2482  * h = { "a" => 100, "b" => 200, "c" => 300 }
2483  * h.delete_if {|key, value| key >= "b" } #=> {"a"=>100}
2484  *
2485  */
2486 
2487 VALUE
2489 {
2490  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2491  rb_hash_modify_check(hash);
2492  if (!RHASH_TABLE_EMPTY_P(hash)) {
2493  rb_hash_foreach(hash, delete_if_i, hash);
2494  }
2495  return hash;
2496 }
2497 
2498 /*
2499  * call-seq:
2500  * hsh.reject! {| key, value | block } -> hsh or nil
2501  * hsh.reject! -> an_enumerator
2502  *
2503  * Equivalent to Hash#delete_if, but returns
2504  * <code>nil</code> if no changes were made.
2505  */
2506 
2507 VALUE
2509 {
2510  st_index_t n;
2511 
2512  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2513  rb_hash_modify(hash);
2514  n = RHASH_SIZE(hash);
2515  if (!n) return Qnil;
2516  rb_hash_foreach(hash, delete_if_i, hash);
2517  if (n == RHASH_SIZE(hash)) return Qnil;
2518  return hash;
2519 }
2520 
2521 static int
2522 reject_i(VALUE key, VALUE value, VALUE result)
2523 {
2524  if (!RTEST(rb_yield_values(2, key, value))) {
2525  rb_hash_aset(result, key, value);
2526  }
2527  return ST_CONTINUE;
2528 }
2529 
2530 /*
2531  * call-seq:
2532  * hsh.reject {|key, value| block} -> a_hash
2533  * hsh.reject -> an_enumerator
2534  *
2535  * Returns a new hash consisting of entries for which the block returns false.
2536  *
2537  * If no block is given, an enumerator is returned instead.
2538  *
2539  * h = { "a" => 100, "b" => 200, "c" => 300 }
2540  * h.reject {|k,v| k < "b"} #=> {"b" => 200, "c" => 300}
2541  * h.reject {|k,v| v > 100} #=> {"a" => 100}
2542  */
2543 
2544 VALUE
2546 {
2547  VALUE result;
2548 
2549  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2550  if (RTEST(ruby_verbose)) {
2551  VALUE klass;
2552  if (HAS_EXTRA_STATES(hash, klass)) {
2553  rb_warn("extra states are no longer copied: %+"PRIsVALUE, hash);
2554  }
2555  }
2556  result = rb_hash_new();
2557  if (!RHASH_EMPTY_P(hash)) {
2558  rb_hash_foreach(hash, reject_i, result);
2559  }
2560  return result;
2561 }
2562 
2563 /*
2564  * call-seq:
2565  * hsh.slice(*keys) -> a_hash
2566  *
2567  * Returns a hash containing only the given keys and their values.
2568  *
2569  * h = { a: 100, b: 200, c: 300 }
2570  * h.slice(:a) #=> {:a=>100}
2571  * h.slice(:b, :c, :d) #=> {:b=>200, :c=>300}
2572  */
2573 
2574 static VALUE
2575 rb_hash_slice(int argc, VALUE *argv, VALUE hash)
2576 {
2577  int i;
2578  VALUE key, value, result;
2579 
2580  if (argc == 0 || RHASH_EMPTY_P(hash)) {
2581  return rb_hash_new();
2582  }
2583  result = rb_hash_new_with_size(argc);
2584 
2585  for (i = 0; i < argc; i++) {
2586  key = argv[i];
2587  value = rb_hash_lookup2(hash, key, Qundef);
2588  if (value != Qundef)
2589  rb_hash_aset(result, key, value);
2590  }
2591 
2592  return result;
2593 }
2594 
2595 /*
2596  * call-seq:
2597  * hsh.values_at(key, ...) -> array
2598  *
2599  * Return an array containing the values associated with the given keys.
2600  * Also see Hash.select.
2601  *
2602  * h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
2603  * h.values_at("cow", "cat") #=> ["bovine", "feline"]
2604  */
2605 
2606 VALUE
2608 {
2609  VALUE result = rb_ary_new2(argc);
2610  long i;
2611 
2612  for (i=0; i<argc; i++) {
2613  rb_ary_push(result, rb_hash_aref(hash, argv[i]));
2614  }
2615  return result;
2616 }
2617 
2618 /*
2619  * call-seq:
2620  * hsh.fetch_values(key, ...) -> array
2621  * hsh.fetch_values(key, ...) { |key| block } -> array
2622  *
2623  * Returns an array containing the values associated with the given keys
2624  * but also raises KeyError when one of keys can't be found.
2625  * Also see Hash#values_at and Hash#fetch.
2626  *
2627  * h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
2628  *
2629  * h.fetch_values("cow", "cat") #=> ["bovine", "feline"]
2630  * h.fetch_values("cow", "bird") # raises KeyError
2631  * h.fetch_values("cow", "bird") { |k| k.upcase } #=> ["bovine", "BIRD"]
2632  */
2633 
2634 VALUE
2636 {
2637  VALUE result = rb_ary_new2(argc);
2638  long i;
2639 
2640  for (i=0; i<argc; i++) {
2641  rb_ary_push(result, rb_hash_fetch(hash, argv[i]));
2642  }
2643  return result;
2644 }
2645 
2646 static int
2647 select_i(VALUE key, VALUE value, VALUE result)
2648 {
2649  if (RTEST(rb_yield_values(2, key, value))) {
2650  rb_hash_aset(result, key, value);
2651  }
2652  return ST_CONTINUE;
2653 }
2654 
2655 /*
2656  * call-seq:
2657  * hsh.select {|key, value| block} -> a_hash
2658  * hsh.select -> an_enumerator
2659  * hsh.filter {|key, value| block} -> a_hash
2660  * hsh.filter -> an_enumerator
2661  *
2662  * Returns a new hash consisting of entries for which the block returns true.
2663  *
2664  * If no block is given, an enumerator is returned instead.
2665  *
2666  * h = { "a" => 100, "b" => 200, "c" => 300 }
2667  * h.select {|k,v| k > "a"} #=> {"b" => 200, "c" => 300}
2668  * h.select {|k,v| v < 200} #=> {"a" => 100}
2669  *
2670  * Hash#filter is an alias for Hash#select.
2671  */
2672 
2673 VALUE
2675 {
2676  VALUE result;
2677 
2678  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2679  result = rb_hash_new();
2680  if (!RHASH_EMPTY_P(hash)) {
2681  rb_hash_foreach(hash, select_i, result);
2682  }
2683  return result;
2684 }
2685 
2686 static int
2687 keep_if_i(VALUE key, VALUE value, VALUE hash)
2688 {
2689  if (!RTEST(rb_yield_values(2, key, value))) {
2690  return ST_DELETE;
2691  }
2692  return ST_CONTINUE;
2693 }
2694 
2695 /*
2696  * call-seq:
2697  * hsh.select! {| key, value | block } -> hsh or nil
2698  * hsh.select! -> an_enumerator
2699  * hsh.filter! {| key, value | block } -> hsh or nil
2700  * hsh.filter! -> an_enumerator
2701  *
2702  * Equivalent to Hash#keep_if, but returns
2703  * +nil+ if no changes were made.
2704  *
2705  * Hash#filter! is an alias for Hash#select!.
2706  */
2707 
2708 VALUE
2710 {
2711  st_index_t n;
2712 
2713  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2714  rb_hash_modify_check(hash);
2715  n = RHASH_SIZE(hash);
2716  if (!n) return Qnil;
2717  rb_hash_foreach(hash, keep_if_i, hash);
2718  if (n == RHASH_SIZE(hash)) return Qnil;
2719  return hash;
2720 }
2721 
2722 /*
2723  * call-seq:
2724  * hsh.keep_if {| key, value | block } -> hsh
2725  * hsh.keep_if -> an_enumerator
2726  *
2727  * Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
2728  * evaluates to +false+.
2729  *
2730  * If no block is given, an enumerator is returned instead.
2731  *
2732  * See also Hash#select!.
2733  */
2734 
2735 VALUE
2737 {
2738  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2739  rb_hash_modify_check(hash);
2740  if (!RHASH_TABLE_EMPTY_P(hash)) {
2741  rb_hash_foreach(hash, keep_if_i, hash);
2742  }
2743  return hash;
2744 }
2745 
2746 static int
2747 clear_i(VALUE key, VALUE value, VALUE dummy)
2748 {
2749  return ST_DELETE;
2750 }
2751 
2752 /*
2753  * call-seq:
2754  * hsh.clear -> hsh
2755  *
2756  * Removes all key-value pairs from <i>hsh</i>.
2757  *
2758  * h = { "a" => 100, "b" => 200 } #=> {"a"=>100, "b"=>200}
2759  * h.clear #=> {}
2760  *
2761  */
2762 
2763 VALUE
2765 {
2766  rb_hash_modify_check(hash);
2767 
2768  if (RHASH_ITER_LEV(hash) > 0) {
2769  rb_hash_foreach(hash, clear_i, 0);
2770  }
2771  else if (RHASH_AR_TABLE_P(hash)) {
2772  ar_clear(hash);
2773  }
2774  else {
2775  st_clear(RHASH_ST_TABLE(hash));
2776  }
2777 
2778  return hash;
2779 }
2780 
2781 static int
2782 hash_aset(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
2783 {
2784  if (existing) {
2785  arg->new_value = arg->arg;
2786  arg->old_value = *val;
2787  }
2788  else {
2789  arg->new_key = *key;
2790  arg->new_value = arg->arg;
2791  }
2792  *val = arg->arg;
2793  return ST_CONTINUE;
2794 }
2795 
2796 VALUE
2798 {
2800  return rb_fstring(key);
2801  }
2802  else {
2803  return rb_str_new_frozen(key);
2804  }
2805 }
2806 
2807 static int
2808 hash_aset_str(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
2809 {
2810  if (!existing && !RB_OBJ_FROZEN(*key)) {
2811  *key = rb_hash_key_str(*key);
2812  }
2813  return hash_aset(key, val, arg, existing);
2814 }
2815 
2816 NOINSERT_UPDATE_CALLBACK(hash_aset)
2817 NOINSERT_UPDATE_CALLBACK(hash_aset_str)
2818 
2819 /*
2820  * call-seq:
2821  * hsh[key] = value -> value
2822  * hsh.store(key, value) -> value
2823  *
2824  * == Element Assignment
2825  *
2826  * Associates the value given by +value+ with the key given by +key+.
2827  *
2828  * h = { "a" => 100, "b" => 200 }
2829  * h["a"] = 9
2830  * h["c"] = 4
2831  * h #=> {"a"=>9, "b"=>200, "c"=>4}
2832  * h.store("d", 42) #=> 42
2833  * h #=> {"a"=>9, "b"=>200, "c"=>4, "d"=>42}
2834  *
2835  * +key+ should not have its value changed while it is in use as a key (an
2836  * <tt>unfrozen String</tt> passed as a key will be duplicated and frozen).
2837  *
2838  * a = "a"
2839  * b = "b".freeze
2840  * h = { a => 100, b => 200 }
2841  * h.key(100).equal? a #=> false
2842  * h.key(200).equal? b #=> true
2843  *
2844  */
2845 
2846 VALUE
2848 {
2849  int iter_lev = RHASH_ITER_LEV(hash);
2850 
2851  rb_hash_modify(hash);
2852 
2853  if (RHASH_TABLE_NULL_P(hash)) {
2854  if (iter_lev > 0) no_new_key();
2855  ar_alloc_table(hash);
2856  }
2857 
2858  if (RHASH_TYPE(hash) == &identhash || rb_obj_class(key) != rb_cString) {
2859  RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset, val);
2860  }
2861  else {
2862  RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset_str, val);
2863  }
2864  return val;
2865 }
2866 
2867 /*
2868  * call-seq:
2869  * hsh.replace(other_hash) -> hsh
2870  *
2871  * Replaces the contents of <i>hsh</i> with the contents of
2872  * <i>other_hash</i>.
2873  *
2874  * h = { "a" => 100, "b" => 200 }
2875  * h.replace({ "c" => 300, "d" => 400 }) #=> {"c"=>300, "d"=>400}
2876  *
2877  */
2878 
2879 static VALUE
2880 rb_hash_replace(VALUE hash, VALUE hash2)
2881 {
2882  rb_hash_modify_check(hash);
2883  if (hash == hash2) return hash;
2884  if (RHASH_ITER_LEV(hash) > 0) {
2885  rb_raise(rb_eRuntimeError, "can't replace hash during iteration");
2886  }
2887  hash2 = to_hash(hash2);
2888 
2889  COPY_DEFAULT(hash, hash2);
2890 
2891  if (RHASH_AR_TABLE_P(hash)) {
2892  if (RHASH_AR_TABLE_P(hash2)) {
2893  ar_clear(hash);
2894  }
2895  else {
2896  ar_free_and_clear_table(hash);
2898  }
2899  }
2900  else {
2901  if (RHASH_AR_TABLE_P(hash2)) {
2903  RHASH_ST_CLEAR(hash);
2904  }
2905  else {
2906  st_clear(RHASH_ST_TABLE(hash));
2907  RHASH_TBL_RAW(hash)->type = RHASH_ST_TABLE(hash2)->type;
2908  }
2909  }
2910  rb_hash_foreach(hash2, rb_hash_rehash_i, (VALUE)hash);
2911 
2913 
2914  return hash;
2915 }
2916 
2917 /*
2918  * call-seq:
2919  * hsh.length -> integer
2920  * hsh.size -> integer
2921  *
2922  * Returns the number of key-value pairs in the hash.
2923  *
2924  * h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
2925  * h.size #=> 4
2926  * h.delete("a") #=> 200
2927  * h.size #=> 3
2928  * h.length #=> 3
2929  *
2930  * Hash#length is an alias for Hash#size.
2931  */
2932 
2933 VALUE
2935 {
2936  return INT2FIX(RHASH_SIZE(hash));
2937 }
2938 
2939 size_t
2941 {
2942  return (long)RHASH_SIZE(hash);
2943 }
2944 
2945 /*
2946  * call-seq:
2947  * hsh.empty? -> true or false
2948  *
2949  * Returns <code>true</code> if <i>hsh</i> contains no key-value pairs.
2950  *
2951  * {}.empty? #=> true
2952  *
2953  */
2954 
2955 static VALUE
2956 rb_hash_empty_p(VALUE hash)
2957 {
2958  return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse;
2959 }
2960 
2961 static int
2962 each_value_i(VALUE key, VALUE value, VALUE _)
2963 {
2964  rb_yield(value);
2965  return ST_CONTINUE;
2966 }
2967 
2968 /*
2969  * call-seq:
2970  * hsh.each_value {| value | block } -> hsh
2971  * hsh.each_value -> an_enumerator
2972  *
2973  * Calls <i>block</i> once for each key in <i>hsh</i>, passing the
2974  * value as a parameter.
2975  *
2976  * If no block is given, an enumerator is returned instead.
2977  *
2978  * h = { "a" => 100, "b" => 200 }
2979  * h.each_value {|value| puts value }
2980  *
2981  * <em>produces:</em>
2982  *
2983  * 100
2984  * 200
2985  */
2986 
2987 static VALUE
2988 rb_hash_each_value(VALUE hash)
2989 {
2990  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2991  rb_hash_foreach(hash, each_value_i, 0);
2992  return hash;
2993 }
2994 
2995 static int
2996 each_key_i(VALUE key, VALUE value, VALUE _)
2997 {
2998  rb_yield(key);
2999  return ST_CONTINUE;
3000 }
3001 
3002 /*
3003  * call-seq:
3004  * hsh.each_key {| key | block } -> hsh
3005  * hsh.each_key -> an_enumerator
3006  *
3007  * Calls <i>block</i> once for each key in <i>hsh</i>, passing the key
3008  * as a parameter.
3009  *
3010  * If no block is given, an enumerator is returned instead.
3011  *
3012  * h = { "a" => 100, "b" => 200 }
3013  * h.each_key {|key| puts key }
3014  *
3015  * <em>produces:</em>
3016  *
3017  * a
3018  * b
3019  */
3020 static VALUE
3021 rb_hash_each_key(VALUE hash)
3022 {
3023  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3024  rb_hash_foreach(hash, each_key_i, 0);
3025  return hash;
3026 }
3027 
3028 static int
3029 each_pair_i(VALUE key, VALUE value, VALUE _)
3030 {
3031  rb_yield(rb_assoc_new(key, value));
3032  return ST_CONTINUE;
3033 }
3034 
3035 static int
3036 each_pair_i_fast(VALUE key, VALUE value, VALUE _)
3037 {
3038  VALUE argv[2];
3039  argv[0] = key;
3040  argv[1] = value;
3041  rb_yield_values2(2, argv);
3042  return ST_CONTINUE;
3043 }
3044 
3045 /*
3046  * call-seq:
3047  * hsh.each {| key, value | block } -> hsh
3048  * hsh.each_pair {| key, value | block } -> hsh
3049  * hsh.each -> an_enumerator
3050  * hsh.each_pair -> an_enumerator
3051  *
3052  * Calls <i>block</i> once for each key in <i>hsh</i>, passing the key-value
3053  * pair as parameters.
3054  *
3055  * If no block is given, an enumerator is returned instead.
3056  *
3057  * h = { "a" => 100, "b" => 200 }
3058  * h.each {|key, value| puts "#{key} is #{value}" }
3059  *
3060  * <em>produces:</em>
3061  *
3062  * a is 100
3063  * b is 200
3064  *
3065  */
3066 
3067 static VALUE
3068 rb_hash_each_pair(VALUE hash)
3069 {
3070  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3071  if (rb_block_arity() > 1)
3072  rb_hash_foreach(hash, each_pair_i_fast, 0);
3073  else
3074  rb_hash_foreach(hash, each_pair_i, 0);
3075  return hash;
3076 }
3077 
3078 static int
3079 transform_keys_i(VALUE key, VALUE value, VALUE result)
3080 {
3081  VALUE new_key = rb_yield(key);
3082  rb_hash_aset(result, new_key, value);
3083  return ST_CONTINUE;
3084 }
3085 
3086 /*
3087  * call-seq:
3088  * hsh.transform_keys {|key| block } -> new_hash
3089  * hsh.transform_keys -> an_enumerator
3090  *
3091  * Returns a new hash with the results of running the block once for
3092  * every key.
3093  * This method does not change the values.
3094  *
3095  * h = { a: 1, b: 2, c: 3 }
3096  * h.transform_keys {|k| k.to_s } #=> { "a" => 1, "b" => 2, "c" => 3 }
3097  * h.transform_keys(&:to_s) #=> { "a" => 1, "b" => 2, "c" => 3 }
3098  * h.transform_keys.with_index {|k, i| "#{k}.#{i}" }
3099  * #=> { "a.0" => 1, "b.1" => 2, "c.2" => 3 }
3100  *
3101  * If no block is given, an enumerator is returned instead.
3102  */
3103 static VALUE
3104 rb_hash_transform_keys(VALUE hash)
3105 {
3106  VALUE result;
3107 
3108  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3109  result = rb_hash_new();
3110  if (!RHASH_EMPTY_P(hash)) {
3111  rb_hash_foreach(hash, transform_keys_i, result);
3112  }
3113 
3114  return result;
3115 }
3116 
3117 static VALUE rb_hash_flatten(int argc, VALUE *argv, VALUE hash);
3118 
3119 /*
3120  * call-seq:
3121  * hsh.transform_keys! {|key| block } -> hsh
3122  * hsh.transform_keys! -> an_enumerator
3123  *
3124  * Invokes the given block once for each key in <i>hsh</i>, replacing it
3125  * with the new key returned by the block, and then returns <i>hsh</i>.
3126  * This method does not change the values.
3127  *
3128  * h = { a: 1, b: 2, c: 3 }
3129  * h.transform_keys! {|k| k.to_s } #=> { "a" => 1, "b" => 2, "c" => 3 }
3130  * h.transform_keys!(&:to_sym) #=> { a: 1, b: 2, c: 3 }
3131  * h.transform_keys!.with_index {|k, i| "#{k}.#{i}" }
3132  * #=> { "a.0" => 1, "b.1" => 2, "c.2" => 3 }
3133  *
3134  * If no block is given, an enumerator is returned instead.
3135  */
3136 static VALUE
3137 rb_hash_transform_keys_bang(VALUE hash)
3138 {
3139  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3140  rb_hash_modify_check(hash);
3141  if (!RHASH_TABLE_EMPTY_P(hash)) {
3142  long i;
3143  VALUE pairs = rb_hash_flatten(0, NULL, hash);
3144  rb_hash_clear(hash);
3145  for (i = 0; i < RARRAY_LEN(pairs); i += 2) {
3146  VALUE key = RARRAY_AREF(pairs, i), new_key = rb_yield(key),
3147  val = RARRAY_AREF(pairs, i+1);
3148  rb_hash_aset(hash, new_key, val);
3149  }
3150  }
3151  return hash;
3152 }
3153 
3154 static int
3155 transform_values_foreach_func(st_data_t key, st_data_t value, st_data_t argp, int error)
3156 {
3157  return ST_REPLACE;
3158 }
3159 
3160 static int
3161 transform_values_foreach_replace(st_data_t *key, st_data_t *value, st_data_t argp, int existing)
3162 {
3163  VALUE new_value = rb_yield((VALUE)*value);
3164  VALUE hash = (VALUE)argp;
3165  RB_OBJ_WRITE(hash, value, new_value);
3166  return ST_CONTINUE;
3167 }
3168 
3169 /*
3170  * call-seq:
3171  * hsh.transform_values {|value| block } -> new_hash
3172  * hsh.transform_values -> an_enumerator
3173  *
3174  * Returns a new hash with the results of running the block once for
3175  * every value.
3176  * This method does not change the keys.
3177  *
3178  * h = { a: 1, b: 2, c: 3 }
3179  * h.transform_values {|v| v * v + 1 } #=> { a: 2, b: 5, c: 10 }
3180  * h.transform_values(&:to_s) #=> { a: "1", b: "2", c: "3" }
3181  * h.transform_values.with_index {|v, i| "#{v}.#{i}" }
3182  * #=> { a: "1.0", b: "2.1", c: "3.2" }
3183  *
3184  * If no block is given, an enumerator is returned instead.
3185  */
3186 static VALUE
3187 rb_hash_transform_values(VALUE hash)
3188 {
3189  VALUE result;
3190 
3191  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3192  result = hash_dup(hash, rb_cHash, 0);
3193 
3194  if (!RHASH_EMPTY_P(hash)) {
3195  rb_hash_stlike_foreach_with_replace(result, transform_values_foreach_func, transform_values_foreach_replace, result);
3196  }
3197 
3198  return result;
3199 }
3200 
3201 /*
3202  * call-seq:
3203  * hsh.transform_values! {|value| block } -> hsh
3204  * hsh.transform_values! -> an_enumerator
3205  *
3206  * Invokes the given block once for each value in <i>hsh</i>, replacing it
3207  * with the new value returned by the block, and then returns <i>hsh</i>.
3208  * This method does not change the keys.
3209  *
3210  * h = { a: 1, b: 2, c: 3 }
3211  * h.transform_values! {|v| v * v + 1 } #=> { a: 2, b: 5, c: 10 }
3212  * h.transform_values!(&:to_s) #=> { a: "2", b: "5", c: "10" }
3213  * h.transform_values!.with_index {|v, i| "#{v}.#{i}" }
3214  * #=> { a: "2.0", b: "5.1", c: "10.2" }
3215  *
3216  * If no block is given, an enumerator is returned instead.
3217  */
3218 static VALUE
3219 rb_hash_transform_values_bang(VALUE hash)
3220 {
3221  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3222  rb_hash_modify_check(hash);
3223 
3224  if (!RHASH_TABLE_EMPTY_P(hash)) {
3225  rb_hash_stlike_foreach_with_replace(hash, transform_values_foreach_func, transform_values_foreach_replace, hash);
3226  }
3227 
3228  return hash;
3229 }
3230 
3231 static int
3232 to_a_i(VALUE key, VALUE value, VALUE ary)
3233 {
3234  rb_ary_push(ary, rb_assoc_new(key, value));
3235  return ST_CONTINUE;
3236 }
3237 
3238 /*
3239  * call-seq:
3240  * hsh.to_a -> array
3241  *
3242  * Converts <i>hsh</i> to a nested array of <code>[</code> <i>key,
3243  * value</i> <code>]</code> arrays.
3244  *
3245  * h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 }
3246  * h.to_a #=> [["c", 300], ["a", 100], ["d", 400]]
3247  */
3248 
3249 static VALUE
3250 rb_hash_to_a(VALUE hash)
3251 {
3252  VALUE ary;
3253 
3254  ary = rb_ary_new_capa(RHASH_SIZE(hash));
3255  rb_hash_foreach(hash, to_a_i, ary);
3256 
3257  return ary;
3258 }
3259 
3260 static int
3261 inspect_i(VALUE key, VALUE value, VALUE str)
3262 {
3263  VALUE str2;
3264 
3265  str2 = rb_inspect(key);
3266  if (RSTRING_LEN(str) > 1) {
3267  rb_str_buf_cat_ascii(str, ", ");
3268  }
3269  else {
3270  rb_enc_copy(str, str2);
3271  }
3272  rb_str_buf_append(str, str2);
3273  rb_str_buf_cat_ascii(str, "=>");
3274  str2 = rb_inspect(value);
3275  rb_str_buf_append(str, str2);
3276 
3277  return ST_CONTINUE;
3278 }
3279 
3280 static VALUE
3281 inspect_hash(VALUE hash, VALUE dummy, int recur)
3282 {
3283  VALUE str;
3284 
3285  if (recur) return rb_usascii_str_new2("{...}");
3286  str = rb_str_buf_new2("{");
3287  rb_hash_foreach(hash, inspect_i, str);
3288  rb_str_buf_cat2(str, "}");
3289 
3290  return str;
3291 }
3292 
3293 /*
3294  * call-seq:
3295  * hsh.to_s -> string
3296  * hsh.inspect -> string
3297  *
3298  * Return the contents of this hash as a string.
3299  *
3300  * h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 }
3301  * h.to_s #=> "{\"c\"=>300, \"a\"=>100, \"d\"=>400}"
3302  */
3303 
3304 static VALUE
3305 rb_hash_inspect(VALUE hash)
3306 {
3307  if (RHASH_EMPTY_P(hash))
3308  return rb_usascii_str_new2("{}");
3309  return rb_exec_recursive(inspect_hash, hash, 0);
3310 }
3311 
3312 /*
3313  * call-seq:
3314  * hsh.to_hash => hsh
3315  *
3316  * Returns +self+.
3317  */
3318 
3319 static VALUE
3320 rb_hash_to_hash(VALUE hash)
3321 {
3322  return hash;
3323 }
3324 
3325 VALUE
3327 {
3328  VALUE pair;
3329 
3330  pair = rb_check_array_type(arg);
3331  if (NIL_P(pair)) {
3332  rb_raise(rb_eTypeError, "wrong element type %s (expected array)",
3334  }
3335  if (RARRAY_LEN(pair) != 2) {
3336  rb_raise(rb_eArgError, "element has wrong array length (expected 2, was %ld)",
3337  RARRAY_LEN(pair));
3338  }
3339  rb_hash_aset(hash, RARRAY_AREF(pair, 0), RARRAY_AREF(pair, 1));
3340  return hash;
3341 }
3342 
3343 static int
3344 to_h_i(VALUE key, VALUE value, VALUE hash)
3345 {
3346  rb_hash_set_pair(hash, rb_yield_values(2, key, value));
3347  return ST_CONTINUE;
3348 }
3349 
3350 static VALUE
3351 rb_hash_to_h_block(VALUE hash)
3352 {
3354  rb_hash_foreach(hash, to_h_i, h);
3355  return h;
3356 }
3357 
3358 /*
3359  * call-seq:
3360  * hsh.to_h -> hsh or new_hash
3361  * hsh.to_h {|key, value| block } -> new_hash
3362  *
3363  * Returns +self+. If called on a subclass of Hash, converts
3364  * the receiver to a Hash object.
3365  *
3366  * If a block is given, the results of the block on each pair of
3367  * the receiver will be used as pairs.
3368  */
3369 
3370 static VALUE
3371 rb_hash_to_h(VALUE hash)
3372 {
3373  if (rb_block_given_p()) {
3374  return rb_hash_to_h_block(hash);
3375  }
3376  if (rb_obj_class(hash) != rb_cHash) {
3377  const VALUE flags = RBASIC(hash)->flags;
3378  hash = hash_dup(hash, rb_cHash, flags & RHASH_PROC_DEFAULT);
3379  }
3380  return hash;
3381 }
3382 
3383 static int
3384 keys_i(VALUE key, VALUE value, VALUE ary)
3385 {
3386  rb_ary_push(ary, key);
3387  return ST_CONTINUE;
3388 }
3389 
3390 /*
3391  * call-seq:
3392  * hsh.keys -> array
3393  *
3394  * Returns a new array populated with the keys from this hash. See also
3395  * Hash#values.
3396  *
3397  * h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
3398  * h.keys #=> ["a", "b", "c", "d"]
3399  *
3400  */
3401 
3404 {
3405  st_index_t size = RHASH_SIZE(hash);
3407 
3408  if (size == 0) return keys;
3409 
3410  if (ST_DATA_COMPATIBLE_P(VALUE)) {
3412  if (RHASH_AR_TABLE_P(hash)) {
3413  size = ar_keys(hash, ptr, size);
3414  }
3415  else {
3416  st_table *table = RHASH_ST_TABLE(hash);
3417  size = st_keys(table, ptr, size);
3418  }
3419  });
3422  }
3423  else {
3424  rb_hash_foreach(hash, keys_i, keys);
3425  }
3426 
3427  return keys;
3428 }
3429 
3430 static int
3431 values_i(VALUE key, VALUE value, VALUE ary)
3432 {
3433  rb_ary_push(ary, value);
3434  return ST_CONTINUE;
3435 }
3436 
3437 /*
3438  * call-seq:
3439  * hsh.values -> array
3440  *
3441  * Returns a new array populated with the values from <i>hsh</i>. See
3442  * also Hash#keys.
3443  *
3444  * h = { "a" => 100, "b" => 200, "c" => 300 }
3445  * h.values #=> [100, 200, 300]
3446  *
3447  */
3448 
3449 VALUE
3451 {
3452  VALUE values;
3453  st_index_t size = RHASH_SIZE(hash);
3454 
3455  values = rb_ary_new_capa(size);
3456  if (size == 0) return values;
3457 
3458  if (ST_DATA_COMPATIBLE_P(VALUE)) {
3459  if (RHASH_AR_TABLE_P(hash)) {
3461  RARRAY_PTR_USE_TRANSIENT(values, ptr, {
3462  size = ar_values(hash, ptr, size);
3463  });
3464  }
3465  else if (RHASH_ST_TABLE_P(hash)) {
3466  st_table *table = RHASH_ST_TABLE(hash);
3468  RARRAY_PTR_USE_TRANSIENT(values, ptr, {
3469  size = st_values(table, ptr, size);
3470  });
3471  }
3472  rb_ary_set_len(values, size);
3473  }
3474  else {
3475  rb_hash_foreach(hash, values_i, values);
3476  }
3477 
3478  return values;
3479 }
3480 
3481 /*
3482  * call-seq:
3483  * hsh.has_key?(key) -> true or false
3484  * hsh.include?(key) -> true or false
3485  * hsh.key?(key) -> true or false
3486  * hsh.member?(key) -> true or false
3487  *
3488  * Returns <code>true</code> if the given key is present in <i>hsh</i>.
3489  *
3490  * h = { "a" => 100, "b" => 200 }
3491  * h.has_key?("a") #=> true
3492  * h.has_key?("z") #=> false
3493  *
3494  * Note that #include? and #member? do not test member
3495  * equality using <code>==</code> as do other Enumerables.
3496  *
3497  * See also Enumerable#include?
3498  */
3499 
3502 {
3503  if (hash_stlike_lookup(hash, key, NULL)) {
3504  return Qtrue;
3505  }
3506  else {
3507  return Qfalse;
3508  }
3509 }
3510 
3511 static int
3512 rb_hash_search_value(VALUE key, VALUE value, VALUE arg)
3513 {
3514  VALUE *data = (VALUE *)arg;
3515 
3516  if (rb_equal(value, data[1])) {
3517  data[0] = Qtrue;
3518  return ST_STOP;
3519  }
3520  return ST_CONTINUE;
3521 }
3522 
3523 /*
3524  * call-seq:
3525  * hsh.has_value?(value) -> true or false
3526  * hsh.value?(value) -> true or false
3527  *
3528  * Returns <code>true</code> if the given value is present for some key
3529  * in <i>hsh</i>.
3530  *
3531  * h = { "a" => 100, "b" => 200 }
3532  * h.value?(100) #=> true
3533  * h.value?(999) #=> false
3534  */
3535 
3536 static VALUE
3537 rb_hash_has_value(VALUE hash, VALUE val)
3538 {
3539  VALUE data[2];
3540 
3541  data[0] = Qfalse;
3542  data[1] = val;
3543  rb_hash_foreach(hash, rb_hash_search_value, (VALUE)data);
3544  return data[0];
3545 }
3546 
3547 struct equal_data {
3550  int eql;
3551 };
3552 
3553 static int
3554 eql_i(VALUE key, VALUE val1, VALUE arg)
3555 {
3556  struct equal_data *data = (struct equal_data *)arg;
3557  st_data_t val2;
3558 
3559  if (!hash_stlike_lookup(data->hash, key, &val2)) {
3560  data->result = Qfalse;
3561  return ST_STOP;
3562  }
3563  else {
3564  if (!(data->eql ? rb_eql(val1, (VALUE)val2) : (int)rb_equal(val1, (VALUE)val2))) {
3565  data->result = Qfalse;
3566  return ST_STOP;
3567  }
3568  return ST_CONTINUE;
3569  }
3570 }
3571 
3572 static VALUE
3573 recursive_eql(VALUE hash, VALUE dt, int recur)
3574 {
3575  struct equal_data *data;
3576 
3577  if (recur) return Qtrue; /* Subtle! */
3578  data = (struct equal_data*)dt;
3579  data->result = Qtrue;
3580  rb_hash_foreach(hash, eql_i, dt);
3581 
3582  return data->result;
3583 }
3584 
3585 static VALUE
3586 hash_equal(VALUE hash1, VALUE hash2, int eql)
3587 {
3588  struct equal_data data;
3589 
3590  if (hash1 == hash2) return Qtrue;
3591  if (!RB_TYPE_P(hash2, T_HASH)) {
3592  if (!rb_respond_to(hash2, idTo_hash)) {
3593  return Qfalse;
3594  }
3595  if (eql) {
3596  if (rb_eql(hash2, hash1)) {
3597  return Qtrue;
3598  }
3599  else {
3600  return Qfalse;
3601  }
3602  }
3603  else {
3604  return rb_equal(hash2, hash1);
3605  }
3606  }
3607  if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2))
3608  return Qfalse;
3609  if (!RHASH_TABLE_EMPTY_P(hash1) && !RHASH_TABLE_EMPTY_P(hash2)) {
3610  if (RHASH_TYPE(hash1) != RHASH_TYPE(hash2)) {
3611  return Qfalse;
3612  }
3613  else {
3614  data.hash = hash2;
3615  data.eql = eql;
3616  return rb_exec_recursive_paired(recursive_eql, hash1, hash2, (VALUE)&data);
3617  }
3618  }
3619 
3620 #if 0
3621  if (!(rb_equal(RHASH_IFNONE(hash1), RHASH_IFNONE(hash2)) &&
3623  return Qfalse;
3624 #endif
3625  return Qtrue;
3626 }
3627 
3628 /*
3629  * call-seq:
3630  * hsh == other_hash -> true or false
3631  *
3632  * Equality---Two hashes are equal if they each contain the same number
3633  * of keys and if each key-value pair is equal to (according to
3634  * Object#==) the corresponding elements in the other hash.
3635  *
3636  * h1 = { "a" => 1, "c" => 2 }
3637  * h2 = { 7 => 35, "c" => 2, "a" => 1 }
3638  * h3 = { "a" => 1, "c" => 2, 7 => 35 }
3639  * h4 = { "a" => 1, "d" => 2, "f" => 35 }
3640  * h1 == h2 #=> false
3641  * h2 == h3 #=> true
3642  * h3 == h4 #=> false
3643  *
3644  * The orders of each hashes are not compared.
3645  *
3646  * h1 = { "a" => 1, "c" => 2 }
3647  * h2 = { "c" => 2, "a" => 1 }
3648  * h1 == h2 #=> true
3649  *
3650  */
3651 
3652 static VALUE
3653 rb_hash_equal(VALUE hash1, VALUE hash2)
3654 {
3655  return hash_equal(hash1, hash2, FALSE);
3656 }
3657 
3658 /*
3659  * call-seq:
3660  * hash.eql?(other) -> true or false
3661  *
3662  * Returns <code>true</code> if <i>hash</i> and <i>other</i> are
3663  * both hashes with the same content.
3664  * The orders of each hashes are not compared.
3665  */
3666 
3667 static VALUE
3668 rb_hash_eql(VALUE hash1, VALUE hash2)
3669 {
3670  return hash_equal(hash1, hash2, TRUE);
3671 }
3672 
3673 static int
3674 hash_i(VALUE key, VALUE val, VALUE arg)
3675 {
3676  st_index_t *hval = (st_index_t *)arg;
3677  st_index_t hdata[2];
3678 
3679  hdata[0] = rb_hash(key);
3680  hdata[1] = rb_hash(val);
3681  *hval ^= st_hash(hdata, sizeof(hdata), 0);
3682  return ST_CONTINUE;
3683 }
3684 
3685 /*
3686  * call-seq:
3687  * hsh.hash -> integer
3688  *
3689  * Compute a hash-code for this hash. Two hashes with the same content
3690  * will have the same hash code (and will compare using <code>eql?</code>).
3691  *
3692  * See also Object#hash.
3693  */
3694 
3695 static VALUE
3696 rb_hash_hash(VALUE hash)
3697 {
3699  st_index_t hval = rb_hash_start(size);
3700  hval = rb_hash_uint(hval, (st_index_t)rb_hash_hash);
3701  if (size) {
3702  rb_hash_foreach(hash, hash_i, (VALUE)&hval);
3703  }
3704  hval = rb_hash_end(hval);
3705  return ST2FIX(hval);
3706 }
3707 
3708 static int
3709 rb_hash_invert_i(VALUE key, VALUE value, VALUE hash)
3710 {
3711  rb_hash_aset(hash, value, key);
3712  return ST_CONTINUE;
3713 }
3714 
3715 /*
3716  * call-seq:
3717  * hsh.invert -> new_hash
3718  *
3719  * Returns a new hash created by using <i>hsh</i>'s values as keys, and
3720  * the keys as values.
3721  * If a key with the same value already exists in the <i>hsh</i>, then
3722  * the last one defined will be used, the earlier value(s) will be discarded.
3723  *
3724  * h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
3725  * h.invert #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}
3726  *
3727  * If there is no key with the same value, Hash#invert is involutive.
3728  *
3729  * h = { a: 1, b: 3, c: 4 }
3730  * h.invert.invert == h #=> true
3731  *
3732  * The condition, no key with the same value, can be tested by comparing
3733  * the size of inverted hash.
3734  *
3735  * # no key with the same value
3736  * h = { a: 1, b: 3, c: 4 }
3737  * h.size == h.invert.size #=> true
3738  *
3739  * # two (or more) keys has the same value
3740  * h = { a: 1, b: 3, c: 1 }
3741  * h.size == h.invert.size #=> false
3742  *
3743  */
3744 
3745 static VALUE
3746 rb_hash_invert(VALUE hash)
3747 {
3749 
3750  rb_hash_foreach(hash, rb_hash_invert_i, h);
3751  return h;
3752 }
3753 
3754 static int
3755 rb_hash_update_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
3756 {
3757  if (existing) {
3758  arg->old_value = *value;
3759  arg->new_value = arg->arg;
3760  }
3761  else {
3762  arg->new_key = *key;
3763  arg->new_value = arg->arg;
3764  }
3765  *value = arg->arg;
3766  return ST_CONTINUE;
3767 }
3768 
3769 NOINSERT_UPDATE_CALLBACK(rb_hash_update_callback)
3770 
3771 static int
3772 rb_hash_update_i(VALUE key, VALUE value, VALUE hash)
3773 {
3774  RHASH_UPDATE(hash, key, rb_hash_update_callback, value);
3775  return ST_CONTINUE;
3776 }
3777 
3778 static int
3779 rb_hash_update_block_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
3780 {
3781  VALUE newvalue = (VALUE)arg->arg;
3782 
3783  if (existing) {
3784  newvalue = rb_yield_values(3, (VALUE)*key, (VALUE)*value, newvalue);
3785  arg->old_value = *value;
3786  }
3787  else {
3788  arg->new_key = *key;
3789  }
3790  arg->new_value = newvalue;
3791  *value = newvalue;
3792  return ST_CONTINUE;
3793 }
3794 
3795 NOINSERT_UPDATE_CALLBACK(rb_hash_update_block_callback)
3796 
3797 static int
3798 rb_hash_update_block_i(VALUE key, VALUE value, VALUE hash)
3799 {
3800  RHASH_UPDATE(hash, key, rb_hash_update_block_callback, value);
3801  return ST_CONTINUE;
3802 }
3803 
3804 /*
3805  * call-seq:
3806  * hsh.merge!(other_hash1, other_hash2, ...) -> hsh
3807  * hsh.update(other_hash1, other_hash2, ...) -> hsh
3808  * hsh.merge!(other_hash1, other_hash2, ...) {|key, oldval, newval| block}
3809  * -> hsh
3810  * hsh.update(other_hash1, other_hash2, ...) {|key, oldval, newval| block}
3811  * -> hsh
3812  *
3813  * Adds the contents of the given hashes to the receiver.
3814  *
3815  * If no block is given, entries with duplicate keys are overwritten
3816  * with the values from each +other_hash+ successively,
3817  * otherwise the value for each duplicate key is determined by
3818  * calling the block with the key, its value in the receiver and
3819  * its value in each +other_hash+.
3820  *
3821  * h1 = { "a" => 100, "b" => 200 }
3822  * h1.merge! #=> {"a"=>100, "b"=>200}
3823  * h1 #=> {"a"=>100, "b"=>200}
3824  *
3825  * h1 = { "a" => 100, "b" => 200 }
3826  * h2 = { "b" => 246, "c" => 300 }
3827  * h1.merge!(h2) #=> {"a"=>100, "b"=>246, "c"=>300}
3828  * h1 #=> {"a"=>100, "b"=>246, "c"=>300}
3829  *
3830  * h1 = { "a" => 100, "b" => 200 }
3831  * h2 = { "b" => 246, "c" => 300 }
3832  * h3 = { "b" => 357, "d" => 400 }
3833  * h1.merge!(h2, h3)
3834  * #=> {"a"=>100, "b"=>357, "c"=>300, "d"=>400}
3835  * h1 #=> {"a"=>100, "b"=>357, "c"=>300, "d"=>400}
3836  *
3837  * h1 = { "a" => 100, "b" => 200 }
3838  * h2 = { "b" => 246, "c" => 300 }
3839  * h3 = { "b" => 357, "d" => 400 }
3840  * h1.merge!(h2, h3) {|key, v1, v2| v1 }
3841  * #=> {"a"=>100, "b"=>200, "c"=>300, "d"=>400}
3842  * h1 #=> {"a"=>100, "b"=>200, "c"=>300, "d"=>400}
3843  *
3844  * Hash#update is an alias for Hash#merge!.
3845  */
3846 
3847 static VALUE
3848 rb_hash_update(int argc, VALUE *argv, VALUE self)
3849 {
3850  int i;
3851  bool block_given = rb_block_given_p();
3852 
3853  rb_hash_modify(self);
3854  for (i = 0; i < argc; i++){
3855  VALUE hash = to_hash(argv[i]);
3856  if (block_given) {
3857  rb_hash_foreach(hash, rb_hash_update_block_i, self);
3858  }
3859  else {
3860  rb_hash_foreach(hash, rb_hash_update_i, self);
3861  }
3862  }
3863  return self;
3864 }
3865 
3870 };
3871 
3872 static int
3873 rb_hash_update_func_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
3874 {
3875  struct update_func_arg *uf_arg = (struct update_func_arg *)arg->arg;
3876  VALUE newvalue = uf_arg->value;
3877 
3878  if (existing) {
3879  newvalue = (*uf_arg->func)((VALUE)*key, (VALUE)*value, newvalue);
3880  arg->old_value = *value;
3881  }
3882  else {
3883  arg->new_key = *key;
3884  }
3885  arg->new_value = newvalue;
3886  *value = newvalue;
3887  return ST_CONTINUE;
3888 }
3889 
3890 NOINSERT_UPDATE_CALLBACK(rb_hash_update_func_callback)
3891 
3892 static int
3893 rb_hash_update_func_i(VALUE key, VALUE value, VALUE arg0)
3894 {
3895  struct update_func_arg *arg = (struct update_func_arg *)arg0;
3896  VALUE hash = arg->hash;
3897 
3898  arg->value = value;
3899  RHASH_UPDATE(hash, key, rb_hash_update_func_callback, (VALUE)arg);
3900  return ST_CONTINUE;
3901 }
3902 
3903 VALUE
3905 {
3906  rb_hash_modify(hash1);
3907  hash2 = to_hash(hash2);
3908  if (func) {
3909  struct update_func_arg arg;
3910  arg.hash = hash1;
3911  arg.func = func;
3912  rb_hash_foreach(hash2, rb_hash_update_func_i, (VALUE)&arg);
3913  }
3914  else {
3915  rb_hash_foreach(hash2, rb_hash_update_i, hash1);
3916  }
3917  return hash1;
3918 }
3919 
3920 /*
3921  * call-seq:
3922  * hsh.merge(other_hash1, other_hash2, ...) -> new_hash
3923  * hsh.merge(other_hash1, other_hash2, ...) {|key, oldval, newval| block}
3924  * -> new_hash
3925  *
3926  * Returns a new hash that combines the contents of the receiver and
3927  * the contents of the given hashes.
3928  *
3929  * If no block is given, entries with duplicate keys are overwritten
3930  * with the values from each +other_hash+ successively,
3931  * otherwise the value for each duplicate key is determined by
3932  * calling the block with the key, its value in the receiver and
3933  * its value in each +other_hash+.
3934  *
3935  * When called without any argument, returns a copy of the receiver.
3936  *
3937  * h1 = { "a" => 100, "b" => 200 }
3938  * h2 = { "b" => 246, "c" => 300 }
3939  * h3 = { "b" => 357, "d" => 400 }
3940  * h1.merge #=> {"a"=>100, "b"=>200}
3941  * h1.merge(h2) #=> {"a"=>100, "b"=>246, "c"=>300}
3942  * h1.merge(h2, h3) #=> {"a"=>100, "b"=>357, "c"=>300, "d"=>400}
3943  * h1.merge(h2) {|key, oldval, newval| newval - oldval}
3944  * #=> {"a"=>100, "b"=>46, "c"=>300}
3945  * h1.merge(h2, h3) {|key, oldval, newval| newval - oldval}
3946  * #=> {"a"=>100, "b"=>311, "c"=>300, "d"=>400}
3947  * h1 #=> {"a"=>100, "b"=>200}
3948  *
3949  */
3950 
3951 static VALUE
3952 rb_hash_merge(int argc, VALUE *argv, VALUE self)
3953 {
3954  return rb_hash_update(argc, argv, rb_hash_dup(self));
3955 }
3956 
3957 static int
3958 assoc_cmp(VALUE a, VALUE b)
3959 {
3960  return !RTEST(rb_equal(a, b));
3961 }
3962 
3963 static VALUE
3964 lookup2_call(VALUE arg)
3965 {
3966  VALUE *args = (VALUE *)arg;
3967  return rb_hash_lookup2(args[0], args[1], Qundef);
3968 }
3969 
3972  const struct st_hash_type *orighash;
3973 };
3974 
3975 static VALUE
3976 reset_hash_type(VALUE arg)
3977 {
3978  struct reset_hash_type_arg *p = (struct reset_hash_type_arg *)arg;
3980  RHASH_ST_TABLE(p->hash)->type = p->orighash;
3981  return Qundef;
3982 }
3983 
3984 static int
3985 assoc_i(VALUE key, VALUE val, VALUE arg)
3986 {
3987  VALUE *args = (VALUE *)arg;
3988 
3989  if (RTEST(rb_equal(args[0], key))) {
3990  args[1] = rb_assoc_new(key, val);
3991  return ST_STOP;
3992  }
3993  return ST_CONTINUE;
3994 }
3995 
3996 /*
3997  * call-seq:
3998  * hash.assoc(obj) -> an_array or nil
3999  *
4000  * Searches through the hash comparing _obj_ with the key using <code>==</code>.
4001  * Returns the key-value pair (two elements array) or +nil+
4002  * if no match is found. See Array#assoc.
4003  *
4004  * h = {"colors" => ["red", "blue", "green"],
4005  * "letters" => ["a", "b", "c" ]}
4006  * h.assoc("letters") #=> ["letters", ["a", "b", "c"]]
4007  * h.assoc("foo") #=> nil
4008  */
4009 
4010 VALUE
4012 {
4013  st_table *table;
4014  const struct st_hash_type *orighash;
4015  VALUE args[2];
4016 
4017  if (RHASH_EMPTY_P(hash)) return Qnil;
4018 
4019  ar_force_convert_table(hash, __FILE__, __LINE__);
4021  table = RHASH_ST_TABLE(hash);
4022  orighash = table->type;
4023 
4024  if (orighash != &identhash) {
4025  VALUE value;
4026  struct reset_hash_type_arg ensure_arg;
4027  struct st_hash_type assochash;
4028 
4029  assochash.compare = assoc_cmp;
4030  assochash.hash = orighash->hash;
4031  table->type = &assochash;
4032  args[0] = hash;
4033  args[1] = key;
4034  ensure_arg.hash = hash;
4035  ensure_arg.orighash = orighash;
4036  value = rb_ensure(lookup2_call, (VALUE)&args, reset_hash_type, (VALUE)&ensure_arg);
4037  if (value != Qundef) return rb_assoc_new(key, value);
4038  }
4039 
4040  args[0] = key;
4041  args[1] = Qnil;
4042  rb_hash_foreach(hash, assoc_i, (VALUE)args);
4043  return args[1];
4044 }
4045 
4046 static int
4047 rassoc_i(VALUE key, VALUE val, VALUE arg)
4048 {
4049  VALUE *args = (VALUE *)arg;
4050 
4051  if (RTEST(rb_equal(args[0], val))) {
4052  args[1] = rb_assoc_new(key, val);
4053  return ST_STOP;
4054  }
4055  return ST_CONTINUE;
4056 }
4057 
4058 /*
4059  * call-seq:
4060  * hash.rassoc(obj) -> an_array or nil
4061  *
4062  * Searches through the hash comparing _obj_ with the value using <code>==</code>.
4063  * Returns the first key-value pair (two-element array) that matches. See
4064  * also Array#rassoc.
4065  *
4066  * a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
4067  * a.rassoc("two") #=> [2, "two"]
4068  * a.rassoc("four") #=> nil
4069  */
4070 
4071 VALUE
4073 {
4074  VALUE args[2];
4075 
4076  args[0] = obj;
4077  args[1] = Qnil;
4078  rb_hash_foreach(hash, rassoc_i, (VALUE)args);
4079  return args[1];
4080 }
4081 
4082 static int
4083 flatten_i(VALUE key, VALUE val, VALUE ary)
4084 {
4085  VALUE pair[2];
4086 
4087  pair[0] = key;
4088  pair[1] = val;
4089  rb_ary_cat(ary, pair, 2);
4090 
4091  return ST_CONTINUE;
4092 }
4093 
4094 /*
4095  * call-seq:
4096  * hash.flatten -> an_array
4097  * hash.flatten(level) -> an_array
4098  *
4099  * Returns a new array that is a one-dimensional flattening of this
4100  * hash. That is, for every key or value that is an array, extract
4101  * its elements into the new array. Unlike Array#flatten, this
4102  * method does not flatten recursively by default. The optional
4103  * <i>level</i> argument determines the level of recursion to flatten.
4104  *
4105  * a = {1=> "one", 2 => [2,"two"], 3 => "three"}
4106  * a.flatten # => [1, "one", 2, [2, "two"], 3, "three"]
4107  * a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]
4108  */
4109 
4110 static VALUE
4111 rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
4112 {
4113  VALUE ary;
4114 
4115  rb_check_arity(argc, 0, 1);
4116 
4117  if (argc) {
4118  int level = NUM2INT(argv[0]);
4119 
4120  if (level == 0) return rb_hash_to_a(hash);
4121 
4122  ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2);
4123  rb_hash_foreach(hash, flatten_i, ary);
4124  level--;
4125 
4126  if (level > 0) {
4127  VALUE ary_flatten_level = INT2FIX(level);
4128  rb_funcallv(ary, id_flatten_bang, 1, &ary_flatten_level);
4129  }
4130  else if (level < 0) {
4131  /* flatten recursively */
4132  rb_funcallv(ary, id_flatten_bang, 0, 0);
4133  }
4134  }
4135  else {
4136  ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2);
4137  rb_hash_foreach(hash, flatten_i, ary);
4138  }
4139 
4140  return ary;
4141 }
4142 
4143 static int
4144 delete_if_nil(VALUE key, VALUE value, VALUE hash)
4145 {
4146  if (NIL_P(value)) {
4147  return ST_DELETE;
4148  }
4149  return ST_CONTINUE;
4150 }
4151 
4152 static int
4153 set_if_not_nil(VALUE key, VALUE value, VALUE hash)
4154 {
4155  if (!NIL_P(value)) {
4156  rb_hash_aset(hash, key, value);
4157  }
4158  return ST_CONTINUE;
4159 }
4160 
4161 /*
4162  * call-seq:
4163  * hsh.compact -> new_hash
4164  *
4165  * Returns a new hash with the nil values/key pairs removed
4166  *
4167  * h = { a: 1, b: false, c: nil }
4168  * h.compact #=> { a: 1, b: false }
4169  * h #=> { a: 1, b: false, c: nil }
4170  *
4171  */
4172 
4173 static VALUE
4174 rb_hash_compact(VALUE hash)
4175 {
4176  VALUE result = rb_hash_new();
4177  if (!RHASH_EMPTY_P(hash)) {
4178  rb_hash_foreach(hash, set_if_not_nil, result);
4179  }
4180  return result;
4181 }
4182 
4183 /*
4184  * call-seq:
4185  * hsh.compact! -> hsh or nil
4186  *
4187  * Removes all nil values from the hash.
4188  * Returns nil if no changes were made, otherwise returns the hash.
4189  *
4190  * h = { a: 1, b: false, c: nil }
4191  * h.compact! #=> { a: 1, b: false }
4192  *
4193  */
4194 
4195 static VALUE
4196 rb_hash_compact_bang(VALUE hash)
4197 {
4198  st_index_t n;
4199  rb_hash_modify_check(hash);
4200  n = RHASH_SIZE(hash);
4201  if (n) {
4202  rb_hash_foreach(hash, delete_if_nil, hash);
4203  if (n != RHASH_SIZE(hash))
4204  return hash;
4205  }
4206  return Qnil;
4207 }
4208 
4209 static st_table *rb_init_identtable_with_size(st_index_t size);
4210 
4211 /*
4212  * call-seq:
4213  * hsh.compare_by_identity -> hsh
4214  *
4215  * Makes <i>hsh</i> compare its keys by their identity, i.e. it
4216  * will consider exact same objects as same keys.
4217  *
4218  * h1 = { "a" => 100, "b" => 200, :c => "c" }
4219  * h1["a"] #=> 100
4220  * h1.compare_by_identity
4221  * h1.compare_by_identity? #=> true
4222  * h1["a".dup] #=> nil # different objects.
4223  * h1[:c] #=> "c" # same symbols are all same.
4224  *
4225  */
4226 
4227 static VALUE
4228 rb_hash_compare_by_id(VALUE hash)
4229 {
4230  VALUE tmp;
4231  st_table *identtable;
4232 
4233  if (rb_hash_compare_by_id_p(hash)) return hash;
4234 
4235  rb_hash_modify_check(hash);
4236  ar_force_convert_table(hash, __FILE__, __LINE__);
4238 
4239  tmp = hash_alloc(0);
4240  identtable = rb_init_identtable_with_size(RHASH_SIZE(hash));
4241  RHASH_ST_TABLE_SET(tmp, identtable);
4242  rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
4244  RHASH_ST_TABLE_SET(hash, identtable);
4245  RHASH_ST_CLEAR(tmp);
4246  rb_gc_force_recycle(tmp);
4247 
4248  return hash;
4249 }
4250 
4251 /*
4252  * call-seq:
4253  * hsh.compare_by_identity? -> true or false
4254  *
4255  * Returns <code>true</code> if <i>hsh</i> will compare its keys by
4256  * their identity. Also see Hash#compare_by_identity.
4257  *
4258  */
4259 
4262 {
4264  return Qtrue;
4265  }
4266  else {
4267  return Qfalse;
4268  }
4269 }
4270 
4271 VALUE
4273 {
4274  VALUE hash = rb_hash_new();
4276  return hash;
4277 }
4278 
4279 st_table *
4281 {
4282  return st_init_table(&identhash);
4283 }
4284 
4285 static st_table *
4286 rb_init_identtable_with_size(st_index_t size)
4287 {
4289 }
4290 
4291 static int
4292 any_p_i(VALUE key, VALUE value, VALUE arg)
4293 {
4294  VALUE ret = rb_yield(rb_assoc_new(key, value));
4295  if (RTEST(ret)) {
4296  *(VALUE *)arg = Qtrue;
4297  return ST_STOP;
4298  }
4299  return ST_CONTINUE;
4300 }
4301 
4302 static int
4303 any_p_i_fast(VALUE key, VALUE value, VALUE arg)
4304 {
4305  VALUE ret = rb_yield_values(2, key, value);
4306  if (RTEST(ret)) {
4307  *(VALUE *)arg = Qtrue;
4308  return ST_STOP;
4309  }
4310  return ST_CONTINUE;
4311 }
4312 
4313 static int
4314 any_p_i_pattern(VALUE key, VALUE value, VALUE arg)
4315 {
4316  VALUE ret = rb_funcall(((VALUE *)arg)[1], idEqq, 1, rb_assoc_new(key, value));
4317  if (RTEST(ret)) {
4318  *(VALUE *)arg = Qtrue;
4319  return ST_STOP;
4320  }
4321  return ST_CONTINUE;
4322 }
4323 
4324 /*
4325  * call-seq:
4326  * hsh.any? [{ |(key, value)| block }] -> true or false
4327  * hsh.any?(pattern) -> true or false
4328  *
4329  * See also Enumerable#any?
4330  */
4331 
4332 static VALUE
4333 rb_hash_any_p(int argc, VALUE *argv, VALUE hash)
4334 {
4335  VALUE args[2];
4336  args[0] = Qfalse;
4337 
4338  rb_check_arity(argc, 0, 1);
4339  if (RHASH_EMPTY_P(hash)) return Qfalse;
4340  if (argc) {
4341  if (rb_block_given_p()) {
4342  rb_warn("given block not used");
4343  }
4344  args[1] = argv[0];
4345 
4346  rb_hash_foreach(hash, any_p_i_pattern, (VALUE)args);
4347  }
4348  else {
4349  if (!rb_block_given_p()) {
4350  /* yields pairs, never false */
4351  return Qtrue;
4352  }
4353  if (rb_block_arity() > 1)
4354  rb_hash_foreach(hash, any_p_i_fast, (VALUE)args);
4355  else
4356  rb_hash_foreach(hash, any_p_i, (VALUE)args);
4357  }
4358  return args[0];
4359 }
4360 
4361 /*
4362  * call-seq:
4363  * hsh.dig(key, ...) -> object
4364  *
4365  * Extracts the nested value specified by the sequence of <i>key</i>
4366  * objects by calling +dig+ at each step, returning +nil+ if any
4367  * intermediate step is +nil+.
4368  *
4369  * h = { foo: {bar: {baz: 1}}}
4370  *
4371  * h.dig(:foo, :bar, :baz) #=> 1
4372  * h.dig(:foo, :zot, :xyz) #=> nil
4373  *
4374  * g = { foo: [10, 11, 12] }
4375  * g.dig(:foo, 1) #=> 11
4376  * g.dig(:foo, 1, 0) #=> TypeError: Integer does not have #dig method
4377  * g.dig(:foo, :bar) #=> TypeError: no implicit conversion of Symbol into Integer
4378  */
4379 
4380 static VALUE
4381 rb_hash_dig(int argc, VALUE *argv, VALUE self)
4382 {
4384  self = rb_hash_aref(self, *argv);
4385  if (!--argc) return self;
4386  ++argv;
4387  return rb_obj_dig(argc, argv, self, Qnil);
4388 }
4389 
4390 static int
4391 hash_le_i(VALUE key, VALUE value, VALUE arg)
4392 {
4393  VALUE *args = (VALUE *)arg;
4394  VALUE v = rb_hash_lookup2(args[0], key, Qundef);
4395  if (v != Qundef && rb_equal(value, v)) return ST_CONTINUE;
4396  args[1] = Qfalse;
4397  return ST_STOP;
4398 }
4399 
4400 static VALUE
4401 hash_le(VALUE hash1, VALUE hash2)
4402 {
4403  VALUE args[2];
4404  args[0] = hash2;
4405  args[1] = Qtrue;
4406  rb_hash_foreach(hash1, hash_le_i, (VALUE)args);
4407  return args[1];
4408 }
4409 
4410 /*
4411  * call-seq:
4412  * hash <= other -> true or false
4413  *
4414  * Returns <code>true</code> if <i>hash</i> is subset of
4415  * <i>other</i> or equals to <i>other</i>.
4416  *
4417  * h1 = {a:1, b:2}
4418  * h2 = {a:1, b:2, c:3}
4419  * h1 <= h2 #=> true
4420  * h2 <= h1 #=> false
4421  * h1 <= h1 #=> true
4422  */
4423 static VALUE
4424 rb_hash_le(VALUE hash, VALUE other)
4425 {
4426  other = to_hash(other);
4427  if (RHASH_SIZE(hash) > RHASH_SIZE(other)) return Qfalse;
4428  return hash_le(hash, other);
4429 }
4430 
4431 /*
4432  * call-seq:
4433  * hash < other -> true or false
4434  *
4435  * Returns <code>true</code> if <i>hash</i> is subset of
4436  * <i>other</i>.
4437  *
4438  * h1 = {a:1, b:2}
4439  * h2 = {a:1, b:2, c:3}
4440  * h1 < h2 #=> true
4441  * h2 < h1 #=> false
4442  * h1 < h1 #=> false
4443  */
4444 static VALUE
4445 rb_hash_lt(VALUE hash, VALUE other)
4446 {
4447  other = to_hash(other);
4448  if (RHASH_SIZE(hash) >= RHASH_SIZE(other)) return Qfalse;
4449  return hash_le(hash, other);
4450 }
4451 
4452 /*
4453  * call-seq:
4454  * hash >= other -> true or false
4455  *
4456  * Returns <code>true</code> if <i>other</i> is subset of
4457  * <i>hash</i> or equals to <i>hash</i>.
4458  *
4459  * h1 = {a:1, b:2}
4460  * h2 = {a:1, b:2, c:3}
4461  * h1 >= h2 #=> false
4462  * h2 >= h1 #=> true
4463  * h1 >= h1 #=> true
4464  */
4465 static VALUE
4466 rb_hash_ge(VALUE hash, VALUE other)
4467 {
4468  other = to_hash(other);
4469  if (RHASH_SIZE(hash) < RHASH_SIZE(other)) return Qfalse;
4470  return hash_le(other, hash);
4471 }
4472 
4473 /*
4474  * call-seq:
4475  * hash > other -> true or false
4476  *
4477  * Returns <code>true</code> if <i>other</i> is subset of
4478  * <i>hash</i>.
4479  *
4480  * h1 = {a:1, b:2}
4481  * h2 = {a:1, b:2, c:3}
4482  * h1 > h2 #=> false
4483  * h2 > h1 #=> true
4484  * h1 > h1 #=> false
4485  */
4486 static VALUE
4487 rb_hash_gt(VALUE hash, VALUE other)
4488 {
4489  other = to_hash(other);
4490  if (RHASH_SIZE(hash) <= RHASH_SIZE(other)) return Qfalse;
4491  return hash_le(other, hash);
4492 }
4493 
4494 static VALUE
4495 hash_proc_call(RB_BLOCK_CALL_FUNC_ARGLIST(key, hash))
4496 {
4497  rb_check_arity(argc, 1, 1);
4498  return rb_hash_aref(hash, *argv);
4499 }
4500 
4501 /*
4502  * call-seq:
4503  * hash.to_proc -> proc
4504  *
4505  * Returns a Proc which maps keys to values.
4506  *
4507  * h = {a:1, b:2}
4508  * hp = h.to_proc
4509  * hp.call(:a) #=> 1
4510  * hp.call(:b) #=> 2
4511  * hp.call(:c) #=> nil
4512  * [:a, :b, :c].map(&h) #=> [1, 2, nil]
4513  */
4514 static VALUE
4515 rb_hash_to_proc(VALUE hash)
4516 {
4517  return rb_func_proc_new(hash_proc_call, hash);
4518 }
4519 
4520 static VALUE
4521 rb_hash_deconstruct_keys(VALUE hash, VALUE keys)
4522 {
4523  return hash;
4524 }
4525 
4526 static int
4527 add_new_i(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
4528 {
4529  VALUE *args = (VALUE *)arg;
4530  if (existing) return ST_STOP;
4531  RB_OBJ_WRITTEN(args[0], Qundef, (VALUE)*key);
4532  RB_OBJ_WRITE(args[0], (VALUE *)val, args[1]);
4533  return ST_CONTINUE;
4534 }
4535 
4536 /*
4537  * add +key+ to +val+ pair if +hash+ does not contain +key+.
4538  * returns non-zero if +key+ was contained.
4539  */
4540 int
4542 {
4543  st_table *tbl;
4544  int ret = 0;
4545  VALUE args[2];
4546  args[0] = hash;
4547  args[1] = val;
4548 
4549  if (RHASH_AR_TABLE_P(hash)) {
4550  hash_ar_table(hash);
4551 
4552  ret = ar_update(hash, (st_data_t)key, add_new_i, (st_data_t)args);
4553  if (ret != -1) {
4554  return ret;
4555  }
4556  ar_try_convert_table(hash);
4557  }
4558  tbl = RHASH_TBL_RAW(hash);
4559  return st_update(tbl, (st_data_t)key, add_new_i, (st_data_t)args);
4560 
4561 }
4562 
4563 static st_data_t
4564 key_stringify(VALUE key)
4565 {
4566  return (rb_obj_class(key) == rb_cString && !RB_OBJ_FROZEN(key)) ?
4567  rb_hash_key_str(key) : key;
4568 }
4569 
4570 static void
4571 ar_bulk_insert(VALUE hash, long argc, const VALUE *argv)
4572 {
4573  long i;
4574  for (i = 0; i < argc; ) {
4575  st_data_t k = key_stringify(argv[i++]);
4576  st_data_t v = argv[i++];
4577  ar_insert(hash, k, v);
4578  RB_OBJ_WRITTEN(hash, Qundef, k);
4580  }
4581 }
4582 
4583 void
4585 {
4586  HASH_ASSERT(argc % 2 == 0);
4587  if (argc > 0) {
4588  st_index_t size = argc / 2;
4589 
4590  if (RHASH_TABLE_NULL_P(hash)) {
4591  if (size <= RHASH_AR_TABLE_MAX_SIZE) {
4592  hash_ar_table(hash);
4593  }
4594  else {
4596  }
4597  }
4598 
4599  if (RHASH_AR_TABLE_P(hash) &&
4601  ar_bulk_insert(hash, argc, argv);
4602  }
4603  else {
4605  }
4606  }
4607 }
4608 
4609 static char **origenviron;
4610 #ifdef _WIN32
4611 #define GET_ENVIRON(e) ((e) = rb_w32_get_environ())
4612 #define FREE_ENVIRON(e) rb_w32_free_environ(e)
4613 static char **my_environ;
4614 #undef environ
4615 #define environ my_environ
4616 #undef getenv
4617 static char *(*w32_getenv)(const char*);
4618 static char *
4619 w32_getenv_unknown(const char *name)
4620 {
4621  char *(*func)(const char*);
4623  func = rb_w32_getenv;
4624  }
4625  else {
4626  func = rb_w32_ugetenv;
4627  }
4628  /* atomic assignment in flat memory model */
4629  return (w32_getenv = func)(name);
4630 }
4631 static char *(*w32_getenv)(const char*) = w32_getenv_unknown;
4632 #define getenv(n) w32_getenv(n)
4633 #elif defined(__APPLE__)
4634 #undef environ
4635 #define environ (*_NSGetEnviron())
4636 #define GET_ENVIRON(e) (e)
4637 #define FREE_ENVIRON(e)
4638 #else
4639 extern char **environ;
4640 #define GET_ENVIRON(e) (e)
4641 #define FREE_ENVIRON(e)
4642 #endif
4643 #ifdef ENV_IGNORECASE
4644 #define ENVMATCH(s1, s2) (STRCASECMP((s1), (s2)) == 0)
4645 #define ENVNMATCH(s1, s2, n) (STRNCASECMP((s1), (s2), (n)) == 0)
4646 #else
4647 #define ENVMATCH(n1, n2) (strcmp((n1), (n2)) == 0)
4648 #define ENVNMATCH(s1, s2, n) (memcmp((s1), (s2), (n)) == 0)
4649 #endif
4650 
4651 static VALUE
4652 env_enc_str_new(const char *ptr, long len, rb_encoding *enc)
4653 {
4654 #ifdef _WIN32
4656  const int ecflags = ECONV_INVALID_REPLACE | ECONV_UNDEF_REPLACE;
4657  rb_encoding *utf8 = rb_utf8_encoding();
4658  VALUE str = rb_enc_str_new(NULL, 0, (internal ? internal : enc));
4659  if (NIL_P(rb_str_cat_conv_enc_opts(str, 0, ptr, len, utf8, ecflags, Qnil))) {
4661  }
4662 #else
4664 #endif
4665 
4666  rb_obj_freeze(str);
4667  return str;
4668 }
4669 
4670 static VALUE
4671 env_enc_str_new_cstr(const char *ptr, rb_encoding *enc)
4672 {
4673  return env_enc_str_new(ptr, strlen(ptr), enc);
4674 }
4675 
4676 static VALUE
4677 env_str_new(const char *ptr, long len)
4678 {
4679  return env_enc_str_new(ptr, len, rb_locale_encoding());
4680 }
4681 
4682 static VALUE
4683 env_str_new2(const char *ptr)
4684 {
4685  if (!ptr) return Qnil;
4686  return env_str_new(ptr, strlen(ptr));
4687 }
4688 
4689 static const char TZ_ENV[] = "TZ";
4690 extern bool ruby_tz_uptodate_p;
4691 
4692 static rb_encoding *
4693 env_encoding_for(const char *name, const char *ptr)
4694 {
4695  if (ENVMATCH(name, PATH_ENV)) {
4696  return rb_filesystem_encoding();
4697  }
4698  else {
4699  return rb_locale_encoding();
4700  }
4701 }
4702 
4703 static VALUE
4704 env_name_new(const char *name, const char *ptr)
4705 {
4706  return env_enc_str_new_cstr(ptr, env_encoding_for(name, ptr));
4707 }
4708 
4709 static void *
4710 get_env_cstr(
4711 #ifdef _WIN32
4712  volatile VALUE *pstr,
4713 #else
4714  VALUE str,
4715 #endif
4716  const char *name)
4717 {
4718 #ifdef _WIN32
4719  VALUE str = *pstr;
4720 #endif
4721  char *var;
4722  rb_encoding *enc = rb_enc_get(str);
4723  if (!rb_enc_asciicompat(enc)) {
4724  rb_raise(rb_eArgError, "bad environment variable %s: ASCII incompatible encoding: %s",
4725  name, rb_enc_name(enc));
4726  }
4727 #ifdef _WIN32
4728  if (!rb_enc_str_asciionly_p(str)) {
4729  *pstr = str = rb_str_conv_enc(str, NULL, rb_utf8_encoding());
4730  }
4731 #endif
4732  var = RSTRING_PTR(str);
4733  if (memchr(var, '\0', RSTRING_LEN(str))) {
4734  rb_raise(rb_eArgError, "bad environment variable %s: contains null byte", name);
4735  }
4736  return rb_str_fill_terminator(str, 1); /* ASCII compatible */
4737 }
4738 
4739 #ifdef _WIN32
4740 #define get_env_ptr(var, val) \
4741  (var = get_env_cstr(&(val), #var))
4742 #else
4743 #define get_env_ptr(var, val) \
4744  (var = get_env_cstr(val, #var))
4745 #endif
4746 
4747 static inline const char *
4748 env_name(volatile VALUE *s)
4749 {
4750  const char *name;
4751  SafeStringValue(*s);
4752  get_env_ptr(name, *s);
4753  return name;
4754 }
4755 
4756 #define env_name(s) env_name(&(s))
4757 
4758 static VALUE env_aset(VALUE nm, VALUE val);
4759 
4760 static VALUE
4761 env_delete(VALUE name)
4762 {
4763  const char *nam, *val;
4764 
4765  nam = env_name(name);
4766  val = getenv(nam);
4767 
4768  /*
4769  * ENV['TZ'] = nil has a special meaning.
4770  * TZ is no longer considered up-to-date and ruby call tzset() as needed.
4771  * It could be useful if sysadmin change /etc/localtime.
4772  * This hack might works only on Linux glibc.
4773  */
4774  if (ENVMATCH(nam, TZ_ENV)) {
4776  }
4777 
4778  if (val) {
4779  VALUE value = env_str_new2(val);
4780 
4781  ruby_setenv(nam, 0);
4782  if (ENVMATCH(nam, PATH_ENV)) {
4783  RB_GC_GUARD(name);
4784  }
4785  return value;
4786  }
4787  return Qnil;
4788 }
4789 
4790 /*
4791  * call-seq:
4792  * ENV.delete(name) -> value
4793  * ENV.delete(name) { |name| block } -> value
4794  *
4795  * Deletes the environment variable with +name+ if it exists and returns its value:
4796  * ENV['foo'] = '0'
4797  * ENV.delete('foo') # => '0'
4798  * Returns +nil+ if the named environment variable does not exist:
4799  * ENV.delete('foo') # => nil
4800  * If a block given and the environment variable does not exist,
4801  * yields +name+ to the block and returns +nil+:
4802  * ENV.delete('foo') { |name| puts name } # => nil
4803  * foo
4804  * If a block given and the environment variable exists,
4805  * deletes the environment variable and returns its value (ignoring the block):
4806  * ENV['foo'] = '0'
4807  * ENV.delete('foo') { |name| fail 'ignored' } # => "0"
4808  * Raises an exception if +name+ is invalid.
4809  * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
4810  */
4811 static VALUE
4812 env_delete_m(VALUE obj, VALUE name)
4813 {
4814  VALUE val;
4815 
4816  val = env_delete(name);
4817  if (NIL_P(val) && rb_block_given_p()) rb_yield(name);
4818  return val;
4819 }
4820 
4821 /*
4822  * call-seq:
4823  * ENV[name] -> value
4824  *
4825  * Returns the value for the environment variable +name+ if it exists:
4826  * ENV['foo'] = '0'
4827  * ENV['foo'] # => "0"
4828  * Returns nil if the named variable does not exist:
4829  * ENV.clear
4830  * ENV['foo'] # => nil
4831  * Raises an exception if +name+ is invalid.
4832  * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
4833  */
4834 static VALUE
4835 rb_f_getenv(VALUE obj, VALUE name)
4836 {
4837  const char *nam, *env;
4838 
4839  nam = env_name(name);
4840  env = getenv(nam);
4841  if (env) {
4842  return env_name_new(nam, env);
4843  }
4844  return Qnil;
4845 }
4846 
4847 /*
4848  * call-seq:
4849  * ENV.fetch(name) -> value
4850  * ENV.fetch(name, default) -> value
4851  * ENV.fetch(name) { |name| block } -> value
4852  *
4853  * If +name+ is the name of an environment variable, returns its value:
4854  * ENV['foo'] = '0'
4855  * ENV.fetch('foo') # => '0'
4856  * Otherwise if a block is given (but not a default value),
4857  * yields +name+ to the block and returns the block's return value:
4858  * ENV.fetch('foo') { |name| :need_not_return_a_string } # => :need_not_return_a_string
4859  * Otherwise if a default value is given (but not a block), returns the default value:
4860  * ENV.delete('foo')
4861  * ENV.fetch('foo', :default_need_not_be_a_string) # => :default_need_not_be_a_string
4862  * If the environment variable does not exist and both default and block are given,
4863  * issues a warning ("warning: block supersedes default value argument"),
4864  * yields +name+ to the block, and returns the block's return value:
4865  * ENV.fetch('foo', :default) { |name| :block_return } # => :block_return
4866  * Raises KeyError if +name+ is valid, but not found,
4867  * and neither default value nor block is given:
4868  * ENV.fetch('foo') # Raises KeyError (key not found: "foo")
4869  * Raises an exception if +name+ is invalid.
4870  * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
4871  */
4872 static VALUE
4873 env_fetch(int argc, VALUE *argv, VALUE _)
4874 {
4875  VALUE key;
4876  long block_given;
4877  const char *nam, *env;
4878 
4879  rb_check_arity(argc, 1, 2);
4880  key = argv[0];
4881  block_given = rb_block_given_p();
4882  if (block_given && argc == 2) {
4883  rb_warn("block supersedes default value argument");
4884  }
4885  nam = env_name(key);
4886  env = getenv(nam);
4887  if (!env) {
4888  if (block_given) return rb_yield(key);
4889  if (argc == 1) {
4890  rb_key_err_raise(rb_sprintf("key not found: \"%"PRIsVALUE"\"", key), envtbl, key);
4891  }
4892  return argv[1];
4893  }
4894  return env_name_new(nam, env);
4895 }
4896 
4897 int
4899 {
4900  rb_warning("rb_env_path_tainted is deprecated and will be removed in Ruby 3.2.");
4901  return 0;
4902 }
4903 
4904 #if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
4905 #elif defined __sun
4906 static int
4907 in_origenv(const char *str)
4908 {
4909  char **env;
4910  for (env = origenviron; *env; ++env) {
4911  if (*env == str) return 1;
4912  }
4913  return 0;
4914 }
4915 #else
4916 static int
4917 envix(const char *nam)
4918 {
4919  register int i, len = strlen(nam);
4920  char **env;
4921 
4922  env = GET_ENVIRON(environ);
4923  for (i = 0; env[i]; i++) {
4924  if (ENVNMATCH(env[i],nam,len) && env[i][len] == '=')
4925  break; /* memcmp must come first to avoid */
4926  } /* potential SEGV's */
4928  return i;
4929 }
4930 #endif
4931 
4932 #if defined(_WIN32)
4933 static size_t
4934 getenvsize(const WCHAR* p)
4935 {
4936  const WCHAR* porg = p;
4937  while (*p++) p += lstrlenW(p) + 1;
4938  return p - porg + 1;
4939 }
4940 
4941 static size_t
4942 getenvblocksize(void)
4943 {
4944 #ifdef _MAX_ENV
4945  return _MAX_ENV;
4946 #else
4947  return 32767;
4948 #endif
4949 }
4950 
4951 static int
4952 check_envsize(size_t n)
4953 {
4954  if (_WIN32_WINNT < 0x0600 && rb_w32_osver() < 6) {
4955  /* https://msdn.microsoft.com/en-us/library/windows/desktop/ms682653(v=vs.85).aspx */
4956  /* Windows Server 2003 and Windows XP: The maximum size of the
4957  * environment block for the process is 32,767 characters. */
4958  WCHAR* p = GetEnvironmentStringsW();
4959  if (!p) return -1; /* never happen */
4960  n += getenvsize(p);
4961  FreeEnvironmentStringsW(p);
4962  if (n >= getenvblocksize()) {
4963  return -1;
4964  }
4965  }
4966  return 0;
4967 }
4968 #endif
4969 
4970 #if defined(_WIN32) || \
4971  (defined(__sun) && !(defined(HAVE_SETENV) && defined(HAVE_UNSETENV)))
4972 
4973 NORETURN(static void invalid_envname(const char *name));
4974 
4975 static void
4976 invalid_envname(const char *name)
4977 {
4978  rb_syserr_fail_str(EINVAL, rb_sprintf("ruby_setenv(%s)", name));
4979 }
4980 
4981 static const char *
4982 check_envname(const char *name)
4983 {
4984  if (strchr(name, '=')) {
4985  invalid_envname(name);
4986  }
4987  return name;
4988 }
4989 #endif
4990 
4991 void
4992 ruby_setenv(const char *name, const char *value)
4993 {
4994 #if defined(_WIN32)
4995 # if defined(MINGW_HAS_SECURE_API) || RUBY_MSVCRT_VERSION >= 80
4996 # define HAVE__WPUTENV_S 1
4997 # endif
4998  VALUE buf;
4999  WCHAR *wname;
5000  WCHAR *wvalue = 0;
5001  int failed = 0;
5002  int len;
5003  check_envname(name);
5004  len = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
5005  if (value) {
5006  int len2;
5007  len2 = MultiByteToWideChar(CP_UTF8, 0, value, -1, NULL, 0);
5008  if (check_envsize((size_t)len + len2)) { /* len and len2 include '\0' */
5009  goto fail; /* 2 for '=' & '\0' */
5010  }
5011  wname = ALLOCV_N(WCHAR, buf, len + len2);
5012  wvalue = wname + len;
5013  MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, len);
5014  MultiByteToWideChar(CP_UTF8, 0, value, -1, wvalue, len2);
5015 #ifndef HAVE__WPUTENV_S
5016  wname[len-1] = L'=';
5017 #endif
5018  }
5019  else {
5020  wname = ALLOCV_N(WCHAR, buf, len + 1);
5021  MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, len);
5022  wvalue = wname + len;
5023  *wvalue = L'\0';
5024 #ifndef HAVE__WPUTENV_S
5025  wname[len-1] = L'=';
5026 #endif
5027  }
5028 #ifndef HAVE__WPUTENV_S
5029  failed = _wputenv(wname);
5030 #else
5031  failed = _wputenv_s(wname, wvalue);
5032 #endif
5033  ALLOCV_END(buf);
5034  /* even if putenv() failed, clean up and try to delete the
5035  * variable from the system area. */
5036  if (!value || !*value) {
5037  /* putenv() doesn't handle empty value */
5038  if (!SetEnvironmentVariable(name, value) &&
5039  GetLastError() != ERROR_ENVVAR_NOT_FOUND) goto fail;
5040  }
5041  if (failed) {
5042  fail:
5043  invalid_envname(name);
5044  }
5045 #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
5046  if (value) {
5047  if (setenv(name, value, 1))
5048  rb_sys_fail_str(rb_sprintf("setenv(%s)", name));
5049  }
5050  else {
5051 #ifdef VOID_UNSETENV
5052  unsetenv(name);
5053 #else
5054  if (unsetenv(name))
5055  rb_sys_fail_str(rb_sprintf("unsetenv(%s)", name));
5056 #endif
5057  }
5058 #elif defined __sun
5059  /* Solaris 9 (or earlier) does not have setenv(3C) and unsetenv(3C). */
5060  /* The below code was tested on Solaris 10 by:
5061  % ./configure ac_cv_func_setenv=no ac_cv_func_unsetenv=no
5062  */
5063  size_t len, mem_size;
5064  char **env_ptr, *str, *mem_ptr;
5065 
5066  check_envname(name);
5067  len = strlen(name);
5068  if (value) {
5069  mem_size = len + strlen(value) + 2;
5070  mem_ptr = malloc(mem_size);
5071  if (mem_ptr == NULL)
5072  rb_sys_fail_str(rb_sprintf("malloc("PRIuSIZE")", mem_size));
5073  snprintf(mem_ptr, mem_size, "%s=%s", name, value);
5074  }
5075  for (env_ptr = GET_ENVIRON(environ); (str = *env_ptr) != 0; ++env_ptr) {
5076  if (!strncmp(str, name, len) && str[len] == '=') {
5077  if (!in_origenv(str)) free(str);
5078  while ((env_ptr[0] = env_ptr[1]) != 0) env_ptr++;
5079  break;
5080  }
5081  }
5082  if (value) {
5083  if (putenv(mem_ptr)) {
5084  free(mem_ptr);
5085  rb_sys_fail_str(rb_sprintf("putenv(%s)", name));
5086  }
5087  }
5088 #else /* WIN32 */
5089  size_t len;
5090  int i;
5091 
5092  i=envix(name); /* where does it go? */
5093 
5094  if (environ == origenviron) { /* need we copy environment? */
5095  int j;
5096  int max;
5097  char **tmpenv;
5098 
5099  for (max = i; environ[max]; max++) ;
5100  tmpenv = ALLOC_N(char*, max+2);
5101  for (j=0; j<max; j++) /* copy environment */
5102  tmpenv[j] = ruby_strdup(environ[j]);
5103  tmpenv[max] = 0;
5104  environ = tmpenv; /* tell exec where it is now */
5105  }
5106  if (environ[i]) {
5107  char **envp = origenviron;
5108  while (*envp && *envp != environ[i]) envp++;
5109  if (!*envp)
5110  xfree(environ[i]);
5111  if (!value) {
5112  while (environ[i]) {
5113  environ[i] = environ[i+1];
5114  i++;
5115  }
5116  return;
5117  }
5118  }
5119  else { /* does not exist yet */
5120  if (!value) return;
5121  REALLOC_N(environ, char*, i+2); /* just expand it a bit */
5122  environ[i+1] = 0; /* make sure it's null terminated */
5123  }
5124  len = strlen(name) + strlen(value) + 2;
5125  environ[i] = ALLOC_N(char, len);
5126  snprintf(environ[i],len,"%s=%s",name,value); /* all that work just for this */
5127 #endif /* WIN32 */
5128 }
5129 
5130 void
5131 ruby_unsetenv(const char *name)
5132 {
5133  ruby_setenv(name, 0);
5134 }
5135 
5136 /*
5137  * call-seq:
5138  * ENV[name] = value -> value
5139  * ENV.store(name, value) -> value
5140  *
5141  * ENV.store is an alias for ENV.[]=.
5142  *
5143  * Creates, updates, or deletes the named environment variable, returning the value.
5144  * Both +name+ and +value+ may be instances of String.
5145  * See {Valid Names and Values}[#class-ENV-label-Valid+Names+and+Values].
5146  *
5147  * - If the named environment variable does not exist:
5148  * - If +value+ is +nil+, does nothing.
5149  * ENV.clear
5150  * ENV['foo'] = nil # => nil
5151  * ENV.include?('foo') # => false
5152  * ENV.store('bar', nil) # => nil
5153  * ENV.include?('bar') # => false
5154  * - If +value+ is not +nil+, creates the environment variable with +name+ and +value+:
5155  * # Create 'foo' using ENV.[]=.
5156  * ENV['foo'] = '0' # => '0'
5157  * ENV['foo'] # => '0'
5158  * # Create 'bar' using ENV.store.
5159  * ENV.store('bar', '1') # => '1'
5160  * ENV['bar'] # => '1'
5161  * - If the named environment variable exists:
5162  * - If +value+ is not +nil+, updates the environment variable with value +value+:
5163  * # Update 'foo' using ENV.[]=.
5164  * ENV['foo'] = '2' # => '2'
5165  * ENV['foo'] # => '2'
5166  * # Update 'bar' using ENV.store.
5167  * ENV.store('bar', '3') # => '3'
5168  * ENV['bar'] # => '3'
5169  * - If +value+ is +nil+, deletes the environment variable:
5170  * # Delete 'foo' using ENV.[]=.
5171  * ENV['foo'] = nil # => nil
5172  * ENV.include?('foo') # => false
5173  * # Delete 'bar' using ENV.store.
5174  * ENV.store('bar', nil) # => nil
5175  * ENV.include?('bar') # => false
5176  *
5177  * Raises an exception if +name+ or +value+ is invalid.
5178  * See {Invalid Names and Values}[#class-ENV-label-Invalid+Names+and+Values].
5179  */
5180 static VALUE
5181 env_aset_m(VALUE obj, VALUE nm, VALUE val)
5182 {
5183  return env_aset(nm, val);
5184 }
5185 
5186 static VALUE
5187 env_aset(VALUE nm, VALUE val)
5188 {
5189  char *name, *value;
5190 
5191  if (NIL_P(val)) {
5192  env_delete(nm);
5193  return Qnil;
5194  }
5195  SafeStringValue(nm);
5196  SafeStringValue(val);
5197  /* nm can be modified in `val.to_str`, don't get `name` before
5198  * check for `val` */
5199  get_env_ptr(name, nm);
5200  get_env_ptr(value, val);
5201 
5202  ruby_setenv(name, value);
5203  if (ENVMATCH(name, PATH_ENV)) {
5204  RB_GC_GUARD(nm);
5205  }
5206  else if (ENVMATCH(name, TZ_ENV)) {
5208  }
5209  return val;
5210 }
5211 
5212 static VALUE
5213 env_keys(void)
5214 {
5215  char **env;
5216  VALUE ary;
5217 
5218  ary = rb_ary_new();
5219  env = GET_ENVIRON(environ);
5220  while (*env) {
5221  char *s = strchr(*env, '=');
5222  if (s) {
5223  rb_ary_push(ary, env_str_new(*env, s-*env));
5224  }
5225  env++;
5226  }
5228  return ary;
5229 }
5230 
5231 /*
5232  * call-seq:
5233  * ENV.keys -> Array
5234  *
5235  * Returns all variable names in an Array:
5236  * ENV.replace('foo' => '0', 'bar' => '1')
5237  * ENV.keys # => ['bar', 'foo']
5238  * The order of the names is OS-dependent.
5239  * See {About Ordering}[#class-ENV-label-About+Ordering].
5240  *
5241  * Returns the empty Array if ENV is empty:
5242  * ENV.clear
5243  * ENV.keys # => []
5244  */
5245 
5246 static VALUE
5247 env_f_keys(VALUE _)
5248 {
5249  return env_keys();
5250 }
5251 
5252 static VALUE
5253 rb_env_size(VALUE ehash, VALUE args, VALUE eobj)
5254 {
5255  char **env;
5256  long cnt = 0;
5257 
5258  env = GET_ENVIRON(environ);
5259  for (; *env ; ++env) {
5260  if (strchr(*env, '=')) {
5261  cnt++;
5262  }
5263  }
5265  return LONG2FIX(cnt);
5266 }
5267 
5268 /*
5269  * call-seq:
5270  * ENV.each_key { |name| block } -> ENV
5271  * ENV.each_key -> Enumerator
5272  *
5273  * Yields each environment variable name:
5274  * ENV.replace('foo' => '0', 'bar' => '1') # => ENV
5275  * names = []
5276  * ENV.each_key { |name| names.push(name) } # => ENV
5277  * names # => ["bar", "foo"]
5278  *
5279  * Returns an Enumerator if no block given:
5280  * e = ENV.each_key # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_key>
5281  * names = []
5282  * e.each { |name| names.push(name) } # => ENV
5283  * names # => ["bar", "foo"]
5284  */
5285 static VALUE
5286 env_each_key(VALUE ehash)
5287 {
5288  VALUE keys;
5289  long i;
5290 
5291  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5292  keys = env_keys();
5293  for (i=0; i<RARRAY_LEN(keys); i++) {
5295  }
5296  return ehash;
5297 }
5298 
5299 static VALUE
5300 env_values(void)
5301 {
5302  VALUE ary;
5303  char **env;
5304 
5305  ary = rb_ary_new();
5306  env = GET_ENVIRON(environ);
5307  while (*env) {
5308  char *s = strchr(*env, '=');
5309  if (s) {
5310  rb_ary_push(ary, env_str_new2(s+1));
5311  }
5312  env++;
5313  }
5315  return ary;
5316 }
5317 
5318 /*
5319  * call-seq:
5320  * ENV.values -> Array
5321  *
5322  * Returns all environment variable values in an Array:
5323  * ENV.replace('foo' => '0', 'bar' => '1')
5324  * ENV.values # => ['1', '0']
5325  * The order of the values is OS-dependent.
5326  * See {About Ordering}[#class-ENV-label-About+Ordering].
5327  *
5328  * Returns the empty Array if ENV is empty:
5329  * ENV.clear
5330  * ENV.values # => []
5331  */
5332 static VALUE
5333 env_f_values(VALUE _)
5334 {
5335  return env_values();
5336 }
5337 
5338 /*
5339  * call-seq:
5340  * ENV.each_value { |value| block } -> ENV
5341  * ENV.each_value -> Enumerator
5342  *
5343  * Yields each environment variable value:
5344  * ENV.replace('foo' => '0', 'bar' => '1') # => ENV
5345  * values = []
5346  * ENV.each_value { |value| values.push(value) } # => ENV
5347  * values # => ["1", "0"]
5348  *
5349  * Returns an Enumerator if no block given:
5350  * e = ENV.each_value # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_value>
5351  * values = []
5352  * e.each { |value| values.push(value) } # => ENV
5353  * values # => ["1", "0"]
5354  */
5355 static VALUE
5356 env_each_value(VALUE ehash)
5357 {
5358  VALUE values;
5359  long i;
5360 
5361  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5362  values = env_values();
5363  for (i=0; i<RARRAY_LEN(values); i++) {
5364  rb_yield(RARRAY_AREF(values, i));
5365  }
5366  return ehash;
5367 }
5368 
5369 /*
5370  * call-seq:
5371  * ENV.each { |name, value| block } -> ENV
5372  * ENV.each -> Enumerator
5373  * ENV.each_pair { |name, value| block } -> ENV
5374  * ENV.each_pair -> Enumerator
5375  *
5376  * Yields each environment variable name and its value as a 2-element Array:
5377  * h = {}
5378  * ENV.each_pair { |name, value| h[name] = value } # => ENV
5379  * h # => {"bar"=>"1", "foo"=>"0"}
5380  *
5381  * Returns an Enumerator if no block given:
5382  * h = {}
5383  * e = ENV.each_pair # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_pair>
5384  * e.each { |name, value| h[name] = value } # => ENV
5385  * h # => {"bar"=>"1", "foo"=>"0"}
5386  */
5387 static VALUE
5388 env_each_pair(VALUE ehash)
5389 {
5390  char **env;
5391  VALUE ary;
5392  long i;
5393 
5394  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5395 
5396  ary = rb_ary_new();
5397  env = GET_ENVIRON(environ);
5398  while (*env) {
5399  char *s = strchr(*env, '=');
5400  if (s) {
5401  rb_ary_push(ary, env_str_new(*env, s-*env));
5402  rb_ary_push(ary, env_str_new2(s+1));
5403  }
5404  env++;
5405  }
5407 
5408  if (rb_block_arity() > 1) {
5409  for (i=0; i<RARRAY_LEN(ary); i+=2) {
5410  rb_yield_values(2, RARRAY_AREF(ary, i), RARRAY_AREF(ary, i+1));
5411  }
5412  }
5413  else {
5414  for (i=0; i<RARRAY_LEN(ary); i+=2) {
5415  rb_yield(rb_assoc_new(RARRAY_AREF(ary, i), RARRAY_AREF(ary, i+1)));
5416  }
5417  }
5418  return ehash;
5419 }
5420 
5421 /*
5422  * call-seq:
5423  * ENV.reject! { |name, value| block } -> ENV or nil
5424  * ENV.reject! -> Enumerator
5425  *
5426  * Similar to ENV.delete_if, but returns +nil+ if no changes were made.
5427  *
5428  * Deletes each environment variable for which the block returns a truthy value,
5429  * returning ENV (if any deletions) or +nil+ (if not):
5430  * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
5431  * ENV.reject! { |name, value| name.start_with?('b') } # => ENV
5432  * ENV # => {"foo"=>"0"}
5433  * ENV.reject! { |name, value| name.start_with?('b') } # => nil
5434  *
5435  * Returns an Enumerator if no block given:
5436  * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
5437  * e = ENV.reject! # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:reject!>
5438  * e.each { |name, value| name.start_with?('b') } # => ENV
5439  * ENV # => {"foo"=>"0"}
5440  * e.each { |name, value| name.start_with?('b') } # => nil
5441  */
5442 static VALUE
5443 env_reject_bang(VALUE ehash)
5444 {
5445  VALUE keys;
5446  long i;
5447  int del = 0;
5448 
5449  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5450  keys = env_keys();
5452  for (i=0; i<RARRAY_LEN(keys); i++) {
5453  VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
5454  if (!NIL_P(val)) {
5455  if (RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
5456  env_delete(RARRAY_AREF(keys, i));
5457  del++;
5458  }
5459  }
5460  }
5461  RB_GC_GUARD(keys);
5462  if (del == 0) return Qnil;
5463  return envtbl;
5464 }
5465 
5466 /*
5467  * call-seq:
5468  * ENV.delete_if { |name, value| block } -> ENV
5469  * ENV.delete_if -> Enumerator
5470  *
5471  * Deletes every environment variable for which the block evaluates to +true+.
5472  *
5473  * If no block is given an enumerator is returned instead.
5474  */
5475 static VALUE
5476 env_delete_if(VALUE ehash)
5477 {
5478  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5479  env_reject_bang(ehash);
5480  return envtbl;
5481 }
5482 
5483 /*
5484  * call-seq:
5485  * ENV.values_at(name, ...) -> Array
5486  *
5487  * Returns an array containing the environment variable values associated with
5488  * the given names. See also ENV.select.
5489  */
5490 static VALUE
5491 env_values_at(int argc, VALUE *argv, VALUE _)
5492 {
5493  VALUE result;
5494  long i;
5495 
5496  result = rb_ary_new();
5497  for (i=0; i<argc; i++) {
5498  rb_ary_push(result, rb_f_getenv(Qnil, argv[i]));
5499  }
5500  return result;
5501 }
5502 
5503 /*
5504  * call-seq:
5505  * ENV.select { |name, value| block } -> Hash
5506  * ENV.select -> Enumerator
5507  * ENV.filter { |name, value| block } -> Hash
5508  * ENV.filter -> Enumerator
5509  *
5510  * Returns a copy of the environment for entries where the block returns true.
5511  *
5512  * Returns an Enumerator if no block was given.
5513  *
5514  * ENV.filter is an alias for ENV.select.
5515  */
5516 static VALUE
5517 env_select(VALUE ehash)
5518 {
5519  VALUE result;
5520  VALUE keys;
5521  long i;
5522 
5523  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5524  result = rb_hash_new();
5525  keys = env_keys();
5526  for (i = 0; i < RARRAY_LEN(keys); ++i) {
5527  VALUE key = RARRAY_AREF(keys, i);
5528  VALUE val = rb_f_getenv(Qnil, key);
5529  if (!NIL_P(val)) {
5530  if (RTEST(rb_yield_values(2, key, val))) {
5531  rb_hash_aset(result, key, val);
5532  }
5533  }
5534  }
5535  RB_GC_GUARD(keys);
5536 
5537  return result;
5538 }
5539 
5540 /*
5541  * call-seq:
5542  * ENV.select! { |name, value| block } -> ENV or nil
5543  * ENV.select! -> Enumerator
5544  * ENV.filter! { |name, value| block } -> ENV or nil
5545  * ENV.filter! -> Enumerator
5546  *
5547  * Equivalent to ENV.keep_if but returns +nil+ if no changes were made.
5548  *
5549  * ENV.filter! is an alias for ENV.select!.
5550  */
5551 static VALUE
5552 env_select_bang(VALUE ehash)
5553 {
5554  VALUE keys;
5555  long i;
5556  int del = 0;
5557 
5558  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5559  keys = env_keys();
5561  for (i=0; i<RARRAY_LEN(keys); i++) {
5562  VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
5563  if (!NIL_P(val)) {
5564  if (!RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
5565  env_delete(RARRAY_AREF(keys, i));
5566  del++;
5567  }
5568  }
5569  }
5570  RB_GC_GUARD(keys);
5571  if (del == 0) return Qnil;
5572  return envtbl;
5573 }
5574 
5575 /*
5576  * call-seq:
5577  * ENV.keep_if { |name, value| block } -> ENV
5578  * ENV.keep_if -> Enumerator
5579  *
5580  * Deletes every environment variable where the block evaluates to +false+.
5581  *
5582  * Returns an enumerator if no block was given.
5583  */
5584 static VALUE
5585 env_keep_if(VALUE ehash)
5586 {
5587  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5588  env_select_bang(ehash);
5589  return envtbl;
5590 }
5591 
5592 /*
5593  * call-seq:
5594  * ENV.slice(*keys) -> a_hash
5595  *
5596  * Returns a hash containing only the given keys from ENV and their values.
5597  *
5598  * ENV.slice("TERM","HOME") #=> {"TERM"=>"xterm-256color", "HOME"=>"/Users/rhc"}
5599  */
5600 static VALUE
5601 env_slice(int argc, VALUE *argv, VALUE _)
5602 {
5603  int i;
5604  VALUE key, value, result;
5605 
5606  if (argc == 0) {
5607  return rb_hash_new();
5608  }
5609  result = rb_hash_new_with_size(argc);
5610 
5611  for (i = 0; i < argc; i++) {
5612  key = argv[i];
5613  value = rb_f_getenv(Qnil, key);
5614  if (value != Qnil)
5615  rb_hash_aset(result, key, value);
5616  }
5617 
5618  return result;
5619 }
5620 
5621 VALUE
5623 {
5624  VALUE keys;
5625  long i;
5626 
5627  keys = env_keys();
5628  for (i=0; i<RARRAY_LEN(keys); i++) {
5629  VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
5630  if (!NIL_P(val)) {
5631  env_delete(RARRAY_AREF(keys, i));
5632  }
5633  }
5634  RB_GC_GUARD(keys);
5635  return envtbl;
5636 }
5637 
5638 /*
5639  * call-seq:
5640  * ENV.clear -> ENV
5641  *
5642  * Removes every environment variable; returns ENV:
5643  * ENV.replace('foo' => '0', 'bar' => '1')
5644  * ENV.size # => 2
5645  * ENV.clear # => ENV
5646  * ENV.size # => 0
5647  */
5648 static VALUE
5649 env_clear(VALUE _)
5650 {
5651  return rb_env_clear();
5652 }
5653 
5654 /*
5655  * call-seq:
5656  * ENV.to_s -> "ENV"
5657  *
5658  * Returns "ENV"
5659  */
5660 static VALUE
5661 env_to_s(VALUE _)
5662 {
5663  return rb_usascii_str_new2("ENV");
5664 }
5665 
5666 /*
5667  * call-seq:
5668  * ENV.inspect -> string
5669  *
5670  * Returns the contents of the environment as a String.
5671  */
5672 static VALUE
5673 env_inspect(VALUE _)
5674 {
5675  char **env;
5676  VALUE str, i;
5677 
5678  str = rb_str_buf_new2("{");
5679  env = GET_ENVIRON(environ);
5680  while (*env) {
5681  char *s = strchr(*env, '=');
5682 
5683  if (env != environ) {
5684  rb_str_buf_cat2(str, ", ");
5685  }
5686  if (s) {
5687  rb_str_buf_cat2(str, "\"");
5688  rb_str_buf_cat(str, *env, s-*env);
5689  rb_str_buf_cat2(str, "\"=>");
5690  i = rb_inspect(rb_str_new2(s+1));
5692  }
5693  env++;
5694  }
5696  rb_str_buf_cat2(str, "}");
5697 
5698  return str;
5699 }
5700 
5701 /*
5702  * call-seq:
5703  * ENV.to_a -> Array
5704  *
5705  * Converts the environment variables into an array of names and value arrays.
5706  *
5707  * ENV.to_a # => [["TERM", "xterm-color"], ["SHELL", "/bin/bash"], ...]
5708  *
5709  */
5710 static VALUE
5711 env_to_a(VALUE _)
5712 {
5713  char **env;
5714  VALUE ary;
5715 
5716  ary = rb_ary_new();
5717  env = GET_ENVIRON(environ);
5718  while (*env) {
5719  char *s = strchr(*env, '=');
5720  if (s) {
5721  rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s-*env),
5722  env_str_new2(s+1)));
5723  }
5724  env++;
5725  }
5727  return ary;
5728 }
5729 
5730 /*
5731  * call-seq:
5732  * ENV.rehash
5733  *
5734  * Re-hashing the environment variables does nothing. It is provided for
5735  * compatibility with Hash.
5736  */
5737 static VALUE
5738 env_none(VALUE _)
5739 {
5740  return Qnil;
5741 }
5742 
5743 /*
5744  * call-seq:
5745  * ENV.length
5746  * ENV.size
5747  *
5748  * Returns the number of environment variables.
5749  */
5750 static VALUE
5751 env_size(VALUE _)
5752 {
5753  int i;
5754  char **env;
5755 
5756  env = GET_ENVIRON(environ);
5757  for (i=0; env[i]; i++)
5758  ;
5760  return INT2FIX(i);
5761 }
5762 
5763 /*
5764  * call-seq:
5765  * ENV.empty? -> true or false
5766  *
5767  * Returns true when there are no environment variables
5768  */
5769 static VALUE
5770 env_empty_p(VALUE _)
5771 {
5772  char **env;
5773 
5774  env = GET_ENVIRON(environ);
5775  if (env[0] == 0) {
5777  return Qtrue;
5778  }
5780  return Qfalse;
5781 }
5782 
5783 /*
5784  * call-seq:
5785  * ENV.include?(name) -> true or false
5786  * ENV.has_key?(name) -> true or false
5787  * ENV.member?(name) -> true or false
5788  * ENV.key?(name) -> true or false
5789  *
5790  * ENV.has_key?, ENV.member?, and ENV.key? are aliases for ENV.include?.
5791  *
5792  * Returns +true+ if there is an environment variable with the given +name+:
5793  * ENV.replace('foo' => '0', 'bar' => '1')
5794  * ENV.include?('foo') # => true
5795  * Returns +false+ if +name+ is a valid String and there is no such environment variable:
5796  * ENV.include?('baz') # => false
5797  * Returns +false+ if +name+ is the empty String or is a String containing character <code>'='</code>:
5798  * ENV.include?('') # => false
5799  * ENV.include?('=') # => false
5800  * Raises an exception if +name+ is a String containing the NUL character <code>"\0"</code>:
5801  * ENV.include?("\0") # Raises ArgumentError (bad environment variable name: contains null byte)
5802  * Raises an exception if +name+ has an encoding that is not ASCII-compatible:
5803  * ENV.include?("\xa1\xa1".force_encoding(Encoding::UTF_16LE))
5804  * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: UTF-16LE)
5805  * Raises an exception if +name+ is not a String:
5806  * ENV.include?(Object.new) # TypeError (no implicit conversion of Object into String)
5807  */
5808 static VALUE
5809 env_has_key(VALUE env, VALUE key)
5810 {
5811  const char *s;
5812 
5813  s = env_name(key);
5814  if (getenv(s)) return Qtrue;
5815  return Qfalse;
5816 }
5817 
5818 /*
5819  * call-seq:
5820  * ENV.assoc(name) -> Array or nil
5821  *
5822  * Returns a 2-element Array containing the name and value of the environment variable
5823  * for +name+ if it exists:
5824  * ENV.replace('foo' => '0', 'bar' => '1')
5825  * ENV.assoc('foo') # => ['foo' '0']
5826  * Returns +nil+ if +name+ is a valid String and there is no such environment variable:
5827  * ENV.assoc('baz') # => false
5828  * Returns +nil+ if +name+ is the empty String or is a String containing character <code>'='</code>:
5829  * ENV.assoc('') # => false
5830  * ENV.assoc('=') # => false
5831  * Raises an exception if +name+ is a String containing the NUL character <code>"\0"</code>:
5832  * ENV.assoc("\0") # Raises ArgumentError (bad environment variable name: contains null byte)
5833  * Raises an exception if +name+ has an encoding that is not ASCII-compatible:
5834  * ENV.assoc("\xa1\xa1".force_encoding(Encoding::UTF_16LE))
5835  * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: UTF-16LE)
5836  * Raises an exception if +name+ is not a String:
5837  * ENV.assoc(Object.new) # TypeError (no implicit conversion of Object into String)
5838  */
5839 static VALUE
5840 env_assoc(VALUE env, VALUE key)
5841 {
5842  const char *s, *e;
5843 
5844  s = env_name(key);
5845  e = getenv(s);
5846  if (e) return rb_assoc_new(key, env_str_new2(e));
5847  return Qnil;
5848 }
5849 
5850 /*
5851  * call-seq:
5852  * ENV.value?(value) -> true or false
5853  * ENV.has_value?(value) -> true or false
5854  *
5855  * Returns +true+ if there is an environment variable with the given +value+.
5856  */
5857 static VALUE
5858 env_has_value(VALUE dmy, VALUE obj)
5859 {
5860  char **env;
5861 
5863  if (NIL_P(obj)) return Qnil;
5864  env = GET_ENVIRON(environ);
5865  while (*env) {
5866  char *s = strchr(*env, '=');
5867  if (s++) {
5868  long len = strlen(s);
5869  if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
5871  return Qtrue;
5872  }
5873  }
5874  env++;
5875  }
5877  return Qfalse;
5878 }
5879 
5880 /*
5881  * call-seq:
5882  * ENV.rassoc(value)
5883  *
5884  * Returns an Array of the name and value of the environment variable with
5885  * +value+ or +nil+ if the value cannot be found.
5886  */
5887 static VALUE
5888 env_rassoc(VALUE dmy, VALUE obj)
5889 {
5890  char **env;
5891 
5893  if (NIL_P(obj)) return Qnil;
5894  env = GET_ENVIRON(environ);
5895  while (*env) {
5896  char *s = strchr(*env, '=');
5897  if (s++) {
5898  long len = strlen(s);
5899  if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
5900  VALUE result = rb_assoc_new(rb_str_new(*env, s-*env-1), obj);
5902  return result;
5903  }
5904  }
5905  env++;
5906  }
5908  return Qnil;
5909 }
5910 
5911 /*
5912  * call-seq:
5913  * ENV.key(value) -> name or nil
5914  *
5915  * Returns the name of the first environment variable with +value+ if it exists:
5916  * ENV.replace('foo' => '0', 'bar' => '1')
5917  * ENV.key('0') # =>'foo'
5918  * The order in which environment variables are examined is OS-dependent.
5919  * See {About Ordering}[#class-ENV-label-About+Ordering].
5920  *
5921  * Returns +nil+ if there is no such value:
5922  * ENV.key('2') # => nil
5923  * Raises an exception if +value+ is not a String:
5924  * ENV.key(Object.new) # raises TypeError (no implicit conversion of Object into String)
5925  */
5926 static VALUE
5927 env_key(VALUE dmy, VALUE value)
5928 {
5929  char **env;
5930  VALUE str;
5931 
5932  SafeStringValue(value);
5933  env = GET_ENVIRON(environ);
5934  while (*env) {
5935  char *s = strchr(*env, '=');
5936  if (s++) {
5937  long len = strlen(s);
5938  if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) {
5939  str = env_str_new(*env, s-*env-1);
5941  return str;
5942  }
5943  }
5944  env++;
5945  }
5947  return Qnil;
5948 }
5949 
5950 /*
5951  * call-seq:
5952  * ENV.index(value) -> key
5953  *
5954  * Deprecated method that is equivalent to ENV.key
5955  */
5956 static VALUE
5957 env_index(VALUE dmy, VALUE value)
5958 {
5959  rb_warn_deprecated("ENV.index", "ENV.key");
5960  return env_key(dmy, value);
5961 }
5962 
5963 static VALUE
5964 env_to_hash(void)
5965 {
5966  char **env;
5967  VALUE hash;
5968 
5969  hash = rb_hash_new();
5970  env = GET_ENVIRON(environ);
5971  while (*env) {
5972  char *s = strchr(*env, '=');
5973  if (s) {
5974  rb_hash_aset(hash, env_str_new(*env, s-*env),
5975  env_str_new2(s+1));
5976  }
5977  env++;
5978  }
5980  return hash;
5981 }
5982 
5983 /*
5984  * call-seq:
5985  * ENV.to_hash -> hash
5986  *
5987  * Creates a hash with a copy of the environment variables.
5988  *
5989  */
5990 
5991 static VALUE
5992 env_f_to_hash(VALUE _)
5993 {
5994  return env_to_hash();
5995 }
5996 
5997 /*
5998  * call-seq:
5999  * ENV.to_h -> hash
6000  * ENV.to_h {|name, value| block } -> hash
6001  *
6002  * Creates a hash with a copy of the environment variables.
6003  *
6004  */
6005 static VALUE
6006 env_to_h(VALUE _)
6007 {
6008  VALUE hash = env_to_hash();
6009  if (rb_block_given_p()) {
6010  hash = rb_hash_to_h_block(hash);
6011  }
6012  return hash;
6013 }
6014 
6015 /*
6016  * call-seq:
6017  * ENV.reject { |name, value| block } -> Hash
6018  * ENV.reject -> Enumerator
6019  *
6020  * Same as ENV.delete_if, but works on (and returns) a copy of the
6021  * environment.
6022  */
6023 static VALUE
6024 env_reject(VALUE _)
6025 {
6026  return rb_hash_delete_if(env_to_hash());
6027 }
6028 
6029 /*
6030  * call-seq:
6031  * ENV.freeze -> raises TypeError
6032  *
6033  * Ruby does not allow ENV to be frozen, so calling ENV.freeze
6034  * raises TypeError.
6035  */
6036 static VALUE
6037 env_freeze(VALUE self)
6038 {
6039  rb_raise(rb_eTypeError, "cannot freeze ENV");
6040  return self; /* Not reached */
6041 }
6042 
6043 /*
6044  * call-seq:
6045  * ENV.shift -> [name, value] or nil
6046  *
6047  * Removes the first environment variable from ENV and returns
6048  * a 2-element Array containing its name and value:
6049  * ENV.replace('foo' => '0', 'bar' => '1')
6050  * ENV.to_hash # => {'bar' => '1', 'foo' => '0'}
6051  * ENV.shift # => ['bar', '1']
6052  * ENV.to_hash # => {'foo' => '0'}
6053  * Exactly which environment variable is "first" is OS-dependent.
6054  * See {About Ordering}[#class-ENV-label-About+Ordering].
6055  *
6056  * Returns +nil+ if the environment is empty:
6057  * ENV.clear
6058  * ENV.shift # => nil
6059  */
6060 static VALUE
6061 env_shift(VALUE _)
6062 {
6063  char **env;
6064  VALUE result = Qnil;
6065 
6066  env = GET_ENVIRON(environ);
6067  if (*env) {
6068  char *s = strchr(*env, '=');
6069  if (s) {
6070  VALUE key = env_str_new(*env, s-*env);
6071  VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
6072  env_delete(key);
6073  result = rb_assoc_new(key, val);
6074  }
6075  }
6077  return result;
6078 }
6079 
6080 /*
6081  * call-seq:
6082  * ENV.invert -> Hash
6083  *
6084  * Returns a new hash created by using environment variable names as values
6085  * and values as names.
6086  */
6087 static VALUE
6088 env_invert(VALUE _)
6089 {
6090  return rb_hash_invert(env_to_hash());
6091 }
6092 
6093 static int
6094 env_replace_i(VALUE key, VALUE val, VALUE keys)
6095 {
6096  env_aset(key, val);
6097  if (rb_ary_includes(keys, key)) {
6099  }
6100  return ST_CONTINUE;
6101 }
6102 
6103 /*
6104  * call-seq:
6105  * ENV.replace(hash) -> ENV
6106  *
6107  * Replaces the entire content of the environment variables
6108  * with the name/value pairs in the given +hash+;
6109  * returns ENV.
6110  *
6111  * Replaces the content of ENV with the given pairs:
6112  * ENV.replace('foo' => '0', 'bar' => '1') # => ENV
6113  * ENV.to_hash # => {"bar"=>"1", "foo"=>"0"}
6114  *
6115  * Raises an exception if a name or value is invalid.
6116  * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
6117  */
6118 static VALUE
6119 env_replace(VALUE env, VALUE hash)
6120 {
6121  VALUE keys;
6122  long i;
6123 
6124  keys = env_keys();
6125  if (env == hash) return env;
6126  hash = to_hash(hash);
6127  rb_hash_foreach(hash, env_replace_i, keys);
6128 
6129  for (i=0; i<RARRAY_LEN(keys); i++) {
6130  env_delete(RARRAY_AREF(keys, i));
6131  }
6132  RB_GC_GUARD(keys);
6133  return env;
6134 }
6135 
6136 static int
6137 env_update_i(VALUE key, VALUE val, VALUE _)
6138 {
6139  env_aset(key, val);
6140  return ST_CONTINUE;
6141 }
6142 
6143 static int
6144 env_update_block_i(VALUE key, VALUE val, VALUE _)
6145 {
6146  VALUE oldval = rb_f_getenv(Qnil, key);
6147  if (!NIL_P(oldval)) {
6148  val = rb_yield_values(3, key, oldval, val);
6149  }
6150  env_aset(key, val);
6151  return ST_CONTINUE;
6152 }
6153 
6154 /*
6155  * call-seq:
6156  * ENV.update(hash) -> ENV
6157  * ENV.update(hash) { |name, old_value, new_value| block } -> ENV
6158  * ENV.merge!(hash) -> ENV
6159  * ENV.merge!(hash) { |name, old_value, new_value| block } -> ENV
6160  *
6161  * Adds the contents of +hash+ to the environment variables. If no block is
6162  * specified entries with duplicate keys are overwritten, otherwise the value
6163  * of each duplicate name is determined by calling the block with the key, its
6164  * value from the environment and its value from the hash.
6165  */
6166 static VALUE
6167 env_update(VALUE env, VALUE hash)
6168 {
6169  if (env == hash) return env;
6170  hash = to_hash(hash);
6171  rb_foreach_func *func = rb_block_given_p() ?
6172  env_update_block_i : env_update_i;
6173  rb_hash_foreach(hash, func, 0);
6174  return env;
6175 }
6176 
6177 /*
6178  * A Hash is a dictionary-like collection of unique keys and their values.
6179  * Also called associative arrays, they are similar to Arrays, but where an
6180  * Array uses integers as its index, a Hash allows you to use any object
6181  * type.
6182  *
6183  * Hashes enumerate their values in the order that the corresponding keys
6184  * were inserted.
6185  *
6186  * A Hash can be easily created by using its implicit form:
6187  *
6188  * grades = { "Jane Doe" => 10, "Jim Doe" => 6 }
6189  *
6190  * Hashes allow an alternate syntax for keys that are symbols.
6191  * Instead of
6192  *
6193  * options = { :font_size => 10, :font_family => "Arial" }
6194  *
6195  * You could write it as:
6196  *
6197  * options = { font_size: 10, font_family: "Arial" }
6198  *
6199  * Each named key is a symbol you can access in hash:
6200  *
6201  * options[:font_size] # => 10
6202  *
6203  * A Hash can also be created through its ::new method:
6204  *
6205  * grades = Hash.new
6206  * grades["Dorothy Doe"] = 9
6207  *
6208  * Hashes have a <em>default value</em> that is returned when accessing
6209  * keys that do not exist in the hash. If no default is set +nil+ is used.
6210  * You can set the default value by sending it as an argument to Hash.new:
6211  *
6212  * grades = Hash.new(0)
6213  *
6214  * Or by using the #default= method:
6215  *
6216  * grades = {"Timmy Doe" => 8}
6217  * grades.default = 0
6218  *
6219  * Accessing a value in a Hash requires using its key:
6220  *
6221  * puts grades["Jane Doe"] # => 0
6222  *
6223  * === Common Uses
6224  *
6225  * Hashes are an easy way to represent data structures, such as
6226  *
6227  * books = {}
6228  * books[:matz] = "The Ruby Programming Language"
6229  * books[:black] = "The Well-Grounded Rubyist"
6230  *
6231  * Hashes are also commonly used as a way to have named parameters in
6232  * functions. Note that no brackets are used below. If a hash is the last
6233  * argument on a method call, no braces are needed, thus creating a really
6234  * clean interface:
6235  *
6236  * Person.create(name: "John Doe", age: 27)
6237  *
6238  * def self.create(params)
6239  * @name = params[:name]
6240  * @age = params[:age]
6241  * end
6242  *
6243  * === Hash Keys
6244  *
6245  * Two objects refer to the same hash key when their <code>hash</code> value
6246  * is identical and the two objects are <code>eql?</code> to each other.
6247  *
6248  * A user-defined class may be used as a hash key if the <code>hash</code>
6249  * and <code>eql?</code> methods are overridden to provide meaningful
6250  * behavior. By default, separate instances refer to separate hash keys.
6251  *
6252  * A typical implementation of <code>hash</code> is based on the
6253  * object's data while <code>eql?</code> is usually aliased to the overridden
6254  * <code>==</code> method:
6255  *
6256  * class Book
6257  * attr_reader :author, :title
6258  *
6259  * def initialize(author, title)
6260  * @author = author
6261  * @title = title
6262  * end
6263  *
6264  * def ==(other)
6265  * self.class === other and
6266  * other.author == @author and
6267  * other.title == @title
6268  * end
6269  *
6270  * alias eql? ==
6271  *
6272  * def hash
6273  * @author.hash ^ @title.hash # XOR
6274  * end
6275  * end
6276  *
6277  * book1 = Book.new 'matz', 'Ruby in a Nutshell'
6278  * book2 = Book.new 'matz', 'Ruby in a Nutshell'
6279  *
6280  * reviews = {}
6281  *
6282  * reviews[book1] = 'Great reference!'
6283  * reviews[book2] = 'Nice and compact!'
6284  *
6285  * reviews.length #=> 1
6286  *
6287  * See also Object#hash and Object#eql?
6288  */
6289 
6290 void
6292 {
6293 #undef rb_intern
6294 #define rb_intern(str) rb_intern_const(str)
6295  id_hash = rb_intern("hash");
6296  id_yield = rb_intern("yield");
6297  id_default = rb_intern("default");
6298  id_flatten_bang = rb_intern("flatten!");
6299  id_hash_iter_lev = rb_make_internal_id();
6300 
6301  rb_cHash = rb_define_class("Hash", rb_cObject);
6302 
6304 
6305  rb_define_alloc_func(rb_cHash, empty_hash_alloc);
6306  rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);
6307  rb_define_singleton_method(rb_cHash, "try_convert", rb_hash_s_try_convert, 1);
6308  rb_define_method(rb_cHash, "initialize", rb_hash_initialize, -1);
6309  rb_define_method(rb_cHash, "initialize_copy", rb_hash_replace, 1);
6310  rb_define_method(rb_cHash, "rehash", rb_hash_rehash, 0);
6311 
6312  rb_define_method(rb_cHash, "to_hash", rb_hash_to_hash, 0);
6313  rb_define_method(rb_cHash, "to_h", rb_hash_to_h, 0);
6314  rb_define_method(rb_cHash, "to_a", rb_hash_to_a, 0);
6315  rb_define_method(rb_cHash, "inspect", rb_hash_inspect, 0);
6316  rb_define_alias(rb_cHash, "to_s", "inspect");
6317  rb_define_method(rb_cHash, "to_proc", rb_hash_to_proc, 0);
6318 
6319  rb_define_method(rb_cHash, "==", rb_hash_equal, 1);
6321  rb_define_method(rb_cHash, "hash", rb_hash_hash, 0);
6322  rb_define_method(rb_cHash, "eql?", rb_hash_eql, 1);
6323  rb_define_method(rb_cHash, "fetch", rb_hash_fetch_m, -1);
6325  rb_define_method(rb_cHash, "store", rb_hash_aset, 2);
6326  rb_define_method(rb_cHash, "default", rb_hash_default, -1);
6327  rb_define_method(rb_cHash, "default=", rb_hash_set_default, 1);
6328  rb_define_method(rb_cHash, "default_proc", rb_hash_default_proc, 0);
6329  rb_define_method(rb_cHash, "default_proc=", rb_hash_set_default_proc, 1);
6330  rb_define_method(rb_cHash, "key", rb_hash_key, 1);
6331  rb_define_method(rb_cHash, "index", rb_hash_index, 1);
6332  rb_define_method(rb_cHash, "size", rb_hash_size, 0);
6333  rb_define_method(rb_cHash, "length", rb_hash_size, 0);
6334  rb_define_method(rb_cHash, "empty?", rb_hash_empty_p, 0);
6335 
6336  rb_define_method(rb_cHash, "each_value", rb_hash_each_value, 0);
6337  rb_define_method(rb_cHash, "each_key", rb_hash_each_key, 0);
6338  rb_define_method(rb_cHash, "each_pair", rb_hash_each_pair, 0);
6339  rb_define_method(rb_cHash, "each", rb_hash_each_pair, 0);
6340 
6341  rb_define_method(rb_cHash, "transform_keys", rb_hash_transform_keys, 0);
6342  rb_define_method(rb_cHash, "transform_keys!", rb_hash_transform_keys_bang, 0);
6343  rb_define_method(rb_cHash, "transform_values", rb_hash_transform_values, 0);
6344  rb_define_method(rb_cHash, "transform_values!", rb_hash_transform_values_bang, 0);
6345 
6346  rb_define_method(rb_cHash, "keys", rb_hash_keys, 0);
6347  rb_define_method(rb_cHash, "values", rb_hash_values, 0);
6348  rb_define_method(rb_cHash, "values_at", rb_hash_values_at, -1);
6349  rb_define_method(rb_cHash, "fetch_values", rb_hash_fetch_values, -1);
6350 
6351  rb_define_method(rb_cHash, "shift", rb_hash_shift, 0);
6352  rb_define_method(rb_cHash, "delete", rb_hash_delete_m, 1);
6353  rb_define_method(rb_cHash, "delete_if", rb_hash_delete_if, 0);
6354  rb_define_method(rb_cHash, "keep_if", rb_hash_keep_if, 0);
6355  rb_define_method(rb_cHash, "select", rb_hash_select, 0);
6357  rb_define_method(rb_cHash, "filter", rb_hash_select, 0);
6359  rb_define_method(rb_cHash, "reject", rb_hash_reject, 0);
6361  rb_define_method(rb_cHash, "slice", rb_hash_slice, -1);
6362  rb_define_method(rb_cHash, "clear", rb_hash_clear, 0);
6363  rb_define_method(rb_cHash, "invert", rb_hash_invert, 0);
6364  rb_define_method(rb_cHash, "update", rb_hash_update, -1);
6365  rb_define_method(rb_cHash, "replace", rb_hash_replace, 1);
6366  rb_define_method(rb_cHash, "merge!", rb_hash_update, -1);
6367  rb_define_method(rb_cHash, "merge", rb_hash_merge, -1);
6368  rb_define_method(rb_cHash, "assoc", rb_hash_assoc, 1);
6369  rb_define_method(rb_cHash, "rassoc", rb_hash_rassoc, 1);
6370  rb_define_method(rb_cHash, "flatten", rb_hash_flatten, -1);
6371  rb_define_method(rb_cHash, "compact", rb_hash_compact, 0);
6372  rb_define_method(rb_cHash, "compact!", rb_hash_compact_bang, 0);
6373 
6374  rb_define_method(rb_cHash, "include?", rb_hash_has_key, 1);
6375  rb_define_method(rb_cHash, "member?", rb_hash_has_key, 1);
6376  rb_define_method(rb_cHash, "has_key?", rb_hash_has_key, 1);
6377  rb_define_method(rb_cHash, "has_value?", rb_hash_has_value, 1);
6379  rb_define_method(rb_cHash, "value?", rb_hash_has_value, 1);
6380 
6381  rb_define_method(rb_cHash, "compare_by_identity", rb_hash_compare_by_id, 0);
6382  rb_define_method(rb_cHash, "compare_by_identity?", rb_hash_compare_by_id_p, 0);
6383 
6384  rb_define_method(rb_cHash, "any?", rb_hash_any_p, -1);
6385  rb_define_method(rb_cHash, "dig", rb_hash_dig, -1);
6386 
6387  rb_define_method(rb_cHash, "<=", rb_hash_le, 1);
6388  rb_define_method(rb_cHash, "<", rb_hash_lt, 1);
6389  rb_define_method(rb_cHash, ">=", rb_hash_ge, 1);
6390  rb_define_method(rb_cHash, ">", rb_hash_gt, 1);
6391 
6392  rb_define_method(rb_cHash, "deconstruct_keys", rb_hash_deconstruct_keys, 1);
6393 
6394  rb_define_singleton_method(rb_cHash, "ruby2_keywords_hash?", rb_hash_s_ruby2_keywords_hash_p, 1);
6395  rb_define_singleton_method(rb_cHash, "ruby2_keywords_hash", rb_hash_s_ruby2_keywords_hash, 1);
6396 
6397  /* Document-class: ENV
6398  *
6399  * ENV is a hash-like accessor for environment variables.
6400  *
6401  * === Interaction with the Operating System
6402  *
6403  * The ENV object interacts with the operating system's environment variables:
6404  *
6405  * - When you get the value for a name in ENV, the value is retrieved from among the current environment variables.
6406  * - When you create or set a name-value pair in ENV, the name and value are immediately set in the environment variables.
6407  * - When you delete a name-value pair in ENV, it is immediately deleted from the environment variables.
6408  *
6409  * === Names and Values
6410  *
6411  * Generally, a name or value is a String.
6412  *
6413  * ==== Valid Names and Values
6414  *
6415  * Each name or value must be one of the following:
6416  *
6417  * - A String.
6418  * - An object that responds to \#to_str by returning a String, in which case that String will be used as the name or value.
6419  *
6420  * ==== Invalid Names and Values
6421  *
6422  * A new name:
6423  *
6424  * - May not be the empty string:
6425  * ENV[''] = '0'
6426  * # Raises Errno::EINVAL (Invalid argument - ruby_setenv())
6427  *
6428  * - May not contain character <code>"="</code>:
6429  * ENV['='] = '0'
6430  * # Raises Errno::EINVAL (Invalid argument - ruby_setenv(=))
6431  *
6432  * A new name or value:
6433  *
6434  * - May not be a non-String that does not respond to \#to_str:
6435  *
6436  * ENV['foo'] = Object.new
6437  * # Raises TypeError (no implicit conversion of Object into String)
6438  * ENV[Object.new] = '0'
6439  * # Raises TypeError (no implicit conversion of Object into String)
6440  *
6441  * - May not contain the NUL character <code>"\0"</code>:
6442  *
6443  * ENV['foo'] = "\0"
6444  * # Raises ArgumentError (bad environment variable value: contains null byte)
6445  * ENV["\0"] == '0'
6446  * # Raises ArgumentError (bad environment variable name: contains null byte)
6447  *
6448  * - May not have an ASCII-incompatible encoding such as UTF-16LE or ISO-2022-JP:
6449  *
6450  * ENV['foo'] = '0'.force_encoding(Encoding::ISO_2022_JP)
6451  * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP)
6452  * ENV["foo".force_encoding(Encoding::ISO_2022_JP)] = '0'
6453  * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP)
6454  *
6455  * === About Ordering
6456  *
6457  * ENV enumerates its name/value pairs in the order found
6458  * in the operating system's environment variables.
6459  * Therefore the ordering of ENV content is OS-dependent, and may be indeterminate.
6460  *
6461  * This will be seen in:
6462  * - A Hash returned by an ENV method.
6463  * - An Enumerator returned by an ENV method.
6464  * - An Array returned by ENV.keys, ENV.values, or ENV.to_a.
6465  * - The String returned by ENV.inspect.
6466  * - The Array returned by ENV.shift.
6467  * - The name returned by ENV.key.
6468  *
6469  * === About the Examples
6470  * Some methods in ENV return ENV itself. Typically, there are many environment variables.
6471  * It's not useful to display a large ENV in the examples here,
6472  * so most example snippets begin by resetting the contents of ENV:
6473  * - ENV.replace replaces ENV with a new collection of entries.
6474  * - ENV.clear empties ENV.
6475  */
6476 
6477  /*
6478  * Hack to get RDoc to regard ENV as a class:
6479  * envtbl = rb_define_class("ENV", rb_cObject);
6480  */
6481  origenviron = environ;
6482  envtbl = rb_obj_alloc(rb_cObject);
6484 
6485  rb_define_singleton_method(envtbl, "[]", rb_f_getenv, 1);
6486  rb_define_singleton_method(envtbl, "fetch", env_fetch, -1);
6487  rb_define_singleton_method(envtbl, "[]=", env_aset_m, 2);
6488  rb_define_singleton_method(envtbl, "store", env_aset_m, 2);
6489  rb_define_singleton_method(envtbl, "each", env_each_pair, 0);
6490  rb_define_singleton_method(envtbl, "each_pair", env_each_pair, 0);
6491  rb_define_singleton_method(envtbl, "each_key", env_each_key, 0);
6492  rb_define_singleton_method(envtbl, "each_value", env_each_value, 0);
6493  rb_define_singleton_method(envtbl, "delete", env_delete_m, 1);
6494  rb_define_singleton_method(envtbl, "delete_if", env_delete_if, 0);
6495  rb_define_singleton_method(envtbl, "keep_if", env_keep_if, 0);
6496  rb_define_singleton_method(envtbl, "slice", env_slice, -1);
6497  rb_define_singleton_method(envtbl, "clear", env_clear, 0);
6498  rb_define_singleton_method(envtbl, "reject", env_reject, 0);
6499  rb_define_singleton_method(envtbl, "reject!", env_reject_bang, 0);
6500  rb_define_singleton_method(envtbl, "select", env_select, 0);
6501  rb_define_singleton_method(envtbl, "select!", env_select_bang, 0);
6502  rb_define_singleton_method(envtbl, "filter", env_select, 0);
6503  rb_define_singleton_method(envtbl, "filter!", env_select_bang, 0);
6504  rb_define_singleton_method(envtbl, "shift", env_shift, 0);
6505  rb_define_singleton_method(envtbl, "freeze", env_freeze, 0);
6506  rb_define_singleton_method(envtbl, "invert", env_invert, 0);
6507  rb_define_singleton_method(envtbl, "replace", env_replace, 1);
6508  rb_define_singleton_method(envtbl, "update", env_update, 1);
6509  rb_define_singleton_method(envtbl, "merge!", env_update, 1);
6510  rb_define_singleton_method(envtbl, "inspect", env_inspect, 0);
6511  rb_define_singleton_method(envtbl, "rehash", env_none, 0);
6512  rb_define_singleton_method(envtbl, "to_a", env_to_a, 0);
6513  rb_define_singleton_method(envtbl, "to_s", env_to_s, 0);
6514  rb_define_singleton_method(envtbl, "key", env_key, 1);
6515  rb_define_singleton_method(envtbl, "index", env_index, 1);
6516  rb_define_singleton_method(envtbl, "size", env_size, 0);
6517  rb_define_singleton_method(envtbl, "length", env_size, 0);
6518  rb_define_singleton_method(envtbl, "empty?", env_empty_p, 0);
6519  rb_define_singleton_method(envtbl, "keys", env_f_keys, 0);
6520  rb_define_singleton_method(envtbl, "values", env_f_values, 0);
6521  rb_define_singleton_method(envtbl, "values_at", env_values_at, -1);
6522  rb_define_singleton_method(envtbl, "include?", env_has_key, 1);
6523  rb_define_singleton_method(envtbl, "member?", env_has_key, 1);
6524  rb_define_singleton_method(envtbl, "has_key?", env_has_key, 1);
6525  rb_define_singleton_method(envtbl, "has_value?", env_has_value, 1);
6526  rb_define_singleton_method(envtbl, "key?", env_has_key, 1);
6527  rb_define_singleton_method(envtbl, "value?", env_has_value, 1);
6528  rb_define_singleton_method(envtbl, "to_hash", env_f_to_hash, 0);
6529  rb_define_singleton_method(envtbl, "to_h", env_to_h, 0);
6530  rb_define_singleton_method(envtbl, "assoc", env_assoc, 1);
6531  rb_define_singleton_method(envtbl, "rassoc", env_rassoc, 1);
6532 
6533  /*
6534  * ENV is a Hash-like accessor for environment variables.
6535  *
6536  * See ENV (the class) for more details.
6537  */
6538  rb_define_global_const("ENV", envtbl);
6539 
6540  /* for callcc */
6541  ruby_register_rollback_func_for_ensure(hash_foreach_ensure, hash_foreach_ensure_rollback);
6542 
6543  HASH_ASSERT(sizeof(ar_hint_t) * RHASH_AR_TABLE_MAX_SIZE == sizeof(VALUE));
6544 }
rb_hash_st_table_set
void rb_hash_st_table_set(VALUE hash, st_table *st)
Definition: hash.c:558
equal_data::eql
int eql
Definition: hash.c:3550
st_foreach_safe
void st_foreach_safe(st_table *table, st_foreach_func *func, st_data_t a)
Definition: hash.c:1294
FLONUM_P
#define FLONUM_P(x)
Definition: ruby.h:430
rehash_arg::hash
VALUE hash
Definition: hash.c:1916
rb_ary_new_capa
VALUE rb_ary_new_capa(long capa)
Definition: array.c:717
rb_hash_update_func
VALUE rb_hash_update_func(VALUE newkey, VALUE oldkey, VALUE value)
Definition: intern.h:573
rb_transient_heap_managed_ptr_p
int rb_transient_heap_managed_ptr_p(const void *ptr)
Definition: transient_heap.c:506
rb_str_ellipsize
VALUE rb_str_ellipsize(VALUE, long)
Shortens str and adds three dots, an ellipsis, if it is longer than len characters.
Definition: string.c:10185
i
uint32_t i
Definition: rb_mjit_min_header-2.7.1.h:5425
rb_proc_lambda_p
VALUE rb_proc_lambda_p(VALUE)
Definition: proc.c:275
UNLIKELY
#define UNLIKELY(x)
Definition: ffi_common.h:126
ID
unsigned long ID
Definition: ruby.h:103
rb_to_hash_type
VALUE rb_to_hash_type(VALUE hash)
Definition: hash.c:1840
ruby_xfree
void ruby_xfree(void *x)
Definition: gc.c:10169
rb_define_class
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:649
equal_data
Definition: hash.c:3547
RHASH_PROC_DEFAULT
@ RHASH_PROC_DEFAULT
Definition: internal.h:819
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.1.h:5703
rb_hash_keep_if
VALUE rb_hash_keep_if(VALUE hash)
Definition: hash.c:2736
rb_raw_obj_info
const char * rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
Definition: gc.c:11438
rb_fstring
VALUE rb_fstring(VALUE)
Definition: string.c:312
STATIC_SYM_P
#define STATIC_SYM_P(x)
Definition: ruby.h:411
Check_Type
#define Check_Type(v, t)
Definition: ruby.h:595
TRUE
#define TRUE
Definition: nkf.h:175
rb_hash_tbl_raw
MJIT_FUNC_EXPORTED struct st_table * rb_hash_tbl_raw(VALUE hash)
Definition: hash.c:1589
rb_check_convert_type_with_id
VALUE rb_check_convert_type_with_id(VALUE, int, const char *, ID)
Definition: object.c:2957
long
#define long
Definition: rb_mjit_min_header-2.7.1.h:2848
rb_block_arity
int rb_block_arity(void)
Definition: proc.c:1144
st_foreach_with_replace
int st_foreach_with_replace(st_table *tab, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
Definition: st.c:1700
T_FLOAT
#define T_FLOAT
Definition: ruby.h:527
rb_include_module
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:869
RHASH_AR_TABLE_MAX_SIZE
#define RHASH_AR_TABLE_MAX_SIZE
Definition: internal.h:821
st_update_callback_func
int st_update_callback_func(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
Definition: st.h:131
rb_assoc_new
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:896
st_copy
st_table * st_copy(st_table *old_tab)
Definition: st.c:1320
rb_str_new2
#define rb_str_new2
Definition: intern.h:903
rb_enc_name
#define rb_enc_name(enc)
Definition: encoding.h:177
rb_filesystem_encoding
rb_encoding * rb_filesystem_encoding(void)
Definition: encoding.c:1387
rb_str_hash
st_index_t rb_str_hash(VALUE)
Definition: string.c:3163
hash_foreach_arg::hash
VALUE hash
Definition: hash.c:1309
rehash_arg
Definition: hash.c:1915
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.1.h:13179
update_callback_arg
Definition: hash.c:1615
st_data_t
unsigned long st_data_t
Definition: rb_mjit_min_header-2.7.1.h:5324
foreach_safe_arg::tbl
st_table * tbl
Definition: hash.c:1274
st_table::num_entries
st_index_t num_entries
Definition: st.h:86
env
#define env
FIX2INT
#define FIX2INT(x)
Definition: ruby.h:717
update_arg::old_value
VALUE old_value
Definition: hash.c:1640
rb_class_has_methods
int rb_class_has_methods(VALUE c)
Definition: class.c:2201
rb_ident_hash_new
VALUE rb_ident_hash_new(void)
Definition: hash.c:4272
rb_hash_new
VALUE rb_hash_new(void)
Definition: hash.c:1523
rb_hash_st_table
st_table * rb_hash_st_table(VALUE hash)
Definition: hash.c:551
ST_CHECK
@ ST_CHECK
Definition: st.h:99
rb_hash_resurrect
MJIT_FUNC_EXPORTED VALUE rb_hash_resurrect(VALUE hash)
Definition: hash.c:1570
rb_str_buf_cat2
#define rb_str_buf_cat2
Definition: intern.h:911
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:313
HASH_ASSERT
#define HASH_ASSERT(expr)
Definition: hash.c:435
rb_block_given_p
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:898
update_arg::arg
st_data_t arg
Definition: hash.c:1635
RHASH_ST_CLEAR
#define RHASH_ST_CLEAR(h)
Definition: internal.h:862
uint64_t
#define uint64_t
Definition: siphash.h:15
rb_hash_values
VALUE rb_hash_values(VALUE hash)
Definition: hash.c:3450
rb_warning
void rb_warning(const char *fmt,...)
Definition: error.c:334
RSHIFT
#define RSHIFT(x, y)
Definition: rb_mjit_min_header-2.7.1.h:408
rb_hash_size_num
size_t rb_hash_size_num(VALUE hash)
Definition: hash.c:2940
gc.h
RBASIC_CLEAR_CLASS
#define RBASIC_CLEAR_CLASS(obj)
Definition: internal.h:1986
ST_STOP
@ ST_STOP
Definition: st.h:99
rb_str_buf_cat_ascii
VALUE rb_str_buf_cat_ascii(VALUE, const char *)
Definition: string.c:2926
update_arg::hash
VALUE hash
Definition: hash.c:1636
idEqq
@ idEqq
Definition: id.h:97
rb_funcall
#define rb_funcall(recv, mid, argc,...)
Definition: rb_mjit_min_header-2.7.1.h:6546
rb_gc_force_recycle
void rb_gc_force_recycle(VALUE obj)
Definition: gc.c:7013
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
rb_make_internal_id
ID rb_make_internal_id(void)
Definition: symbol.c:810
n
const char size_t n
Definition: rb_mjit_min_header-2.7.1.h:5417
rb_hash_clear
VALUE rb_hash_clear(VALUE hash)
Definition: hash.c:2764
fopen
FILE * fopen(const char *__restrict _name, const char *__restrict _type)
RHASH_UPDATE_ITER
#define RHASH_UPDATE_ITER(h, iter_lev, key, func, a)
Definition: hash.c:1685
strchr
char * strchr(char *, char)
RHASH_SET_TRANSIENT_FLAG
#define RHASH_SET_TRANSIENT_FLAG(h)
Definition: internal.h:871
st_hash
st_index_t st_hash(const void *ptr, size_t len, st_index_t h)
Definition: st.c:1897
ruby_xmalloc
void * ruby_xmalloc(size_t size)
Definition: gc.c:11969
rb_hash_default_value
VALUE rb_hash_default_value(VALUE hash, VALUE key)
Definition: hash.c:1985
st
enum ruby_tag_type st
Definition: rb_mjit_min_header-2.7.1.h:11036
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:1009
NUM2LONG
#define NUM2LONG(x)
Definition: ruby.h:679
st_shift
int st_shift(st_table *tab, st_data_t *key, st_data_t *value)
Definition: st.c:1440
rb_hash_reject
VALUE rb_hash_reject(VALUE hash)
Definition: hash.c:2545
rb_hash_aref
VALUE rb_hash_aref(VALUE hash, VALUE key)
Definition: hash.c:2032
EINVAL
#define EINVAL
Definition: rb_mjit_min_header-2.7.1.h:10884
rb_equal
VALUE rb_equal(VALUE, VALUE)
Same as Object#===, case equality.
Definition: object.c:124
rb_locale_encoding
rb_encoding * rb_locale_encoding(void)
Definition: encoding.c:1372
RUBY_SPECIAL_SHIFT
@ RUBY_SPECIAL_SHIFT
Definition: ruby.h:460
VALUE
unsigned long VALUE
Definition: ruby.h:102
rb_hash_size
VALUE rb_hash_size(VALUE hash)
Definition: hash.c:2934
rb_eArgError
VALUE rb_eArgError
Definition: error.c:923
encoding.h
ruby_verbose
#define ruby_verbose
Definition: ruby.h:1925
st_foreach_check
int st_foreach_check(st_table *tab, st_foreach_check_callback_func *func, st_data_t arg, st_data_t never ATTRIBUTE_UNUSED)
Definition: st.c:1726
st_delete
int st_delete(st_table *tab, st_data_t *key, st_data_t *value)
Definition: st.c:1418
RB_TYPE_P
#define RB_TYPE_P(obj, type)
Definition: ruby.h:560
hash_foreach_arg
Definition: generator.c:722
shift_var
Definition: hash.c:2390
setenv
int setenv(const char *__string, const char *__value, int __overwrite)
ENVNMATCH
#define ENVNMATCH(s1, s2, n)
Definition: hash.c:4648
update_arg::new_key
VALUE new_key
Definition: hash.c:1637
rb_enc_get
rb_encoding * rb_enc_get(VALUE obj)
Definition: encoding.c:872
st_add_direct
void st_add_direct(st_table *tab, st_data_t key, st_data_t value)
Definition: st.c:1251
id_yield
ID id_yield
Definition: eventids1.c:136
rb_enc_asciicompat
#define rb_enc_asciicompat(enc)
Definition: encoding.h:245
update_func_arg::func
rb_hash_update_func * func
Definition: hash.c:3869
rb_obj_hash
VALUE rb_obj_hash(VALUE obj)
Definition: hash.c:291
rb_float_value
double rb_float_value(VALUE v)
Definition: numeric.c:5834
ECONV_UNDEF_REPLACE
#define ECONV_UNDEF_REPLACE
Definition: encoding.h:396
RUBY_DTRACE_CREATE_HOOK
#define RUBY_DTRACE_CREATE_HOOK(name, arg)
Definition: internal.h:2589
st_retval
st_retval
Definition: st.h:99
NORETURN
NORETURN(static void no_new_key(void))
id.h
getenv
#define getenv(name)
Definition: win32.c:73
RSYMBOL
#define RSYMBOL(obj)
Definition: symbol.h:33
uint64_t
unsigned long long uint64_t
Definition: sha2.h:102
rb_inspect
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
Definition: object.c:551
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.1.h:5562
shift_var::val
VALUE val
Definition: hash.c:2392
rb_hash_lookup2
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
Definition: hash.c:2045
rb_check_string_type
VALUE rb_check_string_type(VALUE)
Definition: string.c:2314
getpid
pid_t getpid(void)
Qundef
#define Qundef
Definition: ruby.h:470
rb_define_singleton_method
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1755
CHAR_BIT
#define CHAR_BIT
Definition: ruby.h:227
RHASH_ST_TABLE_FLAG
@ RHASH_ST_TABLE_FLAG
Definition: internal.h:820
rb_define_method
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1551
rb_hash_update_by
VALUE rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func)
Definition: hash.c:3904
rb_proc_arity
int rb_proc_arity(VALUE)
Definition: proc.c:1112
rb_hash_keys
MJIT_FUNC_EXPORTED VALUE rb_hash_keys(VALUE hash)
Definition: hash.c:3403
RHASH_AR_TABLE_SIZE_INC
#define RHASH_AR_TABLE_SIZE_INC(h)
Definition: hash.c:607
ptr
struct RIMemo * ptr
Definition: debug.c:74
hash_verify
#define hash_verify(h)
Definition: hash.c:510
rb_str_new
#define rb_str_new(str, len)
Definition: rb_mjit_min_header-2.7.1.h:6077
T_DATA
#define T_DATA
Definition: ruby.h:538
rb_obj_id
VALUE rb_obj_id(VALUE obj)
Definition: gc.c:3772
Qfalse
#define Qfalse
Definition: ruby.h:467
rb_hash_rassoc
VALUE rb_hash_rassoc(VALUE hash, VALUE obj)
Definition: hash.c:4072
update_func_arg::value
VALUE value
Definition: hash.c:3868
RETURN_SIZED_ENUMERATOR
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
Definition: intern.h:271
rb_hash_dup
VALUE rb_hash_dup(VALUE hash)
Definition: hash.c:1559
ar_table_pair
struct ar_table_pair_struct ar_table_pair
RB_OBJ_FROZEN
#define RB_OBJ_FROZEN(x)
Definition: ruby.h:1342
rb_hash_assoc
VALUE rb_hash_assoc(VALUE hash, VALUE key)
Definition: hash.c:4011
rb_hash_stlike_lookup
MJIT_FUNC_EXPORTED int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval)
Definition: hash.c:2012
keys
const rb_iseq_t const char const VALUE keys
Definition: rb_mjit_min_header-2.7.1.h:13428
rb_ary_delete
VALUE rb_ary_delete(VALUE ary, VALUE item)
Definition: array.c:3365
unsetenv
int unsetenv(const char *)
SPECIAL_CONST_P
#define SPECIAL_CONST_P(x)
Definition: ruby.h:1313
rb_hash_select_bang
VALUE rb_hash_select_bang(VALUE hash)
Definition: hash.c:2709
st.h
NULL
#define NULL
Definition: _sdbm.c:101
ST_DELETE
@ ST_DELETE
Definition: st.h:99
uint32_t
unsigned int uint32_t
Definition: sha2.h:101
SafeStringValue
#define SafeStringValue(v)
Definition: ruby.h:607
FL_TEST
#define FL_TEST(x, f)
Definition: ruby.h:1353
functor
Definition: hash.c:909
FL_WB_PROTECTED
#define FL_WB_PROTECTED
Definition: ruby.h:1279
PRIsVALUE
#define PRIsVALUE
Definition: ruby.h:166
rb_init_identtable
st_table * rb_init_identtable(void)
Definition: hash.c:4280
rb_hash_ar_table_p
int rb_hash_ar_table_p(VALUE hash)
Definition: hash.c:532
RHASH_AR_TABLE_SIZE_RAW
#define RHASH_AR_TABLE_SIZE_RAW(h)
Definition: internal.h:841
rb_str_cat_conv_enc_opts
VALUE rb_str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len, rb_encoding *from, int ecflags, VALUE ecopts)
Definition: string.c:943
hash_foreach_arg::arg
VALUE arg
Definition: hash.c:1311
RHASH_AR_TABLE_SIZE
#define RHASH_AR_TABLE_SIZE(h)
Definition: hash.c:422
st_insert
int st_insert(st_table *tab, st_data_t key, st_data_t value)
Definition: st.c:1171
FIX2LONG
#define FIX2LONG(x)
Definition: ruby.h:394
strlen
size_t strlen(const char *)
rb_hash_bulk_insert_into_st_table
void rb_hash_bulk_insert_into_st_table(long, const VALUE *, VALUE)
Definition: st.c:2380
T_SYMBOL
#define T_SYMBOL
Definition: ruby.h:540
rb_hash_set_default_proc
VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc)
Definition: hash.c:2237
rb_ascii8bit_encindex
int rb_ascii8bit_encindex(void)
Definition: encoding.c:1322
foreach_safe_arg::arg
st_data_t arg
Definition: hash.c:1276
rb_big_hash
VALUE rb_big_hash(VALUE x)
Definition: bignum.c:6726
rb_define_alias
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1800
L
#define L(x)
Definition: asm.h:125
rb_respond_to
int rb_respond_to(VALUE, ID)
Definition: vm_method.c:2190
RB_BLOCK_CALL_FUNC_ARGLIST
#define RB_BLOCK_CALL_FUNC_ARGLIST(yielded_arg, callback_arg)
Definition: ruby.h:1964
rb_protect
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *pstate)
Protects a function call from potential global escapes from the function.
Definition: eval.c:1072
rb_check_arity
#define rb_check_arity
Definition: intern.h:347
rb_eql
int rb_eql(VALUE, VALUE)
Determines if obj1 and obj2 are equal in terms of Object::eql?.
Definition: object.c:147
rb_memhash
st_index_t rb_memhash(const void *ptr, long len)
Definition: random.c:1440
rb_hash_new_with_size
MJIT_FUNC_EXPORTED VALUE rb_hash_new_with_size(st_index_t size)
Definition: hash.c:1529
ALLOC_N
#define ALLOC_N(type, n)
Definition: ruby.h:1663
rb_hash_has_key
MJIT_FUNC_EXPORTED VALUE rb_hash_has_key(VALUE hash, VALUE key)
Definition: hash.c:3501
RHASH_AR_TABLE_BOUND
#define RHASH_AR_TABLE_BOUND(h)
Definition: hash.c:429
UNLIMITED_ARGUMENTS
#define UNLIMITED_ARGUMENTS
Definition: intern.h:57
rb_str_fill_terminator
char * rb_str_fill_terminator(VALUE str, const int termlen)
Definition: string.c:2306
st_init_table_with_size
st_table * st_init_table_with_size(const struct st_hash_type *type, st_index_t size)
Definition: st.c:577
rb_hash_delete_entry
VALUE rb_hash_delete_entry(VALUE hash, VALUE key)
Definition: hash.c:2321
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2669
rb_str_hash_cmp
int rb_str_hash_cmp(VALUE, VALUE)
Definition: string.c:3173
rb_ivar_get
VALUE rb_ivar_get(VALUE, ID)
Definition: variable.c:1070
if
if((ID)(DISPID) nameid !=nameid)
Definition: win32ole.c:357
reset_hash_type_arg::hash
VALUE hash
Definition: hash.c:3971
rb_ivar_set_internal
void rb_ivar_set_internal(VALUE obj, ID id, VALUE val)
Definition: variable.c:1308
rb_hash_stlike_update
int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func func, st_data_t arg)
Definition: hash.c:1646
rb_ident_cmp
#define rb_ident_cmp
Definition: hash.c:302
rb_obj_class
VALUE rb_obj_class(VALUE)
Equivalent to Object#class in Ruby.
Definition: object.c:217
rb_integer_pack
int rb_integer_pack(VALUE val, void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
Definition: bignum.c:3547
probes.h
update_callback_arg::arg
st_data_t arg
Definition: hash.c:1617
rb_hash_add_new_element
int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:4541
NOINLINE
NOINLINE(static int ar_equal(VALUE x, VALUE y))
rb_obj_is_proc
VALUE rb_obj_is_proc(VALUE)
Definition: proc.c:152
rb_obj_info
const MJIT_FUNC_EXPORTED char * rb_obj_info(VALUE obj)
Definition: gc.c:11674
PRIuSIZE
#define PRIuSIZE
Definition: ruby.h:208
st_foreach_check_callback_func
int st_foreach_check_callback_func(st_data_t, st_data_t, st_data_t, int)
Definition: st.h:138
ST_REPLACE
@ ST_REPLACE
Definition: st.h:99
OBJ_WB_UNPROTECT
#define OBJ_WB_UNPROTECT(x)
Definition: ruby.h:1495
RHASH_UNSET_TRANSIENT_FLAG
#define RHASH_UNSET_TRANSIENT_FLAG(h)
Definition: internal.h:872
rb_hash_rehash
VALUE rb_hash_rehash(VALUE hash)
Definition: hash.c:1953
st_clear
void st_clear(st_table *tab)
Definition: st.c:698
rb_encoding
const typedef OnigEncodingType rb_encoding
Definition: encoding.h:115
ALLOCV_END
#define ALLOCV_END(v)
Definition: ruby.h:1750
rb_check_frozen
#define rb_check_frozen(obj)
Definition: intern.h:319
rb_hash_transient_heap_evacuate
void rb_hash_transient_heap_evacuate(VALUE hash, int promote)
Definition: hash.c:1244
RHASH_SIZE
#define RHASH_SIZE(hsh)
Definition: fbuffer.h:8
rb_ary_includes
VALUE rb_ary_includes(VALUE ary, VALUE item)
Definition: array.c:4340
rb_hash_compare_by_id_p
MJIT_FUNC_EXPORTED VALUE rb_hash_compare_by_id_p(VALUE hash)
Definition: hash.c:4261
rb_obj_dig
VALUE rb_obj_dig(int argc, VALUE *argv, VALUE self, VALUE notfound)
Definition: object.c:3791
foreach_safe_arg::func
st_foreach_func * func
Definition: hash.c:1275
rb_convert_type_with_id
VALUE rb_convert_type_with_id(VALUE, int, const char *, ID)
Definition: object.c:2914
ALLOCV_N
#define ALLOCV_N(type, v, n)
Definition: ruby.h:1749
reset_hash_type_arg
Definition: hash.c:3970
rb_ary_cat
VALUE rb_ary_cat(VALUE ary, const VALUE *argv, long len)
Definition: array.c:1208
rb_hash_stlike_delete
int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval)
Definition: hash.c:2305
NOINSERT_UPDATE_CALLBACK
#define NOINSERT_UPDATE_CALLBACK(func)
Definition: hash.c:1620
st_foreach_callback_func
int st_foreach_callback_func(st_data_t, st_data_t, st_data_t)
Definition: st.h:137
functor::func
st_foreach_callback_func * func
Definition: hash.c:910
rb_hash_ar_table_size
size_t rb_hash_ar_table_size(void)
Definition: hash.c:355
rb_hash_values_at
VALUE rb_hash_values_at(int argc, VALUE *argv, VALUE hash)
Definition: hash.c:2607
FL_EXIVAR
#define FL_EXIVAR
Definition: ruby.h:1286
h
size_t st_index_t h
Definition: rb_mjit_min_header-2.7.1.h:5423
RB_OBJ_WRITTEN
#define RB_OBJ_WRITTEN(a, oldv, b)
Definition: ruby.h:1509
RHASH_EMPTY_P
#define RHASH_EMPTY_P(h)
Definition: ruby.h:1131
rb_method_basic_definition_p
#define rb_method_basic_definition_p(klass, mid)
Definition: rb_mjit_min_header-2.7.1.h:7827
st_data_t
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: st.h:22
rb_hash_tbl
struct st_table * rb_hash_tbl(VALUE hash, const char *file, int line)
Definition: hash.c:1596
RHASH_LEV_MASK
#define RHASH_LEV_MASK
Definition: internal.h:828
rb_hash_fetch_values
VALUE rb_hash_fetch_values(int argc, VALUE *argv, VALUE hash)
Definition: hash.c:2635
rb_hash_delete_if
VALUE rb_hash_delete_if(VALUE hash)
Definition: hash.c:2488
rb_hash_lookup
VALUE rb_hash_lookup(VALUE hash, VALUE key)
Definition: hash.c:2058
bin
char bin[32]
Definition: siphash.c:135
rb_ary_push
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:1195
st_index_t
st_data_t st_index_t
Definition: st.h:50
st_hash_type
Definition: st.h:61
cnt
rb_atomic_t cnt[RUBY_NSIG]
Definition: signal.c:503
rb_hash_start
st_index_t rb_hash_start(st_index_t)
Definition: random.c:1434
transient_heap.h
rb_obj_freeze
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
Definition: object.c:1080
RHASH_IFNONE
#define RHASH_IFNONE(h)
Definition: ruby.h:1129
malloc
void * malloc(size_t) __attribute__((__malloc__)) __attribute__((__warn_unused_result__)) __attribute__((__alloc_size__(1)))
st_hash_type::compare
int(* compare)(st_data_t, st_data_t)
Definition: st.h:62
rb_hash_bulk_insert
void rb_hash_bulk_insert(long argc, const VALUE *argv, VALUE hash)
Definition: hash.c:4584
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:922
RHASH_PASS_AS_KEYWORDS
@ RHASH_PASS_AS_KEYWORDS
Definition: internal.h:818
RBASIC_CLASS
#define RBASIC_CLASS(obj)
Definition: ruby.h:906
rb_copy_generic_ivar
void rb_copy_generic_ivar(VALUE, VALUE)
Definition: variable.c:1447
rb_ary_set_len
void rb_ary_set_len(VALUE ary, long len)
Definition: array.c:1932
INTEGER_PACK_NATIVE_BYTE_ORDER
#define INTEGER_PACK_NATIVE_BYTE_ORDER
Definition: intern.h:155
rb_eRuntimeError
VALUE rb_eRuntimeError
Definition: error.c:920
RARRAY_AREF
#define RARRAY_AREF(a, i)
Definition: ruby.h:1101
RHASH_TRANSIENT_P
#define RHASH_TRANSIENT_P(hash)
Definition: internal.h:870
rb_transient_heap_alloc
void * rb_transient_heap_alloc(VALUE obj, size_t req_size)
Definition: transient_heap.c:359
rb_enc_copy
void rb_enc_copy(VALUE obj1, VALUE obj2)
Definition: encoding.c:990
symbol.h
size
int size
Definition: encoding.c:58
FALSE
#define FALSE
Definition: nkf.h:174
FIXNUM_P
#define FIXNUM_P(f)
Definition: ruby.h:396
RCLASS_SUPER
#define RCLASS_SUPER(c)
Definition: classext.h:16
RHASH_AR_TABLE_BOUND_MASK
#define RHASH_AR_TABLE_BOUND_MASK
Definition: internal.h:866
rb_to_int
VALUE rb_to_int(VALUE)
Converts val into Integer.
Definition: object.c:3021
rb_env_clear
VALUE rb_env_clear(void)
Definition: hash.c:5622
rb_gc_writebarrier_remember
MJIT_FUNC_EXPORTED void rb_gc_writebarrier_remember(VALUE obj)
Definition: gc.c:6877
rb_hash_foreach
void rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
Definition: hash.c:1483
FL_SET_RAW
#define FL_SET_RAW(x, f)
Definition: ruby.h:1358
rb_str_new_frozen
VALUE rb_str_new_frozen(VALUE)
Definition: string.c:1203
RHash::basic
struct RBasic basic
Definition: internal.h:888
putenv
int putenv(char *__string)
RHASH
#define RHASH(obj)
Definition: internal.h:859
rb_default_internal_encoding
rb_encoding * rb_default_internal_encoding(void)
Definition: encoding.c:1512
rb_w32_ugetenv
char * rb_w32_ugetenv(const char *)
Definition: win32.c:5230
RB_OBJ_WRITE
#define RB_OBJ_WRITE(a, slot, b)
Definition: ruby.h:1508
ar_table
struct ar_table_struct ar_table
st_update
int st_update(st_table *tab, st_data_t key, st_update_callback_func *func, st_data_t arg)
Definition: st.c:1510
rb_extend_object
void rb_extend_object(VALUE obj, VALUE module)
Extend the object with the module.
Definition: eval.c:1701
rb_cHash
VALUE rb_cHash
Definition: hash.c:92
index
int index
Definition: rb_mjit_min_header-2.7.1.h:11171
rb_check_array_type
VALUE rb_check_array_type(VALUE ary)
Definition: array.c:909
ID_SCOPE_SHIFT
#define ID_SCOPE_SHIFT
Definition: id.h:31
key
key
Definition: openssl_missing.h:181
T_HASH
#define T_HASH
Definition: ruby.h:531
rb_yield_values2
VALUE rb_yield_values2(int n, const VALUE *argv)
Definition: vm_eval.c:1271
RHASH_ST_TABLE_P
#define RHASH_ST_TABLE_P(h)
Definition: internal.h:861
memchr
void * memchr(const void *, int, size_t)
rb_hashtype_ident
const struct st_hash_type rb_hashtype_ident
Definition: hash.c:322
rb_hash_set_pair
VALUE rb_hash_set_pair(VALUE hash, VALUE arg)
Definition: hash.c:3326
RHash
Definition: internal.h:887
CLASS_OF
#define CLASS_OF(v)
Definition: ruby.h:484
rb_str_buf_append
VALUE rb_str_buf_append(VALUE, VALUE)
Definition: string.c:2950
idTo_proc
@ idTo_proc
Definition: rb_mjit_min_header-2.7.1.h:8645
rb_exec_recursive_outer
VALUE rb_exec_recursive_outer(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:5098
rb_yield_values
#define rb_yield_values(argc,...)
Definition: rb_mjit_min_header-2.7.1.h:6545
st_values
st_index_t st_values(st_table *tab, st_data_t *values, st_index_t size)
Definition: st.c:1795
crt_externs.h
RARRAY_LEN
#define RARRAY_LEN(a)
Definition: ruby.h:1070
st_foreach
int st_foreach(st_table *tab, st_foreach_callback_func *func, st_data_t arg)
Definition: st.c:1718
RHASH_AR_TABLE
#define RHASH_AR_TABLE(hash)
Definition: internal.h:855
RHASH_ST_TABLE_SET
#define RHASH_ST_TABLE_SET(h, s)
Definition: hash.c:432
rb_check_hash_type
VALUE rb_check_hash_type(VALUE hash)
Definition: hash.c:1847
PATH_ENV
#define PATH_ENV
Definition: defines.h:441
RHASH_AR_TABLE_BOUND_SHIFT
#define RHASH_AR_TABLE_BOUND_SHIFT
Definition: internal.h:867
FL_TEST_RAW
#define FL_TEST_RAW(x, f)
Definition: ruby.h:1352
rb_cObject
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:2010
rb_ary_new2
#define rb_ary_new2
Definition: intern.h:103
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4322
rb_func_proc_new
VALUE rb_func_proc_new(rb_block_call_func_t func, VALUE val)
Definition: proc.c:728
T_BIGNUM
#define T_BIGNUM
Definition: ruby.h:533
rb_foreach_func
int rb_foreach_func(VALUE, VALUE, VALUE)
Definition: hash.c:1306
rb_bug
void rb_bug(const char *fmt,...)
Definition: error.c:634
foreach_safe_arg
Definition: hash.c:1273
internal.h
update_func_arg
Definition: hash.c:3866
error
const rb_iseq_t const char * error
Definition: rb_mjit_min_header-2.7.1.h:13428
argv
char ** argv
Definition: ruby.c:223
f
#define f
RHASH_ST_TABLE
#define RHASH_ST_TABLE(hash)
Definition: internal.h:856
update_arg::new_value
VALUE new_value
Definition: hash.c:1639
ar_table_pair_struct::val
VALUE val
Definition: hash.c:346
rb_define_global_const
void rb_define_global_const(const char *, VALUE)
Definition: variable.c:2892
ST_CONTINUE
@ ST_CONTINUE
Definition: st.h:99
ruby_setenv
void ruby_setenv(const char *name, const char *value)
Definition: hash.c:4992
st_init_table
st_table * st_init_table(const struct st_hash_type *type)
Definition: st.c:645
rb_hash_uint
#define rb_hash_uint(h, i)
Definition: intern.h:815
id_hash
ID id_hash
Definition: eventids1.c:53
st_keys
st_index_t st_keys(st_table *tab, st_data_t *keys, st_index_t size)
Definition: st.c:1757
rb_w32_osver
DWORD rb_w32_osver(void)
Definition: win32.c:319
rb_warn_deprecated
void rb_warn_deprecated(const char *fmt, const char *suggest,...)
Definition: error.c:364
rb_sprintf
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1197
rb_utf8_encoding
rb_encoding * rb_utf8_encoding(void)
Definition: encoding.c:1328
rb_hash
VALUE rb_hash(VALUE obj)
Definition: hash.c:129
rb_obj_alloc
VALUE rb_obj_alloc(VALUE)
Allocates an instance of klass.
Definition: object.c:1895
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
shift_var::key
VALUE key
Definition: hash.c:2391
st_index_hash
#define st_index_hash(index)
Definition: hash.c:265
RGENGC_WB_PROTECTED_HASH
#define RGENGC_WB_PROTECTED_HASH
Definition: ruby.h:805
rb_hash_end
#define rb_hash_end(h)
Definition: intern.h:816
ruby_register_rollback_func_for_ensure
void ruby_register_rollback_func_for_ensure(e_proc *ensure_func, e_proc *rollback_func)
Definition: cont.c:1535
ar_hint_t
unsigned char ar_hint_t
Definition: rb_mjit_min_header-2.7.1.h:6833
debug_counter.h
env_name
#define env_name(s)
Definition: hash.c:4756
functor::arg
st_data_t arg
Definition: hash.c:911
st_table::type
const struct st_hash_type * type
Definition: st.h:84
rb_locale_encindex
int rb_locale_encindex(void)
Definition: encoding.c:1354
rb_hash_aset
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:2847
int
__inline__ int
Definition: rb_mjit_min_header-2.7.1.h:2807
rb_cString
RUBY_EXTERN VALUE rb_cString
Definition: ruby.h:2044
RHASH_SET_IFNONE
#define RHASH_SET_IFNONE(h, ifnone)
Definition: ruby.h:1132
update_arg::old_key
VALUE old_key
Definition: hash.c:1638
rb_obj_info_dump
void rb_obj_info_dump(VALUE obj)
Definition: gc.c:11680
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
rb_hash_delete
VALUE rb_hash_delete(VALUE hash, VALUE key)
Definition: hash.c:2339
snprintf
int snprintf(char *__restrict, size_t, const char *__restrict,...) __attribute__((__format__(__printf__
fail
#define fail()
Definition: date_strptime.c:123
to_hash
#define to_hash
Definition: hash.c:1844
identhash
#define identhash
Definition: hash.c:321
rb_external_str_new_with_enc
VALUE rb_external_str_new_with_enc(const char *ptr, long len, rb_encoding *)
Definition: string.c:1036
argc
int argc
Definition: ruby.c:222
rb_str_initialize
VALUE rb_str_initialize(VALUE str, const char *ptr, long len, rb_encoding *enc)
Definition: string.c:964
rb_exec_recursive
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:5075
rb_obj_classname
const char * rb_obj_classname(VALUE)
Definition: variable.c:289
rb_sys_fail_str
void rb_sys_fail_str(VALUE mesg)
Definition: error.c:2799
rb_hash_fetch
VALUE rb_hash_fetch(VALUE hash, VALUE key)
Definition: hash.c:2129
REALLOC_N
#define REALLOC_N(var, type, n)
Definition: ruby.h:1667
GET_ENVIRON
#define GET_ENVIRON(e)
Definition: hash.c:4640
free
#define free(x)
Definition: dln.c:52
RHASH_ITER_LEV
#define RHASH_ITER_LEV(h)
Definition: ruby.h:1128
recur
#define recur(fmt)
Definition: date_strptime.c:152
RHASH_LEV_SHIFT
@ RHASH_LEV_SHIFT
Definition: internal.h:835
update_callback_arg::hash
VALUE hash
Definition: hash.c:1616
BUILTIN_TYPE
#define BUILTIN_TYPE(x)
Definition: ruby.h:551
xfree
#define xfree
Definition: defines.h:216
v
int VALUE v
Definition: rb_mjit_min_header-2.7.1.h:12257
RBASIC
#define RBASIC(obj)
Definition: ruby.h:1267
RHASH_TYPE
#define RHASH_TYPE(hash)
Definition: hash.c:433
ruby_strdup
char * ruby_strdup(const char *)
Definition: util.c:527
ar_table_struct::pairs
ar_table_pair pairs[RHASH_AR_TABLE_MAX_SIZE]
Definition: hash.c:351
SET_PROC_DEFAULT
#define SET_PROC_DEFAULT(hash, proc)
Definition: hash.c:50
st_hash_t
st_index_t st_hash_t
Definition: hash.c:327
RHASH_AR_TABLE_BOUND_RAW
#define RHASH_AR_TABLE_BOUND_RAW(h)
Definition: hash.c:425
FREE_ENVIRON
#define FREE_ENVIRON(e)
Definition: hash.c:4641
st_foreach_func
int st_foreach_func(st_data_t, st_data_t, st_data_t)
Definition: hash.c:1271
MJIT_FUNC_EXPORTED
#define MJIT_FUNC_EXPORTED
Definition: defines.h:396
_
#define _(args)
Definition: dln.h:28
ar_table_struct
Definition: hash.c:349
Qtrue
#define Qtrue
Definition: ruby.h:468
rb_hash_set_ifnone
VALUE rb_hash_set_ifnone(VALUE hash, VALUE ifnone)
Definition: hash.c:99
ruby_tz_uptodate_p
bool ruby_tz_uptodate_p
Definition: time.c:674
update_func_arg::hash
VALUE hash
Definition: hash.c:3867
HAS_EXTRA_STATES
#define HAS_EXTRA_STATES(hash, klass)
Definition: hash.c:41
equal_data::result
VALUE result
Definition: hash.c:3548
len
uint8_t len
Definition: escape.c:17
SYMBOL_P
#define SYMBOL_P(x)
Definition: ruby.h:413
rb_hash_ar_table
ar_table * rb_hash_ar_table(VALUE hash)
Definition: hash.c:544
RB_DEBUG_COUNTER_INC
#define RB_DEBUG_COUNTER_INC(type)
Definition: debug_counter.h:375
rb_usascii_str_new2
#define rb_usascii_str_new2
Definition: intern.h:909
NUM2LL
#define NUM2LL(x)
tbl_update_func
int(* tbl_update_func)(st_data_t *, st_data_t *, st_data_t, int)
Definition: hash.c:1643
idTo_hash
@ idTo_hash
Definition: rb_mjit_min_header-2.7.1.h:8644
rb_exec_recursive_paired
VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE, VALUE)
Definition: thread.c:5086
LONG2FIX
#define LONG2FIX(i)
Definition: ruby.h:265
T_STRING
#define T_STRING
Definition: ruby.h:528
rb_hash_key_str
VALUE rb_hash_key_str(VALUE key)
Definition: hash.c:2797
MAYBE_UNUSED
#define MAYBE_UNUSED
Definition: ffi_common.h:32
rb_hash_stlike_foreach_with_replace
int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
Definition: hash.c:1453
rb_hash_select
VALUE rb_hash_select(VALUE hash)
Definition: hash.c:2674
hash_foreach_arg::func
rb_foreach_func * func
Definition: hash.c:1310
strncmp
int strncmp(const char *, const char *, size_t)
RHASH_TBL_RAW
#define RHASH_TBL_RAW(h)
Definition: internal.h:1694
stderr
#define stderr
Definition: rb_mjit_min_header-2.7.1.h:1479
rb_yield
VALUE rb_yield(VALUE)
Definition: vm_eval.c:1237
reset_hash_type_arg::orighash
const struct st_hash_type * orighash
Definition: hash.c:3972
rb_hash_stlike_foreach
int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg)
Definition: hash.c:1442
SET_DEFAULT
#define SET_DEFAULT(hash, ifnone)
Definition: hash.c:46
update_arg
Definition: hash.c:1634
rb_ensure
VALUE rb_ensure(VALUE(*b_proc)(VALUE), VALUE data1, VALUE(*e_proc)(VALUE), VALUE data2)
An equivalent to ensure clause.
Definition: eval.c:1115
COPY_DEFAULT
#define COPY_DEFAULT(hash, hash2)
Definition: hash.c:52
ECONV_INVALID_REPLACE
#define ECONV_INVALID_REPLACE
Definition: encoding.h:394
rb_builtin_class_name
const char * rb_builtin_class_name(VALUE x)
Definition: error.c:797
ST2FIX
#define ST2FIX(h)
Definition: ruby_missing.h:21
rb_enc_str_asciionly_p
int rb_enc_str_asciionly_p(VALUE)
Definition: string.c:678
RHASH_AR_TABLE_SIZE_SHIFT
#define RHASH_AR_TABLE_SIZE_SHIFT
Definition: internal.h:865
RHASH_AR_TABLE_SIZE_MASK
#define RHASH_AR_TABLE_SIZE_MASK
Definition: internal.h:864
rb_ary_new
VALUE rb_ary_new(void)
Definition: array.c:723
NEWOBJ_OF
#define NEWOBJ_OF(obj, type, klass, flags)
Definition: ruby.h:785
NUM2INT
#define NUM2INT(x)
Definition: ruby.h:715
Qnil
#define Qnil
Definition: ruby.h:469
ar_table_pair_struct
Definition: hash.c:344
rehash_arg::tbl
st_table * tbl
Definition: hash.c:1917
rb_str_buf_cat
#define rb_str_buf_cat
Definition: intern.h:910
rb_hash_reject_bang
VALUE rb_hash_reject_bang(VALUE hash)
Definition: hash.c:2508
rb_w32_getenv
char * rb_w32_getenv(const char *)
Definition: win32.c:5237
rb_key_err_raise
#define rb_key_err_raise(mesg, recv, name)
Definition: internal.h:1580
rb_mEnumerable
VALUE rb_mEnumerable
Definition: enum.c:20
st_lookup
int st_lookup(st_table *tab, st_data_t key, st_data_t *value)
Definition: st.c:1101
util.h
ar_table_pair_struct::key
VALUE key
Definition: hash.c:345
ST_DATA_COMPATIBLE_P
#define ST_DATA_COMPATIBLE_P(type)
Definition: st.h:72
RB_FL_ANY_RAW
#define RB_FL_ANY_RAW(x, f)
Definition: ruby.h:1318
RB_GC_GUARD
#define RB_GC_GUARD(v)
Definition: ruby.h:585
environ
char ** environ
RARRAY_PTR_USE_TRANSIENT
#define RARRAY_PTR_USE_TRANSIENT(ary, ptr_name, expr)
Definition: ruby.h:1084
RHASH_AR_TABLE_MAX_BOUND
#define RHASH_AR_TABLE_MAX_BOUND
Definition: hash.c:339
rb_hash_freeze
VALUE rb_hash_freeze(VALUE hash)
Definition: hash.c:87
RSTRING_LEN
#define RSTRING_LEN(str)
Definition: ruby.h:1005
st_free_table
void st_free_table(st_table *tab)
Definition: st.c:709
st_table
Definition: st.h:79
RHASH_AR_TABLE_P
#define RHASH_AR_TABLE_P(hash)
Definition: internal.h:854
rb_str_conv_enc
VALUE rb_str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
Definition: string.c:1030
RHASH_UPDATE
#define RHASH_UPDATE(hash, key, func, arg)
Definition: hash.c:1689
ruby_assert.h
rb_intern
#define rb_intern(str)
rb_any_to_s
VALUE rb_any_to_s(VALUE)
Default implementation of #to_s.
Definition: object.c:527
equal_data::hash
VALUE hash
Definition: hash.c:3549
rb_enc_str_new
VALUE rb_enc_str_new(const char *, long, rb_encoding *)
Definition: string.c:796
rb_define_alloc_func
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
rb_dbl_long_hash
long rb_dbl_long_hash(double d)
Definition: hash.c:160
ruby_unsetenv
void ruby_unsetenv(const char *name)
Definition: hash.c:5131
ENVMATCH
#define ENVMATCH(n1, n2)
Definition: hash.c:4647
RTEST
#define RTEST(v)
Definition: ruby.h:481
fprintf
int fprintf(FILE *__restrict, const char *__restrict,...) __attribute__((__format__(__printf__
object_id
#define object_id
Definition: vm_method.c:31
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
rb_str_buf_new2
#define rb_str_buf_new2
Definition: intern.h:908
RHASH_AR_TABLE_REF
#define RHASH_AR_TABLE_REF(hash, n)
Definition: hash.c:341
RHASH_AR_CLEARED_HINT
#define RHASH_AR_CLEARED_HINT
Definition: hash.c:342
__sFILE
Definition: vsnprintf.c:169
get_env_ptr
#define get_env_ptr(var, val)
Definition: hash.c:4743
rb_env_path_tainted
int rb_env_path_tainted(void)
Definition: hash.c:4898
Init_Hash
void Init_Hash(void)
Definition: hash.c:6291
rb_syserr_fail_str
void rb_syserr_fail_str(int e, VALUE mesg)
Definition: error.c:2787
st_hash_type::hash
st_index_t(* hash)(st_data_t)
Definition: st.h:63
RHASH_LEV_MAX
@ RHASH_LEV_MAX
Definition: internal.h:836
name
const char * name
Definition: nkf.c:208
rb_funcallv
#define rb_funcallv(recv, mid, argc, argv)
Definition: rb_mjit_min_header-2.7.1.h:7826
rb_block_proc
VALUE rb_block_proc(void)
Definition: proc.c:837