Ruby 2.0.0p353(2013-11-22revision43784)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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