Ruby  1.9.3p551(2014-11-13revision48407)
variable.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  variable.c -
4 
5  $Author: marcandre $
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 "ruby/ruby.h"
15 #include "ruby/st.h"
16 #include "ruby/util.h"
17 #include "ruby/encoding.h"
18 #include "node.h"
19 #include "constant.h"
20 #include "internal.h"
21 
25 
26 void
28 {
29  rb_global_tbl = st_init_numtable();
30  rb_class_tbl = st_init_numtable();
31  CONST_ID(autoload, "__autoload__");
32  CONST_ID(classpath, "__classpath__");
33  CONST_ID(tmp_classpath, "__tmp_classpath__");
34  CONST_ID(classid, "__classid__");
35 }
36 
37 struct fc_result {
42  struct fc_result *prev;
43 };
44 
45 static VALUE
46 fc_path(struct fc_result *fc, ID name)
47 {
48  VALUE path, tmp;
49 
50  path = rb_str_dup(rb_id2str(name));
51  while (fc) {
52  st_data_t n;
53  if (fc->track == rb_cObject) break;
54  if (RCLASS_IV_TBL(fc->track) &&
56  tmp = rb_str_dup((VALUE)n);
57  rb_str_cat2(tmp, "::");
58  rb_str_append(tmp, path);
59  path = tmp;
60  break;
61  }
62  tmp = rb_str_dup(rb_id2str(fc->name));
63  rb_str_cat2(tmp, "::");
64  rb_str_append(tmp, path);
65  path = tmp;
66  fc = fc->prev;
67  }
68  OBJ_FREEZE(path);
69  return path;
70 }
71 
72 static int
73 fc_i(ID key, rb_const_entry_t *ce, struct fc_result *res)
74 {
75  VALUE value = ce->value;
76  if (!rb_is_const_id(key)) return ST_CONTINUE;
77 
78  if (value == res->klass) {
79  res->path = fc_path(res, key);
80  return ST_STOP;
81  }
82  switch (TYPE(value)) {
83  case T_MODULE:
84  case T_CLASS:
85  if (!RCLASS_CONST_TBL(value)) return ST_CONTINUE;
86  else {
87  struct fc_result arg;
88  struct fc_result *list;
89 
90  list = res;
91  while (list) {
92  if (list->track == value) return ST_CONTINUE;
93  list = list->prev;
94  }
95 
96  arg.name = key;
97  arg.path = 0;
98  arg.klass = res->klass;
99  arg.track = value;
100  arg.prev = res;
101  st_foreach(RCLASS_CONST_TBL(value), fc_i, (st_data_t)&arg);
102  if (arg.path) {
103  res->path = arg.path;
104  return ST_STOP;
105  }
106  }
107  break;
108 
109  default:
110  break;
111  }
112  return ST_CONTINUE;
113 }
114 
115 static VALUE
117 {
118  struct fc_result arg;
119 
120  arg.name = 0;
121  arg.path = 0;
122  arg.klass = klass;
123  arg.track = rb_cObject;
124  arg.prev = 0;
127  }
128  if (arg.path == 0) {
129  st_foreach_safe(rb_class_tbl, fc_i, (st_data_t)&arg);
130  }
131  if (arg.path) {
132  st_data_t tmp = tmp_classpath;
133  if (!RCLASS_IV_TBL(klass)) {
134  RCLASS_IV_TBL(klass) = st_init_numtable();
135  }
137  st_delete(RCLASS_IV_TBL(klass), &tmp, 0);
138  return arg.path;
139  }
140  return Qnil;
141 }
142 
143 static VALUE
145 {
146  VALUE path = Qnil;
147  st_data_t n;
148 
149  if (!klass) klass = rb_cObject;
150  if (RCLASS_IV_TBL(klass)) {
151  if (!st_lookup(RCLASS_IV_TBL(klass), (st_data_t)classpath, &n)) {
152  if (!st_lookup(RCLASS_IV_TBL(klass), (st_data_t)classid, &n)) {
153  return find_class_path(klass);
154  }
155  path = rb_str_dup(rb_id2str(SYM2ID((VALUE)n)));
156  OBJ_FREEZE(path);
157  st_insert(RCLASS_IV_TBL(klass), (st_data_t)classpath, (st_data_t)path);
158  n = classid;
159  st_delete(RCLASS_IV_TBL(klass), &n, 0);
160  }
161  else {
162  path = (VALUE)n;
163  }
164  if (TYPE(path) != T_STRING) {
165  rb_bug("class path is not set properly");
166  }
167  return path;
168  }
169  return find_class_path(klass);
170 }
171 
172 /*
173  * call-seq:
174  * mod.name -> string
175  *
176  * Returns the name of the module <i>mod</i>. Returns nil for anonymous modules.
177  */
178 
179 VALUE
181 {
182  VALUE path = classname(mod);
183 
184  if (!NIL_P(path)) return rb_str_dup(path);
185  return path;
186 }
187 
188 VALUE
190 {
191  VALUE path = classname(klass);
192  st_data_t n = (st_data_t)path;
193 
194  if (!NIL_P(path)) return path;
195  if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),
196  (st_data_t)tmp_classpath, &n)) {
197  return (VALUE)n;
198  }
199  else {
200  const char *s = "Class";
201 
202  if (TYPE(klass) == T_MODULE) {
203  if (rb_obj_class(klass) == rb_cModule) {
204  s = "Module";
205  }
206  else {
207  s = rb_class2name(RBASIC(klass)->klass);
208  }
209  }
210  path = rb_sprintf("#<%s:%p>", s, (void*)klass);
211  OBJ_FREEZE(path);
212  rb_ivar_set(klass, tmp_classpath, path);
213 
214  return path;
215  }
216 }
217 
218 void
220 {
221  VALUE str;
222 
223  if (under == rb_cObject) {
224  str = rb_str_new_frozen(name);
225  }
226  else {
227  str = rb_str_dup(rb_class_path(under));
228  rb_str_cat2(str, "::");
229  rb_str_append(str, name);
230  OBJ_FREEZE(str);
231  }
232  rb_ivar_set(klass, classpath, str);
233 }
234 
235 void
236 rb_set_class_path(VALUE klass, VALUE under, const char *name)
237 {
238  VALUE str;
239 
240  if (under == rb_cObject) {
241  str = rb_str_new2(name);
242  }
243  else {
244  str = rb_str_dup(rb_class_path(under));
245  rb_str_cat2(str, "::");
246  rb_str_cat2(str, name);
247  }
248  OBJ_FREEZE(str);
249  rb_ivar_set(klass, classpath, str);
250 }
251 
252 VALUE
254 {
255  rb_encoding *enc = rb_enc_get(pathname);
256  const char *pbeg, *p, *path = RSTRING_PTR(pathname);
257  ID id;
258  VALUE c = rb_cObject;
259 
260  if (!rb_enc_asciicompat(enc)) {
261  rb_raise(rb_eArgError, "invalid class path encoding (non ASCII)");
262  }
263  pbeg = p = path;
264  if (path[0] == '#') {
265  rb_raise(rb_eArgError, "can't retrieve anonymous class %s", path);
266  }
267  while (*p) {
268  while (*p && *p != ':') p++;
269  id = rb_intern3(pbeg, p-pbeg, enc);
270  if (p[0] == ':') {
271  if (p[1] != ':') goto undefined_class;
272  p += 2;
273  pbeg = p;
274  }
275  if (!rb_const_defined(c, id)) {
276  undefined_class:
277  rb_raise(rb_eArgError, "undefined class/module %.*s", (int)(p-path), path);
278  }
279  c = rb_const_get_at(c, id);
280  switch (TYPE(c)) {
281  case T_MODULE:
282  case T_CLASS:
283  break;
284  default:
285  rb_raise(rb_eTypeError, "%s does not refer to class/module", path);
286  }
287  }
288 
289  return c;
290 }
291 
292 VALUE
293 rb_path2class(const char *path)
294 {
295  return rb_path_to_class(rb_str_new_cstr(path));
296 }
297 
298 void
300 {
301  rb_ivar_set(klass, classid, ID2SYM(id));
302 }
303 
304 VALUE
306 {
307  return rb_class_path(rb_class_real(klass));
308 }
309 
310 const char *
312 {
313  VALUE name = rb_class_name(klass);
314  return RSTRING_PTR(name);
315 }
316 
317 const char *
319 {
320  return rb_class2name(CLASS_OF(obj));
321 }
322 
323 #define global_variable rb_global_variable
324 #define global_entry rb_global_entry
325 
326 #define gvar_getter_t rb_gvar_getter_t
327 #define gvar_setter_t rb_gvar_setter_t
328 #define gvar_marker_t rb_gvar_marker_t
329 
330 struct trace_var {
331  int removed;
332  void (*func)(VALUE arg, VALUE val);
334  struct trace_var *next;
335 };
336 
338  int counter;
339  void *data;
344  struct trace_var *trace;
345 };
346 
347 #define undef_getter rb_gvar_undef_getter
348 #define undef_setter rb_gvar_undef_setter
349 #define undef_marker rb_gvar_undef_marker
350 
351 #define val_getter rb_gvar_val_getter
352 #define val_setter rb_gvar_val_setter
353 #define val_marker rb_gvar_val_marker
354 
355 #define var_getter rb_gvar_var_getter
356 #define var_setter rb_gvar_var_setter
357 #define var_marker rb_gvar_var_marker
358 
359 #define readonly_setter rb_gvar_readonly_setter
360 
361 struct global_entry*
363 {
364  struct global_entry *entry;
365  st_data_t data;
366 
367  if (!st_lookup(rb_global_tbl, (st_data_t)id, &data)) {
368  struct global_variable *var;
369  entry = ALLOC(struct global_entry);
370  var = ALLOC(struct global_variable);
371  entry->id = id;
372  entry->var = var;
373  var->counter = 1;
374  var->data = 0;
375  var->getter = undef_getter;
376  var->setter = undef_setter;
377  var->marker = undef_marker;
378 
379  var->block_trace = 0;
380  var->trace = 0;
381  st_add_direct(rb_global_tbl, id, (st_data_t)entry);
382  }
383  else {
384  entry = (struct global_entry *)data;
385  }
386  return entry;
387 }
388 
389 VALUE
390 undef_getter(ID id, void *data, struct global_variable *var)
391 {
392  rb_warning("global variable `%s' not initialized", rb_id2name(id));
393 
394  return Qnil;
395 }
396 
397 void
398 undef_setter(VALUE val, ID id, void *data, struct global_variable *var)
399 {
400  var->getter = val_getter;
401  var->setter = val_setter;
402  var->marker = val_marker;
403 
404  var->data = (void*)val;
405 }
406 
407 void
409 {
410 }
411 
412 VALUE
413 val_getter(ID id, void *data, struct global_variable *var)
414 {
415  return (VALUE)data;
416 }
417 
418 void
419 val_setter(VALUE val, ID id, void *data, struct global_variable *var)
420 {
421  var->data = (void*)val;
422 }
423 
424 void
426 {
427  VALUE data = (VALUE)var;
428  if (data) rb_gc_mark_maybe(data);
429 }
430 
431 VALUE
432 var_getter(ID id, void *data, struct global_variable *gvar)
433 {
434  VALUE *var = data;
435  if (!var) return Qnil;
436  return *var;
437 }
438 
439 void
440 var_setter(VALUE val, ID id, void *data, struct global_variable *gvar)
441 {
442  *(VALUE *)data = val;
443 }
444 
445 void
447 {
448  if (var) rb_gc_mark_maybe(*var);
449 }
450 
451 void
452 readonly_setter(VALUE val, ID id, void *data, struct global_variable *gvar)
453 {
454  rb_name_error(id, "%s is a read-only variable", rb_id2name(id));
455 }
456 
457 static int
459 {
460  struct trace_var *trace;
461  struct global_variable *var = entry->var;
462 
463  (*var->marker)(var->data);
464  trace = var->trace;
465  while (trace) {
466  if (trace->data) rb_gc_mark_maybe(trace->data);
467  trace = trace->next;
468  }
469  return ST_CONTINUE;
470 }
471 
472 void
474 {
475  if (rb_global_tbl)
476  st_foreach_safe(rb_global_tbl, mark_global_entry, 0);
477 }
478 
479 static ID
480 global_id(const char *name)
481 {
482  ID id;
483 
484  if (name[0] == '$') id = rb_intern(name);
485  else {
486  size_t len = strlen(name);
487  char *buf = ALLOCA_N(char, len+1);
488  buf[0] = '$';
489  memcpy(buf+1, name, len);
490  id = rb_intern2(buf, len+1);
491  }
492  return id;
493 }
494 
495 void
497  const char *name,
498  VALUE *var,
499  VALUE (*getter)(ANYARGS),
500  void (*setter)(ANYARGS))
501 {
502  volatile VALUE tmp = var ? *var : Qnil;
503  ID id = global_id(name);
504  struct global_variable *gvar = rb_global_entry(id)->var;
505 
506  gvar->data = (void*)var;
509  gvar->marker = var_marker;
510 
511  RB_GC_GUARD(tmp);
512 }
513 
514 void
515 rb_define_variable(const char *name, VALUE *var)
516 {
517  rb_define_hooked_variable(name, var, 0, 0);
518 }
519 
520 void
521 rb_define_readonly_variable(const char *name, VALUE *var)
522 {
524 }
525 
526 void
528  const char *name,
529  VALUE (*getter)(ANYARGS),
530  void (*setter)(ANYARGS))
531 {
532  if (!getter) getter = val_getter;
533  if (!setter) setter = readonly_setter;
535 }
536 
537 static void
539 {
540  rb_eval_cmd(cmd, rb_ary_new3(1, val), 0);
541 }
542 
543 /*
544  * call-seq:
545  * trace_var(symbol, cmd ) -> nil
546  * trace_var(symbol) {|val| block } -> nil
547  *
548  * Controls tracing of assignments to global variables. The parameter
549  * +symbol_ identifies the variable (as either a string name or a
550  * symbol identifier). _cmd_ (which may be a string or a
551  * +Proc+ object) or block is executed whenever the variable
552  * is assigned. The block or +Proc+ object receives the
553  * variable's new value as a parameter. Also see
554  * <code>Kernel::untrace_var</code>.
555  *
556  * trace_var :$_, proc {|v| puts "$_ is now '#{v}'" }
557  * $_ = "hello"
558  * $_ = ' there'
559  *
560  * <em>produces:</em>
561  *
562  * $_ is now 'hello'
563  * $_ is now ' there'
564  */
565 
566 VALUE
568 {
569  VALUE var, cmd;
570  struct global_entry *entry;
571  struct trace_var *trace;
572 
573  rb_secure(4);
574  if (rb_scan_args(argc, argv, "11", &var, &cmd) == 1) {
575  cmd = rb_block_proc();
576  }
577  if (NIL_P(cmd)) {
578  return rb_f_untrace_var(argc, argv);
579  }
580  entry = rb_global_entry(rb_to_id(var));
581  if (OBJ_TAINTED(cmd)) {
582  rb_raise(rb_eSecurityError, "Insecure: tainted variable trace");
583  }
584  trace = ALLOC(struct trace_var);
585  trace->next = entry->var->trace;
586  trace->func = rb_trace_eval;
587  trace->data = cmd;
588  trace->removed = 0;
589  entry->var->trace = trace;
590 
591  return Qnil;
592 }
593 
594 static void
596 {
597  struct trace_var *trace = var->trace;
598  struct trace_var t;
599  struct trace_var *next;
600 
601  t.next = trace;
602  trace = &t;
603  while (trace->next) {
604  next = trace->next;
605  if (next->removed) {
606  trace->next = next->next;
607  xfree(next);
608  }
609  else {
610  trace = next;
611  }
612  }
613  var->trace = t.next;
614 }
615 
616 /*
617  * call-seq:
618  * untrace_var(symbol [, cmd] ) -> array or nil
619  *
620  * Removes tracing for the specified command on the given global
621  * variable and returns +nil+. If no command is specified,
622  * removes all tracing for that variable and returns an array
623  * containing the commands actually removed.
624  */
625 
626 VALUE
628 {
629  VALUE var, cmd;
630  ID id;
631  struct global_entry *entry;
632  struct trace_var *trace;
633  st_data_t data;
634 
635  rb_secure(4);
636  rb_scan_args(argc, argv, "11", &var, &cmd);
637  id = rb_to_id(var);
638  if (!st_lookup(rb_global_tbl, (st_data_t)id, &data)) {
639  rb_name_error(id, "undefined global variable %s", rb_id2name(id));
640  }
641 
642  trace = (entry = (struct global_entry *)data)->var->trace;
643  if (NIL_P(cmd)) {
644  VALUE ary = rb_ary_new();
645 
646  while (trace) {
647  struct trace_var *next = trace->next;
648  rb_ary_push(ary, (VALUE)trace->data);
649  trace->removed = 1;
650  trace = next;
651  }
652 
653  if (!entry->var->block_trace) remove_trace(entry->var);
654  return ary;
655  }
656  else {
657  while (trace) {
658  if (trace->data == cmd) {
659  trace->removed = 1;
660  if (!entry->var->block_trace) remove_trace(entry->var);
661  return rb_ary_new3(1, cmd);
662  }
663  trace = trace->next;
664  }
665  }
666  return Qnil;
667 }
668 
669 VALUE
670 rb_gvar_get(struct global_entry *entry)
671 {
672  struct global_variable *var = entry->var;
673  return (*var->getter)(entry->id, var->data, var);
674 }
675 
676 struct trace_data {
677  struct trace_var *trace;
679 };
680 
681 static VALUE
683 {
684  struct trace_var *trace = data->trace;
685 
686  while (trace) {
687  (*trace->func)(trace->data, data->val);
688  trace = trace->next;
689  }
690  return Qnil; /* not reached */
691 }
692 
693 static VALUE
695 {
696  var->block_trace = 0;
697  remove_trace(var);
698  return Qnil; /* not reached */
699 }
700 
701 VALUE
702 rb_gvar_set(struct global_entry *entry, VALUE val)
703 {
704  struct trace_data trace;
705  struct global_variable *var = entry->var;
706 
707  if (rb_safe_level() >= 4)
708  rb_raise(rb_eSecurityError, "Insecure: can't change global variable value");
709  (*var->setter)(val, entry->id, var->data, var);
710 
711  if (var->trace && !var->block_trace) {
712  var->block_trace = 1;
713  trace.trace = var->trace;
714  trace.val = val;
715  rb_ensure(trace_ev, (VALUE)&trace, trace_en, (VALUE)var);
716  }
717  return val;
718 }
719 
720 VALUE
721 rb_gv_set(const char *name, VALUE val)
722 {
723  struct global_entry *entry;
724 
725  entry = rb_global_entry(global_id(name));
726  return rb_gvar_set(entry, val);
727 }
728 
729 VALUE
730 rb_gv_get(const char *name)
731 {
732  struct global_entry *entry;
733 
734  entry = rb_global_entry(global_id(name));
735  return rb_gvar_get(entry);
736 }
737 
738 VALUE
740 {
741  if (entry->var->getter == undef_getter) return Qfalse;
742  return Qtrue;
743 }
744 
745 static int
746 gvar_i(ID key, struct global_entry *entry, VALUE ary)
747 {
748  rb_ary_push(ary, ID2SYM(key));
749  return ST_CONTINUE;
750 }
751 
752 /*
753  * call-seq:
754  * global_variables -> array
755  *
756  * Returns an array of the names of global variables.
757  *
758  * global_variables.grep /std/ #=> [:$stdin, :$stdout, :$stderr]
759  */
760 
761 VALUE
763 {
764  VALUE ary = rb_ary_new();
765  char buf[2];
766  int i;
767 
768  st_foreach_safe(rb_global_tbl, gvar_i, ary);
769  buf[0] = '$';
770  for (i = 1; i <= 9; ++i) {
771  buf[1] = (char)(i + '0');
772  rb_ary_push(ary, ID2SYM(rb_intern2(buf, 2)));
773  }
774  return ary;
775 }
776 
777 void
778 rb_alias_variable(ID name1, ID name2)
779 {
780  struct global_entry *entry1, *entry2;
781  st_data_t data1;
782 
783  if (rb_safe_level() >= 4)
784  rb_raise(rb_eSecurityError, "Insecure: can't alias global variable");
785 
786  entry2 = rb_global_entry(name2);
787  if (!st_lookup(rb_global_tbl, (st_data_t)name1, &data1)) {
788  entry1 = ALLOC(struct global_entry);
789  entry1->id = name1;
790  st_add_direct(rb_global_tbl, name1, (st_data_t)entry1);
791  }
792  else if ((entry1 = (struct global_entry *)data1)->var != entry2->var) {
793  struct global_variable *var = entry1->var;
794  if (var->block_trace) {
795  rb_raise(rb_eRuntimeError, "can't alias in tracer");
796  }
797  var->counter--;
798  if (var->counter == 0) {
799  struct trace_var *trace = var->trace;
800  while (trace) {
801  struct trace_var *next = trace->next;
802  xfree(trace);
803  trace = next;
804  }
805  xfree(var);
806  }
807  }
808  else {
809  return;
810  }
811  entry2->var->counter++;
812  entry1->var = entry2->var;
813 }
814 
815 static int special_generic_ivar = 0;
817 
818 st_table*
820 {
821  st_data_t tbl;
822 
823  if (!FL_TEST(obj, FL_EXIVAR)) return 0;
824  if (!generic_iv_tbl) return 0;
825  if (!st_lookup(generic_iv_tbl, (st_data_t)obj, &tbl)) return 0;
826  return (st_table *)tbl;
827 }
828 
829 static VALUE
830 generic_ivar_get(VALUE obj, ID id, int warn)
831 {
832  st_data_t tbl, val;
833 
834  if (generic_iv_tbl) {
835  if (st_lookup(generic_iv_tbl, (st_data_t)obj, &tbl)) {
836  if (st_lookup((st_table *)tbl, (st_data_t)id, &val)) {
837  return (VALUE)val;
838  }
839  }
840  }
841  if (warn) {
842  rb_warning("instance variable %s not initialized", rb_id2name(id));
843  }
844  return Qnil;
845 }
846 
847 static void
849 {
850  st_table *tbl;
851  st_data_t data;
852 
853  if (rb_special_const_p(obj)) {
854  if (rb_obj_frozen_p(obj)) rb_error_frozen("object");
855  special_generic_ivar = 1;
856  }
857  if (!generic_iv_tbl) {
858  generic_iv_tbl = st_init_numtable();
859  }
860  if (!st_lookup(generic_iv_tbl, (st_data_t)obj, &data)) {
861  FL_SET(obj, FL_EXIVAR);
862  tbl = st_init_numtable();
863  st_add_direct(generic_iv_tbl, (st_data_t)obj, (st_data_t)tbl);
864  st_add_direct(tbl, (st_data_t)id, (st_data_t)val);
865  return;
866  }
867  st_insert((st_table *)data, (st_data_t)id, (st_data_t)val);
868 }
869 
870 static VALUE
872 {
873  st_table *tbl;
874  st_data_t data;
875 
876  if (!generic_iv_tbl) return Qfalse;
877  if (!st_lookup(generic_iv_tbl, (st_data_t)obj, &data)) return Qfalse;
878  tbl = (st_table *)data;
879  if (st_lookup(tbl, (st_data_t)id, &data)) {
880  return Qtrue;
881  }
882  return Qfalse;
883 }
884 
885 static int
887 {
888  st_table *tbl;
889  st_data_t data, key = (st_data_t)id;
890  int status;
891 
892  if (!generic_iv_tbl) return 0;
893  if (!st_lookup(generic_iv_tbl, (st_data_t)obj, &data)) return 0;
894  tbl = (st_table *)data;
895  status = st_delete(tbl, &key, valp);
896  if (tbl->num_entries == 0) {
897  key = (st_data_t)obj;
898  st_delete(generic_iv_tbl, &key, &data);
899  st_free_table((st_table *)data);
900  }
901  return status;
902 }
903 
904 void
906 {
907  st_data_t tbl;
908 
909  if (!generic_iv_tbl) return;
910  if (st_lookup(generic_iv_tbl, (st_data_t)obj, &tbl)) {
911  rb_mark_tbl((st_table *)tbl);
912  }
913 }
914 
915 static int
917 {
918  rb_gc_mark(value);
919  return ST_CONTINUE;
920 }
921 
922 static int
924 {
925  if (rb_special_const_p(obj)) {
926  st_foreach_safe(tbl, givar_mark_i, 0);
927  }
928  return ST_CONTINUE;
929 }
930 
931 void
933 {
934  if (!generic_iv_tbl) return;
935  if (special_generic_ivar == 0) return;
936  st_foreach_safe(generic_iv_tbl, givar_i, 0);
937 }
938 
939 void
941 {
942  st_data_t key = (st_data_t)obj, tbl;
943 
944  if (!generic_iv_tbl) return;
945  if (st_delete(generic_iv_tbl, &key, &tbl))
946  st_free_table((st_table *)tbl);
947 }
948 
949 RUBY_FUNC_EXPORTED size_t
951 {
952  st_data_t tbl;
953  if (st_lookup(generic_iv_tbl, (st_data_t)obj, &tbl))
954  return st_memsize((st_table *)tbl);
955  return 0;
956 }
957 
958 void
960 {
961  st_data_t data;
962 
963  if (!generic_iv_tbl) return;
964  if (!FL_TEST(obj, FL_EXIVAR)) {
965  clear:
966  if (FL_TEST(clone, FL_EXIVAR)) {
967  rb_free_generic_ivar(clone);
968  FL_UNSET(clone, FL_EXIVAR);
969  }
970  return;
971  }
972  if (st_lookup(generic_iv_tbl, (st_data_t)obj, &data)) {
973  st_table *tbl = (st_table *)data;
974 
975  if (tbl->num_entries == 0)
976  goto clear;
977 
978  if (st_lookup(generic_iv_tbl, (st_data_t)clone, &data)) {
979  st_free_table((st_table *)data);
980  st_insert(generic_iv_tbl, (st_data_t)clone, (st_data_t)st_copy(tbl));
981  }
982  else {
983  st_add_direct(generic_iv_tbl, (st_data_t)clone, (st_data_t)st_copy(tbl));
984  FL_SET(clone, FL_EXIVAR);
985  }
986  }
987 }
988 
989 static VALUE
990 ivar_get(VALUE obj, ID id, int warn)
991 {
992  VALUE val, *ptr;
993  struct st_table *iv_index_tbl;
994  long len;
995  st_data_t index;
996 
997  switch (TYPE(obj)) {
998  case T_OBJECT:
999  len = ROBJECT_NUMIV(obj);
1000  ptr = ROBJECT_IVPTR(obj);
1001  iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
1002  if (!iv_index_tbl) break;
1003  if (!st_lookup(iv_index_tbl, (st_data_t)id, &index)) break;
1004  if (len <= (long)index) break;
1005  val = ptr[index];
1006  if (val != Qundef)
1007  return val;
1008  break;
1009  case T_CLASS:
1010  case T_MODULE:
1011  if (RCLASS_IV_TBL(obj) && st_lookup(RCLASS_IV_TBL(obj), (st_data_t)id, &index))
1012  return (VALUE)index;
1013  break;
1014  default:
1015  if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
1016  return generic_ivar_get(obj, id, warn);
1017  break;
1018  }
1019  if (warn) {
1020  rb_warning("instance variable %s not initialized", rb_id2name(id));
1021  }
1022  return Qnil;
1023 }
1024 
1025 VALUE
1027 {
1028  return ivar_get(obj, id, TRUE);
1029 }
1030 
1031 VALUE
1033 {
1034  return ivar_get(obj, id, FALSE);
1035 }
1036 
1037 VALUE
1038 rb_ivar_set(VALUE obj, ID id, VALUE val)
1039 {
1040  struct st_table *iv_index_tbl;
1041  st_data_t index;
1042  long i, len;
1043  int ivar_extended;
1044 
1045  if (!OBJ_UNTRUSTED(obj) && rb_safe_level() >= 4)
1046  rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
1047  rb_check_frozen(obj);
1048  switch (TYPE(obj)) {
1049  case T_OBJECT:
1050  iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
1051  if (!iv_index_tbl) {
1052  VALUE klass = rb_obj_class(obj);
1053  iv_index_tbl = RCLASS_IV_INDEX_TBL(klass);
1054  if (!iv_index_tbl) {
1055  iv_index_tbl = RCLASS_IV_INDEX_TBL(klass) = st_init_numtable();
1056  }
1057  }
1058  ivar_extended = 0;
1059  if (!st_lookup(iv_index_tbl, (st_data_t)id, &index)) {
1060  index = iv_index_tbl->num_entries;
1061  st_add_direct(iv_index_tbl, (st_data_t)id, index);
1062  ivar_extended = 1;
1063  }
1064  len = ROBJECT_NUMIV(obj);
1065  if (len <= (long)index) {
1066  VALUE *ptr = ROBJECT_IVPTR(obj);
1067  if (index < ROBJECT_EMBED_LEN_MAX) {
1068  RBASIC(obj)->flags |= ROBJECT_EMBED;
1069  ptr = ROBJECT(obj)->as.ary;
1070  for (i = 0; i < ROBJECT_EMBED_LEN_MAX; i++) {
1071  ptr[i] = Qundef;
1072  }
1073  }
1074  else {
1075  VALUE *newptr;
1076  long newsize = (index+1) + (index+1)/4; /* (index+1)*1.25 */
1077  if (!ivar_extended &&
1078  iv_index_tbl->num_entries < (st_index_t)newsize) {
1079  newsize = iv_index_tbl->num_entries;
1080  }
1081  if (RBASIC(obj)->flags & ROBJECT_EMBED) {
1082  newptr = ALLOC_N(VALUE, newsize);
1083  MEMCPY(newptr, ptr, VALUE, len);
1084  RBASIC(obj)->flags &= ~ROBJECT_EMBED;
1085  ROBJECT(obj)->as.heap.ivptr = newptr;
1086  }
1087  else {
1088  REALLOC_N(ROBJECT(obj)->as.heap.ivptr, VALUE, newsize);
1089  newptr = ROBJECT(obj)->as.heap.ivptr;
1090  }
1091  for (; len < newsize; len++)
1092  newptr[len] = Qundef;
1093  ROBJECT(obj)->as.heap.numiv = newsize;
1094  ROBJECT(obj)->as.heap.iv_index_tbl = iv_index_tbl;
1095  }
1096  }
1097  ROBJECT_IVPTR(obj)[index] = val;
1098  break;
1099  case T_CLASS:
1100  case T_MODULE:
1101  if (!RCLASS_IV_TBL(obj)) RCLASS_IV_TBL(obj) = st_init_numtable();
1102  st_insert(RCLASS_IV_TBL(obj), (st_data_t)id, val);
1103  break;
1104  default:
1105  generic_ivar_set(obj, id, val);
1106  break;
1107  }
1108  return val;
1109 }
1110 
1111 VALUE
1113 {
1114  VALUE val;
1115  struct st_table *iv_index_tbl;
1116  st_data_t index;
1117  switch (TYPE(obj)) {
1118  case T_OBJECT:
1119  iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
1120  if (!iv_index_tbl) break;
1121  if (!st_lookup(iv_index_tbl, (st_data_t)id, &index)) break;
1122  if (ROBJECT_NUMIV(obj) <= (long)index) break;
1123  val = ROBJECT_IVPTR(obj)[index];
1124  if (val != Qundef)
1125  return Qtrue;
1126  break;
1127  case T_CLASS:
1128  case T_MODULE:
1129  if (RCLASS_IV_TBL(obj) && st_lookup(RCLASS_IV_TBL(obj), (st_data_t)id, 0))
1130  return Qtrue;
1131  break;
1132  default:
1133  if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
1134  return generic_ivar_defined(obj, id);
1135  break;
1136  }
1137  return Qfalse;
1138 }
1139 
1142  int (*func)(ID key, VALUE val, st_data_t arg);
1144 };
1145 
1146 static int
1148 {
1149  struct obj_ivar_tag *data = (struct obj_ivar_tag *)arg;
1150  if ((long)index < ROBJECT_NUMIV(data->obj)) {
1151  VALUE val = ROBJECT_IVPTR(data->obj)[(long)index];
1152  if (val != Qundef) {
1153  return (data->func)((ID)key, val, data->arg);
1154  }
1155  }
1156  return ST_CONTINUE;
1157 }
1158 
1159 static void
1161 {
1162  st_table *tbl;
1163  struct obj_ivar_tag data;
1164 
1165  tbl = ROBJECT_IV_INDEX_TBL(obj);
1166  if (!tbl)
1167  return;
1168 
1169  data.obj = obj;
1170  data.func = (int (*)(ID key, VALUE val, st_data_t arg))func;
1171  data.arg = arg;
1172 
1173  st_foreach_safe(tbl, obj_ivar_i, (st_data_t)&data);
1174 }
1175 
1176 void
1178 {
1179  switch (TYPE(obj)) {
1180  case T_OBJECT:
1181  obj_ivar_each(obj, func, arg);
1182  break;
1183  case T_CLASS:
1184  case T_MODULE:
1185  if (RCLASS_IV_TBL(obj)) {
1186  st_foreach_safe(RCLASS_IV_TBL(obj), func, arg);
1187  }
1188  break;
1189  default:
1190  if (!generic_iv_tbl) break;
1191  if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
1192  st_data_t tbl;
1193 
1194  if (st_lookup(generic_iv_tbl, (st_data_t)obj, &tbl)) {
1195  st_foreach_safe((st_table *)tbl, func, arg);
1196  }
1197  }
1198  break;
1199  }
1200 }
1201 
1202 st_index_t
1204 {
1205  st_table *tbl;
1206  switch (TYPE(obj)) {
1207  case T_OBJECT:
1208  if ((tbl = ROBJECT_IV_INDEX_TBL(obj)) != 0) {
1209  st_index_t i, count, num = tbl->num_entries;
1210  const VALUE *const ivptr = ROBJECT_IVPTR(obj);
1211  for (i = count = 0; i < num; ++i) {
1212  if (ivptr[i] != Qundef) {
1213  count++;
1214  }
1215  }
1216  return count;
1217  }
1218  break;
1219  case T_CLASS:
1220  case T_MODULE:
1221  if ((tbl = RCLASS_IV_TBL(obj)) != 0) {
1222  return tbl->num_entries;
1223  }
1224  break;
1225  default:
1226  if (!generic_iv_tbl) break;
1227  if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
1228  st_data_t data;
1229 
1230  if (st_lookup(generic_iv_tbl, (st_data_t)obj, &data) &&
1231  (tbl = (st_table *)data) != 0) {
1232  return tbl->num_entries;
1233  }
1234  }
1235  break;
1236  }
1237  return 0;
1238 }
1239 
1240 static int
1242 {
1243  if (rb_is_instance_id(key)) {
1244  rb_ary_push(ary, ID2SYM(key));
1245  }
1246  return ST_CONTINUE;
1247 }
1248 
1249 /*
1250  * call-seq:
1251  * obj.instance_variables -> array
1252  *
1253  * Returns an array of instance variable names for the receiver. Note
1254  * that simply defining an accessor does not create the corresponding
1255  * instance variable.
1256  *
1257  * class Fred
1258  * attr_accessor :a1
1259  * def initialize
1260  * @iv = 3
1261  * end
1262  * end
1263  * Fred.new.instance_variables #=> [:@iv]
1264  */
1265 
1266 VALUE
1268 {
1269  VALUE ary;
1270 
1271  ary = rb_ary_new();
1272  rb_ivar_foreach(obj, ivar_i, ary);
1273  return ary;
1274 }
1275 
1276 /*
1277  * call-seq:
1278  * obj.remove_instance_variable(symbol) -> obj
1279  *
1280  * Removes the named instance variable from <i>obj</i>, returning that
1281  * variable's value.
1282  *
1283  * class Dummy
1284  * attr_reader :var
1285  * def initialize
1286  * @var = 99
1287  * end
1288  * def remove
1289  * remove_instance_variable(:@var)
1290  * end
1291  * end
1292  * d = Dummy.new
1293  * d.var #=> 99
1294  * d.remove #=> 99
1295  * d.var #=> nil
1296  */
1297 
1298 VALUE
1300 {
1301  VALUE val = Qnil;
1302  const ID id = rb_to_id(name);
1303  st_data_t n, v;
1304  struct st_table *iv_index_tbl;
1305  st_data_t index;
1306 
1307  if (!OBJ_UNTRUSTED(obj) && rb_safe_level() >= 4)
1308  rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
1309  rb_check_frozen(obj);
1310  if (!rb_is_instance_id(id)) {
1311  rb_name_error(id, "`%s' is not allowed as an instance variable name", rb_id2name(id));
1312  }
1313 
1314  switch (TYPE(obj)) {
1315  case T_OBJECT:
1316  iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
1317  if (!iv_index_tbl) break;
1318  if (!st_lookup(iv_index_tbl, (st_data_t)id, &index)) break;
1319  if (ROBJECT_NUMIV(obj) <= (long)index) break;
1320  val = ROBJECT_IVPTR(obj)[index];
1321  if (val != Qundef) {
1322  ROBJECT_IVPTR(obj)[index] = Qundef;
1323  return val;
1324  }
1325  break;
1326  case T_CLASS:
1327  case T_MODULE:
1328  n = id;
1329  if (RCLASS_IV_TBL(obj) && st_delete(RCLASS_IV_TBL(obj), &n, &v)) {
1330  return (VALUE)v;
1331  }
1332  break;
1333  default:
1334  if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
1335  v = val;
1336  if (generic_ivar_remove(obj, (st_data_t)id, &v)) {
1337  return (VALUE)v;
1338  }
1339  }
1340  break;
1341  }
1342  rb_name_error(id, "instance variable %s not defined", rb_id2name(id));
1343  return Qnil; /* not reached */
1344 }
1345 
1346 NORETURN(static void uninitialized_constant(VALUE, ID));
1347 static void
1349 {
1350  if (klass && rb_class_real(klass) != rb_cObject)
1351  rb_name_error(id, "uninitialized constant %s::%s",
1352  rb_class2name(klass),
1353  rb_id2name(id));
1354  else {
1355  rb_name_error(id, "uninitialized constant %s", rb_id2name(id));
1356  }
1357 }
1358 
1359 static VALUE
1361 {
1362  return rb_funcall(klass, rb_intern("const_missing"), 1, ID2SYM(id));
1363 }
1364 
1365 
1366 /*
1367  * call-seq:
1368  * mod.const_missing(sym) -> obj
1369  *
1370  * Invoked when a reference is made to an undefined constant in
1371  * <i>mod</i>. It is passed a symbol for the undefined constant, and
1372  * returns a value to be used for that constant. The
1373  * following code is an example of the same:
1374  *
1375  * def Foo.const_missing(name)
1376  * name # return the constant name as Symbol
1377  * end
1378  *
1379  * Foo::UNDEFINED_CONST #=> :UNDEFINED_CONST: symbol returned
1380  *
1381  * In the next example when a reference is made to an undefined constant,
1382  * it attempts to load a file whose name is the lowercase version of the
1383  * constant (thus class <code>Fred</code> is assumed to be in file
1384  * <code>fred.rb</code>). If found, it returns the loaded class. It
1385  * therefore implements an autoload feature similar to Kernel#autoload and
1386  * Module#autoload.
1387  *
1388  * def Object.const_missing(name)
1389  * @looked_for ||= {}
1390  * str_name = name.to_s
1391  * raise "Class not found: #{name}" if @looked_for[str_name]
1392  * @looked_for[str_name] = 1
1393  * file = str_name.downcase
1394  * require file
1395  * klass = const_get(name)
1396  * return klass if klass
1397  * raise "Class not found: #{name}"
1398  * end
1399  *
1400  */
1401 
1402 VALUE
1404 {
1405  rb_frame_pop(); /* pop frame for "const_missing" */
1406  uninitialized_constant(klass, rb_to_id(name));
1407  return Qnil; /* not reached */
1408 }
1409 
1410 static void
1411 autoload_mark(void *ptr)
1412 {
1413  rb_mark_tbl((st_table *)ptr);
1414 }
1415 
1416 static void
1417 autoload_free(void *ptr)
1418 {
1419  st_free_table((st_table *)ptr);
1420 }
1421 
1422 static size_t
1423 autoload_memsize(const void *ptr)
1424 {
1425  const st_table *tbl = ptr;
1426  return st_memsize(tbl);
1427 }
1428 
1430  "autoload",
1432 };
1433 
1434 #define check_autoload_table(av) \
1435  (struct st_table *)rb_check_typeddata((av), &autoload_data_type)
1436 
1437 void
1438 rb_autoload(VALUE mod, ID id, const char *file)
1439 {
1440  st_data_t av;
1441  VALUE fn;
1442  struct st_table *tbl;
1443 
1444  if (!rb_is_const_id(id)) {
1445  rb_raise(rb_eNameError, "autoload must be constant name: %s", rb_id2name(id));
1446  }
1447  if (!file || !*file) {
1448  rb_raise(rb_eArgError, "empty file name");
1449  }
1450 
1451  if ((tbl = RCLASS_CONST_TBL(mod)) && st_lookup(tbl, (st_data_t)id, &av) && ((rb_const_entry_t*)av)->value != Qundef)
1452  return;
1453 
1454  rb_const_set(mod, id, Qundef);
1455  tbl = RCLASS_IV_TBL(mod);
1456  if (tbl && st_lookup(tbl, (st_data_t)autoload, &av)) {
1457  tbl = check_autoload_table((VALUE)av);
1458  }
1459  else {
1460  if (!tbl) tbl = RCLASS_IV_TBL(mod) = st_init_numtable();
1461  av = (st_data_t)TypedData_Wrap_Struct(0, &autoload_data_type, 0);
1462  st_add_direct(tbl, (st_data_t)autoload, av);
1463  DATA_PTR(av) = tbl = st_init_numtable();
1464  }
1465  fn = rb_str_new2(file);
1466  FL_UNSET(fn, FL_TAINT);
1467  OBJ_FREEZE(fn);
1469 }
1470 
1471 static NODE*
1473 {
1474  st_data_t val, load = 0, n = id;
1475  rb_const_entry_t *ce;
1476 
1477  st_delete(RCLASS_CONST_TBL(mod), &n, &val);
1478  ce = (rb_const_entry_t*)val;
1479  if (ce) xfree(ce);
1480  if (st_lookup(RCLASS_IV_TBL(mod), (st_data_t)autoload, &val)) {
1481  struct st_table *tbl = check_autoload_table((VALUE)val);
1482 
1483  st_delete(tbl, &n, &load);
1484 
1485  if (tbl->num_entries == 0) {
1486  n = autoload;
1487  st_delete(RCLASS_IV_TBL(mod), &n, &val);
1488  }
1489  }
1490 
1491  return (NODE *)load;
1492 }
1493 
1494 static VALUE
1496 {
1497  const char **p = (const char **)arg;
1498  return rb_feature_provided(*p, p);
1499 }
1500 
1501 static VALUE
1503 {
1504  rb_set_safe_level_force((int)safe);
1505  return safe;
1506 }
1507 
1508 static NODE *
1509 autoload_node(VALUE mod, ID id, const char **loadingpath)
1510 {
1511  VALUE file;
1512  struct st_table *tbl;
1513  st_data_t val;
1514  NODE *load;
1515  const char *loading;
1516  int safe;
1517 
1518  if (!st_lookup(RCLASS_IV_TBL(mod), autoload, &val) ||
1519  !(tbl = check_autoload_table((VALUE)val)) || !st_lookup(tbl, (st_data_t)id, &val)) {
1520  return 0;
1521  }
1522  load = (NODE *)val;
1523  file = load->nd_lit;
1524  Check_Type(file, T_STRING);
1525  if (!RSTRING_PTR(file) || !*RSTRING_PTR(file)) {
1526  rb_raise(rb_eArgError, "empty file name");
1527  }
1528  loading = RSTRING_PTR(file);
1529  safe = rb_safe_level();
1531  if (!rb_ensure(autoload_provided, (VALUE)&loading, reset_safe, (VALUE)safe)) {
1532  return load;
1533  }
1534  if (loadingpath && loading) {
1535  *loadingpath = loading;
1536  return load;
1537  }
1538  return 0;
1539 }
1540 
1541 static int
1543 {
1544  struct st_table *tbl = RCLASS_CONST_TBL(mod);
1545  st_data_t val;
1546 
1547  if (!tbl || !st_lookup(tbl, (st_data_t)id, &val) || ((rb_const_entry_t*)val)->value != Qundef) {
1548  return 0;
1549  }
1550  return 1;
1551 }
1552 
1553 VALUE
1555 {
1556  VALUE file;
1557  NODE *load;
1558  const char *loading = 0, *src;
1559 
1560  if (!autoload_node_id(mod, id)) return Qfalse;
1561  load = autoload_node(mod, id, &loading);
1562  if (!load) return Qfalse;
1563  src = rb_sourcefile();
1564  if (src && loading && strcmp(src, loading) == 0) return Qfalse;
1565  file = load->nd_lit;
1566  return rb_require_safe(file, (int)load->nd_nth);
1567 }
1568 
1569 VALUE
1571 {
1572  VALUE file;
1573  NODE *load;
1574  const char *loading = 0;
1575 
1576  while (!autoload_node_id(mod, id)) {
1577  mod = RCLASS_SUPER(mod);
1578  if (!mod) return Qnil;
1579  }
1580  load = autoload_node(mod, id, &loading);
1581  if (!load) return Qnil;
1582  return load && (file = load->nd_lit) ? file : Qnil;
1583 }
1584 
1585 static VALUE
1586 rb_const_get_0(VALUE klass, ID id, int exclude, int recurse, int visibility)
1587 {
1588  VALUE value, tmp;
1589  int mod_retry = 0;
1590 
1591  tmp = klass;
1592  retry:
1593  while (RTEST(tmp)) {
1594  VALUE am = 0;
1595  st_data_t data;
1596  while (RCLASS_CONST_TBL(tmp) && st_lookup(RCLASS_CONST_TBL(tmp), (st_data_t)id, &data)) {
1597  rb_const_entry_t *ce = (rb_const_entry_t *)data;
1598  if (visibility && ce->flag == CONST_PRIVATE) {
1599  rb_name_error(id, "private constant %s::%s referenced", rb_class2name(klass), rb_id2name(id));
1600  }
1601  value = ce->value;
1602  if (value == Qundef) {
1603  if (am == tmp) break;
1604  am = tmp;
1605  rb_autoload_load(tmp, id);
1606  continue;
1607  }
1608  if (exclude && tmp == rb_cObject && klass != rb_cObject) {
1609  rb_warn("toplevel constant %s referenced by %s::%s",
1610  rb_id2name(id), rb_class2name(klass), rb_id2name(id));
1611  }
1612  return value;
1613  }
1614  if (!recurse) break;
1615  tmp = RCLASS_SUPER(tmp);
1616  }
1617  if (!exclude && !mod_retry && BUILTIN_TYPE(klass) == T_MODULE) {
1618  mod_retry = 1;
1619  tmp = rb_cObject;
1620  goto retry;
1621  }
1622 
1623  value = const_missing(klass, id);
1625  return value;
1626 }
1627 
1628 VALUE
1630 {
1631  return rb_const_get_0(klass, id, TRUE, TRUE, FALSE);
1632 }
1633 
1634 VALUE
1636 {
1637  return rb_const_get_0(klass, id, FALSE, TRUE, FALSE);
1638 }
1639 
1640 VALUE
1642 {
1643  return rb_const_get_0(klass, id, TRUE, FALSE, FALSE);
1644 }
1645 
1646 VALUE
1648 {
1649  return rb_const_get_0(klass, id, TRUE, TRUE, TRUE);
1650 }
1651 
1652 VALUE
1654 {
1655  return rb_const_get_0(klass, id, FALSE, TRUE, TRUE);
1656 }
1657 
1658 VALUE
1660 {
1661  return rb_const_get_0(klass, id, TRUE, FALSE, TRUE);
1662 }
1663 
1664 /*
1665  * call-seq:
1666  * remove_const(sym) -> obj
1667  *
1668  * Removes the definition of the given constant, returning that
1669  * constant's previous value. If that constant referred to
1670  * a module, this will not change that module's name and can lead
1671  * to confusion.
1672  */
1673 
1674 VALUE
1676 {
1677  const ID id = rb_to_id(name);
1678 
1679  if (!rb_is_const_id(id)) {
1680  rb_name_error(id, "`%s' is not allowed as a constant name", rb_id2name(id));
1681  }
1682  return rb_const_remove(mod, id);
1683 }
1684 
1685 VALUE
1687 {
1688  VALUE val;
1689  st_data_t v, n = id;
1690 
1691  if (!OBJ_UNTRUSTED(mod) && rb_safe_level() >= 4)
1692  rb_raise(rb_eSecurityError, "Insecure: can't remove constant");
1693  rb_check_frozen(mod);
1694  if (!RCLASS_CONST_TBL(mod) || !st_delete(RCLASS_CONST_TBL(mod), &n, &v)) {
1695  if (rb_const_defined_at(mod, id)) {
1696  rb_name_error(id, "cannot remove %s::%s",
1697  rb_class2name(mod), rb_id2name(id));
1698  }
1699  rb_name_error(id, "constant %s::%s not defined",
1700  rb_class2name(mod), rb_id2name(id));
1701  }
1702 
1704 
1705  val = ((rb_const_entry_t*)v)->value;
1706  if (val == Qundef) {
1707  autoload_delete(mod, id);
1708  val = Qnil;
1709  }
1710  xfree((rb_const_entry_t*)v);
1711  return val;
1712 }
1713 
1714 static int
1716 {
1717  if (rb_is_const_id(key)) {
1718  if (!st_lookup(tbl, (st_data_t)key, 0)) {
1719  st_insert(tbl, (st_data_t)key, (st_data_t)ce);
1720  }
1721  }
1722  return ST_CONTINUE;
1723 }
1724 
1725 void*
1727 {
1728  st_table *tbl = data;
1729  if (!tbl) {
1730  tbl = st_init_numtable();
1731  }
1732  if (RCLASS_CONST_TBL(mod)) {
1734  }
1735  return tbl;
1736 }
1737 
1738 void*
1740 {
1741  VALUE tmp = mod;
1742  for (;;) {
1743  data = rb_mod_const_at(tmp, data);
1744  tmp = RCLASS_SUPER(tmp);
1745  if (!tmp) break;
1746  if (tmp == rb_cObject && mod != rb_cObject) break;
1747  }
1748  return data;
1749 }
1750 
1751 static int
1753 {
1754  ID sym = (ID)key;
1755  rb_const_entry_t *ce = (rb_const_entry_t *)value;
1756  if (ce->flag != CONST_PRIVATE) rb_ary_push(ary, ID2SYM(sym));
1757  return ST_CONTINUE;
1758 }
1759 
1760 VALUE
1761 rb_const_list(void *data)
1762 {
1763  st_table *tbl = data;
1764  VALUE ary;
1765 
1766  if (!tbl) return rb_ary_new2(0);
1767  ary = rb_ary_new2(tbl->num_entries);
1768  st_foreach_safe(tbl, list_i, ary);
1769  st_free_table(tbl);
1770 
1771  return ary;
1772 }
1773 
1774 /*
1775  * call-seq:
1776  * mod.constants(inherit=true) -> array
1777  *
1778  * Returns an array of the names of the constants accessible in
1779  * <i>mod</i>. This includes the names of constants in any included
1780  * modules (example at start of section), unless the <i>all</i>
1781  * parameter is set to <code>false</code>.
1782  *
1783  * IO.constants.include?(:SYNC) #=> true
1784  * IO.constants(false).include?(:SYNC) #=> false
1785  *
1786  * Also see <code>Module::const_defined?</code>.
1787  */
1788 
1789 VALUE
1791 {
1792  VALUE inherit;
1793  st_table *tbl;
1794 
1795  if (argc == 0) {
1796  inherit = Qtrue;
1797  }
1798  else {
1799  rb_scan_args(argc, argv, "01", &inherit);
1800  }
1801  if (RTEST(inherit)) {
1802  tbl = rb_mod_const_of(mod, 0);
1803  }
1804  else {
1805  tbl = rb_mod_const_at(mod, 0);
1806  }
1807  return rb_const_list(tbl);
1808 }
1809 
1810 static int
1811 rb_const_defined_0(VALUE klass, ID id, int exclude, int recurse, int visibility)
1812 {
1813  st_data_t value;
1814  VALUE tmp;
1815  int mod_retry = 0;
1816 
1817  tmp = klass;
1818  retry:
1819  while (tmp) {
1820  if (RCLASS_CONST_TBL(tmp) && st_lookup(RCLASS_CONST_TBL(tmp), (st_data_t)id, &value)) {
1821  rb_const_entry_t *ce = (rb_const_entry_t *)value;
1822  if (visibility && ce->flag == CONST_PRIVATE) {
1823  return (int)Qfalse;
1824  }
1825  if (ce->value == Qundef && !autoload_node(tmp, id, 0))
1826  return (int)Qfalse;
1827  return (int)Qtrue;
1828  }
1829  if (!recurse) break;
1830  tmp = RCLASS_SUPER(tmp);
1831  }
1832  if (!exclude && !mod_retry && BUILTIN_TYPE(klass) == T_MODULE) {
1833  mod_retry = 1;
1834  tmp = rb_cObject;
1835  goto retry;
1836  }
1837  return (int)Qfalse;
1838 }
1839 
1840 int
1842 {
1843  return rb_const_defined_0(klass, id, TRUE, TRUE, FALSE);
1844 }
1845 
1846 int
1848 {
1849  return rb_const_defined_0(klass, id, FALSE, TRUE, FALSE);
1850 }
1851 
1852 int
1854 {
1855  return rb_const_defined_0(klass, id, TRUE, FALSE, FALSE);
1856 }
1857 
1858 int
1860 {
1861  return rb_const_defined_0(klass, id, TRUE, TRUE, TRUE);
1862 }
1863 
1864 int
1866 {
1867  return rb_const_defined_0(klass, id, FALSE, TRUE, TRUE);
1868 }
1869 
1870 int
1872 {
1873  return rb_const_defined_0(klass, id, TRUE, FALSE, TRUE);
1874 }
1875 
1876 void
1877 check_before_mod_set(VALUE klass, ID id, VALUE val, const char *dest)
1878 {
1879  if (!OBJ_UNTRUSTED(klass) && rb_safe_level() >= 4)
1880  rb_raise(rb_eSecurityError, "Insecure: can't set %s", dest);
1881  rb_check_frozen(klass);
1882 }
1883 
1884 void
1885 rb_const_set(VALUE klass, ID id, VALUE val)
1886 {
1887  rb_const_entry_t *ce;
1888  VALUE visibility = CONST_PUBLIC;
1889 
1890  if (NIL_P(klass)) {
1891  rb_raise(rb_eTypeError, "no class/module to define constant %s",
1892  rb_id2name(id));
1893  }
1894 
1895  check_before_mod_set(klass, id, val, "constant");
1896  if (!RCLASS_CONST_TBL(klass)) {
1898  }
1899  else {
1900  st_data_t value;
1901 
1902  if (st_lookup(RCLASS_CONST_TBL(klass), (st_data_t)id, &value)) {
1903  rb_const_entry_t *ce = (rb_const_entry_t*)value;
1904  if (ce->value == Qundef)
1905  autoload_delete(klass, id);
1906  else {
1907  visibility = ce->flag;
1908  rb_warn("already initialized constant %s", rb_id2name(id));
1909  }
1910  }
1911  }
1912 
1914 
1915  ce = ALLOC(rb_const_entry_t);
1916  ce->flag = (rb_const_flag_t)visibility;
1917  ce->value = val;
1918 
1919  st_insert(RCLASS_CONST_TBL(klass), (st_data_t)id, (st_data_t)ce);
1920 }
1921 
1922 void
1923 rb_define_const(VALUE klass, const char *name, VALUE val)
1924 {
1925  ID id = rb_intern(name);
1926 
1927  if (!rb_is_const_id(id)) {
1928  rb_warn("rb_define_const: invalid name `%s' for constant", name);
1929  }
1930  if (klass == rb_cObject) {
1931  rb_secure(4);
1932  }
1933  rb_const_set(klass, id, val);
1934 }
1935 
1936 void
1937 rb_define_global_const(const char *name, VALUE val)
1938 {
1939  rb_define_const(rb_cObject, name, val);
1940 }
1941 
1942 static void
1944 {
1945  int i;
1946  st_data_t v;
1947  ID id;
1948 
1949  if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(mod)) {
1951  "Insecure: can't change constant visibility");
1952  }
1953 
1954  if (argc == 0) {
1955  rb_warning("%s with no argument is just ignored", rb_id2name(rb_frame_callee()));
1956  }
1957 
1958  for (i = 0; i < argc; i++) {
1959  VALUE val = argv[i];
1960  id = rb_to_id(val);
1961  if (RCLASS_CONST_TBL(mod) &&
1962  st_lookup(RCLASS_CONST_TBL(mod), (st_data_t)id, &v)) {
1963  ((rb_const_entry_t*)v)->flag = flag;
1964  }
1965  else {
1966  if ( i > 0 )
1968  rb_name_error(id, "constant %s::%s not defined", rb_class2name(mod), rb_id2name(id));
1969  }
1970  }
1972 }
1973 
1974 /*
1975  * call-seq:
1976  * mod.private_constant(symbol, ...) => mod
1977  *
1978  * Makes a list of existing constants private.
1979  */
1980 
1981 VALUE
1983 {
1984  set_const_visibility(obj, argc, argv, CONST_PRIVATE);
1985  return obj;
1986 }
1987 
1988 /*
1989  * call-seq:
1990  * mod.public_constant(symbol, ...) => mod
1991  *
1992  * Makes a list of existing constants public.
1993  */
1994 
1995 VALUE
1997 {
1998  set_const_visibility(obj, argc, argv, CONST_PUBLIC);
1999  return obj;
2000 }
2001 
2002 static VALUE
2004 {
2005  if (TYPE(c) == T_ICLASS)
2006  return RBASIC(c)->klass;
2007  return c;
2008 }
2009 
2010 #define CVAR_LOOKUP(v,r) do {\
2011  if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),(st_data_t)id,(v))) {\
2012  r;\
2013  }\
2014  if (FL_TEST(klass, FL_SINGLETON) ) {\
2015  VALUE obj = rb_iv_get(klass, "__attached__");\
2016  switch (TYPE(obj)) {\
2017  case T_MODULE:\
2018  case T_CLASS:\
2019  klass = obj;\
2020  break;\
2021  default:\
2022  klass = RCLASS_SUPER(klass);\
2023  break;\
2024  }\
2025  }\
2026  else {\
2027  klass = RCLASS_SUPER(klass);\
2028  }\
2029  while (klass) {\
2030  if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),(st_data_t)id,(v))) {\
2031  r;\
2032  }\
2033  klass = RCLASS_SUPER(klass);\
2034  }\
2035 } while(0)
2036 
2037 void
2038 rb_cvar_set(VALUE klass, ID id, VALUE val)
2039 {
2040  VALUE tmp, front = 0, target = 0;
2041 
2042  tmp = klass;
2043  CVAR_LOOKUP(0, {if (!front) front = klass; target = klass;});
2044  if (target) {
2045  if (front && target != front) {
2046  st_data_t did = id;
2047 
2048  if (RTEST(ruby_verbose)) {
2049  rb_warning("class variable %s of %s is overtaken by %s",
2051  rb_class2name(original_module(target)));
2052  }
2053  if (BUILTIN_TYPE(front) == T_CLASS) {
2054  st_delete(RCLASS_IV_TBL(front),&did,0);
2055  }
2056  }
2057  }
2058  else {
2059  target = tmp;
2060  }
2061 
2062  check_before_mod_set(target, id, val, "class variable");
2063  if (!RCLASS_IV_TBL(target)) {
2064  RCLASS_IV_TBL(target) = st_init_numtable();
2065  }
2066 
2067  st_insert(RCLASS_IV_TBL(target), (st_data_t)id, (st_data_t)val);
2068 }
2069 
2070 VALUE
2072 {
2073  VALUE tmp, front = 0, target = 0;
2074  st_data_t value;
2075 
2076  tmp = klass;
2077  CVAR_LOOKUP(&value, {if (!front) front = klass; target = klass;});
2078  if (!target) {
2079  rb_name_error(id,"uninitialized class variable %s in %s",
2080  rb_id2name(id), rb_class2name(tmp));
2081  }
2082  if (front && target != front) {
2083  st_data_t did = id;
2084 
2085  if (RTEST(ruby_verbose)) {
2086  rb_warning("class variable %s of %s is overtaken by %s",
2088  rb_class2name(original_module(target)));
2089  }
2090  if (BUILTIN_TYPE(front) == T_CLASS) {
2091  st_delete(RCLASS_IV_TBL(front),&did,0);
2092  }
2093  }
2094  return (VALUE)value;
2095 }
2096 
2097 VALUE
2099 {
2100  if (!klass) return Qfalse;
2101  CVAR_LOOKUP(0,return Qtrue);
2102  return Qfalse;
2103 }
2104 
2105 void
2106 rb_cv_set(VALUE klass, const char *name, VALUE val)
2107 {
2108  ID id = rb_intern(name);
2109  if (!rb_is_class_id(id)) {
2110  rb_name_error(id, "wrong class variable name %s", name);
2111  }
2112  rb_cvar_set(klass, id, val);
2113 }
2114 
2115 VALUE
2116 rb_cv_get(VALUE klass, const char *name)
2117 {
2118  ID id = rb_intern(name);
2119  if (!rb_is_class_id(id)) {
2120  rb_name_error(id, "wrong class variable name %s", name);
2121  }
2122  return rb_cvar_get(klass, id);
2123 }
2124 
2125 void
2126 rb_define_class_variable(VALUE klass, const char *name, VALUE val)
2127 {
2128  ID id = rb_intern(name);
2129 
2130  if (!rb_is_class_id(id)) {
2131  rb_name_error(id, "wrong class variable name %s", name);
2132  }
2133  rb_cvar_set(klass, id, val);
2134 }
2135 
2136 static int
2137 cv_i(ID key, VALUE value, VALUE ary)
2138 {
2139  if (rb_is_class_id(key)) {
2140  VALUE kval = ID2SYM(key);
2141  if (!rb_ary_includes(ary, kval)) {
2142  rb_ary_push(ary, kval);
2143  }
2144  }
2145  return ST_CONTINUE;
2146 }
2147 
2148 /*
2149  * call-seq:
2150  * mod.class_variables -> array
2151  *
2152  * Returns an array of the names of class variables in <i>mod</i>.
2153  *
2154  * class One
2155  * @@var1 = 1
2156  * end
2157  * class Two < One
2158  * @@var2 = 2
2159  * end
2160  * One.class_variables #=> [:@@var1]
2161  * Two.class_variables #=> [:@@var2]
2162  */
2163 
2164 VALUE
2166 {
2167  VALUE ary = rb_ary_new();
2168 
2169  if (RCLASS_IV_TBL(obj)) {
2170  st_foreach_safe(RCLASS_IV_TBL(obj), cv_i, ary);
2171  }
2172  return ary;
2173 }
2174 
2175 /*
2176  * call-seq:
2177  * remove_class_variable(sym) -> obj
2178  *
2179  * Removes the definition of the <i>sym</i>, returning that
2180  * constant's value.
2181  *
2182  * class Dummy
2183  * @@var = 99
2184  * puts @@var
2185  * remove_class_variable(:@@var)
2186  * p(defined? @@var)
2187  * end
2188  *
2189  * <em>produces:</em>
2190  *
2191  * 99
2192  * nil
2193  */
2194 
2195 VALUE
2197 {
2198  const ID id = rb_to_id(name);
2199  st_data_t val, n = id;
2200 
2201  if (!rb_is_class_id(id)) {
2202  rb_name_error(id, "wrong class variable name %s", rb_id2name(id));
2203  }
2204  if (!OBJ_UNTRUSTED(mod) && rb_safe_level() >= 4)
2205  rb_raise(rb_eSecurityError, "Insecure: can't remove class variable");
2206  rb_check_frozen(mod);
2207  if (RCLASS_IV_TBL(mod) && st_delete(RCLASS_IV_TBL(mod), &n, &val)) {
2208  return (VALUE)val;
2209  }
2210  if (rb_cvar_defined(mod, id)) {
2211  rb_name_error(id, "cannot remove %s for %s",
2212  rb_id2name(id), rb_class2name(mod));
2213  }
2214  rb_name_error(id, "class variable %s not defined for %s",
2215  rb_id2name(id), rb_class2name(mod));
2216  return Qnil; /* not reached */
2217 }
2218 
2219 VALUE
2220 rb_iv_get(VALUE obj, const char *name)
2221 {
2222  ID id = rb_intern(name);
2223 
2224  return rb_ivar_get(obj, id);
2225 }
2226 
2227 VALUE
2228 rb_iv_set(VALUE obj, const char *name, VALUE val)
2229 {
2230  ID id = rb_intern(name);
2231 
2232  return rb_ivar_set(obj, id, val);
2233 }
2234