Ruby 2.1.5p273(2014-11-13revision48405)

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