Ruby 2.0.0p247(2013-06-27revision41674)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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