Ruby  2.7.2p137(2020-10-01revision5445e0435260b449decf2ac16f9d09bae3cafe72)
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
322 const struct st_hash_type 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 {
348 
349 typedef struct ar_table_struct {
350  /* 64bit CPU: 8B * 2 * 8 = 128B */
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_copy(VALUE ret, VALUE hash)
1546 {
1547  if (!RHASH_EMPTY_P(hash)) {
1548  if (RHASH_AR_TABLE_P(hash))
1549  ar_copy(ret, hash);
1550  else if (RHASH_ST_TABLE_P(hash))
1552  }
1553  return ret;
1554 }
1555 
1556 static VALUE
1557 hash_dup(VALUE hash, VALUE klass, VALUE flags)
1558 {
1559  return hash_copy(hash_alloc_flags(klass, flags, RHASH_IFNONE(hash)),
1560  hash);
1561 }
1562 
1563 VALUE
1565 {
1566  const VALUE flags = RBASIC(hash)->flags;
1567  VALUE ret = hash_dup(hash, rb_obj_class(hash),
1568  flags & (FL_EXIVAR|RHASH_PROC_DEFAULT));
1569  if (flags & FL_EXIVAR)
1570  rb_copy_generic_ivar(ret, hash);
1571  return ret;
1572 }
1573 
1576 {
1577  VALUE ret = hash_dup(hash, rb_cHash, 0);
1578  return ret;
1579 }
1580 
1581 static void
1582 rb_hash_modify_check(VALUE hash)
1583 {
1585 }
1586 
1588 #if RHASH_CONVERT_TABLE_DEBUG
1589 rb_hash_tbl_raw(VALUE hash, const char *file, int line)
1590 {
1591  return ar_force_convert_table(hash, file, line);
1592 }
1593 #else
1595 {
1596  return ar_force_convert_table(hash, NULL, 0);
1597 }
1598 #endif
1599 
1600 struct st_table *
1601 rb_hash_tbl(VALUE hash, const char *file, int line)
1602 {
1603  OBJ_WB_UNPROTECT(hash);
1604  return RHASH_TBL_RAW(hash);
1605 }
1606 
1607 static void
1608 rb_hash_modify(VALUE hash)
1609 {
1610  rb_hash_modify_check(hash);
1611 }
1612 
1613 NORETURN(static void no_new_key(void));
1614 static void
1615 no_new_key(void)
1616 {
1617  rb_raise(rb_eRuntimeError, "can't add a new key into hash during iteration");
1618 }
1619 
1623 };
1624 
1625 #define NOINSERT_UPDATE_CALLBACK(func) \
1626 static int \
1627 func##_noinsert(st_data_t *key, st_data_t *val, st_data_t arg, int existing) \
1628 { \
1629  if (!existing) no_new_key(); \
1630  return func(key, val, (struct update_arg *)arg, existing); \
1631 } \
1632  \
1633 static int \
1634 func##_insert(st_data_t *key, st_data_t *val, st_data_t arg, int existing) \
1635 { \
1636  return func(key, val, (struct update_arg *)arg, existing); \
1637 }
1638 
1639 struct update_arg {
1646 };
1647 
1649 
1650 int
1652 {
1653  if (RHASH_AR_TABLE_P(hash)) {
1654  int result = ar_update(hash, (st_data_t)key, func, arg);
1655  if (result == -1) {
1656  ar_try_convert_table(hash);
1657  }
1658  else {
1659  return result;
1660  }
1661  }
1662 
1663  return st_update(RHASH_ST_TABLE(hash), (st_data_t)key, func, arg);
1664 }
1665 
1666 static int
1667 tbl_update(VALUE hash, VALUE key, tbl_update_func func, st_data_t optional_arg)
1668 {
1669  struct update_arg arg;
1670  int result;
1671 
1672  arg.arg = optional_arg;
1673  arg.hash = hash;
1674  arg.new_key = 0;
1675  arg.old_key = Qundef;
1676  arg.new_value = 0;
1677  arg.old_value = Qundef;
1678 
1679  result = rb_hash_stlike_update(hash, key, func, (st_data_t)&arg);
1680 
1681  /* write barrier */
1682  if (arg.new_key) RB_OBJ_WRITTEN(hash, arg.old_key, arg.new_key);
1683  if (arg.new_value) RB_OBJ_WRITTEN(hash, arg.old_value, arg.new_value);
1684 
1685  return result;
1686 }
1687 
1688 #define UPDATE_CALLBACK(iter_lev, func) ((iter_lev) > 0 ? func##_noinsert : func##_insert)
1689 
1690 #define RHASH_UPDATE_ITER(h, iter_lev, key, func, a) do { \
1691  tbl_update((h), (key), UPDATE_CALLBACK((iter_lev), func), (st_data_t)(a)); \
1692 } while (0)
1693 
1694 #define RHASH_UPDATE(hash, key, func, arg) \
1695  RHASH_UPDATE_ITER(hash, RHASH_ITER_LEV(hash), key, func, arg)
1696 
1697 static void
1698 set_proc_default(VALUE hash, VALUE proc)
1699 {
1700  if (rb_proc_lambda_p(proc)) {
1701  int n = rb_proc_arity(proc);
1702 
1703  if (n != 2 && (n >= 0 || n < -3)) {
1704  if (n < 0) n = -n-1;
1705  rb_raise(rb_eTypeError, "default_proc takes two arguments (2 for %d)", n);
1706  }
1707  }
1708 
1710  RHASH_SET_IFNONE(hash, proc);
1711 }
1712 
1713 /*
1714  * call-seq:
1715  * Hash.new -> new_hash
1716  * Hash.new(obj) -> new_hash
1717  * Hash.new {|hash, key| block } -> new_hash
1718  *
1719  * Returns a new, empty hash. If this hash is subsequently accessed by
1720  * a key that doesn't correspond to a hash entry, the value returned
1721  * depends on the style of <code>new</code> used to create the hash. In
1722  * the first form, the access returns <code>nil</code>. If
1723  * <i>obj</i> is specified, this single object will be used for
1724  * all <em>default values</em>. If a block is specified, it will be
1725  * called with the hash object and the key, and should return the
1726  * default value. It is the block's responsibility to store the value
1727  * in the hash if required.
1728  *
1729  * h = Hash.new("Go Fish")
1730  * h["a"] = 100
1731  * h["b"] = 200
1732  * h["a"] #=> 100
1733  * h["c"] #=> "Go Fish"
1734  * # The following alters the single default object
1735  * h["c"].upcase! #=> "GO FISH"
1736  * h["d"] #=> "GO FISH"
1737  * h.keys #=> ["a", "b"]
1738  *
1739  * # While this creates a new default object each time
1740  * h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
1741  * h["c"] #=> "Go Fish: c"
1742  * h["c"].upcase! #=> "GO FISH: C"
1743  * h["d"] #=> "Go Fish: d"
1744  * h.keys #=> ["c", "d"]
1745  *
1746  */
1747 
1748 static VALUE
1749 rb_hash_initialize(int argc, VALUE *argv, VALUE hash)
1750 {
1751  VALUE ifnone;
1752 
1753  rb_hash_modify(hash);
1754  if (rb_block_given_p()) {
1755  rb_check_arity(argc, 0, 0);
1756  ifnone = rb_block_proc();
1757  SET_PROC_DEFAULT(hash, ifnone);
1758  }
1759  else {
1760  rb_check_arity(argc, 0, 1);
1761  ifnone = argc == 0 ? Qnil : argv[0];
1762  RHASH_SET_IFNONE(hash, ifnone);
1763  }
1764 
1765  return hash;
1766 }
1767 
1768 /*
1769  * call-seq:
1770  * Hash[ key, value, ... ] -> new_hash
1771  * Hash[ [ [key, value], ... ] ] -> new_hash
1772  * Hash[ object ] -> new_hash
1773  *
1774  * Creates a new hash populated with the given objects.
1775  *
1776  * Similar to the literal <code>{ _key_ => _value_, ... }</code>. In the first
1777  * form, keys and values occur in pairs, so there must be an even number of
1778  * arguments.
1779  *
1780  * The second and third form take a single argument which is either an array
1781  * of key-value pairs or an object convertible to a hash.
1782  *
1783  * Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}
1784  * Hash[ [ ["a", 100], ["b", 200] ] ] #=> {"a"=>100, "b"=>200}
1785  * Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200}
1786  */
1787 
1788 static VALUE
1789 rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
1790 {
1791  VALUE hash, tmp;
1792 
1793  if (argc == 1) {
1794  tmp = rb_hash_s_try_convert(Qnil, argv[0]);
1795  if (!NIL_P(tmp)) {
1796  hash = hash_alloc(klass);
1797  if (RHASH_AR_TABLE_P(tmp)) {
1798  ar_copy(hash, tmp);
1799  }
1800  else {
1802  }
1803  return hash;
1804  }
1805 
1806  tmp = rb_check_array_type(argv[0]);
1807  if (!NIL_P(tmp)) {
1808  long i;
1809 
1810  hash = hash_alloc(klass);
1811  for (i = 0; i < RARRAY_LEN(tmp); ++i) {
1812  VALUE e = RARRAY_AREF(tmp, i);
1814  VALUE key, val = Qnil;
1815 
1816  if (NIL_P(v)) {
1817  rb_raise(rb_eArgError, "wrong element type %s at %ld (expected array)",
1818  rb_builtin_class_name(e), i);
1819  }
1820  switch (RARRAY_LEN(v)) {
1821  default:
1822  rb_raise(rb_eArgError, "invalid number of elements (%ld for 1..2)",
1823  RARRAY_LEN(v));
1824  case 2:
1825  val = RARRAY_AREF(v, 1);
1826  case 1:
1827  key = RARRAY_AREF(v, 0);
1828  rb_hash_aset(hash, key, val);
1829  }
1830  }
1831  return hash;
1832  }
1833  }
1834  if (argc % 2 != 0) {
1835  rb_raise(rb_eArgError, "odd number of arguments for Hash");
1836  }
1837 
1838  hash = hash_alloc(klass);
1840  hash_verify(hash);
1841  return hash;
1842 }
1843 
1844 VALUE
1846 {
1847  return rb_convert_type_with_id(hash, T_HASH, "Hash", idTo_hash);
1848 }
1849 #define to_hash rb_to_hash_type
1850 
1851 VALUE
1853 {
1855 }
1856 
1857 /*
1858  * call-seq:
1859  * Hash.try_convert(obj) -> hash or nil
1860  *
1861  * Try to convert <i>obj</i> into a hash, using to_hash method.
1862  * Returns converted hash or nil if <i>obj</i> cannot be converted
1863  * for any reason.
1864  *
1865  * Hash.try_convert({1=>2}) # => {1=>2}
1866  * Hash.try_convert("1=>2") # => nil
1867  */
1868 static VALUE
1869 rb_hash_s_try_convert(VALUE dummy, VALUE hash)
1870 {
1871  return rb_check_hash_type(hash);
1872 }
1873 
1874 /*
1875  * call-seq:
1876  * Hash.ruby2_keywords_hash?(hash) -> true or false
1877  *
1878  * Checks if a given hash is flagged by Module#ruby2_keywords (or
1879  * Proc#ruby2_keywords).
1880  * This method is not for casual use; debugging, researching, and
1881  * some truly necessary cases like serialization of arguments.
1882  *
1883  * ruby2_keywords def foo(*args)
1884  * Hash.ruby2_keywords_hash?(args.last)
1885  * end
1886  * foo(k: 1) #=> true
1887  * foo({k: 1}) #=> false
1888  */
1889 static VALUE
1890 rb_hash_s_ruby2_keywords_hash_p(VALUE dummy, VALUE hash)
1891 {
1893  return (RHASH(hash)->basic.flags & RHASH_PASS_AS_KEYWORDS) ? Qtrue : Qfalse;
1894 }
1895 
1896 /*
1897  * call-seq:
1898  * Hash.ruby2_keywords_hash(hash) -> hash
1899  *
1900  * Duplicates a given hash and adds a ruby2_keywords flag.
1901  * This method is not for casual use; debugging, researching, and
1902  * some truly necessary cases like deserialization of arguments.
1903  *
1904  * h = {k: 1}
1905  * h = Hash.ruby2_keywords_hash(h)
1906  * def foo(k: 42)
1907  * k
1908  * end
1909  * foo(*[h]) #=> 1 with neither a warning or an error
1910  */
1911 static VALUE
1912 rb_hash_s_ruby2_keywords_hash(VALUE dummy, VALUE hash)
1913 {
1915  hash = rb_hash_dup(hash);
1916  RHASH(hash)->basic.flags |= RHASH_PASS_AS_KEYWORDS;
1917  return hash;
1918 }
1919 
1920 struct rehash_arg {
1923 };
1924 
1925 static int
1926 rb_hash_rehash_i(VALUE key, VALUE value, VALUE arg)
1927 {
1928  if (RHASH_AR_TABLE_P(arg)) {
1929  ar_insert(arg, (st_data_t)key, (st_data_t)value);
1930  }
1931  else {
1933  }
1934  return ST_CONTINUE;
1935 }
1936 
1937 /*
1938  * call-seq:
1939  * hsh.rehash -> hsh
1940  *
1941  * Rebuilds the hash based on the current hash values for each key. If
1942  * values of key objects have changed since they were inserted, this
1943  * method will reindex <i>hsh</i>. If Hash#rehash is
1944  * called while an iterator is traversing the hash, a
1945  * RuntimeError will be raised in the iterator.
1946  *
1947  * a = [ "a", "b" ]
1948  * c = [ "c", "d" ]
1949  * h = { a => 100, c => 300 }
1950  * h[a] #=> 100
1951  * a[0] = "z"
1952  * h[a] #=> nil
1953  * h.rehash #=> {["z", "b"]=>100, ["c", "d"]=>300}
1954  * h[a] #=> 100
1955  */
1956 
1957 VALUE
1959 {
1960  VALUE tmp;
1961  st_table *tbl;
1962 
1963  if (RHASH_ITER_LEV(hash) > 0) {
1964  rb_raise(rb_eRuntimeError, "rehash during iteration");
1965  }
1966  rb_hash_modify_check(hash);
1967  if (RHASH_AR_TABLE_P(hash)) {
1968  tmp = hash_alloc(0);
1969  ar_alloc_table(tmp);
1970  rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
1971  ar_free_and_clear_table(hash);
1972  ar_copy(hash, tmp);
1973  ar_free_and_clear_table(tmp);
1974  }
1975  else if (RHASH_ST_TABLE_P(hash)) {
1976  st_table *old_tab = RHASH_ST_TABLE(hash);
1977  tmp = hash_alloc(0);
1978  tbl = st_init_table_with_size(old_tab->type, old_tab->num_entries);
1979  RHASH_ST_TABLE_SET(tmp, tbl);
1980  rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
1981  st_free_table(old_tab);
1982  RHASH_ST_TABLE_SET(hash, tbl);
1983  RHASH_ST_CLEAR(tmp);
1984  }
1985  hash_verify(hash);
1986  return hash;
1987 }
1988 
1989 VALUE
1991 {
1992  if (rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
1993  VALUE ifnone = RHASH_IFNONE(hash);
1994  if (!FL_TEST(hash, RHASH_PROC_DEFAULT)) return ifnone;
1995  if (key == Qundef) return Qnil;
1996  return rb_funcall(ifnone, id_yield, 2, hash, key);
1997  }
1998  else {
1999  return rb_funcall(hash, id_default, 1, key);
2000  }
2001 }
2002 
2003 static inline int
2004 hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval)
2005 {
2006  hash_verify(hash);
2007 
2008  if (RHASH_AR_TABLE_P(hash)) {
2009  return ar_lookup(hash, key, pval);
2010  }
2011  else {
2012  return st_lookup(RHASH_ST_TABLE(hash), key, pval);
2013  }
2014 }
2015 
2018 {
2019  return hash_stlike_lookup(hash, key, pval);
2020 }
2021 
2022 /*
2023  * call-seq:
2024  * hsh[key] -> value
2025  *
2026  * Element Reference---Retrieves the <i>value</i> object corresponding
2027  * to the <i>key</i> object. If not found, returns the default value (see
2028  * Hash::new for details).
2029  *
2030  * h = { "a" => 100, "b" => 200 }
2031  * h["a"] #=> 100
2032  * h["c"] #=> nil
2033  *
2034  */
2035 
2036 VALUE
2038 {
2039  st_data_t val;
2040 
2041  if (hash_stlike_lookup(hash, key, &val)) {
2042  return (VALUE)val;
2043  }
2044  else {
2045  return rb_hash_default_value(hash, key);
2046  }
2047 }
2048 
2049 VALUE
2051 {
2052  st_data_t val;
2053 
2054  if (hash_stlike_lookup(hash, key, &val)) {
2055  return (VALUE)val;
2056  }
2057  else {
2058  return def; /* without Hash#default */
2059  }
2060 }
2061 
2062 VALUE
2064 {
2065  return rb_hash_lookup2(hash, key, Qnil);
2066 }
2067 
2068 /*
2069  * call-seq:
2070  * hsh.fetch(key [, default] ) -> obj
2071  * hsh.fetch(key) {| key | block } -> obj
2072  *
2073  * Returns a value from the hash for the given key. If the key can't be
2074  * found, there are several options: With no other arguments, it will
2075  * raise a KeyError exception; if <i>default</i> is given,
2076  * then that will be returned; if the optional code block is specified,
2077  * then that will be run and its result returned.
2078  *
2079  * h = { "a" => 100, "b" => 200 }
2080  * h.fetch("a") #=> 100
2081  * h.fetch("z", "go fish") #=> "go fish"
2082  * h.fetch("z") { |el| "go fish, #{el}"} #=> "go fish, z"
2083  *
2084  * The following example shows that an exception is raised if the key
2085  * is not found and a default value is not supplied.
2086  *
2087  * h = { "a" => 100, "b" => 200 }
2088  * h.fetch("z")
2089  *
2090  * <em>produces:</em>
2091  *
2092  * prog.rb:2:in `fetch': key not found (KeyError)
2093  * from prog.rb:2
2094  *
2095  */
2096 
2097 static VALUE
2098 rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash)
2099 {
2100  VALUE key;
2101  st_data_t val;
2102  long block_given;
2103 
2104  rb_check_arity(argc, 1, 2);
2105  key = argv[0];
2106 
2107  block_given = rb_block_given_p();
2108  if (block_given && argc == 2) {
2109  rb_warn("block supersedes default value argument");
2110  }
2111 
2112  if (hash_stlike_lookup(hash, key, &val)) {
2113  return (VALUE)val;
2114  }
2115  else {
2116  if (block_given) {
2117  return rb_yield(key);
2118  }
2119  else if (argc == 1) {
2120  VALUE desc = rb_protect(rb_inspect, key, 0);
2121  if (NIL_P(desc)) {
2122  desc = rb_any_to_s(key);
2123  }
2124  desc = rb_str_ellipsize(desc, 65);
2125  rb_key_err_raise(rb_sprintf("key not found: %"PRIsVALUE, desc), hash, key);
2126  }
2127  else {
2128  return argv[1];
2129  }
2130  }
2131 }
2132 
2133 VALUE
2135 {
2136  return rb_hash_fetch_m(1, &key, hash);
2137 }
2138 
2139 /*
2140  * call-seq:
2141  * hsh.default(key=nil) -> obj
2142  *
2143  * Returns the default value, the value that would be returned by
2144  * <i>hsh</i>[<i>key</i>] if <i>key</i> did not exist in <i>hsh</i>.
2145  * See also Hash::new and Hash#default=.
2146  *
2147  * h = Hash.new #=> {}
2148  * h.default #=> nil
2149  * h.default(2) #=> nil
2150  *
2151  * h = Hash.new("cat") #=> {}
2152  * h.default #=> "cat"
2153  * h.default(2) #=> "cat"
2154  *
2155  * h = Hash.new {|h,k| h[k] = k.to_i*10} #=> {}
2156  * h.default #=> nil
2157  * h.default(2) #=> 20
2158  */
2159 
2160 static VALUE
2161 rb_hash_default(int argc, VALUE *argv, VALUE hash)
2162 {
2163  VALUE args[2], ifnone;
2164 
2165  rb_check_arity(argc, 0, 1);
2166  ifnone = RHASH_IFNONE(hash);
2167  if (FL_TEST(hash, RHASH_PROC_DEFAULT)) {
2168  if (argc == 0) return Qnil;
2169  args[0] = hash;
2170  args[1] = argv[0];
2171  return rb_funcallv(ifnone, id_yield, 2, args);
2172  }
2173  return ifnone;
2174 }
2175 
2176 /*
2177  * call-seq:
2178  * hsh.default = obj -> obj
2179  *
2180  * Sets the default value, the value returned for a key that does not
2181  * exist in the hash. It is not possible to set the default to a
2182  * Proc that will be executed on each key lookup.
2183  *
2184  * h = { "a" => 100, "b" => 200 }
2185  * h.default = "Go fish"
2186  * h["a"] #=> 100
2187  * h["z"] #=> "Go fish"
2188  * # This doesn't do what you might hope...
2189  * h.default = proc do |hash, key|
2190  * hash[key] = key + key
2191  * end
2192  * h[2] #=> #<Proc:0x401b3948@-:6>
2193  * h["cat"] #=> #<Proc:0x401b3948@-:6>
2194  */
2195 
2196 static VALUE
2197 rb_hash_set_default(VALUE hash, VALUE ifnone)
2198 {
2199  rb_hash_modify_check(hash);
2200  SET_DEFAULT(hash, ifnone);
2201  return ifnone;
2202 }
2203 
2204 /*
2205  * call-seq:
2206  * hsh.default_proc -> anObject
2207  *
2208  * If Hash::new was invoked with a block, return that
2209  * block, otherwise return <code>nil</code>.
2210  *
2211  * h = Hash.new {|h,k| h[k] = k*k } #=> {}
2212  * p = h.default_proc #=> #<Proc:0x401b3d08@-:1>
2213  * a = [] #=> []
2214  * p.call(a, 2)
2215  * a #=> [nil, nil, 4]
2216  */
2217 
2218 
2219 static VALUE
2220 rb_hash_default_proc(VALUE hash)
2221 {
2222  if (FL_TEST(hash, RHASH_PROC_DEFAULT)) {
2223  return RHASH_IFNONE(hash);
2224  }
2225  return Qnil;
2226 }
2227 
2228 /*
2229  * call-seq:
2230  * hsh.default_proc = proc_obj or nil
2231  *
2232  * Sets the default proc to be executed on each failed key lookup.
2233  *
2234  * h.default_proc = proc do |hash, key|
2235  * hash[key] = key + key
2236  * end
2237  * h[2] #=> 4
2238  * h["cat"] #=> "catcat"
2239  */
2240 
2241 VALUE
2243 {
2244  VALUE b;
2245 
2246  rb_hash_modify_check(hash);
2247  if (NIL_P(proc)) {
2248  SET_DEFAULT(hash, proc);
2249  return proc;
2250  }
2251  b = rb_check_convert_type_with_id(proc, T_DATA, "Proc", idTo_proc);
2252  if (NIL_P(b) || !rb_obj_is_proc(b)) {
2254  "wrong default_proc type %s (expected Proc)",
2255  rb_obj_classname(proc));
2256  }
2257  proc = b;
2258  SET_PROC_DEFAULT(hash, proc);
2259  return proc;
2260 }
2261 
2262 static int
2263 key_i(VALUE key, VALUE value, VALUE arg)
2264 {
2265  VALUE *args = (VALUE *)arg;
2266 
2267  if (rb_equal(value, args[0])) {
2268  args[1] = key;
2269  return ST_STOP;
2270  }
2271  return ST_CONTINUE;
2272 }
2273 
2274 /*
2275  * call-seq:
2276  * hsh.key(value) -> key
2277  *
2278  * Returns the key of an occurrence of a given value. If the value is
2279  * not found, returns <code>nil</code>.
2280  *
2281  * h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 }
2282  * h.key(200) #=> "b"
2283  * h.key(300) #=> "c"
2284  * h.key(999) #=> nil
2285  *
2286  */
2287 
2288 static VALUE
2289 rb_hash_key(VALUE hash, VALUE value)
2290 {
2291  VALUE args[2];
2292 
2293  args[0] = value;
2294  args[1] = Qnil;
2295 
2296  rb_hash_foreach(hash, key_i, (VALUE)args);
2297 
2298  return args[1];
2299 }
2300 
2301 /* :nodoc: */
2302 static VALUE
2303 rb_hash_index(VALUE hash, VALUE value)
2304 {
2305  rb_warn_deprecated("Hash#index", "Hash#key");
2306  return rb_hash_key(hash, value);
2307 }
2308 
2309 int
2311 {
2312  if (RHASH_AR_TABLE_P(hash)) {
2313  return ar_delete(hash, pkey, pval);
2314  }
2315  else {
2316  return st_delete(RHASH_ST_TABLE(hash), pkey, pval);
2317  }
2318 }
2319 
2320 /*
2321  * delete a specified entry a given key.
2322  * if there is the corresponding entry, return a value of the entry.
2323  * if there is no corresponding entry, return Qundef.
2324  */
2325 VALUE
2327 {
2328  st_data_t ktmp = (st_data_t)key, val;
2329 
2330  if (rb_hash_stlike_delete(hash, &ktmp, &val)) {
2331  return (VALUE)val;
2332  }
2333  else {
2334  return Qundef;
2335  }
2336 }
2337 
2338 /*
2339  * delete a specified entry by a given key.
2340  * if there is the corresponding entry, return a value of the entry.
2341  * if there is no corresponding entry, return Qnil.
2342  */
2343 VALUE
2345 {
2346  VALUE deleted_value = rb_hash_delete_entry(hash, key);
2347 
2348  if (deleted_value != Qundef) { /* likely pass */
2349  return deleted_value;
2350  }
2351  else {
2352  return Qnil;
2353  }
2354 }
2355 
2356 /*
2357  * call-seq:
2358  * hsh.delete(key) -> value
2359  * hsh.delete(key) {| key | block } -> value
2360  *
2361  * Deletes the key-value pair and returns the value from <i>hsh</i> whose
2362  * key is equal to <i>key</i>. If the key is not found, it returns
2363  * <em>nil</em>. If the optional code block is given and the
2364  * key is not found, pass in the key and return the result of
2365  * <i>block</i>.
2366  *
2367  * h = { "a" => 100, "b" => 200 }
2368  * h.delete("a") #=> 100
2369  * h.delete("z") #=> nil
2370  * h.delete("z") { |el| "#{el} not found" } #=> "z not found"
2371  *
2372  */
2373 
2374 static VALUE
2375 rb_hash_delete_m(VALUE hash, VALUE key)
2376 {
2377  VALUE val;
2378 
2379  rb_hash_modify_check(hash);
2380  val = rb_hash_delete_entry(hash, key);
2381 
2382  if (val != Qundef) {
2383  return val;
2384  }
2385  else {
2386  if (rb_block_given_p()) {
2387  return rb_yield(key);
2388  }
2389  else {
2390  return Qnil;
2391  }
2392  }
2393 }
2394 
2395 struct shift_var {
2398 };
2399 
2400 static int
2401 shift_i_safe(VALUE key, VALUE value, VALUE arg)
2402 {
2403  struct shift_var *var = (struct shift_var *)arg;
2404 
2405  var->key = key;
2406  var->val = value;
2407  return ST_STOP;
2408 }
2409 
2410 /*
2411  * call-seq:
2412  * hsh.shift -> anArray or obj
2413  *
2414  * Removes a key-value pair from <i>hsh</i> and returns it as the
2415  * two-item array <code>[</code> <i>key, value</i> <code>]</code>, or
2416  * the hash's default value if the hash is empty.
2417  *
2418  * h = { 1 => "a", 2 => "b", 3 => "c" }
2419  * h.shift #=> [1, "a"]
2420  * h #=> {2=>"b", 3=>"c"}
2421  */
2422 
2423 static VALUE
2424 rb_hash_shift(VALUE hash)
2425 {
2426  struct shift_var var;
2427 
2428  rb_hash_modify_check(hash);
2429  if (RHASH_AR_TABLE_P(hash)) {
2430  var.key = Qundef;
2431  if (RHASH_ITER_LEV(hash) == 0) {
2432  if (ar_shift(hash, &var.key, &var.val)) {
2433  return rb_assoc_new(var.key, var.val);
2434  }
2435  }
2436  else {
2437  rb_hash_foreach(hash, shift_i_safe, (VALUE)&var);
2438  if (var.key != Qundef) {
2439  rb_hash_delete_entry(hash, var.key);
2440  return rb_assoc_new(var.key, var.val);
2441  }
2442  }
2443  }
2444  if (RHASH_ST_TABLE_P(hash)) {
2445  var.key = Qundef;
2446  if (RHASH_ITER_LEV(hash) == 0) {
2447  if (st_shift(RHASH_ST_TABLE(hash), &var.key, &var.val)) {
2448  return rb_assoc_new(var.key, var.val);
2449  }
2450  }
2451  else {
2452  rb_hash_foreach(hash, shift_i_safe, (VALUE)&var);
2453  if (var.key != Qundef) {
2454  rb_hash_delete_entry(hash, var.key);
2455  return rb_assoc_new(var.key, var.val);
2456  }
2457  }
2458  }
2459  return rb_hash_default_value(hash, Qnil);
2460 }
2461 
2462 static int
2463 delete_if_i(VALUE key, VALUE value, VALUE hash)
2464 {
2465  if (RTEST(rb_yield_values(2, key, value))) {
2466  return ST_DELETE;
2467  }
2468  return ST_CONTINUE;
2469 }
2470 
2471 static VALUE
2472 hash_enum_size(VALUE hash, VALUE args, VALUE eobj)
2473 {
2474  return rb_hash_size(hash);
2475 }
2476 
2477 /*
2478  * call-seq:
2479  * hsh.delete_if {| key, value | block } -> hsh
2480  * hsh.delete_if -> an_enumerator
2481  *
2482  * Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
2483  * evaluates to <code>true</code>.
2484  *
2485  * If no block is given, an enumerator is returned instead.
2486  *
2487  * h = { "a" => 100, "b" => 200, "c" => 300 }
2488  * h.delete_if {|key, value| key >= "b" } #=> {"a"=>100}
2489  *
2490  */
2491 
2492 VALUE
2494 {
2495  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2496  rb_hash_modify_check(hash);
2497  if (!RHASH_TABLE_EMPTY_P(hash)) {
2498  rb_hash_foreach(hash, delete_if_i, hash);
2499  }
2500  return hash;
2501 }
2502 
2503 /*
2504  * call-seq:
2505  * hsh.reject! {| key, value | block } -> hsh or nil
2506  * hsh.reject! -> an_enumerator
2507  *
2508  * Equivalent to Hash#delete_if, but returns
2509  * <code>nil</code> if no changes were made.
2510  */
2511 
2512 VALUE
2514 {
2515  st_index_t n;
2516 
2517  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2518  rb_hash_modify(hash);
2519  n = RHASH_SIZE(hash);
2520  if (!n) return Qnil;
2521  rb_hash_foreach(hash, delete_if_i, hash);
2522  if (n == RHASH_SIZE(hash)) return Qnil;
2523  return hash;
2524 }
2525 
2526 static int
2527 reject_i(VALUE key, VALUE value, VALUE result)
2528 {
2529  if (!RTEST(rb_yield_values(2, key, value))) {
2530  rb_hash_aset(result, key, value);
2531  }
2532  return ST_CONTINUE;
2533 }
2534 
2535 /*
2536  * call-seq:
2537  * hsh.reject {|key, value| block} -> a_hash
2538  * hsh.reject -> an_enumerator
2539  *
2540  * Returns a new hash consisting of entries for which the block returns false.
2541  *
2542  * If no block is given, an enumerator is returned instead.
2543  *
2544  * h = { "a" => 100, "b" => 200, "c" => 300 }
2545  * h.reject {|k,v| k < "b"} #=> {"b" => 200, "c" => 300}
2546  * h.reject {|k,v| v > 100} #=> {"a" => 100}
2547  */
2548 
2549 VALUE
2551 {
2552  VALUE result;
2553 
2554  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2555  if (RTEST(ruby_verbose)) {
2556  VALUE klass;
2557  if (HAS_EXTRA_STATES(hash, klass)) {
2558  rb_warn("extra states are no longer copied: %+"PRIsVALUE, hash);
2559  }
2560  }
2561  result = rb_hash_new();
2562  if (!RHASH_EMPTY_P(hash)) {
2563  rb_hash_foreach(hash, reject_i, result);
2564  }
2565  return result;
2566 }
2567 
2568 /*
2569  * call-seq:
2570  * hsh.slice(*keys) -> a_hash
2571  *
2572  * Returns a hash containing only the given keys and their values.
2573  *
2574  * h = { a: 100, b: 200, c: 300 }
2575  * h.slice(:a) #=> {:a=>100}
2576  * h.slice(:b, :c, :d) #=> {:b=>200, :c=>300}
2577  */
2578 
2579 static VALUE
2580 rb_hash_slice(int argc, VALUE *argv, VALUE hash)
2581 {
2582  int i;
2583  VALUE key, value, result;
2584 
2585  if (argc == 0 || RHASH_EMPTY_P(hash)) {
2586  return rb_hash_new();
2587  }
2588  result = rb_hash_new_with_size(argc);
2589 
2590  for (i = 0; i < argc; i++) {
2591  key = argv[i];
2592  value = rb_hash_lookup2(hash, key, Qundef);
2593  if (value != Qundef)
2594  rb_hash_aset(result, key, value);
2595  }
2596 
2597  return result;
2598 }
2599 
2600 /*
2601  * call-seq:
2602  * hsh.values_at(key, ...) -> array
2603  *
2604  * Return an array containing the values associated with the given keys.
2605  * Also see Hash.select.
2606  *
2607  * h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
2608  * h.values_at("cow", "cat") #=> ["bovine", "feline"]
2609  */
2610 
2611 VALUE
2613 {
2614  VALUE result = rb_ary_new2(argc);
2615  long i;
2616 
2617  for (i=0; i<argc; i++) {
2618  rb_ary_push(result, rb_hash_aref(hash, argv[i]));
2619  }
2620  return result;
2621 }
2622 
2623 /*
2624  * call-seq:
2625  * hsh.fetch_values(key, ...) -> array
2626  * hsh.fetch_values(key, ...) { |key| block } -> array
2627  *
2628  * Returns an array containing the values associated with the given keys
2629  * but also raises KeyError when one of keys can't be found.
2630  * Also see Hash#values_at and Hash#fetch.
2631  *
2632  * h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
2633  *
2634  * h.fetch_values("cow", "cat") #=> ["bovine", "feline"]
2635  * h.fetch_values("cow", "bird") # raises KeyError
2636  * h.fetch_values("cow", "bird") { |k| k.upcase } #=> ["bovine", "BIRD"]
2637  */
2638 
2639 VALUE
2641 {
2642  VALUE result = rb_ary_new2(argc);
2643  long i;
2644 
2645  for (i=0; i<argc; i++) {
2646  rb_ary_push(result, rb_hash_fetch(hash, argv[i]));
2647  }
2648  return result;
2649 }
2650 
2651 static int
2652 select_i(VALUE key, VALUE value, VALUE result)
2653 {
2654  if (RTEST(rb_yield_values(2, key, value))) {
2655  rb_hash_aset(result, key, value);
2656  }
2657  return ST_CONTINUE;
2658 }
2659 
2660 /*
2661  * call-seq:
2662  * hsh.select {|key, value| block} -> a_hash
2663  * hsh.select -> an_enumerator
2664  * hsh.filter {|key, value| block} -> a_hash
2665  * hsh.filter -> an_enumerator
2666  *
2667  * Returns a new hash consisting of entries for which the block returns true.
2668  *
2669  * If no block is given, an enumerator is returned instead.
2670  *
2671  * h = { "a" => 100, "b" => 200, "c" => 300 }
2672  * h.select {|k,v| k > "a"} #=> {"b" => 200, "c" => 300}
2673  * h.select {|k,v| v < 200} #=> {"a" => 100}
2674  *
2675  * Hash#filter is an alias for Hash#select.
2676  */
2677 
2678 VALUE
2680 {
2681  VALUE result;
2682 
2683  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2684  result = rb_hash_new();
2685  if (!RHASH_EMPTY_P(hash)) {
2686  rb_hash_foreach(hash, select_i, result);
2687  }
2688  return result;
2689 }
2690 
2691 static int
2692 keep_if_i(VALUE key, VALUE value, VALUE hash)
2693 {
2694  if (!RTEST(rb_yield_values(2, key, value))) {
2695  return ST_DELETE;
2696  }
2697  return ST_CONTINUE;
2698 }
2699 
2700 /*
2701  * call-seq:
2702  * hsh.select! {| key, value | block } -> hsh or nil
2703  * hsh.select! -> an_enumerator
2704  * hsh.filter! {| key, value | block } -> hsh or nil
2705  * hsh.filter! -> an_enumerator
2706  *
2707  * Equivalent to Hash#keep_if, but returns
2708  * +nil+ if no changes were made.
2709  *
2710  * Hash#filter! is an alias for Hash#select!.
2711  */
2712 
2713 VALUE
2715 {
2716  st_index_t n;
2717 
2718  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2719  rb_hash_modify_check(hash);
2720  n = RHASH_SIZE(hash);
2721  if (!n) return Qnil;
2722  rb_hash_foreach(hash, keep_if_i, hash);
2723  if (n == RHASH_SIZE(hash)) return Qnil;
2724  return hash;
2725 }
2726 
2727 /*
2728  * call-seq:
2729  * hsh.keep_if {| key, value | block } -> hsh
2730  * hsh.keep_if -> an_enumerator
2731  *
2732  * Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
2733  * evaluates to +false+.
2734  *
2735  * If no block is given, an enumerator is returned instead.
2736  *
2737  * See also Hash#select!.
2738  */
2739 
2740 VALUE
2742 {
2743  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2744  rb_hash_modify_check(hash);
2745  if (!RHASH_TABLE_EMPTY_P(hash)) {
2746  rb_hash_foreach(hash, keep_if_i, hash);
2747  }
2748  return hash;
2749 }
2750 
2751 static int
2752 clear_i(VALUE key, VALUE value, VALUE dummy)
2753 {
2754  return ST_DELETE;
2755 }
2756 
2757 /*
2758  * call-seq:
2759  * hsh.clear -> hsh
2760  *
2761  * Removes all key-value pairs from <i>hsh</i>.
2762  *
2763  * h = { "a" => 100, "b" => 200 } #=> {"a"=>100, "b"=>200}
2764  * h.clear #=> {}
2765  *
2766  */
2767 
2768 VALUE
2770 {
2771  rb_hash_modify_check(hash);
2772 
2773  if (RHASH_ITER_LEV(hash) > 0) {
2774  rb_hash_foreach(hash, clear_i, 0);
2775  }
2776  else if (RHASH_AR_TABLE_P(hash)) {
2777  ar_clear(hash);
2778  }
2779  else {
2780  st_clear(RHASH_ST_TABLE(hash));
2781  }
2782 
2783  return hash;
2784 }
2785 
2786 static int
2787 hash_aset(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
2788 {
2789  if (existing) {
2790  arg->new_value = arg->arg;
2791  arg->old_value = *val;
2792  }
2793  else {
2794  arg->new_key = *key;
2795  arg->new_value = arg->arg;
2796  }
2797  *val = arg->arg;
2798  return ST_CONTINUE;
2799 }
2800 
2801 VALUE
2803 {
2805  return rb_fstring(key);
2806  }
2807  else {
2808  return rb_str_new_frozen(key);
2809  }
2810 }
2811 
2812 static int
2813 hash_aset_str(st_data_t *key, st_data_t *val, struct update_arg *arg, int existing)
2814 {
2815  if (!existing && !RB_OBJ_FROZEN(*key)) {
2816  *key = rb_hash_key_str(*key);
2817  }
2818  return hash_aset(key, val, arg, existing);
2819 }
2820 
2821 NOINSERT_UPDATE_CALLBACK(hash_aset)
2822 NOINSERT_UPDATE_CALLBACK(hash_aset_str)
2823 
2824 /*
2825  * call-seq:
2826  * hsh[key] = value -> value
2827  * hsh.store(key, value) -> value
2828  *
2829  * == Element Assignment
2830  *
2831  * Associates the value given by +value+ with the key given by +key+.
2832  *
2833  * h = { "a" => 100, "b" => 200 }
2834  * h["a"] = 9
2835  * h["c"] = 4
2836  * h #=> {"a"=>9, "b"=>200, "c"=>4}
2837  * h.store("d", 42) #=> 42
2838  * h #=> {"a"=>9, "b"=>200, "c"=>4, "d"=>42}
2839  *
2840  * +key+ should not have its value changed while it is in use as a key (an
2841  * <tt>unfrozen String</tt> passed as a key will be duplicated and frozen).
2842  *
2843  * a = "a"
2844  * b = "b".freeze
2845  * h = { a => 100, b => 200 }
2846  * h.key(100).equal? a #=> false
2847  * h.key(200).equal? b #=> true
2848  *
2849  */
2850 
2851 VALUE
2853 {
2854  int iter_lev = RHASH_ITER_LEV(hash);
2855 
2856  rb_hash_modify(hash);
2857 
2858  if (RHASH_TABLE_NULL_P(hash)) {
2859  if (iter_lev > 0) no_new_key();
2860  ar_alloc_table(hash);
2861  }
2862 
2863  if (RHASH_TYPE(hash) == &identhash || rb_obj_class(key) != rb_cString) {
2864  RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset, val);
2865  }
2866  else {
2867  RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset_str, val);
2868  }
2869  return val;
2870 }
2871 
2872 /*
2873  * call-seq:
2874  * hsh.replace(other_hash) -> hsh
2875  *
2876  * Replaces the contents of <i>hsh</i> with the contents of
2877  * <i>other_hash</i>.
2878  *
2879  * h = { "a" => 100, "b" => 200 }
2880  * h.replace({ "c" => 300, "d" => 400 }) #=> {"c"=>300, "d"=>400}
2881  *
2882  */
2883 
2884 static VALUE
2885 rb_hash_replace(VALUE hash, VALUE hash2)
2886 {
2887  rb_hash_modify_check(hash);
2888  if (hash == hash2) return hash;
2889  if (RHASH_ITER_LEV(hash) > 0) {
2890  rb_raise(rb_eRuntimeError, "can't replace hash during iteration");
2891  }
2892  hash2 = to_hash(hash2);
2893 
2894  COPY_DEFAULT(hash, hash2);
2895 
2896  if (RHASH_AR_TABLE_P(hash)) {
2897  if (RHASH_AR_TABLE_P(hash2)) {
2898  ar_clear(hash);
2899  }
2900  else {
2901  ar_free_and_clear_table(hash);
2903  }
2904  }
2905  else {
2906  if (RHASH_AR_TABLE_P(hash2)) {
2908  RHASH_ST_CLEAR(hash);
2909  }
2910  else {
2911  st_clear(RHASH_ST_TABLE(hash));
2912  RHASH_TBL_RAW(hash)->type = RHASH_ST_TABLE(hash2)->type;
2913  }
2914  }
2915  rb_hash_foreach(hash2, rb_hash_rehash_i, (VALUE)hash);
2916 
2918 
2919  return hash;
2920 }
2921 
2922 /*
2923  * call-seq:
2924  * hsh.length -> integer
2925  * hsh.size -> integer
2926  *
2927  * Returns the number of key-value pairs in the hash.
2928  *
2929  * h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
2930  * h.size #=> 4
2931  * h.delete("a") #=> 200
2932  * h.size #=> 3
2933  * h.length #=> 3
2934  *
2935  * Hash#length is an alias for Hash#size.
2936  */
2937 
2938 VALUE
2940 {
2941  return INT2FIX(RHASH_SIZE(hash));
2942 }
2943 
2944 size_t
2946 {
2947  return (long)RHASH_SIZE(hash);
2948 }
2949 
2950 /*
2951  * call-seq:
2952  * hsh.empty? -> true or false
2953  *
2954  * Returns <code>true</code> if <i>hsh</i> contains no key-value pairs.
2955  *
2956  * {}.empty? #=> true
2957  *
2958  */
2959 
2960 static VALUE
2961 rb_hash_empty_p(VALUE hash)
2962 {
2963  return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse;
2964 }
2965 
2966 static int
2967 each_value_i(VALUE key, VALUE value, VALUE _)
2968 {
2969  rb_yield(value);
2970  return ST_CONTINUE;
2971 }
2972 
2973 /*
2974  * call-seq:
2975  * hsh.each_value {| value | block } -> hsh
2976  * hsh.each_value -> an_enumerator
2977  *
2978  * Calls <i>block</i> once for each key in <i>hsh</i>, passing the
2979  * value as a parameter.
2980  *
2981  * If no block is given, an enumerator is returned instead.
2982  *
2983  * h = { "a" => 100, "b" => 200 }
2984  * h.each_value {|value| puts value }
2985  *
2986  * <em>produces:</em>
2987  *
2988  * 100
2989  * 200
2990  */
2991 
2992 static VALUE
2993 rb_hash_each_value(VALUE hash)
2994 {
2995  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
2996  rb_hash_foreach(hash, each_value_i, 0);
2997  return hash;
2998 }
2999 
3000 static int
3001 each_key_i(VALUE key, VALUE value, VALUE _)
3002 {
3003  rb_yield(key);
3004  return ST_CONTINUE;
3005 }
3006 
3007 /*
3008  * call-seq:
3009  * hsh.each_key {| key | block } -> hsh
3010  * hsh.each_key -> an_enumerator
3011  *
3012  * Calls <i>block</i> once for each key in <i>hsh</i>, passing the key
3013  * as a parameter.
3014  *
3015  * If no block is given, an enumerator is returned instead.
3016  *
3017  * h = { "a" => 100, "b" => 200 }
3018  * h.each_key {|key| puts key }
3019  *
3020  * <em>produces:</em>
3021  *
3022  * a
3023  * b
3024  */
3025 static VALUE
3026 rb_hash_each_key(VALUE hash)
3027 {
3028  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3029  rb_hash_foreach(hash, each_key_i, 0);
3030  return hash;
3031 }
3032 
3033 static int
3034 each_pair_i(VALUE key, VALUE value, VALUE _)
3035 {
3036  rb_yield(rb_assoc_new(key, value));
3037  return ST_CONTINUE;
3038 }
3039 
3040 static int
3041 each_pair_i_fast(VALUE key, VALUE value, VALUE _)
3042 {
3043  VALUE argv[2];
3044  argv[0] = key;
3045  argv[1] = value;
3046  rb_yield_values2(2, argv);
3047  return ST_CONTINUE;
3048 }
3049 
3050 /*
3051  * call-seq:
3052  * hsh.each {| key, value | block } -> hsh
3053  * hsh.each_pair {| key, value | block } -> hsh
3054  * hsh.each -> an_enumerator
3055  * hsh.each_pair -> an_enumerator
3056  *
3057  * Calls <i>block</i> once for each key in <i>hsh</i>, passing the key-value
3058  * pair as parameters.
3059  *
3060  * If no block is given, an enumerator is returned instead.
3061  *
3062  * h = { "a" => 100, "b" => 200 }
3063  * h.each {|key, value| puts "#{key} is #{value}" }
3064  *
3065  * <em>produces:</em>
3066  *
3067  * a is 100
3068  * b is 200
3069  *
3070  */
3071 
3072 static VALUE
3073 rb_hash_each_pair(VALUE hash)
3074 {
3075  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3076  if (rb_block_arity() > 1)
3077  rb_hash_foreach(hash, each_pair_i_fast, 0);
3078  else
3079  rb_hash_foreach(hash, each_pair_i, 0);
3080  return hash;
3081 }
3082 
3083 static int
3084 transform_keys_i(VALUE key, VALUE value, VALUE result)
3085 {
3086  VALUE new_key = rb_yield(key);
3087  rb_hash_aset(result, new_key, value);
3088  return ST_CONTINUE;
3089 }
3090 
3091 /*
3092  * call-seq:
3093  * hsh.transform_keys {|key| block } -> new_hash
3094  * hsh.transform_keys -> an_enumerator
3095  *
3096  * Returns a new hash with the results of running the block once for
3097  * every key.
3098  * This method does not change the values.
3099  *
3100  * h = { a: 1, b: 2, c: 3 }
3101  * h.transform_keys {|k| k.to_s } #=> { "a" => 1, "b" => 2, "c" => 3 }
3102  * h.transform_keys(&:to_s) #=> { "a" => 1, "b" => 2, "c" => 3 }
3103  * h.transform_keys.with_index {|k, i| "#{k}.#{i}" }
3104  * #=> { "a.0" => 1, "b.1" => 2, "c.2" => 3 }
3105  *
3106  * If no block is given, an enumerator is returned instead.
3107  */
3108 static VALUE
3109 rb_hash_transform_keys(VALUE hash)
3110 {
3111  VALUE result;
3112 
3113  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3114  result = rb_hash_new();
3115  if (!RHASH_EMPTY_P(hash)) {
3116  rb_hash_foreach(hash, transform_keys_i, result);
3117  }
3118 
3119  return result;
3120 }
3121 
3122 static VALUE rb_hash_flatten(int argc, VALUE *argv, VALUE hash);
3123 
3124 /*
3125  * call-seq:
3126  * hsh.transform_keys! {|key| block } -> hsh
3127  * hsh.transform_keys! -> an_enumerator
3128  *
3129  * Invokes the given block once for each key in <i>hsh</i>, replacing it
3130  * with the new key returned by the block, and then returns <i>hsh</i>.
3131  * This method does not change the values.
3132  *
3133  * h = { a: 1, b: 2, c: 3 }
3134  * h.transform_keys! {|k| k.to_s } #=> { "a" => 1, "b" => 2, "c" => 3 }
3135  * h.transform_keys!(&:to_sym) #=> { a: 1, b: 2, c: 3 }
3136  * h.transform_keys!.with_index {|k, i| "#{k}.#{i}" }
3137  * #=> { "a.0" => 1, "b.1" => 2, "c.2" => 3 }
3138  *
3139  * If no block is given, an enumerator is returned instead.
3140  */
3141 static VALUE
3142 rb_hash_transform_keys_bang(VALUE hash)
3143 {
3144  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3145  rb_hash_modify_check(hash);
3146  if (!RHASH_TABLE_EMPTY_P(hash)) {
3147  long i;
3148  VALUE pairs = rb_hash_flatten(0, NULL, hash);
3149  rb_hash_clear(hash);
3150  for (i = 0; i < RARRAY_LEN(pairs); i += 2) {
3151  VALUE key = RARRAY_AREF(pairs, i), new_key = rb_yield(key),
3152  val = RARRAY_AREF(pairs, i+1);
3153  rb_hash_aset(hash, new_key, val);
3154  }
3155  }
3156  return hash;
3157 }
3158 
3159 static int
3160 transform_values_foreach_func(st_data_t key, st_data_t value, st_data_t argp, int error)
3161 {
3162  return ST_REPLACE;
3163 }
3164 
3165 static int
3166 transform_values_foreach_replace(st_data_t *key, st_data_t *value, st_data_t argp, int existing)
3167 {
3168  VALUE new_value = rb_yield((VALUE)*value);
3169  VALUE hash = (VALUE)argp;
3170  RB_OBJ_WRITE(hash, value, new_value);
3171  return ST_CONTINUE;
3172 }
3173 
3174 /*
3175  * call-seq:
3176  * hsh.transform_values {|value| block } -> new_hash
3177  * hsh.transform_values -> an_enumerator
3178  *
3179  * Returns a new hash with the results of running the block once for
3180  * every value.
3181  * This method does not change the keys.
3182  *
3183  * h = { a: 1, b: 2, c: 3 }
3184  * h.transform_values {|v| v * v + 1 } #=> { a: 2, b: 5, c: 10 }
3185  * h.transform_values(&:to_s) #=> { a: "1", b: "2", c: "3" }
3186  * h.transform_values.with_index {|v, i| "#{v}.#{i}" }
3187  * #=> { a: "1.0", b: "2.1", c: "3.2" }
3188  *
3189  * If no block is given, an enumerator is returned instead.
3190  */
3191 static VALUE
3192 rb_hash_transform_values(VALUE hash)
3193 {
3194  VALUE result;
3195 
3196  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3197  result = hash_copy(hash_alloc(rb_cHash), hash);
3198  SET_DEFAULT(result, Qnil);
3199 
3200  if (!RHASH_EMPTY_P(hash)) {
3201  rb_hash_stlike_foreach_with_replace(result, transform_values_foreach_func, transform_values_foreach_replace, result);
3202  }
3203 
3204  return result;
3205 }
3206 
3207 /*
3208  * call-seq:
3209  * hsh.transform_values! {|value| block } -> hsh
3210  * hsh.transform_values! -> an_enumerator
3211  *
3212  * Invokes the given block once for each value in <i>hsh</i>, replacing it
3213  * with the new value returned by the block, and then returns <i>hsh</i>.
3214  * This method does not change the keys.
3215  *
3216  * h = { a: 1, b: 2, c: 3 }
3217  * h.transform_values! {|v| v * v + 1 } #=> { a: 2, b: 5, c: 10 }
3218  * h.transform_values!(&:to_s) #=> { a: "2", b: "5", c: "10" }
3219  * h.transform_values!.with_index {|v, i| "#{v}.#{i}" }
3220  * #=> { a: "2.0", b: "5.1", c: "10.2" }
3221  *
3222  * If no block is given, an enumerator is returned instead.
3223  */
3224 static VALUE
3225 rb_hash_transform_values_bang(VALUE hash)
3226 {
3227  RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size);
3228  rb_hash_modify_check(hash);
3229 
3230  if (!RHASH_TABLE_EMPTY_P(hash)) {
3231  rb_hash_stlike_foreach_with_replace(hash, transform_values_foreach_func, transform_values_foreach_replace, hash);
3232  }
3233 
3234  return hash;
3235 }
3236 
3237 static int
3238 to_a_i(VALUE key, VALUE value, VALUE ary)
3239 {
3240  rb_ary_push(ary, rb_assoc_new(key, value));
3241  return ST_CONTINUE;
3242 }
3243 
3244 /*
3245  * call-seq:
3246  * hsh.to_a -> array
3247  *
3248  * Converts <i>hsh</i> to a nested array of <code>[</code> <i>key,
3249  * value</i> <code>]</code> arrays.
3250  *
3251  * h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 }
3252  * h.to_a #=> [["c", 300], ["a", 100], ["d", 400]]
3253  */
3254 
3255 static VALUE
3256 rb_hash_to_a(VALUE hash)
3257 {
3258  VALUE ary;
3259 
3260  ary = rb_ary_new_capa(RHASH_SIZE(hash));
3261  rb_hash_foreach(hash, to_a_i, ary);
3262 
3263  return ary;
3264 }
3265 
3266 static int
3267 inspect_i(VALUE key, VALUE value, VALUE str)
3268 {
3269  VALUE str2;
3270 
3271  str2 = rb_inspect(key);
3272  if (RSTRING_LEN(str) > 1) {
3273  rb_str_buf_cat_ascii(str, ", ");
3274  }
3275  else {
3276  rb_enc_copy(str, str2);
3277  }
3278  rb_str_buf_append(str, str2);
3279  rb_str_buf_cat_ascii(str, "=>");
3280  str2 = rb_inspect(value);
3281  rb_str_buf_append(str, str2);
3282 
3283  return ST_CONTINUE;
3284 }
3285 
3286 static VALUE
3287 inspect_hash(VALUE hash, VALUE dummy, int recur)
3288 {
3289  VALUE str;
3290 
3291  if (recur) return rb_usascii_str_new2("{...}");
3292  str = rb_str_buf_new2("{");
3293  rb_hash_foreach(hash, inspect_i, str);
3294  rb_str_buf_cat2(str, "}");
3295 
3296  return str;
3297 }
3298 
3299 /*
3300  * call-seq:
3301  * hsh.to_s -> string
3302  * hsh.inspect -> string
3303  *
3304  * Return the contents of this hash as a string.
3305  *
3306  * h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 }
3307  * h.to_s #=> "{\"c\"=>300, \"a\"=>100, \"d\"=>400}"
3308  */
3309 
3310 static VALUE
3311 rb_hash_inspect(VALUE hash)
3312 {
3313  if (RHASH_EMPTY_P(hash))
3314  return rb_usascii_str_new2("{}");
3315  return rb_exec_recursive(inspect_hash, hash, 0);
3316 }
3317 
3318 /*
3319  * call-seq:
3320  * hsh.to_hash => hsh
3321  *
3322  * Returns +self+.
3323  */
3324 
3325 static VALUE
3326 rb_hash_to_hash(VALUE hash)
3327 {
3328  return hash;
3329 }
3330 
3331 VALUE
3333 {
3334  VALUE pair;
3335 
3336  pair = rb_check_array_type(arg);
3337  if (NIL_P(pair)) {
3338  rb_raise(rb_eTypeError, "wrong element type %s (expected array)",
3340  }
3341  if (RARRAY_LEN(pair) != 2) {
3342  rb_raise(rb_eArgError, "element has wrong array length (expected 2, was %ld)",
3343  RARRAY_LEN(pair));
3344  }
3345  rb_hash_aset(hash, RARRAY_AREF(pair, 0), RARRAY_AREF(pair, 1));
3346  return hash;
3347 }
3348 
3349 static int
3350 to_h_i(VALUE key, VALUE value, VALUE hash)
3351 {
3352  rb_hash_set_pair(hash, rb_yield_values(2, key, value));
3353  return ST_CONTINUE;
3354 }
3355 
3356 static VALUE
3357 rb_hash_to_h_block(VALUE hash)
3358 {
3360  rb_hash_foreach(hash, to_h_i, h);
3361  return h;
3362 }
3363 
3364 /*
3365  * call-seq:
3366  * hsh.to_h -> hsh or new_hash
3367  * hsh.to_h {|key, value| block } -> new_hash
3368  *
3369  * Returns +self+. If called on a subclass of Hash, converts
3370  * the receiver to a Hash object.
3371  *
3372  * If a block is given, the results of the block on each pair of
3373  * the receiver will be used as pairs.
3374  */
3375 
3376 static VALUE
3377 rb_hash_to_h(VALUE hash)
3378 {
3379  if (rb_block_given_p()) {
3380  return rb_hash_to_h_block(hash);
3381  }
3382  if (rb_obj_class(hash) != rb_cHash) {
3383  const VALUE flags = RBASIC(hash)->flags;
3384  hash = hash_dup(hash, rb_cHash, flags & RHASH_PROC_DEFAULT);
3385  }
3386  return hash;
3387 }
3388 
3389 static int
3390 keys_i(VALUE key, VALUE value, VALUE ary)
3391 {
3392  rb_ary_push(ary, key);
3393  return ST_CONTINUE;
3394 }
3395 
3396 /*
3397  * call-seq:
3398  * hsh.keys -> array
3399  *
3400  * Returns a new array populated with the keys from this hash. See also
3401  * Hash#values.
3402  *
3403  * h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
3404  * h.keys #=> ["a", "b", "c", "d"]
3405  *
3406  */
3407 
3410 {
3411  st_index_t size = RHASH_SIZE(hash);
3413 
3414  if (size == 0) return keys;
3415 
3416  if (ST_DATA_COMPATIBLE_P(VALUE)) {
3418  if (RHASH_AR_TABLE_P(hash)) {
3419  size = ar_keys(hash, ptr, size);
3420  }
3421  else {
3422  st_table *table = RHASH_ST_TABLE(hash);
3423  size = st_keys(table, ptr, size);
3424  }
3425  });
3428  }
3429  else {
3430  rb_hash_foreach(hash, keys_i, keys);
3431  }
3432 
3433  return keys;
3434 }
3435 
3436 static int
3437 values_i(VALUE key, VALUE value, VALUE ary)
3438 {
3439  rb_ary_push(ary, value);
3440  return ST_CONTINUE;
3441 }
3442 
3443 /*
3444  * call-seq:
3445  * hsh.values -> array
3446  *
3447  * Returns a new array populated with the values from <i>hsh</i>. See
3448  * also Hash#keys.
3449  *
3450  * h = { "a" => 100, "b" => 200, "c" => 300 }
3451  * h.values #=> [100, 200, 300]
3452  *
3453  */
3454 
3455 VALUE
3457 {
3458  VALUE values;
3459  st_index_t size = RHASH_SIZE(hash);
3460 
3461  values = rb_ary_new_capa(size);
3462  if (size == 0) return values;
3463 
3464  if (ST_DATA_COMPATIBLE_P(VALUE)) {
3465  if (RHASH_AR_TABLE_P(hash)) {
3467  RARRAY_PTR_USE_TRANSIENT(values, ptr, {
3468  size = ar_values(hash, ptr, size);
3469  });
3470  }
3471  else if (RHASH_ST_TABLE_P(hash)) {
3472  st_table *table = RHASH_ST_TABLE(hash);
3474  RARRAY_PTR_USE_TRANSIENT(values, ptr, {
3475  size = st_values(table, ptr, size);
3476  });
3477  }
3478  rb_ary_set_len(values, size);
3479  }
3480  else {
3481  rb_hash_foreach(hash, values_i, values);
3482  }
3483 
3484  return values;
3485 }
3486 
3487 /*
3488  * call-seq:
3489  * hsh.has_key?(key) -> true or false
3490  * hsh.include?(key) -> true or false
3491  * hsh.key?(key) -> true or false
3492  * hsh.member?(key) -> true or false
3493  *
3494  * Returns <code>true</code> if the given key is present in <i>hsh</i>.
3495  *
3496  * h = { "a" => 100, "b" => 200 }
3497  * h.has_key?("a") #=> true
3498  * h.has_key?("z") #=> false
3499  *
3500  * Note that #include? and #member? do not test member
3501  * equality using <code>==</code> as do other Enumerables.
3502  *
3503  * See also Enumerable#include?
3504  */
3505 
3508 {
3509  if (hash_stlike_lookup(hash, key, NULL)) {
3510  return Qtrue;
3511  }
3512  else {
3513  return Qfalse;
3514  }
3515 }
3516 
3517 static int
3518 rb_hash_search_value(VALUE key, VALUE value, VALUE arg)
3519 {
3520  VALUE *data = (VALUE *)arg;
3521 
3522  if (rb_equal(value, data[1])) {
3523  data[0] = Qtrue;
3524  return ST_STOP;
3525  }
3526  return ST_CONTINUE;
3527 }
3528 
3529 /*
3530  * call-seq:
3531  * hsh.has_value?(value) -> true or false
3532  * hsh.value?(value) -> true or false
3533  *
3534  * Returns <code>true</code> if the given value is present for some key
3535  * in <i>hsh</i>.
3536  *
3537  * h = { "a" => 100, "b" => 200 }
3538  * h.value?(100) #=> true
3539  * h.value?(999) #=> false
3540  */
3541 
3542 static VALUE
3543 rb_hash_has_value(VALUE hash, VALUE val)
3544 {
3545  VALUE data[2];
3546 
3547  data[0] = Qfalse;
3548  data[1] = val;
3549  rb_hash_foreach(hash, rb_hash_search_value, (VALUE)data);
3550  return data[0];
3551 }
3552 
3553 struct equal_data {
3556  int eql;
3557 };
3558 
3559 static int
3560 eql_i(VALUE key, VALUE val1, VALUE arg)
3561 {
3562  struct equal_data *data = (struct equal_data *)arg;
3563  st_data_t val2;
3564 
3565  if (!hash_stlike_lookup(data->hash, key, &val2)) {
3566  data->result = Qfalse;
3567  return ST_STOP;
3568  }
3569  else {
3570  if (!(data->eql ? rb_eql(val1, (VALUE)val2) : (int)rb_equal(val1, (VALUE)val2))) {
3571  data->result = Qfalse;
3572  return ST_STOP;
3573  }
3574  return ST_CONTINUE;
3575  }
3576 }
3577 
3578 static VALUE
3579 recursive_eql(VALUE hash, VALUE dt, int recur)
3580 {
3581  struct equal_data *data;
3582 
3583  if (recur) return Qtrue; /* Subtle! */
3584  data = (struct equal_data*)dt;
3585  data->result = Qtrue;
3586  rb_hash_foreach(hash, eql_i, dt);
3587 
3588  return data->result;
3589 }
3590 
3591 static VALUE
3592 hash_equal(VALUE hash1, VALUE hash2, int eql)
3593 {
3594  struct equal_data data;
3595 
3596  if (hash1 == hash2) return Qtrue;
3597  if (!RB_TYPE_P(hash2, T_HASH)) {
3598  if (!rb_respond_to(hash2, idTo_hash)) {
3599  return Qfalse;
3600  }
3601  if (eql) {
3602  if (rb_eql(hash2, hash1)) {
3603  return Qtrue;
3604  }
3605  else {
3606  return Qfalse;
3607  }
3608  }
3609  else {
3610  return rb_equal(hash2, hash1);
3611  }
3612  }
3613  if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2))
3614  return Qfalse;
3615  if (!RHASH_TABLE_EMPTY_P(hash1) && !RHASH_TABLE_EMPTY_P(hash2)) {
3616  if (RHASH_TYPE(hash1) != RHASH_TYPE(hash2)) {
3617  return Qfalse;
3618  }
3619  else {
3620  data.hash = hash2;
3621  data.eql = eql;
3622  return rb_exec_recursive_paired(recursive_eql, hash1, hash2, (VALUE)&data);
3623  }
3624  }
3625 
3626 #if 0
3627  if (!(rb_equal(RHASH_IFNONE(hash1), RHASH_IFNONE(hash2)) &&
3629  return Qfalse;
3630 #endif
3631  return Qtrue;
3632 }
3633 
3634 /*
3635  * call-seq:
3636  * hsh == other_hash -> true or false
3637  *
3638  * Equality---Two hashes are equal if they each contain the same number
3639  * of keys and if each key-value pair is equal to (according to
3640  * Object#==) the corresponding elements in the other hash.
3641  *
3642  * h1 = { "a" => 1, "c" => 2 }
3643  * h2 = { 7 => 35, "c" => 2, "a" => 1 }
3644  * h3 = { "a" => 1, "c" => 2, 7 => 35 }
3645  * h4 = { "a" => 1, "d" => 2, "f" => 35 }
3646  * h1 == h2 #=> false
3647  * h2 == h3 #=> true
3648  * h3 == h4 #=> false
3649  *
3650  * The orders of each hashes are not compared.
3651  *
3652  * h1 = { "a" => 1, "c" => 2 }
3653  * h2 = { "c" => 2, "a" => 1 }
3654  * h1 == h2 #=> true
3655  *
3656  */
3657 
3658 static VALUE
3659 rb_hash_equal(VALUE hash1, VALUE hash2)
3660 {
3661  return hash_equal(hash1, hash2, FALSE);
3662 }
3663 
3664 /*
3665  * call-seq:
3666  * hash.eql?(other) -> true or false
3667  *
3668  * Returns <code>true</code> if <i>hash</i> and <i>other</i> are
3669  * both hashes with the same content.
3670  * The orders of each hashes are not compared.
3671  */
3672 
3673 static VALUE
3674 rb_hash_eql(VALUE hash1, VALUE hash2)
3675 {
3676  return hash_equal(hash1, hash2, TRUE);
3677 }
3678 
3679 static int
3680 hash_i(VALUE key, VALUE val, VALUE arg)
3681 {
3682  st_index_t *hval = (st_index_t *)arg;
3683  st_index_t hdata[2];
3684 
3685  hdata[0] = rb_hash(key);
3686  hdata[1] = rb_hash(val);
3687  *hval ^= st_hash(hdata, sizeof(hdata), 0);
3688  return ST_CONTINUE;
3689 }
3690 
3691 /*
3692  * call-seq:
3693  * hsh.hash -> integer
3694  *
3695  * Compute a hash-code for this hash. Two hashes with the same content
3696  * will have the same hash code (and will compare using <code>eql?</code>).
3697  *
3698  * See also Object#hash.
3699  */
3700 
3701 static VALUE
3702 rb_hash_hash(VALUE hash)
3703 {
3705  st_index_t hval = rb_hash_start(size);
3706  hval = rb_hash_uint(hval, (st_index_t)rb_hash_hash);
3707  if (size) {
3708  rb_hash_foreach(hash, hash_i, (VALUE)&hval);
3709  }
3710  hval = rb_hash_end(hval);
3711  return ST2FIX(hval);
3712 }
3713 
3714 static int
3715 rb_hash_invert_i(VALUE key, VALUE value, VALUE hash)
3716 {
3717  rb_hash_aset(hash, value, key);
3718  return ST_CONTINUE;
3719 }
3720 
3721 /*
3722  * call-seq:
3723  * hsh.invert -> new_hash
3724  *
3725  * Returns a new hash created by using <i>hsh</i>'s values as keys, and
3726  * the keys as values.
3727  * If a key with the same value already exists in the <i>hsh</i>, then
3728  * the last one defined will be used, the earlier value(s) will be discarded.
3729  *
3730  * h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
3731  * h.invert #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}
3732  *
3733  * If there is no key with the same value, Hash#invert is involutive.
3734  *
3735  * h = { a: 1, b: 3, c: 4 }
3736  * h.invert.invert == h #=> true
3737  *
3738  * The condition, no key with the same value, can be tested by comparing
3739  * the size of inverted hash.
3740  *
3741  * # no key with the same value
3742  * h = { a: 1, b: 3, c: 4 }
3743  * h.size == h.invert.size #=> true
3744  *
3745  * # two (or more) keys has the same value
3746  * h = { a: 1, b: 3, c: 1 }
3747  * h.size == h.invert.size #=> false
3748  *
3749  */
3750 
3751 static VALUE
3752 rb_hash_invert(VALUE hash)
3753 {
3755 
3756  rb_hash_foreach(hash, rb_hash_invert_i, h);
3757  return h;
3758 }
3759 
3760 static int
3761 rb_hash_update_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
3762 {
3763  if (existing) {
3764  arg->old_value = *value;
3765  arg->new_value = arg->arg;
3766  }
3767  else {
3768  arg->new_key = *key;
3769  arg->new_value = arg->arg;
3770  }
3771  *value = arg->arg;
3772  return ST_CONTINUE;
3773 }
3774 
3775 NOINSERT_UPDATE_CALLBACK(rb_hash_update_callback)
3776 
3777 static int
3778 rb_hash_update_i(VALUE key, VALUE value, VALUE hash)
3779 {
3780  RHASH_UPDATE(hash, key, rb_hash_update_callback, value);
3781  return ST_CONTINUE;
3782 }
3783 
3784 static int
3785 rb_hash_update_block_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
3786 {
3787  VALUE newvalue = (VALUE)arg->arg;
3788 
3789  if (existing) {
3790  newvalue = rb_yield_values(3, (VALUE)*key, (VALUE)*value, newvalue);
3791  arg->old_value = *value;
3792  }
3793  else {
3794  arg->new_key = *key;
3795  }
3796  arg->new_value = newvalue;
3797  *value = newvalue;
3798  return ST_CONTINUE;
3799 }
3800 
3801 NOINSERT_UPDATE_CALLBACK(rb_hash_update_block_callback)
3802 
3803 static int
3804 rb_hash_update_block_i(VALUE key, VALUE value, VALUE hash)
3805 {
3806  RHASH_UPDATE(hash, key, rb_hash_update_block_callback, value);
3807  return ST_CONTINUE;
3808 }
3809 
3810 /*
3811  * call-seq:
3812  * hsh.merge!(other_hash1, other_hash2, ...) -> hsh
3813  * hsh.update(other_hash1, other_hash2, ...) -> hsh
3814  * hsh.merge!(other_hash1, other_hash2, ...) {|key, oldval, newval| block}
3815  * -> hsh
3816  * hsh.update(other_hash1, other_hash2, ...) {|key, oldval, newval| block}
3817  * -> hsh
3818  *
3819  * Adds the contents of the given hashes to the receiver.
3820  *
3821  * If no block is given, entries with duplicate keys are overwritten
3822  * with the values from each +other_hash+ successively,
3823  * otherwise the value for each duplicate key is determined by
3824  * calling the block with the key, its value in the receiver and
3825  * its value in each +other_hash+.
3826  *
3827  * h1 = { "a" => 100, "b" => 200 }
3828  * h1.merge! #=> {"a"=>100, "b"=>200}
3829  * h1 #=> {"a"=>100, "b"=>200}
3830  *
3831  * h1 = { "a" => 100, "b" => 200 }
3832  * h2 = { "b" => 246, "c" => 300 }
3833  * h1.merge!(h2) #=> {"a"=>100, "b"=>246, "c"=>300}
3834  * h1 #=> {"a"=>100, "b"=>246, "c"=>300}
3835  *
3836  * h1 = { "a" => 100, "b" => 200 }
3837  * h2 = { "b" => 246, "c" => 300 }
3838  * h3 = { "b" => 357, "d" => 400 }
3839  * h1.merge!(h2, h3)
3840  * #=> {"a"=>100, "b"=>357, "c"=>300, "d"=>400}
3841  * h1 #=> {"a"=>100, "b"=>357, "c"=>300, "d"=>400}
3842  *
3843  * h1 = { "a" => 100, "b" => 200 }
3844  * h2 = { "b" => 246, "c" => 300 }
3845  * h3 = { "b" => 357, "d" => 400 }
3846  * h1.merge!(h2, h3) {|key, v1, v2| v1 }
3847  * #=> {"a"=>100, "b"=>200, "c"=>300, "d"=>400}
3848  * h1 #=> {"a"=>100, "b"=>200, "c"=>300, "d"=>400}
3849  *
3850  * Hash#update is an alias for Hash#merge!.
3851  */
3852 
3853 static VALUE
3854 rb_hash_update(int argc, VALUE *argv, VALUE self)
3855 {
3856  int i;
3857  bool block_given = rb_block_given_p();
3858 
3859  rb_hash_modify(self);
3860  for (i = 0; i < argc; i++){
3861  VALUE hash = to_hash(argv[i]);
3862  if (block_given) {
3863  rb_hash_foreach(hash, rb_hash_update_block_i, self);
3864  }
3865  else {
3866  rb_hash_foreach(hash, rb_hash_update_i, self);
3867  }
3868  }
3869  return self;
3870 }
3871 
3876 };
3877 
3878 static int
3879 rb_hash_update_func_callback(st_data_t *key, st_data_t *value, struct update_arg *arg, int existing)
3880 {
3881  struct update_func_arg *uf_arg = (struct update_func_arg *)arg->arg;
3882  VALUE newvalue = uf_arg->value;
3883 
3884  if (existing) {
3885  newvalue = (*uf_arg->func)((VALUE)*key, (VALUE)*value, newvalue);
3886  arg->old_value = *value;
3887  }
3888  else {
3889  arg->new_key = *key;
3890  }
3891  arg->new_value = newvalue;
3892  *value = newvalue;
3893  return ST_CONTINUE;
3894 }
3895 
3896 NOINSERT_UPDATE_CALLBACK(rb_hash_update_func_callback)
3897 
3898 static int
3899 rb_hash_update_func_i(VALUE key, VALUE value, VALUE arg0)
3900 {
3901  struct update_func_arg *arg = (struct update_func_arg *)arg0;
3902  VALUE hash = arg->hash;
3903 
3904  arg->value = value;
3905  RHASH_UPDATE(hash, key, rb_hash_update_func_callback, (VALUE)arg);
3906  return ST_CONTINUE;
3907 }
3908 
3909 VALUE
3911 {
3912  rb_hash_modify(hash1);
3913  hash2 = to_hash(hash2);
3914  if (func) {
3915  struct update_func_arg arg;
3916  arg.hash = hash1;
3917  arg.func = func;
3918  rb_hash_foreach(hash2, rb_hash_update_func_i, (VALUE)&arg);
3919  }
3920  else {
3921  rb_hash_foreach(hash2, rb_hash_update_i, hash1);
3922  }
3923  return hash1;
3924 }
3925 
3926 /*
3927  * call-seq:
3928  * hsh.merge(other_hash1, other_hash2, ...) -> new_hash
3929  * hsh.merge(other_hash1, other_hash2, ...) {|key, oldval, newval| block}
3930  * -> new_hash
3931  *
3932  * Returns a new hash that combines the contents of the receiver and
3933  * the contents of the given hashes.
3934  *
3935  * If no block is given, entries with duplicate keys are overwritten
3936  * with the values from each +other_hash+ successively,
3937  * otherwise the value for each duplicate key is determined by
3938  * calling the block with the key, its value in the receiver and
3939  * its value in each +other_hash+.
3940  *
3941  * When called without any argument, returns a copy of the receiver.
3942  *
3943  * h1 = { "a" => 100, "b" => 200 }
3944  * h2 = { "b" => 246, "c" => 300 }
3945  * h3 = { "b" => 357, "d" => 400 }
3946  * h1.merge #=> {"a"=>100, "b"=>200}
3947  * h1.merge(h2) #=> {"a"=>100, "b"=>246, "c"=>300}
3948  * h1.merge(h2, h3) #=> {"a"=>100, "b"=>357, "c"=>300, "d"=>400}
3949  * h1.merge(h2) {|key, oldval, newval| newval - oldval}
3950  * #=> {"a"=>100, "b"=>46, "c"=>300}
3951  * h1.merge(h2, h3) {|key, oldval, newval| newval - oldval}
3952  * #=> {"a"=>100, "b"=>311, "c"=>300, "d"=>400}
3953  * h1 #=> {"a"=>100, "b"=>200}
3954  *
3955  */
3956 
3957 static VALUE
3958 rb_hash_merge(int argc, VALUE *argv, VALUE self)
3959 {
3960  return rb_hash_update(argc, argv, rb_hash_dup(self));
3961 }
3962 
3963 static int
3964 assoc_cmp(VALUE a, VALUE b)
3965 {
3966  return !RTEST(rb_equal(a, b));
3967 }
3968 
3969 static VALUE
3970 lookup2_call(VALUE arg)
3971 {
3972  VALUE *args = (VALUE *)arg;
3973  return rb_hash_lookup2(args[0], args[1], Qundef);
3974 }
3975 
3978  const struct st_hash_type *orighash;
3979 };
3980 
3981 static VALUE
3982 reset_hash_type(VALUE arg)
3983 {
3984  struct reset_hash_type_arg *p = (struct reset_hash_type_arg *)arg;
3986  RHASH_ST_TABLE(p->hash)->type = p->orighash;
3987  return Qundef;
3988 }
3989 
3990 static int
3991 assoc_i(VALUE key, VALUE val, VALUE arg)
3992 {
3993  VALUE *args = (VALUE *)arg;
3994 
3995  if (RTEST(rb_equal(args[0], key))) {
3996  args[1] = rb_assoc_new(key, val);
3997  return ST_STOP;
3998  }
3999  return ST_CONTINUE;
4000 }
4001 
4002 /*
4003  * call-seq:
4004  * hash.assoc(obj) -> an_array or nil
4005  *
4006  * Searches through the hash comparing _obj_ with the key using <code>==</code>.
4007  * Returns the key-value pair (two elements array) or +nil+
4008  * if no match is found. See Array#assoc.
4009  *
4010  * h = {"colors" => ["red", "blue", "green"],
4011  * "letters" => ["a", "b", "c" ]}
4012  * h.assoc("letters") #=> ["letters", ["a", "b", "c"]]
4013  * h.assoc("foo") #=> nil
4014  */
4015 
4016 VALUE
4018 {
4019  st_table *table;
4020  const struct st_hash_type *orighash;
4021  VALUE args[2];
4022 
4023  if (RHASH_EMPTY_P(hash)) return Qnil;
4024 
4025  ar_force_convert_table(hash, __FILE__, __LINE__);
4027  table = RHASH_ST_TABLE(hash);
4028  orighash = table->type;
4029 
4030  if (orighash != &identhash) {
4031  VALUE value;
4032  struct reset_hash_type_arg ensure_arg;
4033  struct st_hash_type assochash;
4034 
4035  assochash.compare = assoc_cmp;
4036  assochash.hash = orighash->hash;
4037  table->type = &assochash;
4038  args[0] = hash;
4039  args[1] = key;
4040  ensure_arg.hash = hash;
4041  ensure_arg.orighash = orighash;
4042  value = rb_ensure(lookup2_call, (VALUE)&args, reset_hash_type, (VALUE)&ensure_arg);
4043  if (value != Qundef) return rb_assoc_new(key, value);
4044  }
4045 
4046  args[0] = key;
4047  args[1] = Qnil;
4048  rb_hash_foreach(hash, assoc_i, (VALUE)args);
4049  return args[1];
4050 }
4051 
4052 static int
4053 rassoc_i(VALUE key, VALUE val, VALUE arg)
4054 {
4055  VALUE *args = (VALUE *)arg;
4056 
4057  if (RTEST(rb_equal(args[0], val))) {
4058  args[1] = rb_assoc_new(key, val);
4059  return ST_STOP;
4060  }
4061  return ST_CONTINUE;
4062 }
4063 
4064 /*
4065  * call-seq:
4066  * hash.rassoc(obj) -> an_array or nil
4067  *
4068  * Searches through the hash comparing _obj_ with the value using <code>==</code>.
4069  * Returns the first key-value pair (two-element array) that matches. See
4070  * also Array#rassoc.
4071  *
4072  * a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
4073  * a.rassoc("two") #=> [2, "two"]
4074  * a.rassoc("four") #=> nil
4075  */
4076 
4077 VALUE
4079 {
4080  VALUE args[2];
4081 
4082  args[0] = obj;
4083  args[1] = Qnil;
4084  rb_hash_foreach(hash, rassoc_i, (VALUE)args);
4085  return args[1];
4086 }
4087 
4088 static int
4089 flatten_i(VALUE key, VALUE val, VALUE ary)
4090 {
4091  VALUE pair[2];
4092 
4093  pair[0] = key;
4094  pair[1] = val;
4095  rb_ary_cat(ary, pair, 2);
4096 
4097  return ST_CONTINUE;
4098 }
4099 
4100 /*
4101  * call-seq:
4102  * hash.flatten -> an_array
4103  * hash.flatten(level) -> an_array
4104  *
4105  * Returns a new array that is a one-dimensional flattening of this
4106  * hash. That is, for every key or value that is an array, extract
4107  * its elements into the new array. Unlike Array#flatten, this
4108  * method does not flatten recursively by default. The optional
4109  * <i>level</i> argument determines the level of recursion to flatten.
4110  *
4111  * a = {1=> "one", 2 => [2,"two"], 3 => "three"}
4112  * a.flatten # => [1, "one", 2, [2, "two"], 3, "three"]
4113  * a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]
4114  */
4115 
4116 static VALUE
4117 rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
4118 {
4119  VALUE ary;
4120 
4121  rb_check_arity(argc, 0, 1);
4122 
4123  if (argc) {
4124  int level = NUM2INT(argv[0]);
4125 
4126  if (level == 0) return rb_hash_to_a(hash);
4127 
4128  ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2);
4129  rb_hash_foreach(hash, flatten_i, ary);
4130  level--;
4131 
4132  if (level > 0) {
4133  VALUE ary_flatten_level = INT2FIX(level);
4134  rb_funcallv(ary, id_flatten_bang, 1, &ary_flatten_level);
4135  }
4136  else if (level < 0) {
4137  /* flatten recursively */
4138  rb_funcallv(ary, id_flatten_bang, 0, 0);
4139  }
4140  }
4141  else {
4142  ary = rb_ary_new_capa(RHASH_SIZE(hash) * 2);
4143  rb_hash_foreach(hash, flatten_i, ary);
4144  }
4145 
4146  return ary;
4147 }
4148 
4149 static int
4150 delete_if_nil(VALUE key, VALUE value, VALUE hash)
4151 {
4152  if (NIL_P(value)) {
4153  return ST_DELETE;
4154  }
4155  return ST_CONTINUE;
4156 }
4157 
4158 static int
4159 set_if_not_nil(VALUE key, VALUE value, VALUE hash)
4160 {
4161  if (!NIL_P(value)) {
4162  rb_hash_aset(hash, key, value);
4163  }
4164  return ST_CONTINUE;
4165 }
4166 
4167 /*
4168  * call-seq:
4169  * hsh.compact -> new_hash
4170  *
4171  * Returns a new hash with the nil values/key pairs removed
4172  *
4173  * h = { a: 1, b: false, c: nil }
4174  * h.compact #=> { a: 1, b: false }
4175  * h #=> { a: 1, b: false, c: nil }
4176  *
4177  */
4178 
4179 static VALUE
4180 rb_hash_compact(VALUE hash)
4181 {
4182  VALUE result = rb_hash_new();
4183  if (!RHASH_EMPTY_P(hash)) {
4184  rb_hash_foreach(hash, set_if_not_nil, result);
4185  }
4186  return result;
4187 }
4188 
4189 /*
4190  * call-seq:
4191  * hsh.compact! -> hsh or nil
4192  *
4193  * Removes all nil values from the hash.
4194  * Returns nil if no changes were made, otherwise returns the hash.
4195  *
4196  * h = { a: 1, b: false, c: nil }
4197  * h.compact! #=> { a: 1, b: false }
4198  *
4199  */
4200 
4201 static VALUE
4202 rb_hash_compact_bang(VALUE hash)
4203 {
4204  st_index_t n;
4205  rb_hash_modify_check(hash);
4206  n = RHASH_SIZE(hash);
4207  if (n) {
4208  rb_hash_foreach(hash, delete_if_nil, hash);
4209  if (n != RHASH_SIZE(hash))
4210  return hash;
4211  }
4212  return Qnil;
4213 }
4214 
4215 static st_table *rb_init_identtable_with_size(st_index_t size);
4216 
4217 /*
4218  * call-seq:
4219  * hsh.compare_by_identity -> hsh
4220  *
4221  * Makes <i>hsh</i> compare its keys by their identity, i.e. it
4222  * will consider exact same objects as same keys.
4223  *
4224  * h1 = { "a" => 100, "b" => 200, :c => "c" }
4225  * h1["a"] #=> 100
4226  * h1.compare_by_identity
4227  * h1.compare_by_identity? #=> true
4228  * h1["a".dup] #=> nil # different objects.
4229  * h1[:c] #=> "c" # same symbols are all same.
4230  *
4231  */
4232 
4233 static VALUE
4234 rb_hash_compare_by_id(VALUE hash)
4235 {
4236  VALUE tmp;
4237  st_table *identtable;
4238 
4239  if (rb_hash_compare_by_id_p(hash)) return hash;
4240 
4241  rb_hash_modify_check(hash);
4242  ar_force_convert_table(hash, __FILE__, __LINE__);
4244 
4245  tmp = hash_alloc(0);
4246  identtable = rb_init_identtable_with_size(RHASH_SIZE(hash));
4247  RHASH_ST_TABLE_SET(tmp, identtable);
4248  rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tmp);
4250  RHASH_ST_TABLE_SET(hash, identtable);
4251  RHASH_ST_CLEAR(tmp);
4252  rb_gc_force_recycle(tmp);
4253 
4254  return hash;
4255 }
4256 
4257 /*
4258  * call-seq:
4259  * hsh.compare_by_identity? -> true or false
4260  *
4261  * Returns <code>true</code> if <i>hsh</i> will compare its keys by
4262  * their identity. Also see Hash#compare_by_identity.
4263  *
4264  */
4265 
4268 {
4270  return Qtrue;
4271  }
4272  else {
4273  return Qfalse;
4274  }
4275 }
4276 
4277 VALUE
4279 {
4280  VALUE hash = rb_hash_new();
4282  return hash;
4283 }
4284 
4285 st_table *
4287 {
4288  return st_init_table(&identhash);
4289 }
4290 
4291 static st_table *
4292 rb_init_identtable_with_size(st_index_t size)
4293 {
4295 }
4296 
4297 static int
4298 any_p_i(VALUE key, VALUE value, VALUE arg)
4299 {
4300  VALUE ret = rb_yield(rb_assoc_new(key, value));
4301  if (RTEST(ret)) {
4302  *(VALUE *)arg = Qtrue;
4303  return ST_STOP;
4304  }
4305  return ST_CONTINUE;
4306 }
4307 
4308 static int
4309 any_p_i_fast(VALUE key, VALUE value, VALUE arg)
4310 {
4311  VALUE ret = rb_yield_values(2, key, value);
4312  if (RTEST(ret)) {
4313  *(VALUE *)arg = Qtrue;
4314  return ST_STOP;
4315  }
4316  return ST_CONTINUE;
4317 }
4318 
4319 static int
4320 any_p_i_pattern(VALUE key, VALUE value, VALUE arg)
4321 {
4322  VALUE ret = rb_funcall(((VALUE *)arg)[1], idEqq, 1, rb_assoc_new(key, value));
4323  if (RTEST(ret)) {
4324  *(VALUE *)arg = Qtrue;
4325  return ST_STOP;
4326  }
4327  return ST_CONTINUE;
4328 }
4329 
4330 /*
4331  * call-seq:
4332  * hsh.any? [{ |(key, value)| block }] -> true or false
4333  * hsh.any?(pattern) -> true or false
4334  *
4335  * See also Enumerable#any?
4336  */
4337 
4338 static VALUE
4339 rb_hash_any_p(int argc, VALUE *argv, VALUE hash)
4340 {
4341  VALUE args[2];
4342  args[0] = Qfalse;
4343 
4344  rb_check_arity(argc, 0, 1);
4345  if (RHASH_EMPTY_P(hash)) return Qfalse;
4346  if (argc) {
4347  if (rb_block_given_p()) {
4348  rb_warn("given block not used");
4349  }
4350  args[1] = argv[0];
4351 
4352  rb_hash_foreach(hash, any_p_i_pattern, (VALUE)args);
4353  }
4354  else {
4355  if (!rb_block_given_p()) {
4356  /* yields pairs, never false */
4357  return Qtrue;
4358  }
4359  if (rb_block_arity() > 1)
4360  rb_hash_foreach(hash, any_p_i_fast, (VALUE)args);
4361  else
4362  rb_hash_foreach(hash, any_p_i, (VALUE)args);
4363  }
4364  return args[0];
4365 }
4366 
4367 /*
4368  * call-seq:
4369  * hsh.dig(key, ...) -> object
4370  *
4371  * Extracts the nested value specified by the sequence of <i>key</i>
4372  * objects by calling +dig+ at each step, returning +nil+ if any
4373  * intermediate step is +nil+.
4374  *
4375  * h = { foo: {bar: {baz: 1}}}
4376  *
4377  * h.dig(:foo, :bar, :baz) #=> 1
4378  * h.dig(:foo, :zot, :xyz) #=> nil
4379  *
4380  * g = { foo: [10, 11, 12] }
4381  * g.dig(:foo, 1) #=> 11
4382  * g.dig(:foo, 1, 0) #=> TypeError: Integer does not have #dig method
4383  * g.dig(:foo, :bar) #=> TypeError: no implicit conversion of Symbol into Integer
4384  */
4385 
4386 static VALUE
4387 rb_hash_dig(int argc, VALUE *argv, VALUE self)
4388 {
4390  self = rb_hash_aref(self, *argv);
4391  if (!--argc) return self;
4392  ++argv;
4393  return rb_obj_dig(argc, argv, self, Qnil);
4394 }
4395 
4396 static int
4397 hash_le_i(VALUE key, VALUE value, VALUE arg)
4398 {
4399  VALUE *args = (VALUE *)arg;
4400  VALUE v = rb_hash_lookup2(args[0], key, Qundef);
4401  if (v != Qundef && rb_equal(value, v)) return ST_CONTINUE;
4402  args[1] = Qfalse;
4403  return ST_STOP;
4404 }
4405 
4406 static VALUE
4407 hash_le(VALUE hash1, VALUE hash2)
4408 {
4409  VALUE args[2];
4410  args[0] = hash2;
4411  args[1] = Qtrue;
4412  rb_hash_foreach(hash1, hash_le_i, (VALUE)args);
4413  return args[1];
4414 }
4415 
4416 /*
4417  * call-seq:
4418  * hash <= other -> true or false
4419  *
4420  * Returns <code>true</code> if <i>hash</i> is subset of
4421  * <i>other</i> or equals to <i>other</i>.
4422  *
4423  * h1 = {a:1, b:2}
4424  * h2 = {a:1, b:2, c:3}
4425  * h1 <= h2 #=> true
4426  * h2 <= h1 #=> false
4427  * h1 <= h1 #=> true
4428  */
4429 static VALUE
4430 rb_hash_le(VALUE hash, VALUE other)
4431 {
4432  other = to_hash(other);
4433  if (RHASH_SIZE(hash) > RHASH_SIZE(other)) return Qfalse;
4434  return hash_le(hash, other);
4435 }
4436 
4437 /*
4438  * call-seq:
4439  * hash < other -> true or false
4440  *
4441  * Returns <code>true</code> if <i>hash</i> is subset of
4442  * <i>other</i>.
4443  *
4444  * h1 = {a:1, b:2}
4445  * h2 = {a:1, b:2, c:3}
4446  * h1 < h2 #=> true
4447  * h2 < h1 #=> false
4448  * h1 < h1 #=> false
4449  */
4450 static VALUE
4451 rb_hash_lt(VALUE hash, VALUE other)
4452 {
4453  other = to_hash(other);
4454  if (RHASH_SIZE(hash) >= RHASH_SIZE(other)) return Qfalse;
4455  return hash_le(hash, other);
4456 }
4457 
4458 /*
4459  * call-seq:
4460  * hash >= other -> true or false
4461  *
4462  * Returns <code>true</code> if <i>other</i> is subset of
4463  * <i>hash</i> or equals to <i>hash</i>.
4464  *
4465  * h1 = {a:1, b:2}
4466  * h2 = {a:1, b:2, c:3}
4467  * h1 >= h2 #=> false
4468  * h2 >= h1 #=> true
4469  * h1 >= h1 #=> true
4470  */
4471 static VALUE
4472 rb_hash_ge(VALUE hash, VALUE other)
4473 {
4474  other = to_hash(other);
4475  if (RHASH_SIZE(hash) < RHASH_SIZE(other)) return Qfalse;
4476  return hash_le(other, hash);
4477 }
4478 
4479 /*
4480  * call-seq:
4481  * hash > other -> true or false
4482  *
4483  * Returns <code>true</code> if <i>other</i> is subset of
4484  * <i>hash</i>.
4485  *
4486  * h1 = {a:1, b:2}
4487  * h2 = {a:1, b:2, c:3}
4488  * h1 > h2 #=> false
4489  * h2 > h1 #=> true
4490  * h1 > h1 #=> false
4491  */
4492 static VALUE
4493 rb_hash_gt(VALUE hash, VALUE other)
4494 {
4495  other = to_hash(other);
4496  if (RHASH_SIZE(hash) <= RHASH_SIZE(other)) return Qfalse;
4497  return hash_le(other, hash);
4498 }
4499 
4500 static VALUE
4501 hash_proc_call(RB_BLOCK_CALL_FUNC_ARGLIST(key, hash))
4502 {
4503  rb_check_arity(argc, 1, 1);
4504  return rb_hash_aref(hash, *argv);
4505 }
4506 
4507 /*
4508  * call-seq:
4509  * hash.to_proc -> proc
4510  *
4511  * Returns a Proc which maps keys to values.
4512  *
4513  * h = {a:1, b:2}
4514  * hp = h.to_proc
4515  * hp.call(:a) #=> 1
4516  * hp.call(:b) #=> 2
4517  * hp.call(:c) #=> nil
4518  * [:a, :b, :c].map(&h) #=> [1, 2, nil]
4519  */
4520 static VALUE
4521 rb_hash_to_proc(VALUE hash)
4522 {
4523  return rb_func_proc_new(hash_proc_call, hash);
4524 }
4525 
4526 static VALUE
4527 rb_hash_deconstruct_keys(VALUE hash, VALUE keys)
4528 {
4529  return hash;
4530 }
4531 
4532 static int
4533 add_new_i(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
4534 {
4535  VALUE *args = (VALUE *)arg;
4536  if (existing) return ST_STOP;
4537  RB_OBJ_WRITTEN(args[0], Qundef, (VALUE)*key);
4538  RB_OBJ_WRITE(args[0], (VALUE *)val, args[1]);
4539  return ST_CONTINUE;
4540 }
4541 
4542 /*
4543  * add +key+ to +val+ pair if +hash+ does not contain +key+.
4544  * returns non-zero if +key+ was contained.
4545  */
4546 int
4548 {
4549  st_table *tbl;
4550  int ret = 0;
4551  VALUE args[2];
4552  args[0] = hash;
4553  args[1] = val;
4554 
4555  if (RHASH_AR_TABLE_P(hash)) {
4556  hash_ar_table(hash);
4557 
4558  ret = ar_update(hash, (st_data_t)key, add_new_i, (st_data_t)args);
4559  if (ret != -1) {
4560  return ret;
4561  }
4562  ar_try_convert_table(hash);
4563  }
4564  tbl = RHASH_TBL_RAW(hash);
4565  return st_update(tbl, (st_data_t)key, add_new_i, (st_data_t)args);
4566 
4567 }
4568 
4569 static st_data_t
4570 key_stringify(VALUE key)
4571 {
4572  return (rb_obj_class(key) == rb_cString && !RB_OBJ_FROZEN(key)) ?
4573  rb_hash_key_str(key) : key;
4574 }
4575 
4576 static void
4577 ar_bulk_insert(VALUE hash, long argc, const VALUE *argv)
4578 {
4579  long i;
4580  for (i = 0; i < argc; ) {
4581  st_data_t k = key_stringify(argv[i++]);
4582  st_data_t v = argv[i++];
4583  ar_insert(hash, k, v);
4584  RB_OBJ_WRITTEN(hash, Qundef, k);
4586  }
4587 }
4588 
4589 void
4591 {
4592  HASH_ASSERT(argc % 2 == 0);
4593  if (argc > 0) {
4594  st_index_t size = argc / 2;
4595 
4596  if (RHASH_TABLE_NULL_P(hash)) {
4597  if (size <= RHASH_AR_TABLE_MAX_SIZE) {
4598  hash_ar_table(hash);
4599  }
4600  else {
4602  }
4603  }
4604 
4605  if (RHASH_AR_TABLE_P(hash) &&
4607  ar_bulk_insert(hash, argc, argv);
4608  }
4609  else {
4611  }
4612  }
4613 }
4614 
4615 static char **origenviron;
4616 #ifdef _WIN32
4617 #define GET_ENVIRON(e) ((e) = rb_w32_get_environ())
4618 #define FREE_ENVIRON(e) rb_w32_free_environ(e)
4619 static char **my_environ;
4620 #undef environ
4621 #define environ my_environ
4622 #undef getenv
4623 static char *(*w32_getenv)(const char*);
4624 static char *
4625 w32_getenv_unknown(const char *name)
4626 {
4627  char *(*func)(const char*);
4629  func = rb_w32_getenv;
4630  }
4631  else {
4632  func = rb_w32_ugetenv;
4633  }
4634  /* atomic assignment in flat memory model */
4635  return (w32_getenv = func)(name);
4636 }
4637 static char *(*w32_getenv)(const char*) = w32_getenv_unknown;
4638 #define getenv(n) w32_getenv(n)
4639 #elif defined(__APPLE__)
4640 #undef environ
4641 #define environ (*_NSGetEnviron())
4642 #define GET_ENVIRON(e) (e)
4643 #define FREE_ENVIRON(e)
4644 #else
4645 extern char **environ;
4646 #define GET_ENVIRON(e) (e)
4647 #define FREE_ENVIRON(e)
4648 #endif
4649 #ifdef ENV_IGNORECASE
4650 #define ENVMATCH(s1, s2) (STRCASECMP((s1), (s2)) == 0)
4651 #define ENVNMATCH(s1, s2, n) (STRNCASECMP((s1), (s2), (n)) == 0)
4652 #else
4653 #define ENVMATCH(n1, n2) (strcmp((n1), (n2)) == 0)
4654 #define ENVNMATCH(s1, s2, n) (memcmp((s1), (s2), (n)) == 0)
4655 #endif
4656 
4657 static VALUE
4658 env_enc_str_new(const char *ptr, long len, rb_encoding *enc)
4659 {
4660 #ifdef _WIN32
4662  const int ecflags = ECONV_INVALID_REPLACE | ECONV_UNDEF_REPLACE;
4663  rb_encoding *utf8 = rb_utf8_encoding();
4664  VALUE str = rb_enc_str_new(NULL, 0, (internal ? internal : enc));
4665  if (NIL_P(rb_str_cat_conv_enc_opts(str, 0, ptr, len, utf8, ecflags, Qnil))) {
4667  }
4668 #else
4670 #endif
4671 
4672  rb_obj_freeze(str);
4673  return str;
4674 }
4675 
4676 static VALUE
4677 env_enc_str_new_cstr(const char *ptr, rb_encoding *enc)
4678 {
4679  return env_enc_str_new(ptr, strlen(ptr), enc);
4680 }
4681 
4682 static VALUE
4683 env_str_new(const char *ptr, long len)
4684 {
4685  return env_enc_str_new(ptr, len, rb_locale_encoding());
4686 }
4687 
4688 static VALUE
4689 env_str_new2(const char *ptr)
4690 {
4691  if (!ptr) return Qnil;
4692  return env_str_new(ptr, strlen(ptr));
4693 }
4694 
4695 static const char TZ_ENV[] = "TZ";
4696 extern bool ruby_tz_uptodate_p;
4697 
4698 static rb_encoding *
4699 env_encoding_for(const char *name, const char *ptr)
4700 {
4701  if (ENVMATCH(name, PATH_ENV)) {
4702  return rb_filesystem_encoding();
4703  }
4704  else {
4705  return rb_locale_encoding();
4706  }
4707 }
4708 
4709 static VALUE
4710 env_name_new(const char *name, const char *ptr)
4711 {
4712  return env_enc_str_new_cstr(ptr, env_encoding_for(name, ptr));
4713 }
4714 
4715 static void *
4716 get_env_cstr(
4717 #ifdef _WIN32
4718  volatile VALUE *pstr,
4719 #else
4720  VALUE str,
4721 #endif
4722  const char *name)
4723 {
4724 #ifdef _WIN32
4725  VALUE str = *pstr;
4726 #endif
4727  char *var;
4728  rb_encoding *enc = rb_enc_get(str);
4729  if (!rb_enc_asciicompat(enc)) {
4730  rb_raise(rb_eArgError, "bad environment variable %s: ASCII incompatible encoding: %s",
4731  name, rb_enc_name(enc));
4732  }
4733 #ifdef _WIN32
4734  if (!rb_enc_str_asciionly_p(str)) {
4735  *pstr = str = rb_str_conv_enc(str, NULL, rb_utf8_encoding());
4736  }
4737 #endif
4738  var = RSTRING_PTR(str);
4739  if (memchr(var, '\0', RSTRING_LEN(str))) {
4740  rb_raise(rb_eArgError, "bad environment variable %s: contains null byte", name);
4741  }
4742  return rb_str_fill_terminator(str, 1); /* ASCII compatible */
4743 }
4744 
4745 #ifdef _WIN32
4746 #define get_env_ptr(var, val) \
4747  (var = get_env_cstr(&(val), #var))
4748 #else
4749 #define get_env_ptr(var, val) \
4750  (var = get_env_cstr(val, #var))
4751 #endif
4752 
4753 static inline const char *
4754 env_name(volatile VALUE *s)
4755 {
4756  const char *name;
4757  SafeStringValue(*s);
4758  get_env_ptr(name, *s);
4759  return name;
4760 }
4761 
4762 #define env_name(s) env_name(&(s))
4763 
4764 static VALUE env_aset(VALUE nm, VALUE val);
4765 
4766 static VALUE
4767 env_delete(VALUE name)
4768 {
4769  const char *nam, *val;
4770 
4771  nam = env_name(name);
4772  val = getenv(nam);
4773 
4774  /*
4775  * ENV['TZ'] = nil has a special meaning.
4776  * TZ is no longer considered up-to-date and ruby call tzset() as needed.
4777  * It could be useful if sysadmin change /etc/localtime.
4778  * This hack might works only on Linux glibc.
4779  */
4780  if (ENVMATCH(nam, TZ_ENV)) {
4782  }
4783 
4784  if (val) {
4785  VALUE value = env_str_new2(val);
4786 
4787  ruby_setenv(nam, 0);
4788  if (ENVMATCH(nam, PATH_ENV)) {
4789  RB_GC_GUARD(name);
4790  }
4791  return value;
4792  }
4793  return Qnil;
4794 }
4795 
4796 /*
4797  * call-seq:
4798  * ENV.delete(name) -> value
4799  * ENV.delete(name) { |name| block } -> value
4800  *
4801  * Deletes the environment variable with +name+ if it exists and returns its value:
4802  * ENV['foo'] = '0'
4803  * ENV.delete('foo') # => '0'
4804  * Returns +nil+ if the named environment variable does not exist:
4805  * ENV.delete('foo') # => nil
4806  * If a block given and the environment variable does not exist,
4807  * yields +name+ to the block and returns +nil+:
4808  * ENV.delete('foo') { |name| puts name } # => nil
4809  * foo
4810  * If a block given and the environment variable exists,
4811  * deletes the environment variable and returns its value (ignoring the block):
4812  * ENV['foo'] = '0'
4813  * ENV.delete('foo') { |name| fail 'ignored' } # => "0"
4814  * Raises an exception if +name+ is invalid.
4815  * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
4816  */
4817 static VALUE
4818 env_delete_m(VALUE obj, VALUE name)
4819 {
4820  VALUE val;
4821 
4822  val = env_delete(name);
4823  if (NIL_P(val) && rb_block_given_p()) rb_yield(name);
4824  return val;
4825 }
4826 
4827 /*
4828  * call-seq:
4829  * ENV[name] -> value
4830  *
4831  * Returns the value for the environment variable +name+ if it exists:
4832  * ENV['foo'] = '0'
4833  * ENV['foo'] # => "0"
4834  * Returns nil if the named variable does not exist:
4835  * ENV.clear
4836  * ENV['foo'] # => nil
4837  * Raises an exception if +name+ is invalid.
4838  * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
4839  */
4840 static VALUE
4841 rb_f_getenv(VALUE obj, VALUE name)
4842 {
4843  const char *nam, *env;
4844 
4845  nam = env_name(name);
4846  env = getenv(nam);
4847  if (env) {
4848  return env_name_new(nam, env);
4849  }
4850  return Qnil;
4851 }
4852 
4853 /*
4854  * call-seq:
4855  * ENV.fetch(name) -> value
4856  * ENV.fetch(name, default) -> value
4857  * ENV.fetch(name) { |name| block } -> value
4858  *
4859  * If +name+ is the name of an environment variable, returns its value:
4860  * ENV['foo'] = '0'
4861  * ENV.fetch('foo') # => '0'
4862  * Otherwise if a block is given (but not a default value),
4863  * yields +name+ to the block and returns the block's return value:
4864  * ENV.fetch('foo') { |name| :need_not_return_a_string } # => :need_not_return_a_string
4865  * Otherwise if a default value is given (but not a block), returns the default value:
4866  * ENV.delete('foo')
4867  * ENV.fetch('foo', :default_need_not_be_a_string) # => :default_need_not_be_a_string
4868  * If the environment variable does not exist and both default and block are given,
4869  * issues a warning ("warning: block supersedes default value argument"),
4870  * yields +name+ to the block, and returns the block's return value:
4871  * ENV.fetch('foo', :default) { |name| :block_return } # => :block_return
4872  * Raises KeyError if +name+ is valid, but not found,
4873  * and neither default value nor block is given:
4874  * ENV.fetch('foo') # Raises KeyError (key not found: "foo")
4875  * Raises an exception if +name+ is invalid.
4876  * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
4877  */
4878 static VALUE
4879 env_fetch(int argc, VALUE *argv, VALUE _)
4880 {
4881  VALUE key;
4882  long block_given;
4883  const char *nam, *env;
4884 
4885  rb_check_arity(argc, 1, 2);
4886  key = argv[0];
4887  block_given = rb_block_given_p();
4888  if (block_given && argc == 2) {
4889  rb_warn("block supersedes default value argument");
4890  }
4891  nam = env_name(key);
4892  env = getenv(nam);
4893  if (!env) {
4894  if (block_given) return rb_yield(key);
4895  if (argc == 1) {
4896  rb_key_err_raise(rb_sprintf("key not found: \"%"PRIsVALUE"\"", key), envtbl, key);
4897  }
4898  return argv[1];
4899  }
4900  return env_name_new(nam, env);
4901 }
4902 
4903 int
4905 {
4906  rb_warning("rb_env_path_tainted is deprecated and will be removed in Ruby 3.2.");
4907  return 0;
4908 }
4909 
4910 #if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
4911 #elif defined __sun
4912 static int
4913 in_origenv(const char *str)
4914 {
4915  char **env;
4916  for (env = origenviron; *env; ++env) {
4917  if (*env == str) return 1;
4918  }
4919  return 0;
4920 }
4921 #else
4922 static int
4923 envix(const char *nam)
4924 {
4925  register int i, len = strlen(nam);
4926  char **env;
4927 
4928  env = GET_ENVIRON(environ);
4929  for (i = 0; env[i]; i++) {
4930  if (ENVNMATCH(env[i],nam,len) && env[i][len] == '=')
4931  break; /* memcmp must come first to avoid */
4932  } /* potential SEGV's */
4934  return i;
4935 }
4936 #endif
4937 
4938 #if defined(_WIN32)
4939 static size_t
4940 getenvsize(const WCHAR* p)
4941 {
4942  const WCHAR* porg = p;
4943  while (*p++) p += lstrlenW(p) + 1;
4944  return p - porg + 1;
4945 }
4946 
4947 static size_t
4948 getenvblocksize(void)
4949 {
4950 #ifdef _MAX_ENV
4951  return _MAX_ENV;
4952 #else
4953  return 32767;
4954 #endif
4955 }
4956 
4957 static int
4958 check_envsize(size_t n)
4959 {
4960  if (_WIN32_WINNT < 0x0600 && rb_w32_osver() < 6) {
4961  /* https://msdn.microsoft.com/en-us/library/windows/desktop/ms682653(v=vs.85).aspx */
4962  /* Windows Server 2003 and Windows XP: The maximum size of the
4963  * environment block for the process is 32,767 characters. */
4964  WCHAR* p = GetEnvironmentStringsW();
4965  if (!p) return -1; /* never happen */
4966  n += getenvsize(p);
4967  FreeEnvironmentStringsW(p);
4968  if (n >= getenvblocksize()) {
4969  return -1;
4970  }
4971  }
4972  return 0;
4973 }
4974 #endif
4975 
4976 #if defined(_WIN32) || \
4977  (defined(__sun) && !(defined(HAVE_SETENV) && defined(HAVE_UNSETENV)))
4978 
4979 NORETURN(static void invalid_envname(const char *name));
4980 
4981 static void
4982 invalid_envname(const char *name)
4983 {
4984  rb_syserr_fail_str(EINVAL, rb_sprintf("ruby_setenv(%s)", name));
4985 }
4986 
4987 static const char *
4988 check_envname(const char *name)
4989 {
4990  if (strchr(name, '=')) {
4991  invalid_envname(name);
4992  }
4993  return name;
4994 }
4995 #endif
4996 
4997 void
4998 ruby_setenv(const char *name, const char *value)
4999 {
5000 #if defined(_WIN32)
5001 # if defined(MINGW_HAS_SECURE_API) || RUBY_MSVCRT_VERSION >= 80
5002 # define HAVE__WPUTENV_S 1
5003 # endif
5004  VALUE buf;
5005  WCHAR *wname;
5006  WCHAR *wvalue = 0;
5007  int failed = 0;
5008  int len;
5009  check_envname(name);
5010  len = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0);
5011  if (value) {
5012  int len2;
5013  len2 = MultiByteToWideChar(CP_UTF8, 0, value, -1, NULL, 0);
5014  if (check_envsize((size_t)len + len2)) { /* len and len2 include '\0' */
5015  goto fail; /* 2 for '=' & '\0' */
5016  }
5017  wname = ALLOCV_N(WCHAR, buf, len + len2);
5018  wvalue = wname + len;
5019  MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, len);
5020  MultiByteToWideChar(CP_UTF8, 0, value, -1, wvalue, len2);
5021 #ifndef HAVE__WPUTENV_S
5022  wname[len-1] = L'=';
5023 #endif
5024  }
5025  else {
5026  wname = ALLOCV_N(WCHAR, buf, len + 1);
5027  MultiByteToWideChar(CP_UTF8, 0, name, -1, wname, len);
5028  wvalue = wname + len;
5029  *wvalue = L'\0';
5030 #ifndef HAVE__WPUTENV_S
5031  wname[len-1] = L'=';
5032 #endif
5033  }
5034 #ifndef HAVE__WPUTENV_S
5035  failed = _wputenv(wname);
5036 #else
5037  failed = _wputenv_s(wname, wvalue);
5038 #endif
5039  ALLOCV_END(buf);
5040  /* even if putenv() failed, clean up and try to delete the
5041  * variable from the system area. */
5042  if (!value || !*value) {
5043  /* putenv() doesn't handle empty value */
5044  if (!SetEnvironmentVariable(name, value) &&
5045  GetLastError() != ERROR_ENVVAR_NOT_FOUND) goto fail;
5046  }
5047  if (failed) {
5048  fail:
5049  invalid_envname(name);
5050  }
5051 #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
5052  if (value) {
5053  if (setenv(name, value, 1))
5054  rb_sys_fail_str(rb_sprintf("setenv(%s)", name));
5055  }
5056  else {
5057 #ifdef VOID_UNSETENV
5058  unsetenv(name);
5059 #else
5060  if (unsetenv(name))
5061  rb_sys_fail_str(rb_sprintf("unsetenv(%s)", name));
5062 #endif
5063  }
5064 #elif defined __sun
5065  /* Solaris 9 (or earlier) does not have setenv(3C) and unsetenv(3C). */
5066  /* The below code was tested on Solaris 10 by:
5067  % ./configure ac_cv_func_setenv=no ac_cv_func_unsetenv=no
5068  */
5069  size_t len, mem_size;
5070  char **env_ptr, *str, *mem_ptr;
5071 
5072  check_envname(name);
5073  len = strlen(name);
5074  if (value) {
5075  mem_size = len + strlen(value) + 2;
5076  mem_ptr = malloc(mem_size);
5077  if (mem_ptr == NULL)
5078  rb_sys_fail_str(rb_sprintf("malloc("PRIuSIZE")", mem_size));
5079  snprintf(mem_ptr, mem_size, "%s=%s", name, value);
5080  }
5081  for (env_ptr = GET_ENVIRON(environ); (str = *env_ptr) != 0; ++env_ptr) {
5082  if (!strncmp(str, name, len) && str[len] == '=') {
5083  if (!in_origenv(str)) free(str);
5084  while ((env_ptr[0] = env_ptr[1]) != 0) env_ptr++;
5085  break;
5086  }
5087  }
5088  if (value) {
5089  if (putenv(mem_ptr)) {
5090  free(mem_ptr);
5091  rb_sys_fail_str(rb_sprintf("putenv(%s)", name));
5092  }
5093  }
5094 #else /* WIN32 */
5095  size_t len;
5096  int i;
5097 
5098  i=envix(name); /* where does it go? */
5099 
5100  if (environ == origenviron) { /* need we copy environment? */
5101  int j;
5102  int max;
5103  char **tmpenv;
5104 
5105  for (max = i; environ[max]; max++) ;
5106  tmpenv = ALLOC_N(char*, max+2);
5107  for (j=0; j<max; j++) /* copy environment */
5108  tmpenv[j] = ruby_strdup(environ[j]);
5109  tmpenv[max] = 0;
5110  environ = tmpenv; /* tell exec where it is now */
5111  }
5112  if (environ[i]) {
5113  char **envp = origenviron;
5114  while (*envp && *envp != environ[i]) envp++;
5115  if (!*envp)
5116  xfree(environ[i]);
5117  if (!value) {
5118  while (environ[i]) {
5119  environ[i] = environ[i+1];
5120  i++;
5121  }
5122  return;
5123  }
5124  }
5125  else { /* does not exist yet */
5126  if (!value) return;
5127  REALLOC_N(environ, char*, i+2); /* just expand it a bit */
5128  environ[i+1] = 0; /* make sure it's null terminated */
5129  }
5130  len = strlen(name) + strlen(value) + 2;
5131  environ[i] = ALLOC_N(char, len);
5132  snprintf(environ[i],len,"%s=%s",name,value); /* all that work just for this */
5133 #endif /* WIN32 */
5134 }
5135 
5136 void
5137 ruby_unsetenv(const char *name)
5138 {
5139  ruby_setenv(name, 0);
5140 }
5141 
5142 /*
5143  * call-seq:
5144  * ENV[name] = value -> value
5145  * ENV.store(name, value) -> value
5146  *
5147  * ENV.store is an alias for ENV.[]=.
5148  *
5149  * Creates, updates, or deletes the named environment variable, returning the value.
5150  * Both +name+ and +value+ may be instances of String.
5151  * See {Valid Names and Values}[#class-ENV-label-Valid+Names+and+Values].
5152  *
5153  * - If the named environment variable does not exist:
5154  * - If +value+ is +nil+, does nothing.
5155  * ENV.clear
5156  * ENV['foo'] = nil # => nil
5157  * ENV.include?('foo') # => false
5158  * ENV.store('bar', nil) # => nil
5159  * ENV.include?('bar') # => false
5160  * - If +value+ is not +nil+, creates the environment variable with +name+ and +value+:
5161  * # Create 'foo' using ENV.[]=.
5162  * ENV['foo'] = '0' # => '0'
5163  * ENV['foo'] # => '0'
5164  * # Create 'bar' using ENV.store.
5165  * ENV.store('bar', '1') # => '1'
5166  * ENV['bar'] # => '1'
5167  * - If the named environment variable exists:
5168  * - If +value+ is not +nil+, updates the environment variable with value +value+:
5169  * # Update 'foo' using ENV.[]=.
5170  * ENV['foo'] = '2' # => '2'
5171  * ENV['foo'] # => '2'
5172  * # Update 'bar' using ENV.store.
5173  * ENV.store('bar', '3') # => '3'
5174  * ENV['bar'] # => '3'
5175  * - If +value+ is +nil+, deletes the environment variable:
5176  * # Delete 'foo' using ENV.[]=.
5177  * ENV['foo'] = nil # => nil
5178  * ENV.include?('foo') # => false
5179  * # Delete 'bar' using ENV.store.
5180  * ENV.store('bar', nil) # => nil
5181  * ENV.include?('bar') # => false
5182  *
5183  * Raises an exception if +name+ or +value+ is invalid.
5184  * See {Invalid Names and Values}[#class-ENV-label-Invalid+Names+and+Values].
5185  */
5186 static VALUE
5187 env_aset_m(VALUE obj, VALUE nm, VALUE val)
5188 {
5189  return env_aset(nm, val);
5190 }
5191 
5192 static VALUE
5193 env_aset(VALUE nm, VALUE val)
5194 {
5195  char *name, *value;
5196 
5197  if (NIL_P(val)) {
5198  env_delete(nm);
5199  return Qnil;
5200  }
5201  SafeStringValue(nm);
5202  SafeStringValue(val);
5203  /* nm can be modified in `val.to_str`, don't get `name` before
5204  * check for `val` */
5205  get_env_ptr(name, nm);
5206  get_env_ptr(value, val);
5207 
5208  ruby_setenv(name, value);
5209  if (ENVMATCH(name, PATH_ENV)) {
5210  RB_GC_GUARD(nm);
5211  }
5212  else if (ENVMATCH(name, TZ_ENV)) {
5214  }
5215  return val;
5216 }
5217 
5218 static VALUE
5219 env_keys(void)
5220 {
5221  char **env;
5222  VALUE ary;
5223 
5224  ary = rb_ary_new();
5225  env = GET_ENVIRON(environ);
5226  while (*env) {
5227  char *s = strchr(*env, '=');
5228  if (s) {
5229  rb_ary_push(ary, env_str_new(*env, s-*env));
5230  }
5231  env++;
5232  }
5234  return ary;
5235 }
5236 
5237 /*
5238  * call-seq:
5239  * ENV.keys -> Array
5240  *
5241  * Returns all variable names in an Array:
5242  * ENV.replace('foo' => '0', 'bar' => '1')
5243  * ENV.keys # => ['bar', 'foo']
5244  * The order of the names is OS-dependent.
5245  * See {About Ordering}[#class-ENV-label-About+Ordering].
5246  *
5247  * Returns the empty Array if ENV is empty:
5248  * ENV.clear
5249  * ENV.keys # => []
5250  */
5251 
5252 static VALUE
5253 env_f_keys(VALUE _)
5254 {
5255  return env_keys();
5256 }
5257 
5258 static VALUE
5259 rb_env_size(VALUE ehash, VALUE args, VALUE eobj)
5260 {
5261  char **env;
5262  long cnt = 0;
5263 
5264  env = GET_ENVIRON(environ);
5265  for (; *env ; ++env) {
5266  if (strchr(*env, '=')) {
5267  cnt++;
5268  }
5269  }
5271  return LONG2FIX(cnt);
5272 }
5273 
5274 /*
5275  * call-seq:
5276  * ENV.each_key { |name| block } -> ENV
5277  * ENV.each_key -> Enumerator
5278  *
5279  * Yields each environment variable name:
5280  * ENV.replace('foo' => '0', 'bar' => '1') # => ENV
5281  * names = []
5282  * ENV.each_key { |name| names.push(name) } # => ENV
5283  * names # => ["bar", "foo"]
5284  *
5285  * Returns an Enumerator if no block given:
5286  * e = ENV.each_key # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_key>
5287  * names = []
5288  * e.each { |name| names.push(name) } # => ENV
5289  * names # => ["bar", "foo"]
5290  */
5291 static VALUE
5292 env_each_key(VALUE ehash)
5293 {
5294  VALUE keys;
5295  long i;
5296 
5297  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5298  keys = env_keys();
5299  for (i=0; i<RARRAY_LEN(keys); i++) {
5301  }
5302  return ehash;
5303 }
5304 
5305 static VALUE
5306 env_values(void)
5307 {
5308  VALUE ary;
5309  char **env;
5310 
5311  ary = rb_ary_new();
5312  env = GET_ENVIRON(environ);
5313  while (*env) {
5314  char *s = strchr(*env, '=');
5315  if (s) {
5316  rb_ary_push(ary, env_str_new2(s+1));
5317  }
5318  env++;
5319  }
5321  return ary;
5322 }
5323 
5324 /*
5325  * call-seq:
5326  * ENV.values -> Array
5327  *
5328  * Returns all environment variable values in an Array:
5329  * ENV.replace('foo' => '0', 'bar' => '1')
5330  * ENV.values # => ['1', '0']
5331  * The order of the values is OS-dependent.
5332  * See {About Ordering}[#class-ENV-label-About+Ordering].
5333  *
5334  * Returns the empty Array if ENV is empty:
5335  * ENV.clear
5336  * ENV.values # => []
5337  */
5338 static VALUE
5339 env_f_values(VALUE _)
5340 {
5341  return env_values();
5342 }
5343 
5344 /*
5345  * call-seq:
5346  * ENV.each_value { |value| block } -> ENV
5347  * ENV.each_value -> Enumerator
5348  *
5349  * Yields each environment variable value:
5350  * ENV.replace('foo' => '0', 'bar' => '1') # => ENV
5351  * values = []
5352  * ENV.each_value { |value| values.push(value) } # => ENV
5353  * values # => ["1", "0"]
5354  *
5355  * Returns an Enumerator if no block given:
5356  * e = ENV.each_value # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_value>
5357  * values = []
5358  * e.each { |value| values.push(value) } # => ENV
5359  * values # => ["1", "0"]
5360  */
5361 static VALUE
5362 env_each_value(VALUE ehash)
5363 {
5364  VALUE values;
5365  long i;
5366 
5367  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5368  values = env_values();
5369  for (i=0; i<RARRAY_LEN(values); i++) {
5370  rb_yield(RARRAY_AREF(values, i));
5371  }
5372  return ehash;
5373 }
5374 
5375 /*
5376  * call-seq:
5377  * ENV.each { |name, value| block } -> ENV
5378  * ENV.each -> Enumerator
5379  * ENV.each_pair { |name, value| block } -> ENV
5380  * ENV.each_pair -> Enumerator
5381  *
5382  * Yields each environment variable name and its value as a 2-element Array:
5383  * h = {}
5384  * ENV.each_pair { |name, value| h[name] = value } # => ENV
5385  * h # => {"bar"=>"1", "foo"=>"0"}
5386  *
5387  * Returns an Enumerator if no block given:
5388  * h = {}
5389  * e = ENV.each_pair # => #<Enumerator: {"bar"=>"1", "foo"=>"0"}:each_pair>
5390  * e.each { |name, value| h[name] = value } # => ENV
5391  * h # => {"bar"=>"1", "foo"=>"0"}
5392  */
5393 static VALUE
5394 env_each_pair(VALUE ehash)
5395 {
5396  char **env;
5397  VALUE ary;
5398  long i;
5399 
5400  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5401 
5402  ary = rb_ary_new();
5403  env = GET_ENVIRON(environ);
5404  while (*env) {
5405  char *s = strchr(*env, '=');
5406  if (s) {
5407  rb_ary_push(ary, env_str_new(*env, s-*env));
5408  rb_ary_push(ary, env_str_new2(s+1));
5409  }
5410  env++;
5411  }
5413 
5414  if (rb_block_arity() > 1) {
5415  for (i=0; i<RARRAY_LEN(ary); i+=2) {
5416  rb_yield_values(2, RARRAY_AREF(ary, i), RARRAY_AREF(ary, i+1));
5417  }
5418  }
5419  else {
5420  for (i=0; i<RARRAY_LEN(ary); i+=2) {
5421  rb_yield(rb_assoc_new(RARRAY_AREF(ary, i), RARRAY_AREF(ary, i+1)));
5422  }
5423  }
5424  return ehash;
5425 }
5426 
5427 /*
5428  * call-seq:
5429  * ENV.reject! { |name, value| block } -> ENV or nil
5430  * ENV.reject! -> Enumerator
5431  *
5432  * Similar to ENV.delete_if, but returns +nil+ if no changes were made.
5433  *
5434  * Deletes each environment variable for which the block returns a truthy value,
5435  * returning ENV (if any deletions) or +nil+ (if not):
5436  * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
5437  * ENV.reject! { |name, value| name.start_with?('b') } # => ENV
5438  * ENV # => {"foo"=>"0"}
5439  * ENV.reject! { |name, value| name.start_with?('b') } # => nil
5440  *
5441  * Returns an Enumerator if no block given:
5442  * ENV.replace('foo' => '0', 'bar' => '1', 'baz' => '2')
5443  * e = ENV.reject! # => #<Enumerator: {"bar"=>"1", "baz"=>"2", "foo"=>"0"}:reject!>
5444  * e.each { |name, value| name.start_with?('b') } # => ENV
5445  * ENV # => {"foo"=>"0"}
5446  * e.each { |name, value| name.start_with?('b') } # => nil
5447  */
5448 static VALUE
5449 env_reject_bang(VALUE ehash)
5450 {
5451  VALUE keys;
5452  long i;
5453  int del = 0;
5454 
5455  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5456  keys = env_keys();
5458  for (i=0; i<RARRAY_LEN(keys); i++) {
5459  VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
5460  if (!NIL_P(val)) {
5461  if (RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
5462  env_delete(RARRAY_AREF(keys, i));
5463  del++;
5464  }
5465  }
5466  }
5467  RB_GC_GUARD(keys);
5468  if (del == 0) return Qnil;
5469  return envtbl;
5470 }
5471 
5472 /*
5473  * call-seq:
5474  * ENV.delete_if { |name, value| block } -> ENV
5475  * ENV.delete_if -> Enumerator
5476  *
5477  * Deletes every environment variable for which the block evaluates to +true+.
5478  *
5479  * If no block is given an enumerator is returned instead.
5480  */
5481 static VALUE
5482 env_delete_if(VALUE ehash)
5483 {
5484  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5485  env_reject_bang(ehash);
5486  return envtbl;
5487 }
5488 
5489 /*
5490  * call-seq:
5491  * ENV.values_at(name, ...) -> Array
5492  *
5493  * Returns an array containing the environment variable values associated with
5494  * the given names. See also ENV.select.
5495  */
5496 static VALUE
5497 env_values_at(int argc, VALUE *argv, VALUE _)
5498 {
5499  VALUE result;
5500  long i;
5501 
5502  result = rb_ary_new();
5503  for (i=0; i<argc; i++) {
5504  rb_ary_push(result, rb_f_getenv(Qnil, argv[i]));
5505  }
5506  return result;
5507 }
5508 
5509 /*
5510  * call-seq:
5511  * ENV.select { |name, value| block } -> Hash
5512  * ENV.select -> Enumerator
5513  * ENV.filter { |name, value| block } -> Hash
5514  * ENV.filter -> Enumerator
5515  *
5516  * Returns a copy of the environment for entries where the block returns true.
5517  *
5518  * Returns an Enumerator if no block was given.
5519  *
5520  * ENV.filter is an alias for ENV.select.
5521  */
5522 static VALUE
5523 env_select(VALUE ehash)
5524 {
5525  VALUE result;
5526  VALUE keys;
5527  long i;
5528 
5529  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5530  result = rb_hash_new();
5531  keys = env_keys();
5532  for (i = 0; i < RARRAY_LEN(keys); ++i) {
5533  VALUE key = RARRAY_AREF(keys, i);
5534  VALUE val = rb_f_getenv(Qnil, key);
5535  if (!NIL_P(val)) {
5536  if (RTEST(rb_yield_values(2, key, val))) {
5537  rb_hash_aset(result, key, val);
5538  }
5539  }
5540  }
5541  RB_GC_GUARD(keys);
5542 
5543  return result;
5544 }
5545 
5546 /*
5547  * call-seq:
5548  * ENV.select! { |name, value| block } -> ENV or nil
5549  * ENV.select! -> Enumerator
5550  * ENV.filter! { |name, value| block } -> ENV or nil
5551  * ENV.filter! -> Enumerator
5552  *
5553  * Equivalent to ENV.keep_if but returns +nil+ if no changes were made.
5554  *
5555  * ENV.filter! is an alias for ENV.select!.
5556  */
5557 static VALUE
5558 env_select_bang(VALUE ehash)
5559 {
5560  VALUE keys;
5561  long i;
5562  int del = 0;
5563 
5564  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5565  keys = env_keys();
5567  for (i=0; i<RARRAY_LEN(keys); i++) {
5568  VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
5569  if (!NIL_P(val)) {
5570  if (!RTEST(rb_yield_values(2, RARRAY_AREF(keys, i), val))) {
5571  env_delete(RARRAY_AREF(keys, i));
5572  del++;
5573  }
5574  }
5575  }
5576  RB_GC_GUARD(keys);
5577  if (del == 0) return Qnil;
5578  return envtbl;
5579 }
5580 
5581 /*
5582  * call-seq:
5583  * ENV.keep_if { |name, value| block } -> ENV
5584  * ENV.keep_if -> Enumerator
5585  *
5586  * Deletes every environment variable where the block evaluates to +false+.
5587  *
5588  * Returns an enumerator if no block was given.
5589  */
5590 static VALUE
5591 env_keep_if(VALUE ehash)
5592 {
5593  RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
5594  env_select_bang(ehash);
5595  return envtbl;
5596 }
5597 
5598 /*
5599  * call-seq:
5600  * ENV.slice(*keys) -> a_hash
5601  *
5602  * Returns a hash containing only the given keys from ENV and their values.
5603  *
5604  * ENV.slice("TERM","HOME") #=> {"TERM"=>"xterm-256color", "HOME"=>"/Users/rhc"}
5605  */
5606 static VALUE
5607 env_slice(int argc, VALUE *argv, VALUE _)
5608 {
5609  int i;
5610  VALUE key, value, result;
5611 
5612  if (argc == 0) {
5613  return rb_hash_new();
5614  }
5615  result = rb_hash_new_with_size(argc);
5616 
5617  for (i = 0; i < argc; i++) {
5618  key = argv[i];
5619  value = rb_f_getenv(Qnil, key);
5620  if (value != Qnil)
5621  rb_hash_aset(result, key, value);
5622  }
5623 
5624  return result;
5625 }
5626 
5627 VALUE
5629 {
5630  VALUE keys;
5631  long i;
5632 
5633  keys = env_keys();
5634  for (i=0; i<RARRAY_LEN(keys); i++) {
5635  VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
5636  if (!NIL_P(val)) {
5637  env_delete(RARRAY_AREF(keys, i));
5638  }
5639  }
5640  RB_GC_GUARD(keys);
5641  return envtbl;
5642 }
5643 
5644 /*
5645  * call-seq:
5646  * ENV.clear -> ENV
5647  *
5648  * Removes every environment variable; returns ENV:
5649  * ENV.replace('foo' => '0', 'bar' => '1')
5650  * ENV.size # => 2
5651  * ENV.clear # => ENV
5652  * ENV.size # => 0
5653  */
5654 static VALUE
5655 env_clear(VALUE _)
5656 {
5657  return rb_env_clear();
5658 }
5659 
5660 /*
5661  * call-seq:
5662  * ENV.to_s -> "ENV"
5663  *
5664  * Returns "ENV"
5665  */
5666 static VALUE
5667 env_to_s(VALUE _)
5668 {
5669  return rb_usascii_str_new2("ENV");
5670 }
5671 
5672 /*
5673  * call-seq:
5674  * ENV.inspect -> string
5675  *
5676  * Returns the contents of the environment as a String.
5677  */
5678 static VALUE
5679 env_inspect(VALUE _)
5680 {
5681  char **env;
5682  VALUE str, i;
5683 
5684  str = rb_str_buf_new2("{");
5685  env = GET_ENVIRON(environ);
5686  while (*env) {
5687  char *s = strchr(*env, '=');
5688 
5689  if (env != environ) {
5690  rb_str_buf_cat2(str, ", ");
5691  }
5692  if (s) {
5693  rb_str_buf_cat2(str, "\"");
5694  rb_str_buf_cat(str, *env, s-*env);
5695  rb_str_buf_cat2(str, "\"=>");
5696  i = rb_inspect(rb_str_new2(s+1));
5698  }
5699  env++;
5700  }
5702  rb_str_buf_cat2(str, "}");
5703 
5704  return str;
5705 }
5706 
5707 /*
5708  * call-seq:
5709  * ENV.to_a -> Array
5710  *
5711  * Converts the environment variables into an array of names and value arrays.
5712  *
5713  * ENV.to_a # => [["TERM", "xterm-color"], ["SHELL", "/bin/bash"], ...]
5714  *
5715  */
5716 static VALUE
5717 env_to_a(VALUE _)
5718 {
5719  char **env;
5720  VALUE ary;
5721 
5722  ary = rb_ary_new();
5723  env = GET_ENVIRON(environ);
5724  while (*env) {
5725  char *s = strchr(*env, '=');
5726  if (s) {
5727  rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s-*env),
5728  env_str_new2(s+1)));
5729  }
5730  env++;
5731  }
5733  return ary;
5734 }
5735 
5736 /*
5737  * call-seq:
5738  * ENV.rehash
5739  *
5740  * Re-hashing the environment variables does nothing. It is provided for
5741  * compatibility with Hash.
5742  */
5743 static VALUE
5744 env_none(VALUE _)
5745 {
5746  return Qnil;
5747 }
5748 
5749 /*
5750  * call-seq:
5751  * ENV.length
5752  * ENV.size
5753  *
5754  * Returns the number of environment variables.
5755  */
5756 static VALUE
5757 env_size(VALUE _)
5758 {
5759  int i;
5760  char **env;
5761 
5762  env = GET_ENVIRON(environ);
5763  for (i=0; env[i]; i++)
5764  ;
5766  return INT2FIX(i);
5767 }
5768 
5769 /*
5770  * call-seq:
5771  * ENV.empty? -> true or false
5772  *
5773  * Returns true when there are no environment variables
5774  */
5775 static VALUE
5776 env_empty_p(VALUE _)
5777 {
5778  char **env;
5779 
5780  env = GET_ENVIRON(environ);
5781  if (env[0] == 0) {
5783  return Qtrue;
5784  }
5786  return Qfalse;
5787 }
5788 
5789 /*
5790  * call-seq:
5791  * ENV.include?(name) -> true or false
5792  * ENV.has_key?(name) -> true or false
5793  * ENV.member?(name) -> true or false
5794  * ENV.key?(name) -> true or false
5795  *
5796  * ENV.has_key?, ENV.member?, and ENV.key? are aliases for ENV.include?.
5797  *
5798  * Returns +true+ if there is an environment variable with the given +name+:
5799  * ENV.replace('foo' => '0', 'bar' => '1')
5800  * ENV.include?('foo') # => true
5801  * Returns +false+ if +name+ is a valid String and there is no such environment variable:
5802  * ENV.include?('baz') # => false
5803  * Returns +false+ if +name+ is the empty String or is a String containing character <code>'='</code>:
5804  * ENV.include?('') # => false
5805  * ENV.include?('=') # => false
5806  * Raises an exception if +name+ is a String containing the NUL character <code>"\0"</code>:
5807  * ENV.include?("\0") # Raises ArgumentError (bad environment variable name: contains null byte)
5808  * Raises an exception if +name+ has an encoding that is not ASCII-compatible:
5809  * ENV.include?("\xa1\xa1".force_encoding(Encoding::UTF_16LE))
5810  * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: UTF-16LE)
5811  * Raises an exception if +name+ is not a String:
5812  * ENV.include?(Object.new) # TypeError (no implicit conversion of Object into String)
5813  */
5814 static VALUE
5815 env_has_key(VALUE env, VALUE key)
5816 {
5817  const char *s;
5818 
5819  s = env_name(key);
5820  if (getenv(s)) return Qtrue;
5821  return Qfalse;
5822 }
5823 
5824 /*
5825  * call-seq:
5826  * ENV.assoc(name) -> Array or nil
5827  *
5828  * Returns a 2-element Array containing the name and value of the environment variable
5829  * for +name+ if it exists:
5830  * ENV.replace('foo' => '0', 'bar' => '1')
5831  * ENV.assoc('foo') # => ['foo' '0']
5832  * Returns +nil+ if +name+ is a valid String and there is no such environment variable:
5833  * ENV.assoc('baz') # => false
5834  * Returns +nil+ if +name+ is the empty String or is a String containing character <code>'='</code>:
5835  * ENV.assoc('') # => false
5836  * ENV.assoc('=') # => false
5837  * Raises an exception if +name+ is a String containing the NUL character <code>"\0"</code>:
5838  * ENV.assoc("\0") # Raises ArgumentError (bad environment variable name: contains null byte)
5839  * Raises an exception if +name+ has an encoding that is not ASCII-compatible:
5840  * ENV.assoc("\xa1\xa1".force_encoding(Encoding::UTF_16LE))
5841  * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: UTF-16LE)
5842  * Raises an exception if +name+ is not a String:
5843  * ENV.assoc(Object.new) # TypeError (no implicit conversion of Object into String)
5844  */
5845 static VALUE
5846 env_assoc(VALUE env, VALUE key)
5847 {
5848  const char *s, *e;
5849 
5850  s = env_name(key);
5851  e = getenv(s);
5852  if (e) return rb_assoc_new(key, env_str_new2(e));
5853  return Qnil;
5854 }
5855 
5856 /*
5857  * call-seq:
5858  * ENV.value?(value) -> true or false
5859  * ENV.has_value?(value) -> true or false
5860  *
5861  * Returns +true+ if there is an environment variable with the given +value+.
5862  */
5863 static VALUE
5864 env_has_value(VALUE dmy, VALUE obj)
5865 {
5866  char **env;
5867 
5869  if (NIL_P(obj)) return Qnil;
5870  env = GET_ENVIRON(environ);
5871  while (*env) {
5872  char *s = strchr(*env, '=');
5873  if (s++) {
5874  long len = strlen(s);
5875  if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
5877  return Qtrue;
5878  }
5879  }
5880  env++;
5881  }
5883  return Qfalse;
5884 }
5885 
5886 /*
5887  * call-seq:
5888  * ENV.rassoc(value)
5889  *
5890  * Returns an Array of the name and value of the environment variable with
5891  * +value+ or +nil+ if the value cannot be found.
5892  */
5893 static VALUE
5894 env_rassoc(VALUE dmy, VALUE obj)
5895 {
5896  char **env;
5897 
5899  if (NIL_P(obj)) return Qnil;
5900  env = GET_ENVIRON(environ);
5901  while (*env) {
5902  char *s = strchr(*env, '=');
5903  if (s++) {
5904  long len = strlen(s);
5905  if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
5906  VALUE result = rb_assoc_new(rb_str_new(*env, s-*env-1), obj);
5908  return result;
5909  }
5910  }
5911  env++;
5912  }
5914  return Qnil;
5915 }
5916 
5917 /*
5918  * call-seq:
5919  * ENV.key(value) -> name or nil
5920  *
5921  * Returns the name of the first environment variable with +value+ if it exists:
5922  * ENV.replace('foo' => '0', 'bar' => '1')
5923  * ENV.key('0') # =>'foo'
5924  * The order in which environment variables are examined is OS-dependent.
5925  * See {About Ordering}[#class-ENV-label-About+Ordering].
5926  *
5927  * Returns +nil+ if there is no such value:
5928  * ENV.key('2') # => nil
5929  * Raises an exception if +value+ is not a String:
5930  * ENV.key(Object.new) # raises TypeError (no implicit conversion of Object into String)
5931  */
5932 static VALUE
5933 env_key(VALUE dmy, VALUE value)
5934 {
5935  char **env;
5936  VALUE str;
5937 
5938  SafeStringValue(value);
5939  env = GET_ENVIRON(environ);
5940  while (*env) {
5941  char *s = strchr(*env, '=');
5942  if (s++) {
5943  long len = strlen(s);
5944  if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) {
5945  str = env_str_new(*env, s-*env-1);
5947  return str;
5948  }
5949  }
5950  env++;
5951  }
5953  return Qnil;
5954 }
5955 
5956 /*
5957  * call-seq:
5958  * ENV.index(value) -> key
5959  *
5960  * Deprecated method that is equivalent to ENV.key
5961  */
5962 static VALUE
5963 env_index(VALUE dmy, VALUE value)
5964 {
5965  rb_warn_deprecated("ENV.index", "ENV.key");
5966  return env_key(dmy, value);
5967 }
5968 
5969 static VALUE
5970 env_to_hash(void)
5971 {
5972  char **env;
5973  VALUE hash;
5974 
5975  hash = rb_hash_new();
5976  env = GET_ENVIRON(environ);
5977  while (*env) {
5978  char *s = strchr(*env, '=');
5979  if (s) {
5980  rb_hash_aset(hash, env_str_new(*env, s-*env),
5981  env_str_new2(s+1));
5982  }
5983  env++;
5984  }
5986  return hash;
5987 }
5988 
5989 /*
5990  * call-seq:
5991  * ENV.to_hash -> hash
5992  *
5993  * Creates a hash with a copy of the environment variables.
5994  *
5995  */
5996 
5997 static VALUE
5998 env_f_to_hash(VALUE _)
5999 {
6000  return env_to_hash();
6001 }
6002 
6003 /*
6004  * call-seq:
6005  * ENV.to_h -> hash
6006  * ENV.to_h {|name, value| block } -> hash
6007  *
6008  * Creates a hash with a copy of the environment variables.
6009  *
6010  */
6011 static VALUE
6012 env_to_h(VALUE _)
6013 {
6014  VALUE hash = env_to_hash();
6015  if (rb_block_given_p()) {
6016  hash = rb_hash_to_h_block(hash);
6017  }
6018  return hash;
6019 }
6020 
6021 /*
6022  * call-seq:
6023  * ENV.reject { |name, value| block } -> Hash
6024  * ENV.reject -> Enumerator
6025  *
6026  * Same as ENV.delete_if, but works on (and returns) a copy of the
6027  * environment.
6028  */
6029 static VALUE
6030 env_reject(VALUE _)
6031 {
6032  return rb_hash_delete_if(env_to_hash());
6033 }
6034 
6035 /*
6036  * call-seq:
6037  * ENV.freeze -> raises TypeError
6038  *
6039  * Ruby does not allow ENV to be frozen, so calling ENV.freeze
6040  * raises TypeError.
6041  */
6042 static VALUE
6043 env_freeze(VALUE self)
6044 {
6045  rb_raise(rb_eTypeError, "cannot freeze ENV");
6046  return self; /* Not reached */
6047 }
6048 
6049 /*
6050  * call-seq:
6051  * ENV.shift -> [name, value] or nil
6052  *
6053  * Removes the first environment variable from ENV and returns
6054  * a 2-element Array containing its name and value:
6055  * ENV.replace('foo' => '0', 'bar' => '1')
6056  * ENV.to_hash # => {'bar' => '1', 'foo' => '0'}
6057  * ENV.shift # => ['bar', '1']
6058  * ENV.to_hash # => {'foo' => '0'}
6059  * Exactly which environment variable is "first" is OS-dependent.
6060  * See {About Ordering}[#class-ENV-label-About+Ordering].
6061  *
6062  * Returns +nil+ if the environment is empty:
6063  * ENV.clear
6064  * ENV.shift # => nil
6065  */
6066 static VALUE
6067 env_shift(VALUE _)
6068 {
6069  char **env;
6070  VALUE result = Qnil;
6071 
6072  env = GET_ENVIRON(environ);
6073  if (*env) {
6074  char *s = strchr(*env, '=');
6075  if (s) {
6076  VALUE key = env_str_new(*env, s-*env);
6077  VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
6078  env_delete(key);
6079  result = rb_assoc_new(key, val);
6080  }
6081  }
6083  return result;
6084 }
6085 
6086 /*
6087  * call-seq:
6088  * ENV.invert -> Hash
6089  *
6090  * Returns a new hash created by using environment variable names as values
6091  * and values as names.
6092  */
6093 static VALUE
6094 env_invert(VALUE _)
6095 {
6096  return rb_hash_invert(env_to_hash());
6097 }
6098 
6099 static void
6100 keylist_delete(VALUE keys, VALUE key)
6101 {
6102  long keylen, elen;
6103  const char *keyptr, *eptr;
6104  RSTRING_GETMEM(key, keyptr, keylen);
6105  for (long i=0; i<RARRAY_LEN(keys); i++) {
6106  VALUE e = RARRAY_AREF(keys, i);
6107  RSTRING_GETMEM(e, eptr, elen);
6108  if (elen != keylen) continue;
6109  if (!ENVNMATCH(keyptr, eptr, elen)) continue;
6111  return;
6112  }
6113 }
6114 
6115 static int
6116 env_replace_i(VALUE key, VALUE val, VALUE keys)
6117 {
6118  env_name(key);
6119  env_aset(key, val);
6120 
6121  keylist_delete(keys, key);
6122  return ST_CONTINUE;
6123 }
6124 
6125 /*
6126  * call-seq:
6127  * ENV.replace(hash) -> ENV
6128  *
6129  * Replaces the entire content of the environment variables
6130  * with the name/value pairs in the given +hash+;
6131  * returns ENV.
6132  *
6133  * Replaces the content of ENV with the given pairs:
6134  * ENV.replace('foo' => '0', 'bar' => '1') # => ENV
6135  * ENV.to_hash # => {"bar"=>"1", "foo"=>"0"}
6136  *
6137  * Raises an exception if a name or value is invalid.
6138  * See {Invalid Names and Values}[#class-ENV-label-Invalid-Names+and+Values].
6139  */
6140 static VALUE
6141 env_replace(VALUE env, VALUE hash)
6142 {
6143  VALUE keys;
6144  long i;
6145 
6146  keys = env_keys();
6147  if (env == hash) return env;
6148  hash = to_hash(hash);
6149  rb_hash_foreach(hash, env_replace_i, keys);
6150 
6151  for (i=0; i<RARRAY_LEN(keys); i++) {
6152  env_delete(RARRAY_AREF(keys, i));
6153  }
6154  RB_GC_GUARD(keys);
6155  return env;
6156 }
6157 
6158 static int
6159 env_update_i(VALUE key, VALUE val, VALUE _)
6160 {
6161  env_aset(key, val);
6162  return ST_CONTINUE;
6163 }
6164 
6165 static int
6166 env_update_block_i(VALUE key, VALUE val, VALUE _)
6167 {
6168  VALUE oldval = rb_f_getenv(Qnil, key);
6169  if (!NIL_P(oldval)) {
6170  val = rb_yield_values(3, key, oldval, val);
6171  }
6172  env_aset(key, val);
6173  return ST_CONTINUE;
6174 }
6175 
6176 /*
6177  * call-seq:
6178  * ENV.update(hash) -> ENV
6179  * ENV.update(hash) { |name, old_value, new_value| block } -> ENV
6180  * ENV.merge!(hash) -> ENV
6181  * ENV.merge!(hash) { |name, old_value, new_value| block } -> ENV
6182  *
6183  * Adds the contents of +hash+ to the environment variables. If no block is
6184  * specified entries with duplicate keys are overwritten, otherwise the value
6185  * of each duplicate name is determined by calling the block with the key, its
6186  * value from the environment and its value from the hash.
6187  */
6188 static VALUE
6189 env_update(VALUE env, VALUE hash)
6190 {
6191  if (env == hash) return env;
6192  hash = to_hash(hash);
6193  rb_foreach_func *func = rb_block_given_p() ?
6194  env_update_block_i : env_update_i;
6195  rb_hash_foreach(hash, func, 0);
6196  return env;
6197 }
6198 
6199 /*
6200  * A Hash is a dictionary-like collection of unique keys and their values.
6201  * Also called associative arrays, they are similar to Arrays, but where an
6202  * Array uses integers as its index, a Hash allows you to use any object
6203  * type.
6204  *
6205  * Hashes enumerate their values in the order that the corresponding keys
6206  * were inserted.
6207  *
6208  * A Hash can be easily created by using its implicit form:
6209  *
6210  * grades = { "Jane Doe" => 10, "Jim Doe" => 6 }
6211  *
6212  * Hashes allow an alternate syntax for keys that are symbols.
6213  * Instead of
6214  *
6215  * options = { :font_size => 10, :font_family => "Arial" }
6216  *
6217  * You could write it as:
6218  *
6219  * options = { font_size: 10, font_family: "Arial" }
6220  *
6221  * Each named key is a symbol you can access in hash:
6222  *
6223  * options[:font_size] # => 10
6224  *
6225  * A Hash can also be created through its ::new method:
6226  *
6227  * grades = Hash.new
6228  * grades["Dorothy Doe"] = 9
6229  *
6230  * Hashes have a <em>default value</em> that is returned when accessing
6231  * keys that do not exist in the hash. If no default is set +nil+ is used.
6232  * You can set the default value by sending it as an argument to Hash.new:
6233  *
6234  * grades = Hash.new(0)
6235  *
6236  * Or by using the #default= method:
6237  *
6238  * grades = {"Timmy Doe" => 8}
6239  * grades.default = 0
6240  *
6241  * Accessing a value in a Hash requires using its key:
6242  *
6243  * puts grades["Jane Doe"] # => 0
6244  *
6245  * === Common Uses
6246  *
6247  * Hashes are an easy way to represent data structures, such as
6248  *
6249  * books = {}
6250  * books[:matz] = "The Ruby Programming Language"
6251  * books[:black] = "The Well-Grounded Rubyist"
6252  *
6253  * Hashes are also commonly used as a way to have named parameters in
6254  * functions. Note that no brackets are used below. If a hash is the last
6255  * argument on a method call, no braces are needed, thus creating a really
6256  * clean interface:
6257  *
6258  * Person.create(name: "John Doe", age: 27)
6259  *
6260  * def self.create(params)
6261  * @name = params[:name]
6262  * @age = params[:age]
6263  * end
6264  *
6265  * === Hash Keys
6266  *
6267  * Two objects refer to the same hash key when their <code>hash</code> value
6268  * is identical and the two objects are <code>eql?</code> to each other.
6269  *
6270  * A user-defined class may be used as a hash key if the <code>hash</code>
6271  * and <code>eql?</code> methods are overridden to provide meaningful
6272  * behavior. By default, separate instances refer to separate hash keys.
6273  *
6274  * A typical implementation of <code>hash</code> is based on the
6275  * object's data while <code>eql?</code> is usually aliased to the overridden
6276  * <code>==</code> method:
6277  *
6278  * class Book
6279  * attr_reader :author, :title
6280  *
6281  * def initialize(author, title)
6282  * @author = author
6283  * @title = title
6284  * end
6285  *
6286  * def ==(other)
6287  * self.class === other and
6288  * other.author == @author and
6289  * other.title == @title
6290  * end
6291  *
6292  * alias eql? ==
6293  *
6294  * def hash
6295  * @author.hash ^ @title.hash # XOR
6296  * end
6297  * end
6298  *
6299  * book1 = Book.new 'matz', 'Ruby in a Nutshell'
6300  * book2 = Book.new 'matz', 'Ruby in a Nutshell'
6301  *
6302  * reviews = {}
6303  *
6304  * reviews[book1] = 'Great reference!'
6305  * reviews[book2] = 'Nice and compact!'
6306  *
6307  * reviews.length #=> 1
6308  *
6309  * See also Object#hash and Object#eql?
6310  */
6311 
6312 void
6314 {
6315 #undef rb_intern
6316 #define rb_intern(str) rb_intern_const(str)
6317  id_hash = rb_intern("hash");
6318  id_yield = rb_intern("yield");
6319  id_default = rb_intern("default");
6320  id_flatten_bang = rb_intern("flatten!");
6321  id_hash_iter_lev = rb_make_internal_id();
6322 
6323  rb_cHash = rb_define_class("Hash", rb_cObject);
6324 
6326 
6327  rb_define_alloc_func(rb_cHash, empty_hash_alloc);
6328  rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);
6329  rb_define_singleton_method(rb_cHash, "try_convert", rb_hash_s_try_convert, 1);
6330  rb_define_method(rb_cHash, "initialize", rb_hash_initialize, -1);
6331  rb_define_method(rb_cHash, "initialize_copy", rb_hash_replace, 1);
6332  rb_define_method(rb_cHash, "rehash", rb_hash_rehash, 0);
6333 
6334  rb_define_method(rb_cHash, "to_hash", rb_hash_to_hash, 0);
6335  rb_define_method(rb_cHash, "to_h", rb_hash_to_h, 0);
6336  rb_define_method(rb_cHash, "to_a", rb_hash_to_a, 0);
6337  rb_define_method(rb_cHash, "inspect", rb_hash_inspect, 0);
6338  rb_define_alias(rb_cHash, "to_s", "inspect");
6339  rb_define_method(rb_cHash, "to_proc", rb_hash_to_proc, 0);
6340 
6341  rb_define_method(rb_cHash, "==", rb_hash_equal, 1);
6343  rb_define_method(rb_cHash, "hash", rb_hash_hash, 0);
6344  rb_define_method(rb_cHash, "eql?", rb_hash_eql, 1);
6345  rb_define_method(rb_cHash, "fetch", rb_hash_fetch_m, -1);
6347  rb_define_method(rb_cHash, "store", rb_hash_aset, 2);
6348  rb_define_method(rb_cHash, "default", rb_hash_default, -1);
6349  rb_define_method(rb_cHash, "default=", rb_hash_set_default, 1);
6350  rb_define_method(rb_cHash, "default_proc", rb_hash_default_proc, 0);
6351  rb_define_method(rb_cHash, "default_proc=", rb_hash_set_default_proc, 1);
6352  rb_define_method(rb_cHash, "key", rb_hash_key, 1);
6353  rb_define_method(rb_cHash, "index", rb_hash_index, 1);
6354  rb_define_method(rb_cHash, "size", rb_hash_size, 0);
6355  rb_define_method(rb_cHash, "length", rb_hash_size, 0);
6356  rb_define_method(rb_cHash, "empty?", rb_hash_empty_p, 0);
6357 
6358  rb_define_method(rb_cHash, "each_value", rb_hash_each_value, 0);
6359  rb_define_method(rb_cHash, "each_key", rb_hash_each_key, 0);
6360  rb_define_method(rb_cHash, "each_pair", rb_hash_each_pair, 0);
6361  rb_define_method(rb_cHash, "each", rb_hash_each_pair, 0);
6362 
6363  rb_define_method(rb_cHash, "transform_keys", rb_hash_transform_keys, 0);
6364  rb_define_method(rb_cHash, "transform_keys!", rb_hash_transform_keys_bang, 0);
6365  rb_define_method(rb_cHash, "transform_values", rb_hash_transform_values, 0);
6366  rb_define_method(rb_cHash, "transform_values!", rb_hash_transform_values_bang, 0);
6367 
6368  rb_define_method(rb_cHash, "keys", rb_hash_keys, 0);
6369  rb_define_method(rb_cHash, "values", rb_hash_values, 0);
6370  rb_define_method(rb_cHash, "values_at", rb_hash_values_at, -1);
6371  rb_define_method(rb_cHash, "fetch_values", rb_hash_fetch_values, -1);
6372 
6373  rb_define_method(rb_cHash, "shift", rb_hash_shift, 0);
6374  rb_define_method(rb_cHash, "delete", rb_hash_delete_m, 1);
6375  rb_define_method(rb_cHash, "delete_if", rb_hash_delete_if, 0);
6376  rb_define_method(rb_cHash, "keep_if", rb_hash_keep_if, 0);
6377  rb_define_method(rb_cHash, "select", rb_hash_select, 0);
6379  rb_define_method(rb_cHash, "filter", rb_hash_select, 0);
6381  rb_define_method(rb_cHash, "reject", rb_hash_reject, 0);
6383  rb_define_method(rb_cHash, "slice", rb_hash_slice, -1);
6384  rb_define_method(rb_cHash, "clear", rb_hash_clear, 0);
6385  rb_define_method(rb_cHash, "invert", rb_hash_invert, 0);
6386  rb_define_method(rb_cHash, "update", rb_hash_update, -1);
6387  rb_define_method(rb_cHash, "replace", rb_hash_replace, 1);
6388  rb_define_method(rb_cHash, "merge!", rb_hash_update, -1);
6389  rb_define_method(rb_cHash, "merge", rb_hash_merge, -1);
6390  rb_define_method(rb_cHash, "assoc", rb_hash_assoc, 1);
6391  rb_define_method(rb_cHash, "rassoc", rb_hash_rassoc, 1);
6392  rb_define_method(rb_cHash, "flatten", rb_hash_flatten, -1);
6393  rb_define_method(rb_cHash, "compact", rb_hash_compact, 0);
6394  rb_define_method(rb_cHash, "compact!", rb_hash_compact_bang, 0);
6395 
6396  rb_define_method(rb_cHash, "include?", rb_hash_has_key, 1);
6397  rb_define_method(rb_cHash, "member?", rb_hash_has_key, 1);
6398  rb_define_method(rb_cHash, "has_key?", rb_hash_has_key, 1);
6399  rb_define_method(rb_cHash, "has_value?", rb_hash_has_value, 1);
6401  rb_define_method(rb_cHash, "value?", rb_hash_has_value, 1);
6402 
6403  rb_define_method(rb_cHash, "compare_by_identity", rb_hash_compare_by_id, 0);
6404  rb_define_method(rb_cHash, "compare_by_identity?", rb_hash_compare_by_id_p, 0);
6405 
6406  rb_define_method(rb_cHash, "any?", rb_hash_any_p, -1);
6407  rb_define_method(rb_cHash, "dig", rb_hash_dig, -1);
6408 
6409  rb_define_method(rb_cHash, "<=", rb_hash_le, 1);
6410  rb_define_method(rb_cHash, "<", rb_hash_lt, 1);
6411  rb_define_method(rb_cHash, ">=", rb_hash_ge, 1);
6412  rb_define_method(rb_cHash, ">", rb_hash_gt, 1);
6413 
6414  rb_define_method(rb_cHash, "deconstruct_keys", rb_hash_deconstruct_keys, 1);
6415 
6416  rb_define_singleton_method(rb_cHash, "ruby2_keywords_hash?", rb_hash_s_ruby2_keywords_hash_p, 1);
6417  rb_define_singleton_method(rb_cHash, "ruby2_keywords_hash", rb_hash_s_ruby2_keywords_hash, 1);
6418 
6419  /* Document-class: ENV
6420  *
6421  * ENV is a hash-like accessor for environment variables.
6422  *
6423  * === Interaction with the Operating System
6424  *
6425  * The ENV object interacts with the operating system's environment variables:
6426  *
6427  * - When you get the value for a name in ENV, the value is retrieved from among the current environment variables.
6428  * - When you create or set a name-value pair in ENV, the name and value are immediately set in the environment variables.
6429  * - When you delete a name-value pair in ENV, it is immediately deleted from the environment variables.
6430  *
6431  * === Names and Values
6432  *
6433  * Generally, a name or value is a String.
6434  *
6435  * ==== Valid Names and Values
6436  *
6437  * Each name or value must be one of the following:
6438  *
6439  * - A String.
6440  * - An object that responds to \#to_str by returning a String, in which case that String will be used as the name or value.
6441  *
6442  * ==== Invalid Names and Values
6443  *
6444  * A new name:
6445  *
6446  * - May not be the empty string:
6447  * ENV[''] = '0'
6448  * # Raises Errno::EINVAL (Invalid argument - ruby_setenv())
6449  *
6450  * - May not contain character <code>"="</code>:
6451  * ENV['='] = '0'
6452  * # Raises Errno::EINVAL (Invalid argument - ruby_setenv(=))
6453  *
6454  * A new name or value:
6455  *
6456  * - May not be a non-String that does not respond to \#to_str:
6457  *
6458  * ENV['foo'] = Object.new
6459  * # Raises TypeError (no implicit conversion of Object into String)
6460  * ENV[Object.new] = '0'
6461  * # Raises TypeError (no implicit conversion of Object into String)
6462  *
6463  * - May not contain the NUL character <code>"\0"</code>:
6464  *
6465  * ENV['foo'] = "\0"
6466  * # Raises ArgumentError (bad environment variable value: contains null byte)
6467  * ENV["\0"] == '0'
6468  * # Raises ArgumentError (bad environment variable name: contains null byte)
6469  *
6470  * - May not have an ASCII-incompatible encoding such as UTF-16LE or ISO-2022-JP:
6471  *
6472  * ENV['foo'] = '0'.force_encoding(Encoding::ISO_2022_JP)
6473  * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP)
6474  * ENV["foo".force_encoding(Encoding::ISO_2022_JP)] = '0'
6475  * # Raises ArgumentError (bad environment variable name: ASCII incompatible encoding: ISO-2022-JP)
6476  *
6477  * === About Ordering
6478  *
6479  * ENV enumerates its name/value pairs in the order found
6480  * in the operating system's environment variables.
6481  * Therefore the ordering of ENV content is OS-dependent, and may be indeterminate.
6482  *
6483  * This will be seen in:
6484  * - A Hash returned by an ENV method.
6485  * - An Enumerator returned by an ENV method.
6486  * - An Array returned by ENV.keys, ENV.values, or ENV.to_a.
6487  * - The String returned by ENV.inspect.
6488  * - The Array returned by ENV.shift.
6489  * - The name returned by ENV.key.
6490  *
6491  * === About the Examples
6492  * Some methods in ENV return ENV itself. Typically, there are many environment variables.
6493  * It's not useful to display a large ENV in the examples here,
6494  * so most example snippets begin by resetting the contents of ENV:
6495  * - ENV.replace replaces ENV with a new collection of entries.
6496  * - ENV.clear empties ENV.
6497  */
6498 
6499  /*
6500  * Hack to get RDoc to regard ENV as a class:
6501  * envtbl = rb_define_class("ENV", rb_cObject);
6502  */
6503  origenviron = environ;
6504  envtbl = rb_obj_alloc(rb_cObject);
6506 
6507  rb_define_singleton_method(envtbl, "[]", rb_f_getenv, 1);
6508  rb_define_singleton_method(envtbl, "fetch", env_fetch, -1);
6509  rb_define_singleton_method(envtbl, "[]=", env_aset_m, 2);
6510  rb_define_singleton_method(envtbl, "store", env_aset_m, 2);
6511  rb_define_singleton_method(envtbl, "each", env_each_pair, 0);
6512  rb_define_singleton_method(envtbl, "each_pair", env_each_pair, 0);
6513  rb_define_singleton_method(envtbl, "each_key", env_each_key, 0);
6514  rb_define_singleton_method(envtbl, "each_value", env_each_value, 0);
6515  rb_define_singleton_method(envtbl, "delete", env_delete_m, 1);
6516  rb_define_singleton_method(envtbl, "delete_if", env_delete_if, 0);
6517  rb_define_singleton_method(envtbl, "keep_if", env_keep_if, 0);
6518  rb_define_singleton_method(envtbl, "slice", env_slice, -1);
6519  rb_define_singleton_method(envtbl, "clear", env_clear, 0);
6520  rb_define_singleton_method(envtbl, "reject", env_reject, 0);
6521  rb_define_singleton_method(envtbl, "reject!", env_reject_bang, 0);
6522  rb_define_singleton_method(envtbl, "select", env_select, 0);
6523  rb_define_singleton_method(envtbl, "select!", env_select_bang, 0);
6524  rb_define_singleton_method(envtbl, "filter", env_select, 0);
6525  rb_define_singleton_method(envtbl, "filter!", env_select_bang, 0);
6526  rb_define_singleton_method(envtbl, "shift", env_shift, 0);
6527  rb_define_singleton_method(envtbl, "freeze", env_freeze, 0);
6528  rb_define_singleton_method(envtbl, "invert", env_invert, 0);
6529  rb_define_singleton_method(envtbl, "replace", env_replace, 1);
6530  rb_define_singleton_method(envtbl, "update", env_update, 1);
6531  rb_define_singleton_method(envtbl, "merge!", env_update, 1);
6532  rb_define_singleton_method(envtbl, "inspect", env_inspect, 0);
6533  rb_define_singleton_method(envtbl, "rehash", env_none, 0);
6534  rb_define_singleton_method(envtbl, "to_a", env_to_a, 0);
6535  rb_define_singleton_method(envtbl, "to_s", env_to_s, 0);
6536  rb_define_singleton_method(envtbl, "key", env_key, 1);
6537  rb_define_singleton_method(envtbl, "index", env_index, 1);
6538  rb_define_singleton_method(envtbl, "size", env_size, 0);
6539  rb_define_singleton_method(envtbl, "length", env_size, 0);
6540  rb_define_singleton_method(envtbl, "empty?", env_empty_p, 0);
6541  rb_define_singleton_method(envtbl, "keys", env_f_keys, 0);
6542  rb_define_singleton_method(envtbl, "values", env_f_values, 0);
6543  rb_define_singleton_method(envtbl, "values_at", env_values_at, -1);
6544  rb_define_singleton_method(envtbl, "include?", env_has_key, 1);
6545  rb_define_singleton_method(envtbl, "member?", env_has_key, 1);
6546  rb_define_singleton_method(envtbl, "has_key?", env_has_key, 1);
6547  rb_define_singleton_method(envtbl, "has_value?", env_has_value, 1);
6548  rb_define_singleton_method(envtbl, "key?", env_has_key, 1);
6549  rb_define_singleton_method(envtbl, "value?", env_has_value, 1);
6550  rb_define_singleton_method(envtbl, "to_hash", env_f_to_hash, 0);
6551  rb_define_singleton_method(envtbl, "to_h", env_to_h, 0);
6552  rb_define_singleton_method(envtbl, "assoc", env_assoc, 1);
6553  rb_define_singleton_method(envtbl, "rassoc", env_rassoc, 1);
6554 
6555  /*
6556  * ENV is a Hash-like accessor for environment variables.
6557  *
6558  * See ENV (the class) for more details.
6559  */
6560  rb_define_global_const("ENV", envtbl);
6561 
6562  /* for callcc */
6563  ruby_register_rollback_func_for_ensure(hash_foreach_ensure, hash_foreach_ensure_rollback);
6564 
6565  HASH_ASSERT(sizeof(ar_hint_t) * RHASH_AR_TABLE_MAX_SIZE == sizeof(VALUE));
6566 }
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:3556
strncmp
int strncmp(const char *, const char *, size_t)
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:1921
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
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:1845
ruby_xfree
void ruby_xfree(void *x)
Definition: gc.c:10170
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:3553
RHASH_PROC_DEFAULT
@ RHASH_PROC_DEFAULT
Definition: internal.h:819
rb_hash_keep_if
VALUE rb_hash_keep_if(VALUE hash)
Definition: hash.c:2741
rb_raw_obj_info
const char * rb_raw_obj_info(char *buff, const int buff_size, VALUE obj)
Definition: gc.c:11447
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:1594
rb_check_convert_type_with_id
VALUE rb_check_convert_type_with_id(VALUE, int, const char *, ID)
Definition: object.c:2957
error
const rb_iseq_t const char * error
Definition: rb_mjit_min_header-2.7.2.h:13554
RSTRING_GETMEM
#define RSTRING_GETMEM(str, ptrvar, lenvar)
Definition: ruby.h:1018
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:1920
update_callback_arg
Definition: hash.c:1620
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:1645
RSHIFT
#define RSHIFT(x, y)
Definition: rb_mjit_min_header-2.7.2.h:415
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:4278
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:1575
rb_str_buf_cat2
#define rb_str_buf_cat2
Definition: intern.h:911
rb_warn
void rb_warn(const char *fmt,...)
Definition: error.c:315
idTo_hash
@ idTo_hash
Definition: rb_mjit_min_header-2.7.2.h:8759
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:1640
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:3456
rb_warning
void rb_warning(const char *fmt,...)
Definition: error.c:336
rb_hash_size_num
size_t rb_hash_size_num(VALUE hash)
Definition: hash.c:2945
gc.h
int
__inline__ int
Definition: rb_mjit_min_header-2.7.2.h:2877
RBASIC_CLEAR_CLASS
#define RBASIC_CLEAR_CLASS(obj)
Definition: internal.h:1987
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:1641
idEqq
@ idEqq
Definition: id.h:97
rb_gc_force_recycle
void rb_gc_force_recycle(VALUE obj)
Definition: gc.c:7014
INT2FIX
#define INT2FIX(i)
Definition: ruby.h:263
rb_make_internal_id
ID rb_make_internal_id(void)
Definition: symbol.c:810
rb_hash_clear
VALUE rb_hash_clear(VALUE hash)
Definition: hash.c:2769
RHASH_UPDATE_ITER
#define RHASH_UPDATE_ITER(h, iter_lev, key, func, a)
Definition: hash.c:1690
strchr
char * strchr(char *, char)
rb_obj_info
MJIT_FUNC_EXPORTED const char * rb_obj_info(VALUE obj)
Definition: gc.c:11683
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:11978
rb_hash_default_value
VALUE rb_hash_default_value(VALUE hash, VALUE key)
Definition: hash.c:1990
RHASH_SIZE
#define RHASH_SIZE(h)
Definition: ruby.h:1130
RSTRING_PTR
#define RSTRING_PTR(str)
Definition: ruby.h:1009
i
uint32_t i
Definition: rb_mjit_min_header-2.7.2.h:5499
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:2550
rb_hash_aref
VALUE rb_hash_aref(VALUE hash, VALUE key)
Definition: hash.c:2037
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:2939
long
#define long
Definition: rb_mjit_min_header-2.7.2.h:2921
rb_eArgError
VALUE rb_eArgError
Definition: error.c:925
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:2395
ENVNMATCH
#define ENVNMATCH(s1, s2, n)
Definition: hash.c:4654
update_arg::new_key
VALUE new_key
Definition: hash.c:1642
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:3875
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:2590
st_retval
st_retval
Definition: st.h:99
NORETURN
NORETURN(static void no_new_key(void))
NUM2LL
#define NUM2LL(x)
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
shift_var::val
VALUE val
Definition: hash.c:2397
rb_hash_lookup2
VALUE rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
Definition: hash.c:2050
rb_check_string_type
VALUE rb_check_string_type(VALUE)
Definition: string.c:2314
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:3910
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:3409
RHASH_AR_TABLE_SIZE_INC
#define RHASH_AR_TABLE_SIZE_INC(h)
Definition: hash.c:607
ptr
struct RIMemo * ptr
Definition: debug.c:65
hash_verify
#define hash_verify(h)
Definition: hash.c:510
T_DATA
#define T_DATA
Definition: ruby.h:538
rb_obj_id
VALUE rb_obj_id(VALUE obj)
Definition: gc.c:3773
Qfalse
#define Qfalse
Definition: ruby.h:467
rb_hash_rassoc
VALUE rb_hash_rassoc(VALUE hash, VALUE obj)
Definition: hash.c:4078
update_func_arg::value
VALUE value
Definition: hash.c:3874
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:1564
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:4017
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:2017
rb_yield_values
#define rb_yield_values(argc,...)
Definition: rb_mjit_min_header-2.7.2.h:6619
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:2714
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:4286
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:2242
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:3507
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:2326
rb_raise
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2671
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:3977
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:1651
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:1622
rb_hash_add_new_element
int rb_hash_add_new_element(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:4547
NOINLINE
NOINLINE(static int ar_equal(VALUE x, VALUE y))
rb_obj_is_proc
VALUE rb_obj_is_proc(VALUE)
Definition: proc.c:152
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
snprintf
int snprintf(char *__restrict, size_t, const char *__restrict,...) __attribute__((__format__(__printf__
ST_REPLACE
@ ST_REPLACE
Definition: st.h:99
keys
const rb_iseq_t const char const VALUE keys
Definition: rb_mjit_min_header-2.7.2.h:13554
OBJ_WB_UNPROTECT
#define OBJ_WB_UNPROTECT(x)
Definition: ruby.h:1495
unsetenv
int unsetenv(const char *)
klass
VALUE klass
Definition: rb_mjit_min_header-2.7.2.h:13302
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:1958
st_clear
void st_clear(st_table *tab)
Definition: st.c:698
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
h
size_t st_index_t h
Definition: rb_mjit_min_header-2.7.2.h:5497
rb_hash_compare_by_id_p
MJIT_FUNC_EXPORTED VALUE rb_hash_compare_by_id_p(VALUE hash)
Definition: hash.c:4267
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:3976
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:2310
NOINSERT_UPDATE_CALLBACK
#define NOINSERT_UPDATE_CALLBACK(func)
Definition: hash.c:1625
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:2612
FL_EXIVAR
#define FL_EXIVAR
Definition: ruby.h:1286
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
OnigEncodingTypeST
Definition: onigmo.h:160
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:1601
RHASH_LEV_MASK
#define RHASH_LEV_MASK
Definition: internal.h:828
st
enum ruby_tag_type st
Definition: rb_mjit_min_header-2.7.2.h:11159
rb_hash_fetch_values
VALUE rb_hash_fetch_values(int argc, VALUE *argv, VALUE hash)
Definition: hash.c:2640
rb_hash_delete_if
VALUE rb_hash_delete_if(VALUE hash)
Definition: hash.c:2493
getpid
pid_t getpid(void)
rb_hash_lookup
VALUE rb_hash_lookup(VALUE hash, VALUE key)
Definition: hash.c:2063
bin
char bin[32]
Definition: siphash.c:135
rb_method_basic_definition_p
#define rb_method_basic_definition_p(klass, mid)
Definition: rb_mjit_min_header-2.7.2.h:7941
memchr
void * memchr(const void *, int, size_t)
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
RARRAY_AREF
#define RARRAY_AREF(a, i)
Definition: psych_emitter.c:7
RHASH_IFNONE
#define RHASH_IFNONE(h)
Definition: ruby.h:1129
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:4590
setenv
int setenv(const char *__string, const char *__value, int __overwrite)
rb_eTypeError
VALUE rb_eTypeError
Definition: error.c:924
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:922
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
putenv
int putenv(char *__string)
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:5628
arg
VALUE arg
Definition: rb_mjit_min_header-2.7.2.h:5636
rb_gc_writebarrier_remember
MJIT_FUNC_EXPORTED void rb_gc_writebarrier_remember(VALUE obj)
Definition: gc.c:6878
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
idTo_proc
@ idTo_proc
Definition: rb_mjit_min_header-2.7.2.h:8760
RHash::basic
struct RBasic basic
Definition: internal.h:888
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
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
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:3332
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
rb_exec_recursive_outer
VALUE rb_exec_recursive_outer(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:5098
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:1852
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
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.2.h:5777
uint128_t
#define uint128_t
Definition: rb_mjit_min_header-2.7.2.h:235
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:636
foreach_safe_arg
Definition: hash.c:1273
internal.h
update_func_arg
Definition: hash.c:3872
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:1644
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:2903
ST_CONTINUE
@ ST_CONTINUE
Definition: st.h:99
ruby_setenv
void ruby_setenv(const char *name, const char *value)
Definition: hash.c:4998
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:366
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
rb_ary_delete_at
VALUE rb_ary_delete_at(VALUE ary, long pos)
Definition: array.c:3419
shift_var::key
VALUE key
Definition: hash.c:2396
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
debug_counter.h
env_name
#define env_name(s)
Definition: hash.c:4762
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:2852
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:1643
rb_obj_info_dump
void rb_obj_info_dump(VALUE obj)
Definition: gc.c:11689
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
rb_funcall
#define rb_funcall(recv, mid, argc,...)
Definition: rb_mjit_min_header-2.7.2.h:6620
rb_hash_delete
VALUE rb_hash_delete(VALUE hash, VALUE key)
Definition: hash.c:2344
fail
#define fail()
Definition: date_strptime.c:123
to_hash
#define to_hash
Definition: hash.c:1849
ar_hint_t
unsigned char ar_hint_t
Definition: rb_mjit_min_header-2.7.2.h:6922
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:2801
rb_hash_fetch
VALUE rb_hash_fetch(VALUE hash, VALUE key)
Definition: hash.c:2134
REALLOC_N
#define REALLOC_N(var, type, n)
Definition: ruby.h:1667
GET_ENVIRON
#define GET_ENVIRON(e)
Definition: hash.c:4646
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:1621
BUILTIN_TYPE
#define BUILTIN_TYPE(x)
Definition: ruby.h:551
xfree
#define xfree
Definition: defines.h:216
st_data_t
unsigned long st_data_t
Definition: rb_mjit_min_header-2.7.2.h:5398
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:4647
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:3873
v
int VALUE v
Definition: rb_mjit_min_header-2.7.2.h:12380
HAS_EXTRA_STATES
#define HAS_EXTRA_STATES(hash, klass)
Definition: hash.c:41
equal_data::result
VALUE result
Definition: hash.c:3554
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
tbl_update_func
int(* tbl_update_func)(st_data_t *, st_data_t *, st_data_t, int)
Definition: hash.c:1648
stderr
#define stderr
Definition: rb_mjit_min_header-2.7.2.h:1522
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:2802
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_funcallv
#define rb_funcallv(recv, mid, argc, argv)
Definition: rb_mjit_min_header-2.7.2.h:7940
rb_hash_select
VALUE rb_hash_select(VALUE hash)
Definition: hash.c:2679
hash_foreach_arg::func
rb_foreach_func * func
Definition: hash.c:1310
index
int index
Definition: rb_mjit_min_header-2.7.2.h:11294
RHASH_TBL_RAW
#define RHASH_TBL_RAW(h)
Definition: internal.h:1695
malloc
void * malloc(size_t) __attribute__((__malloc__)) __attribute__((__warn_unused_result__)) __attribute__((__alloc_size__(1)))
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:3978
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:1639
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
EINVAL
#define EINVAL
Definition: rb_mjit_min_header-2.7.2.h:11007
rb_builtin_class_name
const char * rb_builtin_class_name(VALUE x)
Definition: error.c:799
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
rb_str_new
#define rb_str_new(str, len)
Definition: rb_mjit_min_header-2.7.2.h:6151
ar_table_pair_struct
Definition: hash.c:344
rehash_arg::tbl
st_table * tbl
Definition: hash.c:1922
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:2513
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:1581
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
fprintf
int fprintf(FILE *__restrict, const char *__restrict,...) __attribute__((__format__(__printf__
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:1694
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:3555
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:5137
ENVMATCH
#define ENVMATCH(n1, n2)
Definition: hash.c:4653
RTEST
#define RTEST(v)
Definition: ruby.h:481
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:4749
rb_env_path_tainted
int rb_env_path_tainted(void)
Definition: hash.c:4904
Init_Hash
void Init_Hash(void)
Definition: hash.c:6313
rb_syserr_fail_str
void rb_syserr_fail_str(int e, VALUE mesg)
Definition: error.c:2789
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
n
const char size_t n
Definition: rb_mjit_min_header-2.7.2.h:5491
fopen
FILE * fopen(const char *__restrict _name, const char *__restrict _type)
rb_block_proc
VALUE rb_block_proc(void)
Definition: proc.c:837