Ruby  2.4.2p198(2017-09-14revision59899)
variable.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  variable.c -
4 
5  $Author: nagachika $
6  created at: Tue Apr 19 23:55:15 JST 1994
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 "internal.h"
15 #include "ruby/st.h"
16 #include "ruby/util.h"
17 #include "id_table.h"
18 #include "constant.h"
19 #include "id.h"
20 #include "ccan/list/list.h"
21 #include "id_table.h"
22 
23 struct rb_id_table *rb_global_tbl;
25 
26 static void check_before_mod_set(VALUE, ID, VALUE, const char *);
28 static VALUE rb_const_search(VALUE klass, ID id, int exclude, int recurse, int visibility);
31 
32 /* per-object */
33 struct gen_ivtbl {
35  VALUE ivptr[1]; /* flexible array */
36 };
37 
38 struct ivar_update {
39  union {
41  struct gen_ivtbl *ivtbl;
42  } u;
45 };
46 
47 void
49 {
51  generic_iv_tbl = st_init_numtable();
52  autoload = rb_intern_const("__autoload__");
53  /* __classpath__: fully qualified class path */
54  classpath = rb_intern_const("__classpath__");
55  /* __tmp_classpath__: temporary class path which contains anonymous names */
56  tmp_classpath = rb_intern_const("__tmp_classpath__");
57  /* __classid__: name given to class/module under an anonymous namespace */
58  classid = rb_intern_const("__classid__");
59 }
60 
61 struct fc_result {
66  struct fc_result *prev;
67 };
68 
69 static VALUE
70 fc_path(struct fc_result *fc, ID name)
71 {
72  VALUE path, tmp;
73 
74  path = rb_id2str(name);
75  while (fc) {
76  st_data_t n;
77  if (fc->track == rb_cObject) break;
78  if (RCLASS_IV_TBL(fc->track) &&
80  tmp = rb_str_dup((VALUE)n);
81  rb_str_cat2(tmp, "::");
82  rb_str_append(tmp, path);
83  path = tmp;
84  break;
85  }
86  tmp = rb_str_dup(rb_id2str(fc->name));
87  rb_str_cat2(tmp, "::");
88  rb_str_append(tmp, path);
89  path = tmp;
90  fc = fc->prev;
91  }
92  OBJ_FREEZE(path);
93  return path;
94 }
95 
97 fc_i(ID key, VALUE v, void *a)
98 {
100  struct fc_result *res = a;
101  VALUE value = ce->value;
102  if (!rb_is_const_id(key)) return ID_TABLE_CONTINUE;
103 
104  if (value == res->klass && (!res->preferred || key == res->preferred)) {
105  res->path = fc_path(res, key);
106  return ID_TABLE_STOP;
107  }
108  if (RB_TYPE_P(value, T_MODULE) || RB_TYPE_P(value, T_CLASS)) {
109  if (!RCLASS_CONST_TBL(value)) return ID_TABLE_CONTINUE;
110  else {
111  struct fc_result arg;
112  struct fc_result *list;
113 
114  list = res;
115  while (list) {
116  if (list->track == value) return ID_TABLE_CONTINUE;
117  list = list->prev;
118  }
119 
120  arg.name = key;
121  arg.preferred = res->preferred;
122  arg.path = 0;
123  arg.klass = res->klass;
124  arg.track = value;
125  arg.prev = res;
127  if (arg.path) {
128  res->path = arg.path;
129  return ID_TABLE_STOP;
130  }
131  }
132  }
133  return ID_TABLE_CONTINUE;
134 }
135 
143 static VALUE
145 {
146  struct fc_result arg;
147 
148  arg.preferred = preferred;
149  arg.name = 0;
150  arg.path = 0;
151  arg.klass = klass;
152  arg.track = rb_cObject;
153  arg.prev = 0;
156  }
157  if (arg.path) {
158  st_data_t tmp = tmp_classpath;
159  if (!RCLASS_IV_TBL(klass)) {
160  RCLASS_IV_TBL(klass) = st_init_numtable();
161  }
162  rb_class_ivar_set(klass, classpath, arg.path);
163 
164  st_delete(RCLASS_IV_TBL(klass), &tmp, 0);
165  return arg.path;
166  }
167  return Qnil;
168 }
169 
177 static VALUE
178 classname(VALUE klass, int *permanent)
179 {
180  VALUE path = Qnil;
181  st_data_t n;
182 
183  if (!klass) klass = rb_cObject;
184  *permanent = 1;
185  if (RCLASS_IV_TBL(klass)) {
186  if (!st_lookup(RCLASS_IV_TBL(klass), (st_data_t)classpath, &n)) {
187  ID cid = 0;
188  if (st_lookup(RCLASS_IV_TBL(klass), (st_data_t)classid, &n)) {
189  VALUE cname = (VALUE)n;
190  cid = rb_check_id(&cname);
191  if (cid) path = find_class_path(klass, cid);
192  }
193  if (NIL_P(path)) {
194  path = find_class_path(klass, (ID)0);
195  }
196  if (NIL_P(path)) {
197  if (!cid) {
198  return Qnil;
199  }
200  if (!st_lookup(RCLASS_IV_TBL(klass), (st_data_t)tmp_classpath, &n)) {
201  path = rb_id2str(cid);
202  return path;
203  }
204  *permanent = 0;
205  path = (VALUE)n;
206  return path;
207  }
208  }
209  else {
210  path = (VALUE)n;
211  }
212  if (!RB_TYPE_P(path, T_STRING)) {
213  rb_bug("class path is not set properly");
214  }
215  return path;
216  }
217  return find_class_path(klass, (ID)0);
218 }
219 
220 /*
221  * call-seq:
222  * mod.name -> string
223  *
224  * Returns the name of the module <i>mod</i>. Returns nil for anonymous modules.
225  */
226 
227 VALUE
229 {
230  int permanent;
231  VALUE path = classname(mod, &permanent);
232 
233  if (!NIL_P(path)) return rb_str_dup(path);
234  return path;
235 }
236 
237 static VALUE
239 {
240  VALUE path;
241  switch (klass) {
242  case Qnil:
243  path = rb_sprintf("#<Class:%p>", (void*)obj);
244  break;
245  case Qfalse:
246  path = rb_sprintf("#<Module:%p>", (void*)obj);
247  break;
248  default:
249  path = rb_sprintf("#<%"PRIsVALUE":%p>", klass, (void*)obj);
250  break;
251  }
252  OBJ_FREEZE(path);
253  return path;
254 }
255 
257 
258 static VALUE
259 rb_tmp_class_path(VALUE klass, int *permanent, path_cache_func cache_path)
260 {
261  VALUE path = classname(klass, permanent);
262  st_data_t n = (st_data_t)path;
263 
264  if (!NIL_P(path)) {
265  return path;
266  }
267  if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),
268  (st_data_t)tmp_classpath, &n)) {
269  *permanent = 0;
270  return (VALUE)n;
271  }
272  else {
273  if (RB_TYPE_P(klass, T_MODULE)) {
274  if (rb_obj_class(klass) == rb_cModule) {
275  path = Qfalse;
276  }
277  else {
278  int perm;
279  path = rb_tmp_class_path(RBASIC(klass)->klass, &perm, cache_path);
280  }
281  }
282  *permanent = 0;
283  return cache_path(klass, path);
284  }
285 }
286 
287 static VALUE
289 {
290  return rb_ivar_set(obj, tmp_classpath, make_temporary_path(obj, name));
291 }
292 
293 VALUE
295 {
296  int permanent;
297  VALUE path = rb_tmp_class_path(klass, &permanent, ivar_cache);
298  if (!NIL_P(path)) path = rb_str_dup(path);
299  return path;
300 }
301 
302 static VALUE
304 {
305  return make_temporary_path(obj, name);
306 }
307 
308 VALUE
310 {
311  int permanent;
312  VALUE path = rb_tmp_class_path(klass, &permanent, null_cache);
313  if (!NIL_P(path)) path = rb_str_dup(path);
314  return path;
315 }
316 
317 VALUE
319 {
320  st_table *ivtbl = RCLASS_IV_TBL(klass);
321  st_data_t n;
322 
323  if (!ivtbl) return Qnil;
324  if (st_lookup(ivtbl, (st_data_t)classpath, &n)) return (VALUE)n;
325  if (st_lookup(ivtbl, (st_data_t)tmp_classpath, &n)) return (VALUE)n;
326  return Qnil;
327 }
328 
329 static VALUE
331 {
332  return name;
333 }
334 
335 VALUE
337 {
338  int permanent;
339  return rb_tmp_class_path(klass, &permanent, never_cache);
340 }
341 
342 void
344 {
345  VALUE str;
346  ID pathid = classpath;
347 
348  if (under == rb_cObject) {
349  str = rb_str_new_frozen(name);
350  }
351  else {
352  int permanent;
353  str = rb_str_dup(rb_tmp_class_path(under, &permanent, ivar_cache));
354  rb_str_cat2(str, "::");
355  rb_str_append(str, name);
356  OBJ_FREEZE(str);
357  if (!permanent) {
358  pathid = tmp_classpath;
359  rb_ivar_set(klass, classid, rb_str_intern(name));
360  }
361  }
362  rb_ivar_set(klass, pathid, str);
363 }
364 
365 void
366 rb_set_class_path(VALUE klass, VALUE under, const char *name)
367 {
368  VALUE str;
369  ID pathid = classpath;
370 
371  if (under == rb_cObject) {
372  str = rb_str_new2(name);
373  }
374  else {
375  int permanent;
376  str = rb_str_dup(rb_tmp_class_path(under, &permanent, ivar_cache));
377  rb_str_cat2(str, "::");
378  rb_str_cat2(str, name);
379  if (!permanent) {
380  pathid = tmp_classpath;
382  }
383  }
384  OBJ_FREEZE(str);
385  rb_ivar_set(klass, pathid, str);
386 }
387 
388 VALUE
390 {
391  rb_encoding *enc = rb_enc_get(pathname);
392  const char *pbeg, *pend, *p, *path = RSTRING_PTR(pathname);
393  ID id;
394  VALUE c = rb_cObject;
395 
396  if (!rb_enc_asciicompat(enc)) {
397  rb_raise(rb_eArgError, "invalid class path encoding (non ASCII)");
398  }
399  pbeg = p = path;
400  pend = path + RSTRING_LEN(pathname);
401  if (path == pend || path[0] == '#') {
402  rb_raise(rb_eArgError, "can't retrieve anonymous class %"PRIsVALUE,
403  QUOTE(pathname));
404  }
405  while (p < pend) {
406  while (p < pend && *p != ':') p++;
407  id = rb_check_id_cstr(pbeg, p-pbeg, enc);
408  if (p < pend && p[0] == ':') {
409  if ((size_t)(pend - p) < 2 || p[1] != ':') goto undefined_class;
410  p += 2;
411  pbeg = p;
412  }
413  if (!id) {
414  undefined_class:
415  rb_raise(rb_eArgError, "undefined class/module % "PRIsVALUE,
416  rb_str_subseq(pathname, 0, p-path));
417  }
418  c = rb_const_search(c, id, TRUE, FALSE, FALSE);
419  if (c == Qundef) goto undefined_class;
420  if (!RB_TYPE_P(c, T_MODULE) && !RB_TYPE_P(c, T_CLASS)) {
421  rb_raise(rb_eTypeError, "%"PRIsVALUE" does not refer to class/module",
422  pathname);
423  }
424  }
425  RB_GC_GUARD(pathname);
426 
427  return c;
428 }
429 
430 VALUE
431 rb_path2class(const char *path)
432 {
433  return rb_path_to_class(rb_str_new_cstr(path));
434 }
435 
436 void
438 {
439  rb_ivar_set(klass, classid, ID2SYM(id));
440 }
441 
442 VALUE
444 {
445  return rb_class_path(rb_class_real(klass));
446 }
447 
448 const char *
450 {
451  int permanent;
452  VALUE path = rb_tmp_class_path(rb_class_real(klass), &permanent, ivar_cache);
453  if (NIL_P(path)) return NULL;
454  return RSTRING_PTR(path);
455 }
456 
457 const char *
459 {
460  return rb_class2name(CLASS_OF(obj));
461 }
462 
463 struct trace_var {
464  int removed;
465  void (*func)(VALUE arg, VALUE val);
467  struct trace_var *next;
468 };
469 
471  int counter;
473  void *data;
477  struct trace_var *trace;
478 };
479 
480 struct rb_global_entry*
482 {
483  struct rb_global_entry *entry;
484  VALUE data;
485 
486  if (!rb_id_table_lookup(rb_global_tbl, id, &data)) {
487  struct rb_global_variable *var;
488  entry = ALLOC(struct rb_global_entry);
489  var = ALLOC(struct rb_global_variable);
490  entry->id = id;
491  entry->var = var;
492  var->counter = 1;
493  var->data = 0;
497 
498  var->block_trace = 0;
499  var->trace = 0;
501  }
502  else {
503  entry = (struct rb_global_entry *)data;
504  }
505  return entry;
506 }
507 
508 VALUE
510 {
511  rb_warning("global variable `%"PRIsVALUE"' not initialized", QUOTE_ID(id));
512 
513  return Qnil;
514 }
515 
516 void
518 {
519  var->getter = rb_gvar_val_getter;
520  var->setter = rb_gvar_val_setter;
521  var->marker = rb_gvar_val_marker;
522 
523  var->data = (void*)val;
524 }
525 
526 void
528 {
529 }
530 
531 VALUE
532 rb_gvar_val_getter(ID id, void *data, struct rb_global_variable *var)
533 {
534  return (VALUE)data;
535 }
536 
537 void
539 {
540  var->data = (void*)val;
541 }
542 
543 void
545 {
546  VALUE data = (VALUE)var;
547  if (data) rb_gc_mark_maybe(data);
548 }
549 
550 VALUE
551 rb_gvar_var_getter(ID id, void *data, struct rb_global_variable *gvar)
552 {
553  VALUE *var = data;
554  if (!var) return Qnil;
555  return *var;
556 }
557 
558 void
559 rb_gvar_var_setter(VALUE val, ID id, void *data, struct rb_global_variable *g)
560 {
561  *(VALUE *)data = val;
562 }
563 
564 void
566 {
567  if (var) rb_gc_mark_maybe(*var);
568 }
569 
570 void
572 {
573  rb_name_error(id, "%"PRIsVALUE" is a read-only variable", QUOTE_ID(id));
574 }
575 
576 static enum rb_id_table_iterator_result
577 mark_global_entry(VALUE v, void *ignored)
578 {
579  struct rb_global_entry *entry = (struct rb_global_entry *)v;
580  struct trace_var *trace;
581  struct rb_global_variable *var = entry->var;
582 
583  (*var->marker)(var->data);
584  trace = var->trace;
585  while (trace) {
586  if (trace->data) rb_gc_mark_maybe(trace->data);
587  trace = trace->next;
588  }
589  return ID_TABLE_CONTINUE;
590 }
591 
592 void
594 {
595  if (rb_global_tbl)
597 }
598 
599 static ID
600 global_id(const char *name)
601 {
602  ID id;
603 
604  if (name[0] == '$') id = rb_intern(name);
605  else {
606  size_t len = strlen(name);
607  char *buf = ALLOCA_N(char, len+1);
608  buf[0] = '$';
609  memcpy(buf+1, name, len);
610  id = rb_intern2(buf, len+1);
611  }
612  return id;
613 }
614 
615 void
617  const char *name,
618  VALUE *var,
619  VALUE (*getter)(ANYARGS),
620  void (*setter)(ANYARGS))
621 {
622  volatile VALUE tmp = var ? *var : Qnil;
623  ID id = global_id(name);
624  struct rb_global_variable *gvar = rb_global_entry(id)->var;
625 
626  gvar->data = (void*)var;
629  gvar->marker = rb_gvar_var_marker;
630 
631  RB_GC_GUARD(tmp);
632 }
633 
634 void
635 rb_define_variable(const char *name, VALUE *var)
636 {
637  rb_define_hooked_variable(name, var, 0, 0);
638 }
639 
640 void
641 rb_define_readonly_variable(const char *name, const VALUE *var)
642 {
644 }
645 
646 void
648  const char *name,
649  VALUE (*getter)(ANYARGS),
650  void (*setter)(ANYARGS))
651 {
655 }
656 
657 static void
659 {
660  rb_eval_cmd(cmd, rb_ary_new3(1, val), 0);
661 }
662 
663 /*
664  * call-seq:
665  * trace_var(symbol, cmd ) -> nil
666  * trace_var(symbol) {|val| block } -> nil
667  *
668  * Controls tracing of assignments to global variables. The parameter
669  * +symbol+ identifies the variable (as either a string name or a
670  * symbol identifier). _cmd_ (which may be a string or a
671  * +Proc+ object) or block is executed whenever the variable
672  * is assigned. The block or +Proc+ object receives the
673  * variable's new value as a parameter. Also see
674  * <code>Kernel::untrace_var</code>.
675  *
676  * trace_var :$_, proc {|v| puts "$_ is now '#{v}'" }
677  * $_ = "hello"
678  * $_ = ' there'
679  *
680  * <em>produces:</em>
681  *
682  * $_ is now 'hello'
683  * $_ is now ' there'
684  */
685 
686 VALUE
688 {
689  VALUE var, cmd;
690  struct rb_global_entry *entry;
691  struct trace_var *trace;
692 
693  if (rb_scan_args(argc, argv, "11", &var, &cmd) == 1) {
694  cmd = rb_block_proc();
695  }
696  if (NIL_P(cmd)) {
697  return rb_f_untrace_var(argc, argv);
698  }
699  entry = rb_global_entry(rb_to_id(var));
700  if (OBJ_TAINTED(cmd)) {
701  rb_raise(rb_eSecurityError, "Insecure: tainted variable trace");
702  }
703  trace = ALLOC(struct trace_var);
704  trace->next = entry->var->trace;
705  trace->func = rb_trace_eval;
706  trace->data = cmd;
707  trace->removed = 0;
708  entry->var->trace = trace;
709 
710  return Qnil;
711 }
712 
713 static void
715 {
716  struct trace_var *trace = var->trace;
717  struct trace_var t;
718  struct trace_var *next;
719 
720  t.next = trace;
721  trace = &t;
722  while (trace->next) {
723  next = trace->next;
724  if (next->removed) {
725  trace->next = next->next;
726  xfree(next);
727  }
728  else {
729  trace = next;
730  }
731  }
732  var->trace = t.next;
733 }
734 
735 /*
736  * call-seq:
737  * untrace_var(symbol [, cmd] ) -> array or nil
738  *
739  * Removes tracing for the specified command on the given global
740  * variable and returns +nil+. If no command is specified,
741  * removes all tracing for that variable and returns an array
742  * containing the commands actually removed.
743  */
744 
745 VALUE
747 {
748  VALUE var, cmd;
749  ID id;
750  struct rb_global_entry *entry;
751  struct trace_var *trace;
752  VALUE data;
753 
754  rb_scan_args(argc, argv, "11", &var, &cmd);
755  id = rb_check_id(&var);
756  if (!id) {
757  rb_name_error_str(var, "undefined global variable %"PRIsVALUE"", QUOTE(var));
758  }
759  if (!rb_id_table_lookup(rb_global_tbl, id, &data)) {
760  rb_name_error(id, "undefined global variable %"PRIsVALUE"", QUOTE_ID(id));
761  }
762 
763  trace = (entry = (struct rb_global_entry *)data)->var->trace;
764  if (NIL_P(cmd)) {
765  VALUE ary = rb_ary_new();
766 
767  while (trace) {
768  struct trace_var *next = trace->next;
769  rb_ary_push(ary, (VALUE)trace->data);
770  trace->removed = 1;
771  trace = next;
772  }
773 
774  if (!entry->var->block_trace) remove_trace(entry->var);
775  return ary;
776  }
777  else {
778  while (trace) {
779  if (trace->data == cmd) {
780  trace->removed = 1;
781  if (!entry->var->block_trace) remove_trace(entry->var);
782  return rb_ary_new3(1, cmd);
783  }
784  trace = trace->next;
785  }
786  }
787  return Qnil;
788 }
789 
790 VALUE
792 {
793  struct rb_global_variable *var = entry->var;
794  return (*var->getter)(entry->id, var->data, var);
795 }
796 
797 struct trace_data {
798  struct trace_var *trace;
800 };
801 
802 static VALUE
804 {
805  struct trace_var *trace = data->trace;
806 
807  while (trace) {
808  (*trace->func)(trace->data, data->val);
809  trace = trace->next;
810  }
811 
812  return Qnil;
813 }
814 
815 static VALUE
817 {
818  var->block_trace = 0;
819  remove_trace(var);
820  return Qnil; /* not reached */
821 }
822 
823 VALUE
825 {
826  struct trace_data trace;
827  struct rb_global_variable *var = entry->var;
828 
829  (*var->setter)(val, entry->id, var->data, var);
830 
831  if (var->trace && !var->block_trace) {
832  var->block_trace = 1;
833  trace.trace = var->trace;
834  trace.val = val;
835  rb_ensure(trace_ev, (VALUE)&trace, trace_en, (VALUE)var);
836  }
837  return val;
838 }
839 
840 VALUE
841 rb_gv_set(const char *name, VALUE val)
842 {
843  struct rb_global_entry *entry;
844 
845  entry = rb_global_entry(global_id(name));
846  return rb_gvar_set(entry, val);
847 }
848 
849 VALUE
850 rb_gv_get(const char *name)
851 {
852  struct rb_global_entry *entry;
853 
854  entry = rb_global_entry(global_id(name));
855  return rb_gvar_get(entry);
856 }
857 
858 VALUE
860 {
861  if (entry->var->getter == rb_gvar_undef_getter) return Qfalse;
862  return Qtrue;
863 }
864 
865 static enum rb_id_table_iterator_result
866 gvar_i(ID key, VALUE val, void *a)
867 {
868  VALUE ary = (VALUE)a;
869  rb_ary_push(ary, ID2SYM(key));
870  return ID_TABLE_CONTINUE;
871 }
872 
873 /*
874  * call-seq:
875  * global_variables -> array
876  *
877  * Returns an array of the names of global variables.
878  *
879  * global_variables.grep /std/ #=> [:$stdin, :$stdout, :$stderr]
880  */
881 
882 VALUE
884 {
885  VALUE ary = rb_ary_new();
886  VALUE sym, backref = rb_backref_get();
887 
889  if (!NIL_P(backref)) {
890  char buf[2];
891  int i, nmatch = rb_match_count(backref);
892  buf[0] = '$';
893  for (i = 1; i <= nmatch; ++i) {
894  if (!rb_match_nth_defined(i, backref)) continue;
895  if (i < 10) {
896  /* probably reused, make static ID */
897  buf[1] = (char)(i + '0');
898  sym = ID2SYM(rb_intern2(buf, 2));
899  }
900  else {
901  /* dynamic symbol */
902  sym = rb_str_intern(rb_sprintf("$%d", i));
903  }
904  rb_ary_push(ary, sym);
905  }
906  }
907  return ary;
908 }
909 
910 void
911 rb_alias_variable(ID name1, ID name2)
912 {
913  struct rb_global_entry *entry1, *entry2;
914  VALUE data1;
915 
916  entry2 = rb_global_entry(name2);
917  if (!rb_id_table_lookup(rb_global_tbl, name1, &data1)) {
918  entry1 = ALLOC(struct rb_global_entry);
919  entry1->id = name1;
920  rb_id_table_insert(rb_global_tbl, name1, (VALUE)entry1);
921  }
922  else if ((entry1 = (struct rb_global_entry *)data1)->var != entry2->var) {
923  struct rb_global_variable *var = entry1->var;
924  if (var->block_trace) {
925  rb_raise(rb_eRuntimeError, "can't alias in tracer");
926  }
927  var->counter--;
928  if (var->counter == 0) {
929  struct trace_var *trace = var->trace;
930  while (trace) {
931  struct trace_var *next = trace->next;
932  xfree(trace);
933  trace = next;
934  }
935  xfree(var);
936  }
937  }
938  else {
939  return;
940  }
941  entry2->var->counter++;
942  entry1->var = entry2->var;
943 }
944 
946  struct gen_ivtbl *ivtbl;
948 };
949 
950 static int
952 {
953  struct gen_ivar_compat_tbl *a = (struct gen_ivar_compat_tbl *)arg;
954 
955  if (index < a->ivtbl->numiv) {
956  VALUE val = a->ivtbl->ivptr[index];
957  if (val != Qundef) {
958  st_add_direct(a->tbl, id, (st_data_t)val);
959  }
960  }
961  return ST_CONTINUE;
962 }
963 
964 static int
966 {
967  st_data_t data;
968 
969  if (st_lookup(generic_iv_tbl, (st_data_t)obj, &data)) {
970  *ivtbl = (struct gen_ivtbl *)data;
971  return 1;
972  }
973  return 0;
974 }
975 
976 /* for backwards compatibility only */
977 st_table*
979 {
980  st_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
981  struct gen_ivar_compat_tbl a;
982  st_data_t d;
983 
984  if (!iv_index_tbl) return 0;
985  if (!FL_TEST(obj, FL_EXIVAR)) return 0;
986  if (!gen_ivtbl_get(obj, &a.ivtbl)) return 0;
987 
988  a.tbl = 0;
989  if (!generic_iv_tbl_compat) {
990  generic_iv_tbl_compat = st_init_numtable();
991  }
992  else {
993  if (st_lookup(generic_iv_tbl_compat, (st_data_t)obj, &d)) {
994  a.tbl = (st_table *)d;
995  st_clear(a.tbl);
996  }
997  }
998  if (!a.tbl) {
999  a.tbl = st_init_numtable();
1000  d = (st_data_t)a.tbl;
1001  st_add_direct(generic_iv_tbl_compat, (st_data_t)obj, d);
1002  }
1003  st_foreach_safe(iv_index_tbl, gen_ivar_compat_tbl_i, (st_data_t)&a);
1004 
1005  return a.tbl;
1006 }
1007 
1008 static VALUE
1010 {
1011  struct gen_ivtbl *ivtbl;
1012 
1013  if (gen_ivtbl_get(obj, &ivtbl)) {
1014  st_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
1015  st_data_t index;
1016 
1017  if (st_lookup(iv_index_tbl, (st_data_t)id, &index)) {
1018  if (index < ivtbl->numiv) {
1019  VALUE ret = ivtbl->ivptr[index];
1020 
1021  ivtbl->ivptr[index] = Qundef;
1022  return ret == Qundef ? undef : ret;
1023  }
1024  }
1025  }
1026  return undef;
1027 }
1028 
1029 static VALUE
1031 {
1032  struct gen_ivtbl *ivtbl;
1033 
1034  if (gen_ivtbl_get(obj, &ivtbl)) {
1035  st_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
1036  st_data_t index;
1037 
1038  if (st_lookup(iv_index_tbl, (st_data_t)id, &index)) {
1039  if (index < ivtbl->numiv) {
1040  VALUE ret = ivtbl->ivptr[index];
1041 
1042  return ret == Qundef ? undef : ret;
1043  }
1044  }
1045  }
1046  return undef;
1047 }
1048 
1049 static size_t
1051 {
1052  return sizeof(struct gen_ivtbl) + n * sizeof(VALUE) - sizeof(VALUE);
1053 }
1054 
1055 static struct gen_ivtbl *
1057 {
1058  uint32_t len = old ? old->numiv : 0;
1059  struct gen_ivtbl *ivtbl = xrealloc(old, gen_ivtbl_bytes(n));
1060 
1061  ivtbl->numiv = n;
1062  for (; len < n; len++) {
1063  ivtbl->ivptr[len] = Qundef;
1064  }
1065 
1066  return ivtbl;
1067 }
1068 
1069 #if 0
1070 static struct gen_ivtbl *
1071 gen_ivtbl_dup(const struct gen_ivtbl *orig)
1072 {
1073  size_t s = gen_ivtbl_bytes(orig->numiv);
1074  struct gen_ivtbl *ivtbl = xmalloc(s);
1075 
1076  memcpy(ivtbl, orig, s);
1077 
1078  return ivtbl;
1079 }
1080 #endif
1081 
1082 static uint32_t
1084 {
1085  uint32_t index = (uint32_t)ivup->index; /* should not overflow */
1086  uint32_t newsize = (index+1) + (index+1)/4; /* (index+1)*1.25 */
1087 
1088  if (!ivup->iv_extended &&
1089  ivup->u.iv_index_tbl->num_entries < (st_index_t)newsize) {
1090  newsize = (uint32_t)ivup->u.iv_index_tbl->num_entries;
1091  }
1092  return newsize;
1093 }
1094 
1095 static int
1097 {
1098  VALUE obj = (VALUE)*k;
1099  struct ivar_update *ivup = (struct ivar_update *)u;
1100  uint32_t newsize;
1101  int ret = ST_CONTINUE;
1102  struct gen_ivtbl *ivtbl;
1103 
1104  if (existing) {
1105  ivtbl = (struct gen_ivtbl *)*v;
1106  if (ivup->index >= ivtbl->numiv) {
1107  goto resize;
1108  }
1109  ret = ST_STOP;
1110  }
1111  else {
1112  FL_SET(obj, FL_EXIVAR);
1113  ivtbl = 0;
1114 resize:
1115  newsize = iv_index_tbl_newsize(ivup);
1116  ivtbl = gen_ivtbl_resize(ivtbl, newsize);
1117  *v = (st_data_t)ivtbl;
1118  }
1119  ivup->u.ivtbl = ivtbl;
1120  return ret;
1121 }
1122 
1123 static VALUE
1125 {
1126  struct gen_ivtbl *ivtbl;
1127  st_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
1128  st_data_t index;
1129 
1130  if (!iv_index_tbl) return Qfalse;
1131  if (!st_lookup(iv_index_tbl, (st_data_t)id, &index)) return Qfalse;
1132  if (!gen_ivtbl_get(obj, &ivtbl)) return Qfalse;
1133 
1134  if ((index < ivtbl->numiv) && (ivtbl->ivptr[index] != Qundef))
1135  return Qtrue;
1136 
1137  return Qfalse;
1138 }
1139 
1140 static int
1142 {
1143  struct gen_ivtbl *ivtbl;
1144  st_data_t key = (st_data_t)id;
1145  st_data_t index;
1146  st_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
1147 
1148  if (!iv_index_tbl) return 0;
1149  if (!st_lookup(iv_index_tbl, key, &index)) return 0;
1150  if (!gen_ivtbl_get(obj, &ivtbl)) return 0;
1151 
1152  if (index < ivtbl->numiv) {
1153  if (ivtbl->ivptr[index] != Qundef) {
1154  *valp = ivtbl->ivptr[index];
1155  ivtbl->ivptr[index] = Qundef;
1156  return 1;
1157  }
1158  }
1159  return 0;
1160 }
1161 
1162 static void
1163 gen_ivtbl_mark(const struct gen_ivtbl *ivtbl)
1164 {
1165  uint32_t i;
1166 
1167  for (i = 0; i < ivtbl->numiv; i++) {
1168  rb_gc_mark(ivtbl->ivptr[i]);
1169  }
1170 }
1171 
1172 void
1174 {
1175  struct gen_ivtbl *ivtbl;
1176 
1177  if (gen_ivtbl_get(obj, &ivtbl)) {
1178  gen_ivtbl_mark(ivtbl);
1179  }
1180 }
1181 
1182 void
1184 {
1185  st_data_t key = (st_data_t)obj;
1186  struct gen_ivtbl *ivtbl;
1187 
1188  if (st_delete(generic_iv_tbl, &key, (st_data_t *)&ivtbl))
1189  xfree(ivtbl);
1190 
1191  if (generic_iv_tbl_compat) {
1192  st_table *tbl;
1193 
1194  if (st_delete(generic_iv_tbl_compat, &key, (st_data_t *)&tbl))
1195  st_free_table(tbl);
1196  }
1197 }
1198 
1199 RUBY_FUNC_EXPORTED size_t
1201 {
1202  struct gen_ivtbl *ivtbl;
1203 
1204  if (gen_ivtbl_get(obj, &ivtbl))
1205  return gen_ivtbl_bytes(ivtbl->numiv);
1206  return 0;
1207 }
1208 
1209 static size_t
1210 gen_ivtbl_count(const struct gen_ivtbl *ivtbl)
1211 {
1212  uint32_t i;
1213  size_t n = 0;
1214 
1215  for (i = 0; i < ivtbl->numiv; i++) {
1216  if (ivtbl->ivptr[i] != Qundef) {
1217  n++;
1218  }
1219  }
1220 
1221  return n;
1222 }
1223 
1224 VALUE
1225 rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
1226 {
1227  VALUE val, *ptr;
1228  struct st_table *iv_index_tbl;
1229  uint32_t len;
1230  st_data_t index;
1231 
1232  if (SPECIAL_CONST_P(obj)) return undef;
1233  switch (BUILTIN_TYPE(obj)) {
1234  case T_OBJECT:
1235  len = ROBJECT_NUMIV(obj);
1236  ptr = ROBJECT_IVPTR(obj);
1237  iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
1238  if (!iv_index_tbl) break;
1239  if (!st_lookup(iv_index_tbl, (st_data_t)id, &index)) break;
1240  if (len <= index) break;
1241  val = ptr[index];
1242  if (val != Qundef)
1243  return val;
1244  break;
1245  case T_CLASS:
1246  case T_MODULE:
1247  if (RCLASS_IV_TBL(obj) &&
1248  st_lookup(RCLASS_IV_TBL(obj), (st_data_t)id, &index))
1249  return (VALUE)index;
1250  break;
1251  default:
1252  if (FL_TEST(obj, FL_EXIVAR))
1253  return generic_ivar_get(obj, id, undef);
1254  break;
1255  }
1256  return undef;
1257 }
1258 
1259 VALUE
1261 {
1262  VALUE iv = rb_ivar_lookup(obj, id, Qundef);
1263 
1264  if (iv == Qundef) {
1265  if (RTEST(ruby_verbose))
1266  rb_warning("instance variable %"PRIsVALUE" not initialized", QUOTE_ID(id));
1267  iv = Qnil;
1268  }
1269  return iv;
1270 }
1271 
1272 VALUE
1274 {
1275  return rb_ivar_lookup(obj, id, Qnil);
1276 }
1277 
1278 static VALUE
1279 rb_ivar_delete(VALUE obj, ID id, VALUE undef)
1280 {
1281  VALUE val, *ptr;
1282  struct st_table *iv_index_tbl;
1283  uint32_t len;
1284  st_data_t index;
1285 
1286  rb_check_frozen(obj);
1287  switch (BUILTIN_TYPE(obj)) {
1288  case T_OBJECT:
1289  len = ROBJECT_NUMIV(obj);
1290  ptr = ROBJECT_IVPTR(obj);
1291  iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
1292  if (!iv_index_tbl) break;
1293  if (!st_lookup(iv_index_tbl, (st_data_t)id, &index)) break;
1294  if (len <= index) break;
1295  val = ptr[index];
1296  ptr[index] = Qundef;
1297  if (val != Qundef)
1298  return val;
1299  break;
1300  case T_CLASS:
1301  case T_MODULE:
1302  if (RCLASS_IV_TBL(obj) &&
1303  st_delete(RCLASS_IV_TBL(obj), (st_data_t *)&id, &index))
1304  return (VALUE)index;
1305  break;
1306  default:
1307  if (FL_TEST(obj, FL_EXIVAR))
1308  return generic_ivar_delete(obj, id, undef);
1309  break;
1310  }
1311  return undef;
1312 }
1313 
1314 VALUE
1316 {
1317  return rb_ivar_delete(obj, id, Qnil);
1318 }
1319 
1320 static st_table *
1322 {
1323  VALUE klass = rb_obj_class(obj);
1324  st_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(klass);
1325 
1326  if (!iv_index_tbl) {
1327  iv_index_tbl = RCLASS_IV_INDEX_TBL(klass) = st_init_numtable();
1328  }
1329 
1330  return iv_index_tbl;
1331 }
1332 
1333 static void
1335 {
1336  if (st_lookup(ivup->u.iv_index_tbl, (st_data_t)id, &ivup->index)) {
1337  return;
1338  }
1339  if (ivup->u.iv_index_tbl->num_entries >= INT_MAX) {
1340  rb_raise(rb_eArgError, "too many instance variables");
1341  }
1342  ivup->index = (st_data_t)ivup->u.iv_index_tbl->num_entries;
1343  st_add_direct(ivup->u.iv_index_tbl, (st_data_t)id, ivup->index);
1344  ivup->iv_extended = 1;
1345 }
1346 
1347 static void
1349 {
1350  struct ivar_update ivup;
1351 
1352  ivup.iv_extended = 0;
1353  ivup.u.iv_index_tbl = iv_index_tbl_make(obj);
1354  iv_index_tbl_extend(&ivup, id);
1355  st_update(generic_iv_tbl, (st_data_t)obj, generic_ivar_update,
1356  (st_data_t)&ivup);
1357 
1358  ivup.u.ivtbl->ivptr[ivup.index] = val;
1359 
1360  RB_OBJ_WRITTEN(obj, Qundef, val);
1361 }
1362 
1363 VALUE
1365 {
1366  struct ivar_update ivup;
1367  uint32_t i, len;
1368 
1369  rb_check_frozen(obj);
1370 
1371  switch (BUILTIN_TYPE(obj)) {
1372  case T_OBJECT:
1373  ivup.iv_extended = 0;
1374  ivup.u.iv_index_tbl = iv_index_tbl_make(obj);
1375  iv_index_tbl_extend(&ivup, id);
1376  len = ROBJECT_NUMIV(obj);
1377  if (len <= ivup.index) {
1378  VALUE *ptr = ROBJECT_IVPTR(obj);
1379  if (ivup.index < ROBJECT_EMBED_LEN_MAX) {
1380  RBASIC(obj)->flags |= ROBJECT_EMBED;
1381  ptr = ROBJECT(obj)->as.ary;
1382  for (i = 0; i < ROBJECT_EMBED_LEN_MAX; i++) {
1383  ptr[i] = Qundef;
1384  }
1385  }
1386  else {
1387  VALUE *newptr;
1388  uint32_t newsize = iv_index_tbl_newsize(&ivup);
1389 
1390  if (RBASIC(obj)->flags & ROBJECT_EMBED) {
1391  newptr = ALLOC_N(VALUE, newsize);
1392  MEMCPY(newptr, ptr, VALUE, len);
1393  RBASIC(obj)->flags &= ~ROBJECT_EMBED;
1394  ROBJECT(obj)->as.heap.ivptr = newptr;
1395  }
1396  else {
1397  REALLOC_N(ROBJECT(obj)->as.heap.ivptr, VALUE, newsize);
1398  newptr = ROBJECT(obj)->as.heap.ivptr;
1399  }
1400  for (; len < newsize; len++)
1401  newptr[len] = Qundef;
1402  ROBJECT(obj)->as.heap.numiv = newsize;
1403  ROBJECT(obj)->as.heap.iv_index_tbl = ivup.u.iv_index_tbl;
1404  }
1405  }
1406  RB_OBJ_WRITE(obj, &ROBJECT_IVPTR(obj)[ivup.index], val);
1407  break;
1408  case T_CLASS:
1409  case T_MODULE:
1410  if (!RCLASS_IV_TBL(obj)) RCLASS_IV_TBL(obj) = st_init_numtable();
1411  rb_class_ivar_set(obj, id, val);
1412  break;
1413  default:
1414  generic_ivar_set(obj, id, val);
1415  break;
1416  }
1417  return val;
1418 }
1419 
1420 VALUE
1422 {
1423  VALUE val;
1424  struct st_table *iv_index_tbl;
1425  st_data_t index;
1426 
1427  if (SPECIAL_CONST_P(obj)) return Qfalse;
1428  switch (BUILTIN_TYPE(obj)) {
1429  case T_OBJECT:
1430  iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
1431  if (!iv_index_tbl) break;
1432  if (!st_lookup(iv_index_tbl, (st_data_t)id, &index)) break;
1433  if (ROBJECT_NUMIV(obj) <= index) break;
1434  val = ROBJECT_IVPTR(obj)[index];
1435  if (val != Qundef)
1436  return Qtrue;
1437  break;
1438  case T_CLASS:
1439  case T_MODULE:
1440  if (RCLASS_IV_TBL(obj) && st_lookup(RCLASS_IV_TBL(obj), (st_data_t)id, 0))
1441  return Qtrue;
1442  break;
1443  default:
1444  if (FL_TEST(obj, FL_EXIVAR))
1445  return generic_ivar_defined(obj, id);
1446  break;
1447  }
1448  return Qfalse;
1449 }
1450 
1453  int (*func)(ID key, VALUE val, st_data_t arg);
1455 };
1456 
1457 static int
1459 {
1460  struct obj_ivar_tag *data = (struct obj_ivar_tag *)arg;
1461  if (index < ROBJECT_NUMIV(data->obj)) {
1462  VALUE val = ROBJECT_IVPTR(data->obj)[index];
1463  if (val != Qundef) {
1464  return (data->func)((ID)key, val, data->arg);
1465  }
1466  }
1467  return ST_CONTINUE;
1468 }
1469 
1470 static void
1472 {
1473  st_table *tbl;
1474  struct obj_ivar_tag data;
1475 
1476  tbl = ROBJECT_IV_INDEX_TBL(obj);
1477  if (!tbl)
1478  return;
1479 
1480  data.obj = obj;
1481  data.func = (int (*)(ID key, VALUE val, st_data_t arg))func;
1482  data.arg = arg;
1483 
1484  st_foreach_safe(tbl, obj_ivar_i, (st_data_t)&data);
1485 }
1486 
1488  struct gen_ivtbl *ivtbl;
1489  int (*func)(ID key, VALUE val, st_data_t arg);
1491 };
1492 
1493 static int
1495 {
1496  struct gen_ivar_tag *arg = (struct gen_ivar_tag *)data;
1497 
1498  if (index < arg->ivtbl->numiv) {
1499  VALUE val = arg->ivtbl->ivptr[index];
1500  if (val != Qundef) {
1501  return (arg->func)((ID)key, val, arg->arg);
1502  }
1503  }
1504  return ST_CONTINUE;
1505 }
1506 
1507 static void
1509 {
1510  struct gen_ivar_tag data;
1511  st_table *iv_index_tbl = RCLASS_IV_INDEX_TBL(rb_obj_class(obj));
1512 
1513  if (!iv_index_tbl) return;
1514  if (!gen_ivtbl_get(obj, &data.ivtbl)) return;
1515 
1516  data.func = (int (*)(ID key, VALUE val, st_data_t arg))func;
1517  data.arg = arg;
1518 
1519  st_foreach_safe(iv_index_tbl, gen_ivar_each_i, (st_data_t)&data);
1520 }
1521 
1522 struct givar_copy {
1525  struct gen_ivtbl *ivtbl;
1526 };
1527 
1528 static int
1530 {
1531  struct givar_copy *c = (struct givar_copy *)arg;
1532  struct ivar_update ivup;
1533 
1534  ivup.iv_extended = 0;
1535  ivup.u.iv_index_tbl = c->iv_index_tbl;
1536  iv_index_tbl_extend(&ivup, id);
1537  if (ivup.index >= c->ivtbl->numiv) {
1538  uint32_t newsize = iv_index_tbl_newsize(&ivup);
1539  c->ivtbl = gen_ivtbl_resize(c->ivtbl, newsize);
1540  }
1541  c->ivtbl->ivptr[ivup.index] = val;
1542 
1543  RB_OBJ_WRITTEN(c->obj, Qundef, val);
1544 
1545  return ST_CONTINUE;
1546 }
1547 
1548 void
1550 {
1551  struct gen_ivtbl *ivtbl;
1552 
1553  rb_check_frozen(clone);
1554 
1555  if (!FL_TEST(obj, FL_EXIVAR)) {
1556  clear:
1557  if (FL_TEST(clone, FL_EXIVAR)) {
1558  rb_free_generic_ivar(clone);
1559  FL_UNSET(clone, FL_EXIVAR);
1560  }
1561  return;
1562  }
1563  if (gen_ivtbl_get(obj, &ivtbl)) {
1564  struct givar_copy c;
1565  uint32_t i;
1566 
1567  if (gen_ivtbl_count(ivtbl) == 0)
1568  goto clear;
1569 
1570  if (gen_ivtbl_get(clone, &c.ivtbl)) {
1571  for (i = 0; i < c.ivtbl->numiv; i++)
1572  c.ivtbl->ivptr[i] = Qundef;
1573  }
1574  else {
1575  c.ivtbl = gen_ivtbl_resize(0, ivtbl->numiv);
1576  FL_SET(clone, FL_EXIVAR);
1577  }
1578 
1579  c.iv_index_tbl = iv_index_tbl_make(clone);
1580  c.obj = clone;
1582  /*
1583  * c.ivtbl may change in gen_ivar_copy due to realloc,
1584  * no need to free
1585  */
1586  st_insert(generic_iv_tbl, (st_data_t)clone, (st_data_t)c.ivtbl);
1587  }
1588 }
1589 
1590 void
1592 {
1593  if (SPECIAL_CONST_P(obj)) return;
1594  switch (BUILTIN_TYPE(obj)) {
1595  case T_OBJECT:
1596  obj_ivar_each(obj, func, arg);
1597  break;
1598  case T_CLASS:
1599  case T_MODULE:
1600  if (RCLASS_IV_TBL(obj)) {
1601  st_foreach_safe(RCLASS_IV_TBL(obj), func, arg);
1602  }
1603  break;
1604  default:
1605  if (FL_TEST(obj, FL_EXIVAR)) {
1606  gen_ivar_each(obj, func, arg);
1607  }
1608  break;
1609  }
1610 }
1611 
1612 st_index_t
1614 {
1615  st_table *tbl;
1616 
1617  if (SPECIAL_CONST_P(obj)) return 0;
1618 
1619  switch (BUILTIN_TYPE(obj)) {
1620  case T_OBJECT:
1621  if ((tbl = ROBJECT_IV_INDEX_TBL(obj)) != 0) {
1622  st_index_t i, count, num = ROBJECT_NUMIV(obj);
1623  const VALUE *const ivptr = ROBJECT_IVPTR(obj);
1624  for (i = count = 0; i < num; ++i) {
1625  if (ivptr[i] != Qundef) {
1626  count++;
1627  }
1628  }
1629  return count;
1630  }
1631  break;
1632  case T_CLASS:
1633  case T_MODULE:
1634  if ((tbl = RCLASS_IV_TBL(obj)) != 0) {
1635  return tbl->num_entries;
1636  }
1637  break;
1638  default:
1639  if (FL_TEST(obj, FL_EXIVAR)) {
1640  struct gen_ivtbl *ivtbl;
1641 
1642  if (gen_ivtbl_get(obj, &ivtbl)) {
1643  return gen_ivtbl_count(ivtbl);
1644  }
1645  }
1646  break;
1647  }
1648  return 0;
1649 }
1650 
1651 static int
1653 {
1654  ID key = (ID)k;
1655  VALUE ary = (VALUE)a;
1656 
1657  if (rb_is_instance_id(key)) {
1658  rb_ary_push(ary, ID2SYM(key));
1659  }
1660  return ST_CONTINUE;
1661 }
1662 
1663 /*
1664  * call-seq:
1665  * obj.instance_variables -> array
1666  *
1667  * Returns an array of instance variable names for the receiver. Note
1668  * that simply defining an accessor does not create the corresponding
1669  * instance variable.
1670  *
1671  * class Fred
1672  * attr_accessor :a1
1673  * def initialize
1674  * @iv = 3
1675  * end
1676  * end
1677  * Fred.new.instance_variables #=> [:@iv]
1678  */
1679 
1680 VALUE
1682 {
1683  VALUE ary;
1684 
1685  ary = rb_ary_new();
1686  rb_ivar_foreach(obj, ivar_i, ary);
1687  return ary;
1688 }
1689 
1690 #define rb_is_constant_id rb_is_const_id
1691 #define rb_is_constant_name rb_is_const_name
1692 #define id_for_var(obj, name, part, type) \
1693  id_for_var_message(obj, name, type, "`%1$s' is not allowed as "#part" "#type" variable name")
1694 #define id_for_var_message(obj, name, type, message) \
1695  check_id_type(obj, &(name), rb_is_##type##_id, rb_is_##type##_name, message, strlen(message))
1696 static ID
1698  int (*valid_id_p)(ID), int (*valid_name_p)(VALUE),
1699  const char *message, size_t message_len)
1700 {
1701  ID id = rb_check_id(pname);
1702  VALUE name = *pname;
1703 
1704  if (id ? !valid_id_p(id) : !valid_name_p(name)) {
1705  rb_name_err_raise_str(rb_fstring_new(message, message_len),
1706  obj, name);
1707  }
1708  return id;
1709 }
1710 
1711 /*
1712  * call-seq:
1713  * obj.remove_instance_variable(symbol) -> obj
1714  *
1715  * Removes the named instance variable from <i>obj</i>, returning that
1716  * variable's value.
1717  *
1718  * class Dummy
1719  * attr_reader :var
1720  * def initialize
1721  * @var = 99
1722  * end
1723  * def remove
1724  * remove_instance_variable(:@var)
1725  * end
1726  * end
1727  * d = Dummy.new
1728  * d.var #=> 99
1729  * d.remove #=> 99
1730  * d.var #=> nil
1731  */
1732 
1733 VALUE
1735 {
1736  VALUE val = Qnil;
1737  const ID id = id_for_var(obj, name, an, instance);
1738  st_data_t n, v;
1739  struct st_table *iv_index_tbl;
1740  st_data_t index;
1741 
1742  rb_check_frozen(obj);
1743  if (!id) {
1744  goto not_defined;
1745  }
1746 
1747  switch (BUILTIN_TYPE(obj)) {
1748  case T_OBJECT:
1749  iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
1750  if (!iv_index_tbl) break;
1751  if (!st_lookup(iv_index_tbl, (st_data_t)id, &index)) break;
1752  if (ROBJECT_NUMIV(obj) <= index) break;
1753  val = ROBJECT_IVPTR(obj)[index];
1754  if (val != Qundef) {
1755  ROBJECT_IVPTR(obj)[index] = Qundef;
1756  return val;
1757  }
1758  break;
1759  case T_CLASS:
1760  case T_MODULE:
1761  n = id;
1762  if (RCLASS_IV_TBL(obj) && st_delete(RCLASS_IV_TBL(obj), &n, &v)) {
1763  return (VALUE)v;
1764  }
1765  break;
1766  default:
1767  if (FL_TEST(obj, FL_EXIVAR)) {
1768  if (generic_ivar_remove(obj, id, &val)) {
1769  return val;
1770  }
1771  }
1772  break;
1773  }
1774 
1775  not_defined:
1776  rb_name_err_raise("instance variable %1$s not defined",
1777  obj, name);
1778  UNREACHABLE;
1779 }
1780 
1782 static void
1784 {
1785  if (klass && rb_class_real(klass) != rb_cObject)
1786  rb_name_err_raise("uninitialized constant %2$s::%1$s",
1787  klass, name);
1788  else
1789  rb_name_err_raise("uninitialized constant %1$s",
1790  klass, name);
1791 }
1792 
1793 VALUE
1795 {
1796  VALUE value = rb_funcallv(klass, rb_intern("const_missing"), 1, &name);
1798  return value;
1799 }
1800 
1801 
1802 /*
1803  * call-seq:
1804  * mod.const_missing(sym) -> obj
1805  *
1806  * Invoked when a reference is made to an undefined constant in
1807  * <i>mod</i>. It is passed a symbol for the undefined constant, and
1808  * returns a value to be used for that constant. The
1809  * following code is an example of the same:
1810  *
1811  * def Foo.const_missing(name)
1812  * name # return the constant name as Symbol
1813  * end
1814  *
1815  * Foo::UNDEFINED_CONST #=> :UNDEFINED_CONST: symbol returned
1816  *
1817  * In the next example when a reference is made to an undefined constant,
1818  * it attempts to load a file whose name is the lowercase version of the
1819  * constant (thus class <code>Fred</code> is assumed to be in file
1820  * <code>fred.rb</code>). If found, it returns the loaded class. It
1821  * therefore implements an autoload feature similar to Kernel#autoload and
1822  * Module#autoload.
1823  *
1824  * def Object.const_missing(name)
1825  * @looked_for ||= {}
1826  * str_name = name.to_s
1827  * raise "Class not found: #{name}" if @looked_for[str_name]
1828  * @looked_for[str_name] = 1
1829  * file = str_name.downcase
1830  * require file
1831  * klass = const_get(name)
1832  * return klass if klass
1833  * raise "Class not found: #{name}"
1834  * end
1835  *
1836  */
1837 
1838 VALUE
1840 {
1842  uninitialized_constant(klass, name);
1843 
1844  UNREACHABLE;
1845 }
1846 
1847 static void
1848 autoload_mark(void *ptr)
1849 {
1850  rb_mark_tbl((st_table *)ptr);
1851 }
1852 
1853 static void
1854 autoload_free(void *ptr)
1855 {
1856  st_free_table((st_table *)ptr);
1857 }
1858 
1859 static size_t
1860 autoload_memsize(const void *ptr)
1861 {
1862  const st_table *tbl = ptr;
1863  return st_memsize(tbl);
1864 }
1865 
1867  "autoload",
1870 };
1871 
1872 #define check_autoload_table(av) \
1873  (struct st_table *)rb_check_typeddata((av), &autoload_data_type)
1874 
1875 static VALUE
1877 {
1878  struct st_table *tbl;
1879  st_data_t val;
1880 
1881  if (!st_lookup(RCLASS_IV_TBL(mod), autoload, &val) ||
1882  !(tbl = check_autoload_table((VALUE)val)) ||
1883  !st_lookup(tbl, (st_data_t)id, &val)) {
1884  return 0;
1885  }
1886  return (VALUE)val;
1887 }
1888 
1889 /* always on stack, no need to mark */
1896  union {
1897  struct list_node node;
1898  struct list_head head;
1899  } waitq;
1900 };
1901 
1906  struct autoload_state *state; /* points to on-stack struct */
1907 };
1908 
1909 static void
1911 {
1912  struct autoload_data_i *p = ptr;
1913  rb_gc_mark(p->feature);
1914  rb_gc_mark(p->value);
1915 }
1916 
1917 static size_t
1918 autoload_i_memsize(const void *ptr)
1919 {
1920  return sizeof(struct autoload_data_i);
1921 }
1922 
1924  "autoload_i",
1926  0, 0, RUBY_TYPED_FREE_IMMEDIATELY
1927 };
1928 
1929 #define check_autoload_data(av) \
1930  (struct autoload_data_i *)rb_check_typeddata((av), &autoload_data_i_type)
1931 
1932 void
1933 rb_autoload(VALUE mod, ID id, const char *file)
1934 {
1935  if (!file || !*file) {
1936  rb_raise(rb_eArgError, "empty file name");
1937  }
1938  rb_autoload_str(mod, id, rb_fstring_cstr(file));
1939 }
1940 
1941 void
1943 {
1944  st_data_t av;
1945  VALUE ad;
1946  struct st_table *tbl;
1947  struct autoload_data_i *ele;
1948  rb_const_entry_t *ce;
1949 
1950  if (!rb_is_const_id(id)) {
1951  rb_raise(rb_eNameError, "autoload must be constant name: %"PRIsVALUE"",
1952  QUOTE_ID(id));
1953  }
1954 
1955  Check_Type(file, T_STRING);
1956  if (!RSTRING_LEN(file)) {
1957  rb_raise(rb_eArgError, "empty file name");
1958  }
1959 
1960  ce = rb_const_lookup(mod, id);
1961  if (ce && ce->value != Qundef) {
1962  return;
1963  }
1964 
1965  rb_const_set(mod, id, Qundef);
1966  tbl = RCLASS_IV_TBL(mod);
1967  if (tbl && st_lookup(tbl, (st_data_t)autoload, &av)) {
1968  tbl = check_autoload_table((VALUE)av);
1969  }
1970  else {
1971  if (!tbl) tbl = RCLASS_IV_TBL(mod) = st_init_numtable();
1972  av = (st_data_t)TypedData_Wrap_Struct(0, &autoload_data_type, 0);
1973  st_add_direct(tbl, (st_data_t)autoload, av);
1974  RB_OBJ_WRITTEN(mod, Qnil, av);
1975  DATA_PTR(av) = tbl = st_init_numtable();
1976  }
1977 
1978  ad = TypedData_Make_Struct(0, struct autoload_data_i, &autoload_data_i_type, ele);
1979  if (OBJ_TAINTED(file)) {
1980  file = rb_str_dup(file);
1981  FL_UNSET(file, FL_TAINT);
1982  }
1983  ele->feature = rb_fstring(file);
1984  ele->safe_level = rb_safe_level();
1985  ele->value = Qundef;
1986  ele->state = 0;
1987  st_insert(tbl, (st_data_t)id, (st_data_t)ad);
1988 }
1989 
1990 static void
1992 {
1993  st_data_t val, load = 0, n = id;
1994 
1995  if (st_lookup(RCLASS_IV_TBL(mod), (st_data_t)autoload, &val)) {
1996  struct st_table *tbl = check_autoload_table((VALUE)val);
1997 
1998  st_delete(tbl, &n, &load);
1999 
2000  if (tbl->num_entries == 0) {
2001  n = autoload;
2002  st_delete(RCLASS_IV_TBL(mod), &n, &val);
2003  }
2004  }
2005 }
2006 
2007 static VALUE
2009 {
2010  const char **p = (const char **)arg;
2011  return rb_feature_provided(*p, p);
2012 }
2013 
2014 static VALUE
2016 {
2017  rb_set_safe_level_force((int)safe);
2018  return safe;
2019 }
2020 
2021 static VALUE
2022 check_autoload_required(VALUE mod, ID id, const char **loadingpath)
2023 {
2024  VALUE file, load;
2025  struct autoload_data_i *ele;
2026  const char *loading;
2027  int safe;
2028 
2029  if (!(load = autoload_data(mod, id)) || !(ele = check_autoload_data(load))) {
2030  return 0;
2031  }
2032  file = ele->feature;
2033  Check_Type(file, T_STRING);
2034  if (!RSTRING_LEN(file) || !*RSTRING_PTR(file)) {
2035  rb_raise(rb_eArgError, "empty file name");
2036  }
2037 
2038  /*
2039  * if somebody else is autoloading, we MUST wait for them, since
2040  * rb_provide_feature can provide a feature before autoload_const_set
2041  * completes. We must wait until autoload_const_set finishes in
2042  * the other thread.
2043  */
2044  if (ele->state && ele->state->thread != rb_thread_current()) {
2045  return load;
2046  }
2047 
2048  loading = RSTRING_PTR(file);
2049  safe = rb_safe_level();
2051  if (!rb_ensure(autoload_provided, (VALUE)&loading, reset_safe, (VALUE)safe)) {
2052  return load;
2053  }
2054  if (loadingpath && loading) {
2055  *loadingpath = loading;
2056  return load;
2057  }
2058  return 0;
2059 }
2060 
2061 int
2063 {
2064  VALUE load;
2065  struct autoload_data_i *ele;
2066 
2067  if (!(load = autoload_data(mod, id)) || !(ele = check_autoload_data(load))) {
2068  return 0;
2069  }
2070  if (ele->state && ele->state->thread == rb_thread_current()) {
2071  if (ele->value != Qundef) {
2072  if (value) {
2073  *value = ele->value;
2074  }
2075  return 1;
2076  }
2077  }
2078  return 0;
2079 }
2080 
2081 static int
2083 {
2084  rb_const_entry_t *ce = rb_const_lookup(mod, id);
2085 
2086  if (!ce || ce->value != Qundef) {
2087  return 0;
2088  }
2089  return !rb_autoloading_value(mod, id, NULL);
2090 }
2091 
2096 };
2097 
2098 static void const_tbl_update(struct autoload_const_set_args *);
2099 
2100 static VALUE
2102 {
2103  struct autoload_const_set_args* args = (struct autoload_const_set_args *)arg;
2104  VALUE klass = args->mod;
2105  ID id = args->id;
2106  check_before_mod_set(klass, id, args->value, "constant");
2107  const_tbl_update(args);
2108  return 0; /* ignored */
2109 }
2110 
2111 static VALUE
2113 {
2114  struct autoload_state *state = (struct autoload_state *)arg;
2115 
2116  /* this may release GVL and switch threads: */
2117  state->result = rb_funcall(rb_vm_top_self(), rb_intern("require"), 1,
2118  state->ele->feature);
2119 
2120  return state->result;
2121 }
2122 
2123 static VALUE
2125 {
2126  struct autoload_state *state = (struct autoload_state *)arg;
2127  int need_wakeups = 0;
2128 
2129  if (state->ele->state == state) {
2130  need_wakeups = 1;
2131  state->ele->state = 0;
2132  }
2133 
2134  /* At the last, move a value defined in autoload to constant table */
2135  if (RTEST(state->result) && state->ele->value != Qundef) {
2136  int safe_backup;
2137  struct autoload_const_set_args args;
2138 
2139  args.mod = state->mod;
2140  args.id = state->id;
2141  args.value = state->ele->value;
2142  safe_backup = rb_safe_level();
2145  reset_safe, (VALUE)safe_backup);
2146  }
2147 
2148  /* wakeup any waiters we had */
2149  if (need_wakeups) {
2150  struct autoload_state *cur = 0, *nxt;
2151 
2152  list_for_each_safe(&state->waitq.head, cur, nxt, waitq.node) {
2153  VALUE th = cur->thread;
2154 
2155  cur->thread = Qfalse;
2156  list_del_init(&cur->waitq.node); /* idempotent */
2157 
2158  /*
2159  * cur is stored on the stack of cur->waiting_th,
2160  * do not touch cur after waking up waiting_th
2161  */
2163  }
2164  }
2165 
2166  return 0; /* ignored */
2167 }
2168 
2169 static VALUE
2171 {
2172  struct autoload_state *state = (struct autoload_state *)arg;
2173 
2174  /*
2175  * autoload_reset in other thread will resume us and remove us
2176  * from the waitq list
2177  */
2178  do {
2180  } while (state->thread != Qfalse);
2181 
2182  return Qfalse;
2183 }
2184 
2185 static VALUE
2187 {
2188  struct autoload_state *state = (struct autoload_state *)arg;
2189 
2190  if (state->thread != Qfalse && rb_thread_to_be_killed(state->thread)) {
2191  list_del_init(&state->waitq.node); /* idempotent */
2192  }
2193 
2194  return Qfalse;
2195 }
2196 
2197 VALUE
2199 {
2200  VALUE load, result;
2201  const char *loading = 0, *src;
2202  struct autoload_data_i *ele;
2203  struct autoload_state state;
2204 
2205  if (!autoload_defined_p(mod, id)) return Qfalse;
2206  load = check_autoload_required(mod, id, &loading);
2207  if (!load) return Qfalse;
2208  src = rb_sourcefile();
2209  if (src && loading && strcmp(src, loading) == 0) return Qfalse;
2210 
2211  /* set ele->state for a marker of autoloading thread */
2212  if (!(ele = check_autoload_data(load))) {
2213  return Qfalse;
2214  }
2215 
2216  state.ele = ele;
2217  state.mod = mod;
2218  state.id = id;
2219  state.thread = rb_thread_current();
2220  if (!ele->state) {
2221  ele->state = &state;
2222 
2223  /*
2224  * autoload_reset will wake up any threads added to this
2225  * iff the GVL is released during autoload_require
2226  */
2227  list_head_init(&state.waitq.head);
2228  }
2229  else if (state.thread == ele->state->thread) {
2230  return Qfalse;
2231  }
2232  else {
2233  list_add_tail(&ele->state->waitq.head, &state.waitq.node);
2234 
2235  rb_ensure(autoload_sleep, (VALUE)&state,
2236  autoload_sleep_done, (VALUE)&state);
2237  }
2238 
2239  /* autoload_data_i can be deleted by another thread while require */
2240  result = rb_ensure(autoload_require, (VALUE)&state,
2241  autoload_reset, (VALUE)&state);
2242 
2243  RB_GC_GUARD(load);
2244  return result;
2245 }
2246 
2247 VALUE
2249 {
2250  VALUE load;
2251  struct autoload_data_i *ele;
2252 
2253  while (!autoload_defined_p(mod, id)) {
2254  mod = RCLASS_SUPER(mod);
2255  if (!mod) return Qnil;
2256  }
2257  load = check_autoload_required(mod, id, 0);
2258  if (!load) return Qnil;
2259  return (ele = check_autoload_data(load)) ? ele->feature : Qnil;
2260 }
2261 
2262 void
2264 {
2265  if (RB_CONST_DEPRECATED_P(ce)) {
2266  if (klass == rb_cObject) {
2267  rb_warn("constant ::%"PRIsVALUE" is deprecated", QUOTE_ID(id));
2268  }
2269  else {
2270  rb_warn("constant %"PRIsVALUE"::%"PRIsVALUE" is deprecated",
2271  rb_class_name(klass), QUOTE_ID(id));
2272  }
2273  }
2274 }
2275 
2276 static VALUE
2277 rb_const_get_0(VALUE klass, ID id, int exclude, int recurse, int visibility)
2278 {
2279  VALUE c = rb_const_search(klass, id, exclude, recurse, visibility);
2280  if (c != Qundef) return c;
2281  return rb_const_missing(klass, ID2SYM(id));
2282 }
2283 
2284 static VALUE
2285 rb_const_search(VALUE klass, ID id, int exclude, int recurse, int visibility)
2286 {
2287  VALUE value, tmp, av;
2288  int mod_retry = 0;
2289 
2290  tmp = klass;
2291  retry:
2292  while (RTEST(tmp)) {
2293  VALUE am = 0;
2294  rb_const_entry_t *ce;
2295 
2296  while ((ce = rb_const_lookup(tmp, id))) {
2297  if (visibility && RB_CONST_PRIVATE_P(ce)) {
2298  rb_name_err_raise("private constant %2$s::%1$s referenced",
2299  tmp, ID2SYM(id));
2300  }
2301  rb_const_warn_if_deprecated(ce, tmp, id);
2302  value = ce->value;
2303  if (value == Qundef) {
2304  if (am == tmp) break;
2305  am = tmp;
2306  if (rb_autoloading_value(tmp, id, &av)) return av;
2307  rb_autoload_load(tmp, id);
2308  continue;
2309  }
2310  if (exclude && tmp == rb_cObject && klass != rb_cObject) {
2311  rb_warn("toplevel constant %"PRIsVALUE" referenced by %"PRIsVALUE"::%"PRIsVALUE"",
2312  QUOTE_ID(id), rb_class_name(klass), QUOTE_ID(id));
2313  }
2314  return value;
2315  }
2316  if (!recurse) break;
2317  tmp = RCLASS_SUPER(tmp);
2318  }
2319  if (!exclude && !mod_retry && BUILTIN_TYPE(klass) == T_MODULE) {
2320  mod_retry = 1;
2321  tmp = rb_cObject;
2322  goto retry;
2323  }
2324 
2325  return Qundef;
2326 }
2327 
2328 VALUE
2330 {
2331  return rb_const_get_0(klass, id, TRUE, TRUE, FALSE);
2332 }
2333 
2334 VALUE
2336 {
2337  return rb_const_get_0(klass, id, FALSE, TRUE, FALSE);
2338 }
2339 
2340 VALUE
2342 {
2343  return rb_const_get_0(klass, id, TRUE, FALSE, FALSE);
2344 }
2345 
2346 VALUE
2348 {
2349  return rb_const_get_0(klass, id, TRUE, TRUE, TRUE);
2350 }
2351 
2352 VALUE
2354 {
2355  return rb_const_get_0(klass, id, FALSE, TRUE, TRUE);
2356 }
2357 
2358 VALUE
2360 {
2361  return rb_const_get_0(klass, id, TRUE, FALSE, TRUE);
2362 }
2363 
2364 /*
2365  * call-seq:
2366  * remove_const(sym) -> obj
2367  *
2368  * Removes the definition of the given constant, returning that
2369  * constant's previous value. If that constant referred to
2370  * a module, this will not change that module's name and can lead
2371  * to confusion.
2372  */
2373 
2374 VALUE
2376 {
2377  const ID id = id_for_var(mod, name, a, constant);
2378 
2379  if (!id) {
2380  rb_name_err_raise("constant %2$s::%1$s not defined",
2381  mod, name);
2382  }
2383  return rb_const_remove(mod, id);
2384 }
2385 
2386 VALUE
2388 {
2389  VALUE val;
2390  rb_const_entry_t *ce;
2391 
2392  rb_check_frozen(mod);
2393  ce = rb_const_lookup(mod, id);
2394  if (!ce || !rb_id_table_delete(RCLASS_CONST_TBL(mod), id)) {
2395  if (rb_const_defined_at(mod, id)) {
2396  rb_name_err_raise("cannot remove %2$s::%1$s",
2397  mod, ID2SYM(id));
2398  }
2399  rb_name_err_raise("constant %2$s::%1$s not defined",
2400  mod, ID2SYM(id));
2401  }
2402 
2404 
2405  val = ce->value;
2406  if (val == Qundef) {
2407  autoload_delete(mod, id);
2408  val = Qnil;
2409  }
2410  xfree(ce);
2411  return val;
2412 }
2413 
2414 static int
2415 cv_i_update(st_data_t *k, st_data_t *v, st_data_t a, int existing)
2416 {
2417  if (existing) return ST_STOP;
2418  *v = a;
2419  return ST_CONTINUE;
2420 }
2421 
2422 static enum rb_id_table_iterator_result
2423 sv_i(ID key, VALUE v, void *a)
2424 {
2426  st_table *tbl = a;
2427 
2428  if (rb_is_const_id(key)) {
2429  st_update(tbl, (st_data_t)key, cv_i_update, (st_data_t)ce);
2430  }
2431  return ID_TABLE_CONTINUE;
2432 }
2433 
2434 static enum rb_id_table_iterator_result
2435 rb_local_constants_i(ID const_name, VALUE const_value, void *ary)
2436 {
2437  if (rb_is_const_id(const_name) && !RB_CONST_PRIVATE_P((rb_const_entry_t *)const_value)) {
2438  rb_ary_push((VALUE)ary, ID2SYM(const_name));
2439  }
2440  return ID_TABLE_CONTINUE;
2441 }
2442 
2443 static VALUE
2445 {
2446  struct rb_id_table *tbl = RCLASS_CONST_TBL(mod);
2447  VALUE ary;
2448 
2449  if (!tbl) return rb_ary_new2(0);
2450 
2451  ary = rb_ary_new2(rb_id_table_size(tbl));
2452  rb_id_table_foreach(tbl, rb_local_constants_i, (void *)ary);
2453  return ary;
2454 }
2455 
2456 void*
2458 {
2459  st_table *tbl = data;
2460  if (!tbl) {
2461  tbl = st_init_numtable();
2462  }
2463  if (RCLASS_CONST_TBL(mod)) {
2465  }
2466  return tbl;
2467 }
2468 
2469 void*
2471 {
2472  VALUE tmp = mod;
2473  for (;;) {
2474  data = rb_mod_const_at(tmp, data);
2475  tmp = RCLASS_SUPER(tmp);
2476  if (!tmp) break;
2477  if (tmp == rb_cObject && mod != rb_cObject) break;
2478  }
2479  return data;
2480 }
2481 
2482 static int
2484 {
2485  ID sym = (ID)key;
2486  rb_const_entry_t *ce = (rb_const_entry_t *)value;
2487  if (RB_CONST_PUBLIC_P(ce)) rb_ary_push(ary, ID2SYM(sym));
2488  return ST_CONTINUE;
2489 }
2490 
2491 VALUE
2492 rb_const_list(void *data)
2493 {
2494  st_table *tbl = data;
2495  VALUE ary;
2496 
2497  if (!tbl) return rb_ary_new2(0);
2498  ary = rb_ary_new2(tbl->num_entries);
2499  st_foreach_safe(tbl, list_i, ary);
2500  st_free_table(tbl);
2501 
2502  return ary;
2503 }
2504 
2505 /*
2506  * call-seq:
2507  * mod.constants(inherit=true) -> array
2508  *
2509  * Returns an array of the names of the constants accessible in
2510  * <i>mod</i>. This includes the names of constants in any included
2511  * modules (example at start of section), unless the <i>inherit</i>
2512  * parameter is set to <code>false</code>.
2513  *
2514  * The implementation makes no guarantees about the order in which the
2515  * constants are yielded.
2516  *
2517  * IO.constants.include?(:SYNC) #=> true
2518  * IO.constants(false).include?(:SYNC) #=> false
2519  *
2520  * Also see <code>Module::const_defined?</code>.
2521  */
2522 
2523 VALUE
2525 {
2526  VALUE inherit;
2527 
2528  if (argc == 0) {
2529  inherit = Qtrue;
2530  }
2531  else {
2532  rb_scan_args(argc, argv, "01", &inherit);
2533  }
2534 
2535  if (RTEST(inherit)) {
2536  return rb_const_list(rb_mod_const_of(mod, 0));
2537  }
2538  else {
2539  return rb_local_constants(mod);
2540  }
2541 }
2542 
2543 static int
2544 rb_const_defined_0(VALUE klass, ID id, int exclude, int recurse, int visibility)
2545 {
2546  VALUE tmp;
2547  int mod_retry = 0;
2548  rb_const_entry_t *ce;
2549 
2550  tmp = klass;
2551  retry:
2552  while (tmp) {
2553  if ((ce = rb_const_lookup(tmp, id))) {
2554  if (visibility && RB_CONST_PRIVATE_P(ce)) {
2555  return (int)Qfalse;
2556  }
2557  if (ce->value == Qundef && !check_autoload_required(tmp, id, 0) &&
2558  !rb_autoloading_value(tmp, id, 0))
2559  return (int)Qfalse;
2560  return (int)Qtrue;
2561  }
2562  if (!recurse) break;
2563  tmp = RCLASS_SUPER(tmp);
2564  }
2565  if (!exclude && !mod_retry && BUILTIN_TYPE(klass) == T_MODULE) {
2566  mod_retry = 1;
2567  tmp = rb_cObject;
2568  goto retry;
2569  }
2570  return (int)Qfalse;
2571 }
2572 
2573 int
2575 {
2576  return rb_const_defined_0(klass, id, TRUE, TRUE, FALSE);
2577 }
2578 
2579 int
2581 {
2582  return rb_const_defined_0(klass, id, FALSE, TRUE, FALSE);
2583 }
2584 
2585 int
2587 {
2588  return rb_const_defined_0(klass, id, TRUE, FALSE, FALSE);
2589 }
2590 
2591 int
2593 {
2594  return rb_const_defined_0(klass, id, TRUE, TRUE, TRUE);
2595 }
2596 
2597 int
2599 {
2600  return rb_const_defined_0(klass, id, FALSE, TRUE, TRUE);
2601 }
2602 
2603 int
2605 {
2606  return rb_const_defined_0(klass, id, TRUE, FALSE, TRUE);
2607 }
2608 
2609 static void
2610 check_before_mod_set(VALUE klass, ID id, VALUE val, const char *dest)
2611 {
2612  rb_check_frozen(klass);
2613 }
2614 
2615 void
2617 {
2618  rb_const_entry_t *ce;
2619  struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
2620 
2621  if (NIL_P(klass)) {
2622  rb_raise(rb_eTypeError, "no class/module to define constant %"PRIsVALUE"",
2623  QUOTE_ID(id));
2624  }
2625 
2626  check_before_mod_set(klass, id, val, "constant");
2627  if (!tbl) {
2628  RCLASS_CONST_TBL(klass) = tbl = rb_id_table_create(0);
2630  ce = ZALLOC(rb_const_entry_t);
2631  rb_id_table_insert(tbl, id, (VALUE)ce);
2632  setup_const_entry(ce, klass, val, CONST_PUBLIC);
2633  }
2634  else {
2635  struct autoload_const_set_args args;
2636  args.mod = klass;
2637  args.id = id;
2638  args.value = val;
2639  const_tbl_update(&args);
2640  }
2641  /*
2642  * Resolve and cache class name immediately to resolve ambiguity
2643  * and avoid order-dependency on const_tbl
2644  */
2645  if (rb_cObject && (RB_TYPE_P(val, T_MODULE) || RB_TYPE_P(val, T_CLASS))) {
2646  if (NIL_P(rb_class_path_cached(val))) {
2647  if (klass == rb_cObject) {
2648  rb_ivar_set(val, classpath, rb_id2str(id));
2649  rb_name_class(val, id);
2650  }
2651  else {
2652  VALUE path;
2653  ID pathid;
2654  st_data_t n;
2655  st_table *ivtbl = RCLASS_IV_TBL(klass);
2656  if (ivtbl &&
2657  (st_lookup(ivtbl, (st_data_t)(pathid = classpath), &n) ||
2658  st_lookup(ivtbl, (st_data_t)(pathid = tmp_classpath), &n))) {
2659  path = rb_str_dup((VALUE)n);
2660  rb_str_append(rb_str_cat2(path, "::"), rb_id2str(id));
2661  OBJ_FREEZE(path);
2662  rb_ivar_set(val, pathid, path);
2663  rb_name_class(val, id);
2664  }
2665  }
2666  }
2667  }
2668 }
2669 
2670 static void
2672 {
2673  VALUE value;
2674  VALUE klass = args->mod;
2675  VALUE val = args->value;
2676  ID id = args->id;
2677  struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
2678  rb_const_flag_t visibility = CONST_PUBLIC;
2679  rb_const_entry_t *ce;
2680 
2681  if (rb_id_table_lookup(tbl, id, &value)) {
2682  ce = (rb_const_entry_t *)value;
2683  if (ce->value == Qundef) {
2684  VALUE load;
2685  struct autoload_data_i *ele;
2686 
2687  load = autoload_data(klass, id);
2688  /* for autoloading thread, keep the defined value to autoloading storage */
2689  if (load && (ele = check_autoload_data(load)) && ele->state &&
2690  (ele->state->thread == rb_thread_current())) {
2692 
2693  ele->value = val; /* autoload_i is non-WB-protected */
2694  return;
2695  }
2696  /* otherwise, allow to override */
2697  autoload_delete(klass, id);
2698  }
2699  else {
2700  VALUE name = QUOTE_ID(id);
2701  visibility = ce->flag;
2702  if (klass == rb_cObject)
2703  rb_warn("already initialized constant %"PRIsVALUE"", name);
2704  else
2705  rb_warn("already initialized constant %"PRIsVALUE"::%"PRIsVALUE"",
2706  rb_class_name(klass), name);
2707  if (!NIL_P(ce->file) && ce->line) {
2709  "previous definition of %"PRIsVALUE" was here", name);
2710  }
2711  }
2713  setup_const_entry(ce, klass, val, visibility);
2714  }
2715  else {
2717 
2718  ce = ZALLOC(rb_const_entry_t);
2719  rb_id_table_insert(tbl, id, (VALUE)ce);
2720  setup_const_entry(ce, klass, val, visibility);
2721  }
2722 }
2723 
2724 static void
2726  rb_const_flag_t visibility)
2727 {
2728  ce->flag = visibility;
2729  RB_OBJ_WRITE(klass, &ce->value, val);
2730  RB_OBJ_WRITE(klass, &ce->file, rb_source_location(&ce->line));
2731 }
2732 
2733 void
2734 rb_define_const(VALUE klass, const char *name, VALUE val)
2735 {
2736  ID id = rb_intern(name);
2737 
2738  if (!rb_is_const_id(id)) {
2739  rb_warn("rb_define_const: invalid name `%s' for constant", name);
2740  }
2741  rb_const_set(klass, id, val);
2742 }
2743 
2744 void
2746 {
2747  rb_define_const(rb_cObject, name, val);
2748 }
2749 
2750 static void
2752  rb_const_flag_t flag, rb_const_flag_t mask)
2753 {
2754  int i;
2755  rb_const_entry_t *ce;
2756  ID id;
2757 
2758  rb_frozen_class_p(mod);
2759  if (argc == 0) {
2760  rb_warning("%"PRIsVALUE" with no argument is just ignored",
2762  return;
2763  }
2764 
2765  for (i = 0; i < argc; i++) {
2766  VALUE val = argv[i];
2767  id = rb_check_id(&val);
2768  if (!id) {
2769  if (i > 0) {
2771  }
2772 
2773  rb_name_err_raise("constant %2$s::%1$s not defined",
2774  mod, val);
2775  }
2776  if ((ce = rb_const_lookup(mod, id))) {
2777  ce->flag &= ~mask;
2778  ce->flag |= flag;
2779  }
2780  else {
2781  if (i > 0) {
2783  }
2784  rb_name_err_raise("constant %2$s::%1$s not defined",
2785  mod, ID2SYM(id));
2786  }
2787  }
2789 }
2790 
2791 void
2792 rb_deprecate_constant(VALUE mod, const char *name)
2793 {
2794  rb_const_entry_t *ce;
2795  ID id;
2796  long len = strlen(name);
2797 
2798  rb_frozen_class_p(mod);
2799  if (!(id = rb_check_id_cstr(name, len, NULL)) ||
2800  !(ce = rb_const_lookup(mod, id))) {
2801  rb_name_err_raise("constant %2$s::%1$s not defined",
2802  mod, rb_fstring_new(name, len));
2803  }
2804  ce->flag |= CONST_DEPRECATED;
2805 }
2806 
2807 /*
2808  * call-seq:
2809  * mod.private_constant(symbol, ...) => mod
2810  *
2811  * Makes a list of existing constants private.
2812  */
2813 
2814 VALUE
2816 {
2818  return obj;
2819 }
2820 
2821 /*
2822  * call-seq:
2823  * mod.public_constant(symbol, ...) => mod
2824  *
2825  * Makes a list of existing constants public.
2826  */
2827 
2828 VALUE
2830 {
2832  return obj;
2833 }
2834 
2835 /*
2836  * call-seq:
2837  * mod.deprecate_constant(symbol, ...) => mod
2838  *
2839  * Makes a list of existing constants deprecated.
2840  */
2841 
2842 VALUE
2844 {
2846  return obj;
2847 }
2848 
2849 static VALUE
2851 {
2852  if (RB_TYPE_P(c, T_ICLASS))
2853  return RBASIC(c)->klass;
2854  return c;
2855 }
2856 
2857 static int
2859 {
2860  if (!RCLASS_IV_TBL(klass)) return 0;
2861  return st_lookup(RCLASS_IV_TBL(klass), (st_data_t)id, v);
2862 }
2863 
2864 static VALUE
2866 {
2867  if (FL_TEST(klass, FL_SINGLETON)) {
2868  VALUE obj = rb_ivar_get(klass, id__attached__);
2869  if (RB_TYPE_P(obj, T_MODULE) || RB_TYPE_P(obj, T_CLASS)) {
2870  return obj;
2871  }
2872  }
2873  return RCLASS_SUPER(klass);
2874 }
2875 
2876 #define CVAR_FOREACH_ANCESTORS(klass, v, r) \
2877  for (klass = cvar_front_klass(klass); klass; klass = RCLASS_SUPER(klass)) { \
2878  if (cvar_lookup_at(klass, id, (v))) { \
2879  r; \
2880  } \
2881  }
2882 
2883 #define CVAR_LOOKUP(v,r) do {\
2884  if (cvar_lookup_at(klass, id, (v))) {r;}\
2885  CVAR_FOREACH_ANCESTORS(klass, v, r);\
2886 } while(0)
2887 
2888 void
2890 {
2891  VALUE tmp, front = 0, target = 0;
2892 
2893  tmp = klass;
2894  CVAR_LOOKUP(0, {if (!front) front = klass; target = klass;});
2895  if (target) {
2896  if (front && target != front) {
2897  st_data_t did = id;
2898 
2899  if (RTEST(ruby_verbose)) {
2900  rb_warning("class variable %"PRIsVALUE" of %"PRIsVALUE" is overtaken by %"PRIsVALUE"",
2901  QUOTE_ID(id), rb_class_name(original_module(front)),
2902  rb_class_name(original_module(target)));
2903  }
2904  if (BUILTIN_TYPE(front) == T_CLASS) {
2905  st_delete(RCLASS_IV_TBL(front),&did,0);
2906  }
2907  }
2908  }
2909  else {
2910  target = tmp;
2911  }
2912 
2913  check_before_mod_set(target, id, val, "class variable");
2914  if (!RCLASS_IV_TBL(target)) {
2915  RCLASS_IV_TBL(target) = st_init_numtable();
2916  }
2917 
2918  rb_class_ivar_set(target, id, val);
2919 }
2920 
2921 VALUE
2923 {
2924  VALUE tmp, front = 0, target = 0;
2925  st_data_t value;
2926 
2927  tmp = klass;
2928  CVAR_LOOKUP(&value, {if (!front) front = klass; target = klass;});
2929  if (!target) {
2930  rb_name_err_raise("uninitialized class variable %1$s in %2$s",
2931  tmp, ID2SYM(id));
2932  }
2933  if (front && target != front) {
2934  st_data_t did = id;
2935 
2936  if (RTEST(ruby_verbose)) {
2937  rb_warning("class variable %"PRIsVALUE" of %"PRIsVALUE" is overtaken by %"PRIsVALUE"",
2938  QUOTE_ID(id), rb_class_name(original_module(front)),
2939  rb_class_name(original_module(target)));
2940  }
2941  if (BUILTIN_TYPE(front) == T_CLASS) {
2942  st_delete(RCLASS_IV_TBL(front),&did,0);
2943  }
2944  }
2945  return (VALUE)value;
2946 }
2947 
2948 VALUE
2950 {
2951  if (!klass) return Qfalse;
2952  CVAR_LOOKUP(0,return Qtrue);
2953  return Qfalse;
2954 }
2955 
2956 static ID
2957 cv_intern(VALUE klass, const char *name)
2958 {
2959  ID id = rb_intern(name);
2960  if (!rb_is_class_id(id)) {
2961  rb_name_err_raise("wrong class variable name %1$s",
2962  klass, rb_str_new_cstr(name));
2963  }
2964  return id;
2965 }
2966 
2967 void
2968 rb_cv_set(VALUE klass, const char *name, VALUE val)
2969 {
2970  ID id = cv_intern(klass, name);
2971  rb_cvar_set(klass, id, val);
2972 }
2973 
2974 VALUE
2975 rb_cv_get(VALUE klass, const char *name)
2976 {
2977  ID id = cv_intern(klass, name);
2978  return rb_cvar_get(klass, id);
2979 }
2980 
2981 void
2982 rb_define_class_variable(VALUE klass, const char *name, VALUE val)
2983 {
2984  ID id = cv_intern(klass, name);
2985  rb_cvar_set(klass, id, val);
2986 }
2987 
2988 static int
2990 {
2991  ID key = (ID)k;
2992  st_table *tbl = (st_table *)a;
2993 
2994  if (rb_is_class_id(key)) {
2995  st_update(tbl, (st_data_t)key, cv_i_update, 0);
2996  }
2997  return ST_CONTINUE;
2998 }
2999 
3000 static void*
3001 mod_cvar_at(VALUE mod, void *data)
3002 {
3003  st_table *tbl = data;
3004  if (!tbl) {
3005  tbl = st_init_numtable();
3006  }
3007  if (RCLASS_IV_TBL(mod)) {
3009  }
3010  return tbl;
3011 }
3012 
3013 static void*
3014 mod_cvar_of(VALUE mod, void *data)
3015 {
3016  VALUE tmp = mod;
3017  for (;;) {
3018  data = mod_cvar_at(tmp, data);
3019  tmp = RCLASS_SUPER(tmp);
3020  if (!tmp) break;
3021  }
3022  return data;
3023 }
3024 
3025 static int
3027 {
3028  ID sym = (ID)key;
3029  rb_ary_push(ary, ID2SYM(sym));
3030  return ST_CONTINUE;
3031 }
3032 
3033 static VALUE
3034 cvar_list(void *data)
3035 {
3036  st_table *tbl = data;
3037  VALUE ary;
3038 
3039  if (!tbl) return rb_ary_new2(0);
3040  ary = rb_ary_new2(tbl->num_entries);
3041  st_foreach_safe(tbl, cv_list_i, ary);
3042  st_free_table(tbl);
3043 
3044  return ary;
3045 }
3046 
3047 /*
3048  * call-seq:
3049  * mod.class_variables(inherit=true) -> array
3050  *
3051  * Returns an array of the names of class variables in <i>mod</i>.
3052  * This includes the names of class variables in any included
3053  * modules, unless the <i>inherit</i> parameter is set to
3054  * <code>false</code>.
3055  *
3056  * class One
3057  * @@var1 = 1
3058  * end
3059  * class Two < One
3060  * @@var2 = 2
3061  * end
3062  * One.class_variables #=> [:@@var1]
3063  * Two.class_variables #=> [:@@var2, :@@var1]
3064  * Two.class_variables(false) #=> [:@@var2]
3065  */
3066 
3067 VALUE
3069 {
3070  VALUE inherit;
3071  st_table *tbl;
3072 
3073  if (argc == 0) {
3074  inherit = Qtrue;
3075  }
3076  else {
3077  rb_scan_args(argc, argv, "01", &inherit);
3078  }
3079  if (RTEST(inherit)) {
3080  tbl = mod_cvar_of(mod, 0);
3081  }
3082  else {
3083  tbl = mod_cvar_at(mod, 0);
3084  }
3085  return cvar_list(tbl);
3086 }
3087 
3088 /*
3089  * call-seq:
3090  * remove_class_variable(sym) -> obj
3091  *
3092  * Removes the definition of the <i>sym</i>, returning that
3093  * constant's value.
3094  *
3095  * class Dummy
3096  * @@var = 99
3097  * puts @@var
3098  * remove_class_variable(:@@var)
3099  * p(defined? @@var)
3100  * end
3101  *
3102  * <em>produces:</em>
3103  *
3104  * 99
3105  * nil
3106  */
3107 
3108 VALUE
3110 {
3111  const ID id = id_for_var_message(mod, name, class, "wrong class variable name %1$s");
3112  st_data_t val, n = id;
3113 
3114  if (!id) {
3115  not_defined:
3116  rb_name_err_raise("class variable %1$s not defined for %2$s",
3117  mod, name);
3118  }
3119  rb_check_frozen(mod);
3120  if (RCLASS_IV_TBL(mod) && st_delete(RCLASS_IV_TBL(mod), &n, &val)) {
3121  return (VALUE)val;
3122  }
3123  if (rb_cvar_defined(mod, id)) {
3124  rb_name_err_raise("cannot remove %1$s for %2$s", mod, ID2SYM(id));
3125  }
3126  goto not_defined;
3127 }
3128 
3129 VALUE
3130 rb_iv_get(VALUE obj, const char *name)
3131 {
3132  ID id = rb_intern(name);
3133 
3134  return rb_ivar_get(obj, id);
3135 }
3136 
3137 VALUE
3138 rb_iv_set(VALUE obj, const char *name, VALUE val)
3139 {
3140  ID id = rb_intern(name);
3141 
3142  return rb_ivar_set(obj, id, val);
3143 }
3144 
3145 /* tbl = xx(obj); tbl[key] = value; */
3146 int
3148 {
3149  st_table *tbl = RCLASS_IV_TBL(obj);
3150  int result = st_insert(tbl, (st_data_t)key, (st_data_t)value);
3151  RB_OBJ_WRITTEN(obj, Qundef, value);
3152  return result;
3153 }
3154 
3155 static int
3157 {
3158  RB_OBJ_WRITTEN((VALUE)data, Qundef, (VALUE)value);
3159  return ST_CONTINUE;
3160 }
3161 
3162 st_table *
3163 rb_st_copy(VALUE obj, struct st_table *orig_tbl)
3164 {
3165  st_table *new_tbl = st_copy(orig_tbl);
3166  st_foreach(new_tbl, tbl_copy_i, (st_data_t)obj);
3167  return new_tbl;
3168 }
3169 
3172 {
3173  struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
3174  VALUE val;
3175 
3176  if (tbl && rb_id_table_lookup(tbl, id, &val)) {
3177  return (rb_const_entry_t *)val;
3178  }
3179  return 0;
3180 }
st_table * rb_st_copy(VALUE obj, struct st_table *orig_tbl)
Definition: variable.c:3163
void rb_mark_generic_ivar(VALUE obj)
Definition: variable.c:1173
static VALUE classname(VALUE klass, int *permanent)
Returns +classpath+ of klass, if it is named, or +nil+ for anonymous +class+/+module+.
Definition: variable.c:178
void rb_define_readonly_variable(const char *name, const VALUE *var)
Definition: variable.c:641
void rb_define_hooked_variable(const char *name, VALUE *var, VALUE(*getter)(ANYARGS), void(*setter)(ANYARGS))
Definition: variable.c:616
union autoload_state::@185 waitq
#define T_OBJECT
Definition: ruby.h:491
void rb_set_class_path_string(VALUE klass, VALUE under, VALUE name)
Definition: variable.c:343
VALUE rb_gvar_defined(struct rb_global_entry *entry)
Definition: variable.c:859
ID rb_check_id(volatile VALUE *)
Returns ID for the given name if it is interned already, or 0.
Definition: symbol.c:923
static enum rb_id_table_iterator_result mark_global_entry(VALUE v, void *ignored)
Definition: variable.c:577
int rb_is_instance_id(ID id)
Definition: symbol.c:846
static VALUE rb_const_get_0(VALUE klass, ID id, int exclude, int recurse, int visibility)
Definition: variable.c:2277
static VALUE cvar_list(void *data)
Definition: variable.c:3034
#define FL_EXIVAR
Definition: ruby.h:1222
void rb_vm_inc_const_missing_count(void)
Definition: vm.c:323
void rb_bug(const char *fmt,...)
Definition: error.c:482
rb_const_entry_t * rb_const_lookup(VALUE klass, ID id)
Definition: variable.c:3171
#define FALSE
Definition: nkf.h:174
#define RUBY_TYPED_FREE_IMMEDIATELY
Definition: ruby.h:1145
size_t strlen(const char *)
VALUE rb_mod_const_missing(VALUE klass, VALUE name)
Definition: variable.c:1839
void * rb_mod_const_at(VALUE mod, void *data)
Definition: variable.c:2457
VALUE rb_gvar_undef_getter(ID id, void *data, struct rb_global_variable *var)
Definition: variable.c:509
#define RCLASS_CONST_TBL(c)
Definition: internal.h:689
Definition: constant.h:31
Definition: st.h:79
Definition: st.h:99
static st_table * iv_index_tbl_make(VALUE obj)
Definition: variable.c:1321
VALUE rb_f_global_variables(void)
Definition: variable.c:883
VALUE klass
Definition: variable.c:63
int count
Definition: encoding.c:56
ID rb_intern2(const char *, long)
Definition: symbol.c:604
static VALUE generic_ivar_defined(VALUE obj, ID id)
Definition: variable.c:1124
#define RB_OBJ_WRITTEN(a, oldv, b)
Definition: ruby.h:1438
static int autoload_defined_p(VALUE mod, ID id)
Definition: variable.c:2082
static st_table * generic_iv_tbl
Definition: variable.c:29
void rb_define_const(VALUE klass, const char *name, VALUE val)
Definition: variable.c:2734
static int cv_i(st_data_t k, st_data_t v, st_data_t a)
Definition: variable.c:2989
st_data_t arg
Definition: variable.c:1490
void rb_define_variable(const char *name, VALUE *var)
Definition: variable.c:635
VALUE path
Definition: variable.c:64
#define QUOTE_ID(id)
Definition: internal.h:1473
static enum rb_id_table_iterator_result gvar_i(ID key, VALUE val, void *a)
Definition: variable.c:866
void rb_thread_sleep_deadly(void)
Definition: thread.c:1163
#define FL_TAINT
Definition: ruby.h:1220
#define CLASS_OF(v)
Definition: ruby.h:453
VALUE rb_fstring_cstr(const char *str)
Definition: string.c:387
#define RB_CONST_DEPRECATED_P(ce)
Definition: constant.h:28
#define rb_name_err_raise_str(mesg, recv, name)
Definition: internal.h:1022
#define T_MODULE
Definition: ruby.h:494
const VALUE file
Definition: constant.h:35
#define st_foreach
Definition: regint.h:186
static VALUE rb_const_search(VALUE klass, ID id, int exclude, int recurse, int visibility)
Definition: variable.c:2285
VALUE rb_ivar_defined(VALUE obj, ID id)
Definition: variable.c:1421
void rb_autoload_str(VALUE mod, ID id, VALUE file)
Definition: variable.c:1942
#define Qtrue
Definition: ruby.h:437
static int gen_ivar_copy(ID id, VALUE val, st_data_t arg)
Definition: variable.c:1529
static VALUE autoload_require(VALUE arg)
Definition: variable.c:2112
#define TypedData_Wrap_Struct(klass, data_type, sval)
Definition: ruby.h:1169
static VALUE rb_tmp_class_path(VALUE klass, int *permanent, path_cache_func cache_path)
Definition: variable.c:259
#define rb_id2str(id)
Definition: vm_backtrace.c:29
Definition: st.h:99
const int id
Definition: nkf.c:209
void rb_id_table_foreach_values(struct rb_id_table *tbl, rb_id_table_foreach_values_func_t *func, void *data)
ID rb_check_id_cstr(const char *ptr, long len, rb_encoding *enc)
Definition: symbol.c:992
int rb_is_const_id(ID id)
Definition: symbol.c:828
rb_gvar_getter_t * getter
Definition: variable.c:474
static VALUE find_class_path(VALUE klass, ID preferred)
Traverse constant namespace and find +classpath+ for klass.
Definition: variable.c:144
static enum rb_id_table_iterator_result sv_i(ID key, VALUE v, void *a)
Definition: variable.c:2423
VALUE(* path_cache_func)(VALUE obj, VALUE name)
Definition: variable.c:256
VALUE rb_eTypeError
Definition: error.c:762
void rb_autoload(VALUE mod, ID id, const char *file)
Definition: variable.c:1933
#define UNREACHABLE
Definition: ruby.h:46
VALUE rb_autoload_p(VALUE mod, ID id)
Definition: variable.c:2248
void rb_define_virtual_variable(const char *name, VALUE(*getter)(ANYARGS), void(*setter)(ANYARGS))
Definition: variable.c:647
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:905
static int cvar_lookup_at(VALUE klass, ID id, st_data_t *v)
Definition: variable.c:2858
SSL_METHOD *(* func)(void)
Definition: ossl_ssl.c:54
int rb_id_table_lookup(struct rb_id_table *tbl, ID id, VALUE *valp)
VALUE rb_ivar_get(VALUE obj, ID id)
Definition: variable.c:1260
VALUE rb_const_list(void *data)
Definition: variable.c:2492
void rb_define_global_const(const char *name, VALUE val)
Definition: variable.c:2745
const char * rb_class2name(VALUE klass)
Definition: variable.c:449
const char * rb_sourcefile(void)
Definition: vm.c:1247
#define check_autoload_table(av)
Definition: variable.c:1872
VALUE rb_public_const_get_at(VALUE klass, ID id)
Definition: variable.c:2359
VALUE rb_mod_remove_const(VALUE mod, VALUE name)
Definition: variable.c:2375
static int obj_ivar_i(st_data_t key, st_data_t index, st_data_t arg)
Definition: variable.c:1458
VALUE rb_funcall(VALUE, ID, int,...)
Calls a method.
Definition: vm_eval.c:821
void rb_gc_mark_global_tbl(void)
Definition: variable.c:593
static VALUE cvar_front_klass(VALUE klass)
Definition: variable.c:2865
#define ROBJECT_IV_INDEX_TBL(o)
Definition: ruby.h:908
VALUE rb_backref_get(void)
Definition: vm.c:1207
VALUE rb_mod_name(VALUE mod)
Definition: variable.c:228
#define Check_Type(v, t)
Definition: ruby.h:562
VALUE rb_cv_get(VALUE klass, const char *name)
Definition: variable.c:2975
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2207
static VALUE autoload_const_set(VALUE arg)
Definition: variable.c:2101
void rb_compile_warn(const char *file, int line, const char *fmt,...)
Definition: error.c:181
VALUE rb_path2class(const char *path)
Definition: variable.c:431
rb_gvar_marker_t * marker
Definition: variable.c:476
#define RB_GC_GUARD(v)
Definition: ruby.h:552
void rb_clear_constant_cache(void)
Definition: vm_method.c:90
int rb_public_const_defined(VALUE klass, ID id)
Definition: variable.c:2598
const VALUE value
Definition: constant.h:34
st_table * iv_index_tbl
Definition: variable.c:40
VALUE rb_eSecurityError
Definition: error.c:771
#define DATA_PTR(dta)
Definition: ruby.h:1113
static VALUE autoload_sleep_done(VALUE arg)
Definition: variable.c:2186
VALUE ivptr[1]
Definition: variable.c:35
static VALUE autoload_provided(VALUE arg)
Definition: variable.c:2008
void rb_gc_mark(VALUE ptr)
Definition: gc.c:4394
int rb_feature_provided(const char *, const char **)
Definition: load.c:528
st_data_t st_index_t
Definition: st.h:50
#define st_delete
Definition: regint.h:182
#define st_lookup
Definition: regint.h:185
static void gen_ivar_each(VALUE obj, int(*func)(ANYARGS), st_data_t arg)
Definition: variable.c:1508
int st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg)
Definition: st.c:1371
VALUE rb_gvar_get(struct rb_global_entry *entry)
Definition: variable.c:791
ID id
Definition: internal.h:889
#define ROBJECT_NUMIV(o)
Definition: ruby.h:900
#define check_autoload_data(av)
Definition: variable.c:1929
VALUE rb_const_get(VALUE klass, ID id)
Definition: variable.c:2335
int rb_public_const_defined_at(VALUE klass, ID id)
Definition: variable.c:2604
VALUE rb_public_const_get(VALUE klass, ID id)
Definition: variable.c:2353
struct rb_global_entry * rb_global_entry(ID id)
Definition: variable.c:481
void rb_deprecate_constant(VALUE mod, const char *name)
Definition: variable.c:2792
VALUE rb_f_untrace_var(int argc, const VALUE *argv)
Definition: variable.c:746
int(* func)(ID key, VALUE val, st_data_t arg)
Definition: variable.c:1489
int rb_match_count(VALUE match)
Definition: re.c:1266
#define rb_name_err_raise(mesg, recv, name)
Definition: internal.h:1024
#define OBJ_TAINTED(x)
Definition: ruby.h:1298
static void rb_trace_eval(VALUE cmd, VALUE val)
Definition: variable.c:658
#define rb_ary_new2
Definition: intern.h:90
void rb_name_error_str(VALUE str, const char *fmt,...)
Definition: error.c:1219
static int gen_ivar_each_i(st_data_t key, st_data_t index, st_data_t data)
Definition: variable.c:1494
RUBY_FUNC_EXPORTED size_t rb_generic_ivar_memsize(VALUE obj)
Definition: variable.c:1200
static VALUE autoload_reset(VALUE arg)
Definition: variable.c:2124
int line
Definition: constant.h:33
#define id_for_var(obj, name, part, type)
Definition: variable.c:1692
#define sym(x)
Definition: date_core.c:3721
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: st.h:22
void rb_name_error(ID id, const char *fmt,...)
Definition: error.c:1204
void(* func)(VALUE arg, VALUE val)
Definition: variable.c:465
VALUE rb_autoload_load(VALUE mod, ID id)
Definition: variable.c:2198
rb_const_flag_t
Definition: constant.h:14
#define CVAR_LOOKUP(v, r)
Definition: variable.c:2883
static st_table * generic_iv_tbl_compat
Definition: variable.c:30
static ID cv_intern(VALUE klass, const char *name)
Definition: variable.c:2957
static int list_i(st_data_t key, st_data_t value, VALUE ary)
Definition: variable.c:2483
rb_const_flag_t flag
Definition: constant.h:32
static enum rb_id_table_iterator_result fc_i(ID key, VALUE v, void *a)
Definition: variable.c:97
static VALUE ivar_cache(VALUE obj, VALUE name)
Definition: variable.c:288
#define FL_SINGLETON
Definition: ruby.h:1215
#define RB_TYPE_P(obj, type)
Definition: ruby.h:527
VALUE rb_gvar_val_getter(ID id, void *data, struct rb_global_variable *var)
Definition: variable.c:532
VALUE rb_eNameError
Definition: error.c:767
VALUE rb_cvar_defined(VALUE klass, ID id)
Definition: variable.c:2949
void rb_const_set(VALUE klass, ID id, VALUE val)
Definition: variable.c:2616
#define id_for_var_message(obj, name, type, message)
Definition: variable.c:1694
#define FL_TEST(x, f)
Definition: ruby.h:1284
static void autoload_free(void *ptr)
Definition: variable.c:1854
st_data_t arg
Definition: variable.c:1454
VALUE rb_search_class_path(VALUE klass)
Definition: variable.c:336
static void autoload_delete(VALUE mod, ID id)
Definition: variable.c:1991
static int cv_list_i(st_data_t key, st_data_t value, VALUE ary)
Definition: variable.c:3026
VALUE rb_attr_delete(VALUE obj, ID id)
Definition: variable.c:1315
VALUE rb_class_path(VALUE klass)
Definition: variable.c:294
VALUE rb_gvar_set(struct rb_global_entry *entry, VALUE val)
Definition: variable.c:824
#define ROBJECT_IVPTR(o)
Definition: ruby.h:904
#define ALLOC_N(type, n)
Definition: ruby.h:1587
struct fc_result * prev
Definition: variable.c:66
struct list_head head
Definition: variable.c:1898
#define val
Definition: internal.h:887
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1872
VALUE rb_eRuntimeError
Definition: error.c:761
int rb_is_class_id(ID id)
Definition: symbol.c:834
size_t st_memsize(const st_table *tab)
Definition: st.c:674
VALUE rb_str_cat2(VALUE, const char *)
union ivar_update::@184 u
VALUE rb_ary_new(void)
Definition: array.c:493
static void uninitialized_constant(VALUE klass, VALUE name)
Definition: variable.c:1783
int iv_extended
Definition: variable.c:44
VALUE rb_thread_current(void)
Definition: thread.c:2504
ID preferred
Definition: variable.c:62
int rb_id_table_delete(struct rb_id_table *tbl, ID id)
#define NIL_P(v)
Definition: ruby.h:451
struct rb_id_table * rb_id_table_create(size_t size)
struct gen_ivtbl * ivtbl
Definition: variable.c:41
int rb_match_nth_defined(int nth, VALUE match)
Definition: re.c:1276
struct list_node node
Definition: variable.c:1897
struct gen_ivtbl * ivtbl
Definition: variable.c:946
st_table * tbl
Definition: variable.c:947
#define RCLASS_IV_TBL(c)
Definition: internal.h:688
int removed
Definition: variable.c:464
const char * rb_obj_classname(VALUE obj)
Definition: variable.c:458
static void setup_const_entry(rb_const_entry_t *, VALUE, VALUE, rb_const_flag_t)
Definition: variable.c:2725
int argc
Definition: ruby.c:183
#define Qfalse
Definition: ruby.h:436
int rb_class_ivar_set(VALUE obj, ID key, VALUE value)
Definition: variable.c:3147
#define ALLOCA_N(type, n)
Definition: ruby.h:1593
RUBY_EXTERN VALUE rb_cModule
Definition: ruby.h:1895
VALUE rb_gv_get(const char *name)
Definition: variable.c:850
void rb_cv_set(VALUE klass, const char *name, VALUE val)
Definition: variable.c:2968
#define RUBY_FUNC_EXPORTED
Definition: defines.h:263
#define MEMCPY(p1, p2, type, n)
Definition: ruby.h:1661
#define rb_str_new2
Definition: intern.h:857
int rb_const_defined(VALUE klass, ID id)
Definition: variable.c:2580
static int gen_ivar_compat_tbl_i(st_data_t id, st_data_t index, st_data_t arg)
Definition: variable.c:951
#define OBJ_FREEZE(x)
Definition: ruby.h:1308
void rb_set_class_path(VALUE klass, VALUE under, const char *name)
Definition: variable.c:366
static void iv_index_tbl_extend(struct ivar_update *ivup, ID id)
Definition: variable.c:1334
static ID global_id(const char *name)
Definition: variable.c:600
VALUE rb_ivar_set(VALUE obj, ID id, VALUE val)
Definition: variable.c:1364
VALUE rb_thread_wakeup_alive(VALUE)
Definition: thread.c:2390
int rb_public_const_defined_from(VALUE klass, ID id)
Definition: variable.c:2592
static int gen_ivtbl_get(VALUE obj, struct gen_ivtbl **ivtbl)
Definition: variable.c:965
#define ALLOC(type)
Definition: ruby.h:1588
VALUE rb_gvar_getter_t(ID id, void *data, struct rb_global_variable *gvar)
Definition: ruby.h:1683
VALUE rb_class_name(VALUE klass)
Definition: variable.c:443
VALUE rb_mod_class_variables(int argc, const VALUE *argv, VALUE mod)
Definition: variable.c:3068
void st_foreach_safe(st_table *table, int(*func)(ANYARGS), st_data_t a)
Definition: hash.c:327
VALUE rb_str_subseq(VALUE, long, long)
Definition: string.c:2324
static VALUE generic_ivar_get(VALUE obj, ID id, VALUE undef)
Definition: variable.c:1030
#define ZALLOC(type)
Definition: ruby.h:1590
size_t rb_id_table_size(const struct rb_id_table *tbl)
#define RSTRING_LEN(str)
Definition: ruby.h:978
static void remove_trace(struct rb_global_variable *var)
Definition: variable.c:714
static void * mod_cvar_at(VALUE mod, void *data)
Definition: variable.c:3001
#define REALLOC_N(var, type, n)
Definition: ruby.h:1591
#define TRUE
Definition: nkf.h:175
VALUE rb_gvar_var_getter(ID id, void *data, struct rb_global_variable *gvar)
Definition: variable.c:551
void rb_gvar_var_setter(VALUE val, ID id, void *data, struct rb_global_variable *g)
Definition: variable.c:559
int rb_const_defined_at(VALUE klass, ID id)
Definition: variable.c:2586
static int generic_ivar_update(st_data_t *k, st_data_t *v, st_data_t u, int existing)
Definition: variable.c:1096
VALUE rb_sprintf(const char *format,...)
Definition: sprintf.c:1440
static void * mod_cvar_of(VALUE mod, void *data)
Definition: variable.c:3014
void rb_gvar_readonly_setter(VALUE v, ID id, void *d, struct rb_global_variable *g)
Definition: variable.c:571
void rb_gvar_val_marker(VALUE *var)
Definition: variable.c:544
ID name
Definition: variable.c:62
VALUE rb_attr_get(VALUE obj, ID id)
Definition: variable.c:1273
static VALUE trace_en(struct rb_global_variable *var)
Definition: variable.c:816
VALUE rb_obj_remove_instance_variable(VALUE obj, VALUE name)
Definition: variable.c:1734
st_table * rb_generic_ivar_table(VALUE obj)
Definition: variable.c:978
void rb_gvar_val_setter(VALUE val, ID id, void *data, struct rb_global_variable *var)
Definition: variable.c:538
void Init_var_tables(void)
Definition: variable.c:48
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1919
VALUE rb_mod_deprecate_constant(int argc, const VALUE *argv, VALUE obj)
Definition: variable.c:2843
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4309
void rb_vm_pop_cfunc_frame(void)
Definition: vm.c:523
#define PRIsVALUE
Definition: ruby.h:135
VALUE rb_const_get_at(VALUE klass, ID id)
Definition: variable.c:2341
unsigned long ID
Definition: ruby.h:86
static int ivar_i(st_data_t k, st_data_t v, st_data_t a)
Definition: variable.c:1652
#define Qnil
Definition: ruby.h:438
struct trace_var * trace
Definition: variable.c:477
#define BUILTIN_TYPE(x)
Definition: ruby.h:518
int rb_autoloading_value(VALUE mod, ID id, VALUE *value)
Definition: variable.c:2062
unsigned long VALUE
Definition: ruby.h:85
VALUE rb_vm_top_self(void)
Definition: vm.c:3151
static VALUE make_temporary_path(VALUE obj, VALUE klass)
Definition: variable.c:238
static VALUE result
Definition: nkf.c:40
#define RB_CONST_PRIVATE_P(ce)
Definition: constant.h:23
#define RBASIC(obj)
Definition: ruby.h:1204
VALUE rb_public_const_get_from(VALUE klass, ID id)
Definition: variable.c:2347
void rb_mark_tbl(st_table *tbl)
Definition: gc.c:4229
VALUE val
Definition: variable.c:799
st_data_t index
Definition: variable.c:43
#define rb_ary_new3
Definition: intern.h:91
static size_t gen_ivtbl_bytes(size_t n)
Definition: variable.c:1050
struct autoload_data_i * ele
Definition: variable.c:1891
#define rb_enc_asciicompat(enc)
Definition: encoding.h:239
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
Definition: eval.c:923
VALUE rb_str_new_cstr(const char *)
Definition: string.c:770
void rb_const_warn_if_deprecated(const rb_const_entry_t *ce, VALUE klass, ID id)
Definition: variable.c:2263
static const rb_data_type_t autoload_data_i_type
Definition: variable.c:1923
VALUE rb_fstring(VALUE)
Definition: string.c:305
static ID classid
Definition: variable.c:24
VALUE rb_str_dup(VALUE)
Definition: string.c:1436
static void generic_ivar_set(VALUE obj, ID id, VALUE val)
Definition: variable.c:1348
void rb_define_class_variable(VALUE klass, const char *name, VALUE val)
Definition: variable.c:2982
VALUE rb_fstring_new(const char *ptr, long len)
Definition: string.c:373
struct rb_global_variable * var
Definition: internal.h:888
VALUE rb_class_real(VALUE cl)
Definition: object.c:207
#define FL_UNSET(x, f)
Definition: ruby.h:1292
#define ROBJECT(obj)
Definition: ruby.h:1205
#define rb_funcallv
Definition: console.c:21
static void check_before_mod_set(VALUE, ID, VALUE, const char *)
Definition: variable.c:2610
unsigned int uint32_t
Definition: sha2.h:101
int rb_thread_to_be_killed(VALUE thread)
Definition: thread.c:2311
register unsigned int len
Definition: zonetab.h:51
static VALUE generic_ivar_delete(VALUE obj, ID id, VALUE undef)
Definition: variable.c:1009
void rb_set_safe_level_force(int)
Definition: safe.c:41
VALUE rb_obj_instance_variables(VALUE obj)
Definition: variable.c:1681
#define RSTRING_PTR(str)
Definition: ruby.h:982
static VALUE autoload_data(VALUE mod, ID id)
Definition: variable.c:1876
VALUE track
Definition: variable.c:65
VALUE rb_class_path_cached(VALUE klass)
Definition: variable.c:318
rb_encoding * rb_enc_get(VALUE obj)
Definition: encoding.c:860
static VALUE trace_ev(struct trace_data *data)
Definition: variable.c:803
st_index_t rb_ivar_count(VALUE obj)
Definition: variable.c:1613
#define RCLASS_SUPER(c)
Definition: classext.h:16
int rb_safe_level(void)
Definition: safe.c:35
void rb_name_class(VALUE klass, ID id)
Definition: variable.c:437
ID rb_frame_callee(void)
Definition: eval.c:985
VALUE obj
Definition: variable.c:1523
VALUE rb_block_proc(void)
Definition: proc.c:787
static VALUE autoload_sleep(VALUE arg)
Definition: variable.c:2170
#define xmalloc
Definition: defines.h:183
#define st_init_numtable
Definition: regint.h:178
#define ANYARGS
Definition: defines.h:173
static ID check_id_type(VALUE obj, VALUE *pname, int(*valid_id_p)(ID), int(*valid_name_p)(VALUE), const char *message, size_t message_len)
Definition: variable.c:1697
void rb_ivar_foreach(VALUE obj, int(*func)(ANYARGS), st_data_t arg)
Definition: variable.c:1591
static size_t gen_ivtbl_count(const struct gen_ivtbl *ivtbl)
Definition: variable.c:1210
VALUE rb_iv_set(VALUE obj, const char *name, VALUE val)
Definition: variable.c:3138
VALUE rb_iv_get(VALUE obj, const char *name)
Definition: variable.c:3130
VALUE rb_cvar_get(VALUE klass, ID id)
Definition: variable.c:2922
VALUE rb_gv_set(const char *name, VALUE val)
Definition: variable.c:841
VALUE rb_path_to_class(VALUE pathname)
Definition: variable.c:389
#define RB_CONST_PUBLIC_P(ce)
Definition: constant.h:25
static const rb_data_type_t autoload_data_type
Definition: variable.c:1866
#define RCLASS_IV_INDEX_TBL(c)
Definition: internal.h:692
VALUE rb_const_get_from(VALUE klass, ID id)
Definition: variable.c:2329
void rb_gvar_var_marker(VALUE *var)
Definition: variable.c:565
#define RTEST(v)
Definition: ruby.h:450
void rb_gvar_marker_t(VALUE *var)
Definition: ruby.h:1685
#define T_STRING
Definition: ruby.h:496
static VALUE fc_path(struct fc_result *fc, ID name)
Definition: variable.c:70
static uint32_t iv_index_tbl_newsize(struct ivar_update *ivup)
Definition: variable.c:1083
struct rb_encoding_entry * list
Definition: encoding.c:55
void rb_alias_variable(ID name1, ID name2)
Definition: variable.c:911
#define st_add_direct
Definition: regint.h:187
static ID classpath
Definition: variable.c:24
#define TypedData_Make_Struct(klass, type, data_type, sval)
Definition: ruby.h:1182
rb_gvar_setter_t * setter
Definition: variable.c:475
VALUE data
Definition: variable.c:466
VALUE rb_const_missing(VALUE klass, VALUE name)
Definition: variable.c:1794
VALUE rb_eval_cmd(VALUE, VALUE, int)
Definition: vm_eval.c:1558
void rb_cvar_set(VALUE klass, ID id, VALUE val)
Definition: variable.c:2889
struct autoload_state * state
Definition: variable.c:1906
static int cv_i_update(st_data_t *k, st_data_t *v, st_data_t a, int existing)
Definition: variable.c:2415
static int rb_const_defined_0(VALUE klass, ID id, int exclude, int recurse, int visibility)
Definition: variable.c:2544
#define st_insert
Definition: regint.h:184
#define T_CLASS
Definition: ruby.h:492
VALUE rb_mod_remove_cvar(VALUE mod, VALUE name)
Definition: variable.c:3109
struct gen_ivtbl * ivtbl
Definition: variable.c:1525
static enum rb_id_table_iterator_result rb_local_constants_i(ID const_name, VALUE const_value, void *ary)
Definition: variable.c:2435
VALUE rb_mod_constants(int argc, const VALUE *argv, VALUE mod)
Definition: variable.c:2524
void rb_gc_mark_maybe(VALUE obj)
Definition: gc.c:4247
void rb_frozen_class_p(VALUE klass)
Definition: eval.c:396
static VALUE reset_safe(VALUE safe)
Definition: variable.c:2015
const char * name
Definition: nkf.c:208
static size_t autoload_memsize(const void *ptr)
Definition: variable.c:1860
#define xrealloc
Definition: defines.h:186
#define FL_SET(x, f)
Definition: ruby.h:1290
#define ID2SYM(x)
Definition: ruby.h:383
static VALUE check_autoload_required(VALUE mod, ID id, const char **loadingpath)
Definition: variable.c:2022
static VALUE rb_ivar_delete(VALUE obj, ID id, VALUE undef)
Definition: variable.c:1279
static void set_const_visibility(VALUE mod, int argc, const VALUE *argv, rb_const_flag_t flag, rb_const_flag_t mask)
Definition: variable.c:2751
static void autoload_i_mark(void *ptr)
Definition: variable.c:1910
struct gen_ivtbl * ivtbl
Definition: variable.c:1488
VALUE rb_str_new_frozen(VALUE)
Definition: string.c:1123
static int generic_ivar_remove(VALUE obj, ID id, VALUE *valp)
Definition: variable.c:1141
VALUE rb_source_location(int *pline)
Definition: vm.c:1275
st_table * iv_index_tbl
Definition: variable.c:1524
struct rb_id_table * rb_global_tbl
Definition: variable.c:23
#define st_free_table
Definition: regint.h:188
static size_t autoload_i_memsize(const void *ptr)
Definition: variable.c:1918
void rb_warning(const char *fmt,...)
Definition: error.c:250
void st_clear(st_table *)
Definition: st.c:653
#define QUOTE(str)
Definition: internal.h:1472
#define rb_check_frozen(obj)
Definition: intern.h:276
static void gen_ivtbl_mark(const struct gen_ivtbl *ivtbl)
Definition: variable.c:1163
VALUE rb_mod_private_constant(int argc, const VALUE *argv, VALUE obj)
Definition: variable.c:2815
rb_id_table_iterator_result
Definition: id_table.h:8
#define RUBY_TYPED_DEFAULT_FREE
Definition: ruby.h:1141
static int tbl_copy_i(st_data_t key, st_data_t value, st_data_t data)
Definition: variable.c:3156
VALUE rb_str_intern(VALUE)
Definition: symbol.c:661
#define rb_intern_const(str)
Definition: ruby.h:1756
#define memcpy(d, s, n)
Definition: ffi_common.h:55
static void obj_ivar_each(VALUE obj, int(*func)(ANYARGS), st_data_t arg)
Definition: variable.c:1471
static VALUE never_cache(VALUE obj, VALUE name)
Definition: variable.c:330
VALUE rb_class_path_no_cache(VALUE klass)
Definition: variable.c:309
#define SPECIAL_CONST_P(x)
Definition: ruby.h:1249
struct trace_var * next
Definition: variable.c:467
static ID autoload
Definition: variable.c:24
void void xfree(void *)
#define rb_intern(str)
int(* func)(ID key, VALUE val, st_data_t arg)
Definition: variable.c:1453
uint32_t numiv
Definition: variable.c:34
VALUE rb_mod_public_constant(int argc, const VALUE *argv, VALUE obj)
Definition: variable.c:2829
#define mod(x, y)
Definition: date_strftime.c:28
void rb_gvar_setter_t(VALUE val, ID id, void *data, struct rb_global_variable *gvar)
Definition: ruby.h:1684
#define st_copy
Definition: regint.h:190
#define NULL
Definition: _sdbm.c:102
#define Qundef
Definition: ruby.h:439
#define T_ICLASS
Definition: ruby.h:493
static VALUE original_module(VALUE c)
Definition: variable.c:2850
void * rb_mod_const_of(VALUE mod, void *data)
Definition: variable.c:2470
VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
Definition: variable.c:1225
VALUE rb_f_trace_var(int argc, const VALUE *argv)
Definition: variable.c:687
struct trace_var * trace
Definition: variable.c:798
st_index_t num_entries
Definition: st.h:86
static VALUE rb_local_constants(VALUE mod)
Definition: variable.c:2444
#define ruby_verbose
Definition: ruby.h:1792
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2818
static void const_tbl_update(struct autoload_const_set_args *)
Definition: variable.c:2671
VALUE rb_const_remove(VALUE mod, ID id)
Definition: variable.c:2387
static VALUE null_cache(VALUE obj, VALUE name)
Definition: variable.c:303
void rb_warn(const char *fmt,...)
Definition: error.c:221
ID rb_to_id(VALUE)
Definition: string.c:9979
void rb_id_table_foreach(struct rb_id_table *tbl, rb_id_table_foreach_func_t *func, void *data)
VALUE rb_eArgError
Definition: error.c:763
static struct gen_ivtbl * gen_ivtbl_resize(struct gen_ivtbl *old, uint32_t n)
Definition: variable.c:1056
static void autoload_mark(void *ptr)
Definition: variable.c:1848
int rb_id_table_insert(struct rb_id_table *tbl, ID id, VALUE val)
void rb_free_generic_ivar(VALUE obj)
Definition: variable.c:1183
#define RB_OBJ_WRITE(a, slot, b)
Definition: ruby.h:1437
char ** argv
Definition: ruby.c:184
void rb_copy_generic_ivar(VALUE clone, VALUE obj)
Definition: variable.c:1549
void rb_gvar_undef_marker(VALUE *var)
Definition: variable.c:527
int rb_const_defined_from(VALUE klass, ID id)
Definition: variable.c:2574
void rb_gvar_undef_setter(VALUE val, ID id, void *d, struct rb_global_variable *var)
Definition: variable.c:517
NORETURN(static void uninitialized_constant(VALUE, VALUE))
VALUE rb_obj_class(VALUE)
Definition: object.c:229
static ID tmp_classpath
Definition: variable.c:24