1 /**********************************************************************
6 created at: Tue Apr 19 23:55:15 JST 1994
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
12 **********************************************************************/
14 #include "ruby/ruby.h"
15 #include "ruby/node.h"
17 #include "ruby/util.h"
19 void rb_vm_change_state(void);
20 st_table
*rb_global_tbl
;
21 st_table
*rb_class_tbl
;
22 static ID autoload
, classpath
, tmp_classpath
;
27 rb_global_tbl
= st_init_numtable();
28 rb_class_tbl
= st_init_numtable();
29 CONST_ID(autoload
, "__autoload__");
30 CONST_ID(classpath
, "__classpath__");
31 CONST_ID(tmp_classpath
, "__tmp_classpath__");
39 struct fc_result
*prev
;
43 fc_path(struct fc_result
*fc
, ID name
)
47 path
= rb_str_dup(rb_id2str(name
));
49 if (fc
->track
== rb_cObject
) break;
50 if (RCLASS_IV_TBL(fc
->track
) &&
51 st_lookup(RCLASS_IV_TBL(fc
->track
), classpath
, &tmp
)) {
52 tmp
= rb_str_dup(tmp
);
53 rb_str_cat2(tmp
, "::");
54 rb_str_append(tmp
, path
);
58 tmp
= rb_str_dup(rb_id2str(fc
->name
));
59 rb_str_cat2(tmp
, "::");
60 rb_str_append(tmp
, path
);
69 fc_i(ID key
, VALUE value
, struct fc_result
*res
)
71 if (!rb_is_const_id(key
)) return ST_CONTINUE
;
73 if (value
== res
->klass
) {
74 res
->path
= fc_path(res
, key
);
77 switch (TYPE(value
)) {
80 if (!RCLASS_IV_TBL(value
)) return ST_CONTINUE
;
83 struct fc_result
*list
;
87 if (list
->track
== value
) return ST_CONTINUE
;
93 arg
.klass
= res
->klass
;
96 st_foreach(RCLASS_IV_TBL(value
), fc_i
, (st_data_t
)&arg
);
111 find_class_path(VALUE klass
)
113 struct fc_result arg
;
118 arg
.track
= rb_cObject
;
120 if (RCLASS_IV_TBL(rb_cObject
)) {
121 st_foreach_safe(RCLASS_IV_TBL(rb_cObject
), fc_i
, (st_data_t
)&arg
);
124 st_foreach_safe(rb_class_tbl
, fc_i
, (st_data_t
)&arg
);
127 if (!RCLASS_IV_TBL(klass
)) {
128 RCLASS_IV_TBL(klass
) = st_init_numtable();
130 st_insert(RCLASS_IV_TBL(klass
), classpath
, arg
.path
);
131 st_delete(RCLASS_IV_TBL(klass
), &tmp_classpath
, 0);
138 classname(VALUE klass
)
142 if (!klass
) klass
= rb_cObject
;
143 if (RCLASS_IV_TBL(klass
)) {
144 if (!st_lookup(RCLASS_IV_TBL(klass
), classpath
, &path
)) {
147 CONST_ID(classid
, "__classid__");
149 if (!st_lookup(RCLASS_IV_TBL(klass
), classid
, &path
)) {
150 return find_class_path(klass
);
152 path
= rb_str_dup(rb_id2str(SYM2ID(path
)));
154 st_insert(RCLASS_IV_TBL(klass
), classpath
, path
);
155 st_delete(RCLASS_IV_TBL(klass
), (st_data_t
*)&classid
, 0);
157 if (TYPE(path
) != T_STRING
) {
158 rb_bug("class path is not set properly");
162 return find_class_path(klass
);
169 * Returns the name of the module <i>mod</i>. Returns nil for anonymous modules.
173 rb_mod_name(VALUE mod
)
175 VALUE path
= classname(mod
);
177 if (!NIL_P(path
)) return rb_str_dup(path
);
182 rb_class_path(VALUE klass
)
184 VALUE path
= classname(klass
);
186 if (!NIL_P(path
)) return path
;
187 if (RCLASS_IV_TBL(klass
) && st_lookup(RCLASS_IV_TBL(klass
),
188 tmp_classpath
, &path
)) {
192 const char *s
= "Class";
194 if (TYPE(klass
) == T_MODULE
) {
195 if (rb_obj_class(klass
) == rb_cModule
) {
199 s
= rb_class2name(RBASIC(klass
)->klass
);
202 path
= rb_sprintf("#<%s:%p>", s
, (void*)klass
);
204 rb_ivar_set(klass
, tmp_classpath
, path
);
211 rb_set_class_path(VALUE klass
, VALUE under
, const char *name
)
215 if (under
== rb_cObject
) {
216 str
= rb_str_new2(name
);
219 str
= rb_str_dup(rb_class_path(under
));
220 rb_str_cat2(str
, "::");
221 rb_str_cat2(str
, name
);
224 rb_ivar_set(klass
, classpath
, str
);
228 rb_path2class(const char *path
)
230 const char *pbeg
, *p
;
232 VALUE c
= rb_cObject
;
234 if (path
[0] == '#') {
235 rb_raise(rb_eArgError
, "can't retrieve anonymous class %s", path
);
239 while (*p
&& *p
!= ':') p
++;
240 id
= rb_intern2(pbeg
, p
-pbeg
);
242 if (p
[1] != ':') goto undefined_class
;
246 if (!rb_const_defined(c
, id
)) {
248 rb_raise(rb_eArgError
, "undefined class/module %.*s", (int)(p
-path
), path
);
250 c
= rb_const_get_at(c
, id
);
256 rb_raise(rb_eTypeError
, "%s does not refer class/module", path
);
264 rb_name_class(VALUE klass
, ID id
)
266 rb_iv_set(klass
, "__classid__", ID2SYM(id
));
270 rb_class_name(VALUE klass
)
272 return rb_class_path(rb_class_real(klass
));
276 rb_class2name(VALUE klass
)
278 return RSTRING_PTR(rb_class_name(klass
));
282 rb_obj_classname(VALUE obj
)
284 return rb_class2name(CLASS_OF(obj
));
291 struct trace_var
*next
;
294 struct global_variable
{
301 struct trace_var
*trace
;
304 struct global_entry
{
305 struct global_variable
*var
;
309 static VALUE
undef_getter(ID id
);
310 static void undef_setter(VALUE val
, ID id
, void *data
, struct global_variable
*var
);
311 static void undef_marker(void);
313 static VALUE
val_getter(ID id
, VALUE val
);
314 static void val_setter(VALUE val
, ID id
, void *data
, struct global_variable
*var
);
315 static void val_marker(VALUE data
);
317 static VALUE
var_getter(ID id
, VALUE
*var
);
318 static void var_setter(VALUE val
, ID id
, VALUE
*var
);
319 static void var_marker(VALUE
*var
);
322 rb_global_entry(ID id
)
324 struct global_entry
*entry
;
327 if (!st_lookup(rb_global_tbl
, id
, &data
)) {
328 struct global_variable
*var
;
329 entry
= ALLOC(struct global_entry
);
330 var
= ALLOC(struct global_variable
);
335 var
->getter
= undef_getter
;
336 var
->setter
= undef_setter
;
337 var
->marker
= undef_marker
;
339 var
->block_trace
= 0;
341 st_add_direct(rb_global_tbl
, id
, (st_data_t
)entry
);
344 entry
= (struct global_entry
*)data
;
352 rb_warning("global variable `%s' not initialized", rb_id2name(id
));
358 undef_setter(VALUE val
, ID id
, void *data
, struct global_variable
*var
)
360 var
->getter
= val_getter
;
361 var
->setter
= val_setter
;
362 var
->marker
= val_marker
;
364 var
->data
= (void*)val
;
373 val_getter(ID id
, VALUE val
)
379 val_setter(VALUE val
, ID id
, void *data
, struct global_variable
*var
)
381 var
->data
= (void*)val
;
385 val_marker(VALUE data
)
387 if (data
) rb_gc_mark_maybe(data
);
391 var_getter(ID id
, VALUE
*var
)
393 if (!var
) return Qnil
;
398 var_setter(VALUE val
, ID id
, VALUE
*var
)
404 var_marker(VALUE
*var
)
406 if (var
) rb_gc_mark_maybe(*var
);
410 readonly_setter(VALUE val
, ID id
, void *var
)
412 rb_name_error(id
, "%s is a read-only variable", rb_id2name(id
));
416 mark_global_entry(ID key
, struct global_entry
*entry
)
418 struct trace_var
*trace
;
419 struct global_variable
*var
= entry
->var
;
421 (*var
->marker
)(var
->data
);
424 if (trace
->data
) rb_gc_mark_maybe(trace
->data
);
431 rb_gc_mark_global_tbl(void)
434 st_foreach_safe(rb_global_tbl
, mark_global_entry
, 0);
438 global_id(const char *name
)
442 if (name
[0] == '$') id
= rb_intern(name
);
444 char *buf
= ALLOCA_N(char, strlen(name
)+2);
453 rb_define_hooked_variable(
456 VALUE (*getter
)(ANYARGS
),
457 void (*setter
)(ANYARGS
))
459 struct global_variable
*gvar
;
466 id
= global_id(name
);
467 gvar
= rb_global_entry(id
)->var
;
468 gvar
->data
= (void*)var
;
469 gvar
->getter
= getter
?getter
:var_getter
;
470 gvar
->setter
= setter
?setter
:var_setter
;
471 gvar
->marker
= var_marker
;
477 rb_define_variable(const char *name
, VALUE
*var
)
479 rb_define_hooked_variable(name
, var
, 0, 0);
483 rb_define_readonly_variable(const char *name
, VALUE
*var
)
485 rb_define_hooked_variable(name
, var
, 0, readonly_setter
);
489 rb_define_virtual_variable(
491 VALUE (*getter
)(ANYARGS
),
492 void (*setter
)(ANYARGS
))
494 if (!getter
) getter
= val_getter
;
495 if (!setter
) setter
= readonly_setter
;
496 rb_define_hooked_variable(name
, 0, getter
, setter
);
500 rb_trace_eval(VALUE cmd
, VALUE val
)
502 rb_eval_cmd(cmd
, rb_ary_new3(1, val
), 0);
507 * trace_var(symbol, cmd ) => nil
508 * trace_var(symbol) {|val| block } => nil
510 * Controls tracing of assignments to global variables. The parameter
511 * +symbol_ identifies the variable (as either a string name or a
512 * symbol identifier). _cmd_ (which may be a string or a
513 * +Proc+ object) or block is executed whenever the variable
514 * is assigned. The block or +Proc+ object receives the
515 * variable's new value as a parameter. Also see
516 * <code>Kernel::untrace_var</code>.
518 * trace_var :$_, proc {|v| puts "$_ is now '#{v}'" }
529 rb_f_trace_var(int argc
, VALUE
*argv
)
532 struct global_entry
*entry
;
533 struct trace_var
*trace
;
536 if (rb_scan_args(argc
, argv
, "11", &var
, &cmd
) == 1) {
537 cmd
= rb_block_proc();
540 return rb_f_untrace_var(argc
, argv
);
542 entry
= rb_global_entry(rb_to_id(var
));
543 if (OBJ_TAINTED(cmd
)) {
544 rb_raise(rb_eSecurityError
, "Insecure: tainted variable trace");
546 trace
= ALLOC(struct trace_var
);
547 trace
->next
= entry
->var
->trace
;
548 trace
->func
= rb_trace_eval
;
551 entry
->var
->trace
= trace
;
557 remove_trace(struct global_variable
*var
)
559 struct trace_var
*trace
= var
->trace
;
561 struct trace_var
*next
;
565 while (trace
->next
) {
568 trace
->next
= next
->next
;
580 * untrace_var(symbol [, cmd] ) => array or nil
582 * Removes tracing for the specified command on the given global
583 * variable and returns +nil+. If no command is specified,
584 * removes all tracing for that variable and returns an array
585 * containing the commands actually removed.
589 rb_f_untrace_var(int argc
, VALUE
*argv
)
593 struct global_entry
*entry
;
594 struct trace_var
*trace
;
598 rb_scan_args(argc
, argv
, "11", &var
, &cmd
);
600 if (!st_lookup(rb_global_tbl
, id
, &data
)) {
601 rb_name_error(id
, "undefined global variable %s", rb_id2name(id
));
604 trace
= (entry
= (struct global_entry
*)data
)->var
->trace
;
606 VALUE ary
= rb_ary_new();
609 struct trace_var
*next
= trace
->next
;
610 rb_ary_push(ary
, (VALUE
)trace
->data
);
615 if (!entry
->var
->block_trace
) remove_trace(entry
->var
);
620 if (trace
->data
== cmd
) {
622 if (!entry
->var
->block_trace
) remove_trace(entry
->var
);
623 return rb_ary_new3(1, cmd
);
632 rb_gvar_get(struct global_entry
*entry
)
634 struct global_variable
*var
= entry
->var
;
635 return (*var
->getter
)(entry
->id
, var
->data
, var
);
639 struct trace_var
*trace
;
644 trace_ev(struct trace_data
*data
)
646 struct trace_var
*trace
= data
->trace
;
649 (*trace
->func
)(trace
->data
, data
->val
);
652 return Qnil
; /* not reached */
656 trace_en(struct global_variable
*var
)
658 var
->block_trace
= 0;
660 return Qnil
; /* not reached */
664 rb_gvar_set(struct global_entry
*entry
, VALUE val
)
666 struct trace_data trace
;
667 struct global_variable
*var
= entry
->var
;
669 if (rb_safe_level() >= 4)
670 rb_raise(rb_eSecurityError
, "Insecure: can't change global variable value");
671 (*var
->setter
)(val
, entry
->id
, var
->data
, var
);
673 if (var
->trace
&& !var
->block_trace
) {
674 var
->block_trace
= 1;
675 trace
.trace
= var
->trace
;
677 rb_ensure(trace_ev
, (VALUE
)&trace
, trace_en
, (VALUE
)var
);
683 rb_gv_set(const char *name
, VALUE val
)
685 struct global_entry
*entry
;
687 entry
= rb_global_entry(global_id(name
));
688 return rb_gvar_set(entry
, val
);
692 rb_gv_get(const char *name
)
694 struct global_entry
*entry
;
696 entry
= rb_global_entry(global_id(name
));
697 return rb_gvar_get(entry
);
701 rb_gvar_defined(struct global_entry
*entry
)
703 if (entry
->var
->getter
== undef_getter
) return Qfalse
;
708 gvar_i(ID key
, struct global_entry
*entry
, VALUE ary
)
710 rb_ary_push(ary
, ID2SYM(key
));
716 * global_variables => array
718 * Returns an array of the names of global variables.
720 * global_variables.grep /std/ #=> [:$stdin, :$stdout, :$stderr]
724 rb_f_global_variables(void)
726 VALUE ary
= rb_ary_new();
728 const char *s
= "123456789";
730 st_foreach_safe(rb_global_tbl
, gvar_i
, ary
);
732 sprintf(buf
, "$%c", *s
++);
733 rb_ary_push(ary
, ID2SYM(rb_intern(buf
)));
739 rb_alias_variable(ID name1
, ID name2
)
741 struct global_entry
*entry1
, *entry2
;
744 if (rb_safe_level() >= 4)
745 rb_raise(rb_eSecurityError
, "Insecure: can't alias global variable");
747 entry2
= rb_global_entry(name2
);
748 if (!st_lookup(rb_global_tbl
, name1
, &data1
)) {
749 entry1
= ALLOC(struct global_entry
);
751 st_add_direct(rb_global_tbl
, name1
, (st_data_t
)entry1
);
753 else if ((entry1
= (struct global_entry
*)data1
)->var
!= entry2
->var
) {
754 struct global_variable
*var
= entry1
->var
;
755 if (var
->block_trace
) {
756 rb_raise(rb_eRuntimeError
, "can't alias in tracer");
759 if (var
->counter
== 0) {
760 struct trace_var
*trace
= var
->trace
;
762 struct trace_var
*next
= trace
->next
;
772 entry2
->var
->counter
++;
773 entry1
->var
= entry2
->var
;
776 static int special_generic_ivar
= 0;
777 static st_table
*generic_iv_tbl
;
780 rb_generic_ivar_table(VALUE obj
)
784 if (!FL_TEST(obj
, FL_EXIVAR
)) return 0;
785 if (!generic_iv_tbl
) return 0;
786 if (!st_lookup(generic_iv_tbl
, obj
, &tbl
)) return 0;
787 return (st_table
*)tbl
;
791 generic_ivar_get(VALUE obj
, ID id
, int warn
)
796 if (generic_iv_tbl
) {
797 if (st_lookup(generic_iv_tbl
, obj
, &tbl
)) {
798 if (st_lookup((st_table
*)tbl
, id
, &val
)) {
804 rb_warning("instance variable %s not initialized", rb_id2name(id
));
810 generic_ivar_set(VALUE obj
, ID id
, VALUE val
)
815 if (rb_special_const_p(obj
)) {
816 if (rb_obj_frozen_p(obj
)) rb_error_frozen("object");
817 special_generic_ivar
= 1;
819 if (!generic_iv_tbl
) {
820 generic_iv_tbl
= st_init_numtable();
822 if (!st_lookup(generic_iv_tbl
, obj
, &data
)) {
823 FL_SET(obj
, FL_EXIVAR
);
824 tbl
= st_init_numtable();
825 st_add_direct(generic_iv_tbl
, obj
, (st_data_t
)tbl
);
826 st_add_direct(tbl
, id
, val
);
829 st_insert((st_table
*)data
, id
, val
);
833 generic_ivar_defined(VALUE obj
, ID id
)
839 if (!generic_iv_tbl
) return Qfalse
;
840 if (!st_lookup(generic_iv_tbl
, obj
, &data
)) return Qfalse
;
841 tbl
= (st_table
*)data
;
842 if (st_lookup(tbl
, id
, &val
)) {
849 generic_ivar_remove(VALUE obj
, ID id
, VALUE
*valp
)
855 if (!generic_iv_tbl
) return 0;
856 if (!st_lookup(generic_iv_tbl
, obj
, &data
)) return 0;
857 tbl
= (st_table
*)data
;
858 status
= st_delete(tbl
, &id
, valp
);
859 if (tbl
->num_entries
== 0) {
860 st_delete(generic_iv_tbl
, &obj
, &data
);
861 st_free_table((st_table
*)data
);
867 rb_mark_generic_ivar(VALUE obj
)
871 if (!generic_iv_tbl
) return;
872 if (st_lookup(generic_iv_tbl
, obj
, &tbl
)) {
873 rb_mark_tbl((st_table
*)tbl
);
878 givar_mark_i(ID key
, VALUE value
)
885 givar_i(VALUE obj
, st_table
*tbl
)
887 if (rb_special_const_p(obj
)) {
888 st_foreach_safe(tbl
, givar_mark_i
, 0);
894 rb_mark_generic_ivar_tbl(void)
896 if (!generic_iv_tbl
) return;
897 if (special_generic_ivar
== 0) return;
898 st_foreach_safe(generic_iv_tbl
, givar_i
, 0);
902 rb_free_generic_ivar(VALUE obj
)
906 if (!generic_iv_tbl
) return;
907 if (st_delete(generic_iv_tbl
, &obj
, &tbl
))
908 st_free_table((st_table
*)tbl
);
912 rb_copy_generic_ivar(VALUE clone
, VALUE obj
)
916 if (!generic_iv_tbl
) return;
917 if (!FL_TEST(obj
, FL_EXIVAR
)) {
919 if (FL_TEST(clone
, FL_EXIVAR
)) {
920 rb_free_generic_ivar(clone
);
921 FL_UNSET(clone
, FL_EXIVAR
);
925 if (st_lookup(generic_iv_tbl
, obj
, &data
)) {
926 st_table
*tbl
= (st_table
*)data
;
928 if (tbl
->num_entries
== 0)
931 if (st_lookup(generic_iv_tbl
, clone
, &data
)) {
932 st_free_table((st_table
*)data
);
933 st_insert(generic_iv_tbl
, clone
, (st_data_t
)st_copy(tbl
));
936 st_add_direct(generic_iv_tbl
, clone
, (st_data_t
)st_copy(tbl
));
937 FL_SET(clone
, FL_EXIVAR
);
943 ivar_get(VALUE obj
, ID id
, int warn
)
946 struct st_table
*iv_index_tbl
;
952 len
= ROBJECT_NUMIV(obj
);
953 ptr
= ROBJECT_IVPTR(obj
);
954 iv_index_tbl
= ROBJECT_IV_INDEX_TBL(obj
);
955 if (!iv_index_tbl
) break;
956 if (!st_lookup(iv_index_tbl
, id
, &index
)) break;
957 if (len
<= index
) break;
964 if (RCLASS_IV_TBL(obj
) && st_lookup(RCLASS_IV_TBL(obj
), id
, &val
))
968 if (FL_TEST(obj
, FL_EXIVAR
) || rb_special_const_p(obj
))
969 return generic_ivar_get(obj
, id
, warn
);
973 rb_warning("instance variable %s not initialized", rb_id2name(id
));
979 rb_ivar_get(VALUE obj
, ID id
)
981 return ivar_get(obj
, id
, Qtrue
);
985 rb_attr_get(VALUE obj
, ID id
)
987 return ivar_get(obj
, id
, Qfalse
);
991 rb_ivar_set(VALUE obj
, ID id
, VALUE val
)
993 struct st_table
*iv_index_tbl
;
998 if (!OBJ_UNTRUSTED(obj
) && rb_safe_level() >= 4)
999 rb_raise(rb_eSecurityError
, "Insecure: can't modify instance variable");
1000 if (OBJ_FROZEN(obj
)) rb_error_frozen("object");
1001 switch (TYPE(obj
)) {
1003 iv_index_tbl
= ROBJECT_IV_INDEX_TBL(obj
);
1004 if (!iv_index_tbl
) {
1005 VALUE klass
= rb_obj_class(obj
);
1006 iv_index_tbl
= RCLASS_IV_INDEX_TBL(klass
);
1007 if (!iv_index_tbl
) {
1008 iv_index_tbl
= RCLASS_IV_INDEX_TBL(klass
) = st_init_numtable();
1012 if (!st_lookup(iv_index_tbl
, id
, &index
)) {
1013 index
= iv_index_tbl
->num_entries
;
1014 st_add_direct(iv_index_tbl
, id
, index
);
1017 len
= ROBJECT_NUMIV(obj
);
1019 VALUE
*ptr
= ROBJECT_IVPTR(obj
);
1020 if (index
< ROBJECT_EMBED_LEN_MAX
) {
1021 RBASIC(obj
)->flags
|= ROBJECT_EMBED
;
1022 ptr
= ROBJECT(obj
)->as
.ary
;
1023 for (i
= 0; i
< ROBJECT_EMBED_LEN_MAX
; i
++) {
1029 long newsize
= (index
+1) + (index
+1)/4; /* (index+1)*1.25 */
1030 if (!ivar_extended
&&
1031 iv_index_tbl
->num_entries
< newsize
) {
1032 newsize
= iv_index_tbl
->num_entries
;
1034 if (RBASIC(obj
)->flags
& ROBJECT_EMBED
) {
1035 newptr
= ALLOC_N(VALUE
, newsize
);
1036 MEMCPY(newptr
, ptr
, VALUE
, len
);
1037 RBASIC(obj
)->flags
&= ~ROBJECT_EMBED
;
1038 ROBJECT(obj
)->as
.heap
.ivptr
= newptr
;
1041 REALLOC_N(ROBJECT(obj
)->as
.heap
.ivptr
, VALUE
, newsize
);
1042 newptr
= ROBJECT(obj
)->as
.heap
.ivptr
;
1044 for (; len
< newsize
; len
++)
1045 newptr
[len
] = Qundef
;
1046 ROBJECT(obj
)->as
.heap
.numiv
= newsize
;
1047 ROBJECT(obj
)->as
.heap
.iv_index_tbl
= iv_index_tbl
;
1050 ROBJECT_IVPTR(obj
)[index
] = val
;
1054 if (!RCLASS_IV_TBL(obj
)) RCLASS_IV_TBL(obj
) = st_init_numtable();
1055 st_insert(RCLASS_IV_TBL(obj
), id
, val
);
1058 generic_ivar_set(obj
, id
, val
);
1065 rb_ivar_defined(VALUE obj
, ID id
)
1068 struct st_table
*iv_index_tbl
;
1070 switch (TYPE(obj
)) {
1072 iv_index_tbl
= ROBJECT_IV_INDEX_TBL(obj
);
1073 if (!iv_index_tbl
) break;
1074 if (!st_lookup(iv_index_tbl
, id
, &index
)) break;
1075 if (ROBJECT_NUMIV(obj
) <= index
) break;
1076 val
= ROBJECT_IVPTR(obj
)[index
];
1082 if (RCLASS_IV_TBL(obj
) && st_lookup(RCLASS_IV_TBL(obj
), id
, 0))
1086 if (FL_TEST(obj
, FL_EXIVAR
) || rb_special_const_p(obj
))
1087 return generic_ivar_defined(obj
, id
);
1093 struct obj_ivar_tag
{
1095 int (*func
)(ID key
, VALUE val
, st_data_t arg
);
1100 obj_ivar_i(ID key
, VALUE index
, struct obj_ivar_tag
*data
)
1102 if (index
< ROBJECT_NUMIV(data
->obj
)) {
1103 VALUE val
= ROBJECT_IVPTR(data
->obj
)[index
];
1104 if (val
!= Qundef
) {
1105 return (data
->func
)(key
, val
, data
->arg
);
1112 obj_ivar_each(VALUE obj
, int (*func
)(ANYARGS
), st_data_t arg
)
1115 struct obj_ivar_tag data
;
1117 tbl
= ROBJECT_IV_INDEX_TBL(obj
);
1122 data
.func
= (int (*)(ID key
, VALUE val
, st_data_t arg
))func
;
1125 st_foreach_safe(tbl
, obj_ivar_i
, (st_data_t
)&data
);
1128 void rb_ivar_foreach(VALUE obj
, int (*func
)(ANYARGS
), st_data_t arg
)
1130 switch (TYPE(obj
)) {
1132 obj_ivar_each(obj
, func
, arg
);
1136 if (RCLASS_IV_TBL(obj
)) {
1137 st_foreach_safe(RCLASS_IV_TBL(obj
), func
, arg
);
1141 if (!generic_iv_tbl
) break;
1142 if (FL_TEST(obj
, FL_EXIVAR
) || rb_special_const_p(obj
)) {
1145 if (st_lookup(generic_iv_tbl
, obj
, &tbl
)) {
1146 st_foreach_safe((st_table
*)tbl
, func
, arg
);
1154 ivar_i(ID key
, VALUE val
, VALUE ary
)
1156 if (rb_is_instance_id(key
)) {
1157 rb_ary_push(ary
, ID2SYM(key
));
1164 * obj.instance_variables => array
1166 * Returns an array of instance variable names for the receiver. Note
1167 * that simply defining an accessor does not create the corresponding
1168 * instance variable.
1176 * Fred.new.instance_variables #=> [:@iv]
1180 rb_obj_instance_variables(VALUE obj
)
1185 rb_ivar_foreach(obj
, ivar_i
, ary
);
1191 * obj.remove_instance_variable(symbol) => obj
1193 * Removes the named instance variable from <i>obj</i>, returning that
1202 * remove_instance_variable(:@var)
1212 rb_obj_remove_instance_variable(VALUE obj
, VALUE name
)
1215 ID id
= rb_to_id(name
);
1216 struct st_table
*iv_index_tbl
;
1219 if (!OBJ_UNTRUSTED(obj
) && rb_safe_level() >= 4)
1220 rb_raise(rb_eSecurityError
, "Insecure: can't modify instance variable");
1221 if (OBJ_FROZEN(obj
)) rb_error_frozen("object");
1222 if (!rb_is_instance_id(id
)) {
1223 rb_name_error(id
, "`%s' is not allowed as an instance variable name", rb_id2name(id
));
1226 switch (TYPE(obj
)) {
1228 iv_index_tbl
= ROBJECT_IV_INDEX_TBL(obj
);
1229 if (!iv_index_tbl
) break;
1230 if (!st_lookup(iv_index_tbl
, id
, &index
)) break;
1231 if (ROBJECT_NUMIV(obj
) <= index
) break;
1232 val
= ROBJECT_IVPTR(obj
)[index
];
1233 if (val
!= Qundef
) {
1234 ROBJECT_IVPTR(obj
)[index
] = Qundef
;
1240 if (RCLASS_IV_TBL(obj
) && st_delete(RCLASS_IV_TBL(obj
), (st_data_t
*)&id
, &val
)) {
1245 if (FL_TEST(obj
, FL_EXIVAR
) || rb_special_const_p(obj
)) {
1246 if (generic_ivar_remove(obj
, id
, &val
)) {
1252 rb_name_error(id
, "instance variable %s not defined", rb_id2name(id
));
1253 return Qnil
; /* not reached */
1256 NORETURN(static void uninitialized_constant(VALUE
, ID
));
1258 uninitialized_constant(VALUE klass
, ID id
)
1260 if (klass
&& klass
!= rb_cObject
)
1261 rb_name_error(id
, "uninitialized constant %s::%s",
1262 rb_class2name(klass
),
1265 rb_name_error(id
, "uninitialized constant %s", rb_id2name(id
));
1270 const_missing(VALUE klass
, ID id
)
1272 return rb_funcall(klass
, rb_intern("const_missing"), 1, ID2SYM(id
));
1278 * mod.const_missing(sym) => obj
1280 * Invoked when a reference is made to an undefined constant in
1281 * <i>mod</i>. It is passed a symbol for the undefined constant, and
1282 * returns a value to be used for that constant. The
1283 * following code is a (very bad) example: if reference is made to
1284 * an undefined constant, it attempts to load a file whose name is
1285 * the lowercase version of the constant (thus class <code>Fred</code> is
1286 * assumed to be in file <code>fred.rb</code>). If found, it returns the
1287 * value of the loaded class. It therefore implements a perverse
1288 * kind of autoload facility.
1290 * def Object.const_missing(name)
1291 * @looked_for ||= {}
1292 * str_name = name.to_s
1293 * raise "Class not found: #{name}" if @looked_for[str_name]
1294 * @looked_for[str_name] = 1
1295 * file = str_name.downcase
1297 * klass = const_get(name)
1298 * return klass if klass
1299 * raise "Class not found: #{name}"
1305 rb_mod_const_missing(VALUE klass
, VALUE name
)
1307 rb_frame_pop(); /* pop frame for "const_missing" */
1308 uninitialized_constant(klass
, rb_to_id(name
));
1309 return Qnil
; /* not reached */
1312 static struct st_table
*
1313 check_autoload_table(VALUE av
)
1315 Check_Type(av
, T_DATA
);
1316 if (RDATA(av
)->dmark
!= (RUBY_DATA_FUNC
)rb_mark_tbl
||
1317 RDATA(av
)->dfree
!= (RUBY_DATA_FUNC
)st_free_table
) {
1318 VALUE desc
= rb_inspect(av
);
1319 rb_raise(rb_eTypeError
, "wrong autoload table: %s", RSTRING_PTR(desc
));
1321 return (struct st_table
*)DATA_PTR(av
);
1325 rb_autoload(VALUE mod
, ID id
, const char *file
)
1328 struct st_table
*tbl
;
1330 if (!rb_is_const_id(id
)) {
1331 rb_raise(rb_eNameError
, "autoload must be constant name: %s", rb_id2name(id
));
1333 if (!file
|| !*file
) {
1334 rb_raise(rb_eArgError
, "empty file name");
1337 if ((tbl
= RCLASS_IV_TBL(mod
)) && st_lookup(tbl
, id
, &av
) && av
!= Qundef
)
1340 rb_const_set(mod
, id
, Qundef
);
1341 tbl
= RCLASS_IV_TBL(mod
);
1342 if (st_lookup(tbl
, autoload
, &av
)) {
1343 tbl
= check_autoload_table(av
);
1346 av
= Data_Wrap_Struct(0, rb_mark_tbl
, st_free_table
, 0);
1347 st_add_direct(tbl
, autoload
, av
);
1348 DATA_PTR(av
) = tbl
= st_init_numtable();
1350 fn
= rb_str_new2(file
);
1351 FL_UNSET(fn
, FL_TAINT
);
1353 st_insert(tbl
, id
, (st_data_t
)rb_node_newnode(NODE_MEMO
, fn
, rb_safe_level(), 0));
1357 autoload_delete(VALUE mod
, ID id
)
1362 st_delete(RCLASS_IV_TBL(mod
), (st_data_t
*)&id
, 0);
1363 if (st_lookup(RCLASS_IV_TBL(mod
), autoload
, &val
)) {
1364 struct st_table
*tbl
= check_autoload_table(val
);
1366 st_delete(tbl
, (st_data_t
*)&id
, &load
);
1368 if (tbl
->num_entries
== 0) {
1372 if (st_delete(RCLASS_IV_TBL(mod
), (st_data_t
*)&id
, &val
)) {
1373 rb_gc_force_recycle(val
);
1378 return (NODE
*)load
;
1382 rb_autoload_load(VALUE klass
, ID id
)
1385 NODE
*load
= autoload_delete(klass
, id
);
1387 if (!load
|| !(file
= load
->nd_lit
)) {
1390 return rb_require_safe(file
, load
->nd_nth
);
1394 autoload_file(VALUE mod
, ID id
)
1397 struct st_table
*tbl
;
1400 if (!st_lookup(RCLASS_IV_TBL(mod
), autoload
, &val
) ||
1401 !(tbl
= check_autoload_table(val
)) || !st_lookup(tbl
, id
, &load
)) {
1404 file
= ((NODE
*)load
)->nd_lit
;
1405 Check_Type(file
, T_STRING
);
1406 if (!RSTRING_PTR(file
) || !*RSTRING_PTR(file
)) {
1407 rb_raise(rb_eArgError
, "empty file name");
1409 if (!rb_provided(RSTRING_PTR(file
))) {
1413 /* already loaded but not defined */
1414 st_delete(tbl
, (st_data_t
*)&id
, 0);
1415 if (!tbl
->num_entries
) {
1419 if (st_delete(RCLASS_IV_TBL(mod
), (st_data_t
*)&id
, &val
)) {
1420 rb_gc_force_recycle(val
);
1427 rb_autoload_p(VALUE mod
, ID id
)
1429 struct st_table
*tbl
= RCLASS_IV_TBL(mod
);
1432 if (!tbl
|| !st_lookup(tbl
, id
, &val
) || val
!= Qundef
) {
1435 return autoload_file(mod
, id
);
1439 rb_const_get_0(VALUE klass
, ID id
, int exclude
, int recurse
)
1446 while (RTEST(tmp
)) {
1447 while (RCLASS_IV_TBL(tmp
) && st_lookup(RCLASS_IV_TBL(tmp
),id
,&value
)) {
1448 if (value
== Qundef
) {
1449 if (!RTEST(rb_autoload_load(tmp
, id
))) break;
1452 if (exclude
&& tmp
== rb_cObject
&& klass
!= rb_cObject
) {
1453 rb_warn("toplevel constant %s referenced by %s::%s",
1454 rb_id2name(id
), rb_class2name(klass
), rb_id2name(id
));
1458 if (!recurse
&& klass
!= rb_cObject
) break;
1459 tmp
= RCLASS_SUPER(tmp
);
1461 if (!exclude
&& !mod_retry
&& BUILTIN_TYPE(klass
) == T_MODULE
) {
1467 return const_missing(klass
, id
);
1471 rb_const_get_from(VALUE klass
, ID id
)
1473 return rb_const_get_0(klass
, id
, Qtrue
, Qtrue
);
1477 rb_const_get(VALUE klass
, ID id
)
1479 return rb_const_get_0(klass
, id
, Qfalse
, Qtrue
);
1483 rb_const_get_at(VALUE klass
, ID id
)
1485 return rb_const_get_0(klass
, id
, Qtrue
, Qfalse
);
1490 * remove_const(sym) => obj
1492 * Removes the definition of the given constant, returning that
1493 * constant's value. Predefined classes and singleton objects (such as
1494 * <i>true</i>) cannot be removed.
1498 rb_mod_remove_const(VALUE mod
, VALUE name
)
1500 ID id
= rb_to_id(name
);
1503 rb_vm_change_state();
1505 if (!rb_is_const_id(id
)) {
1506 rb_name_error(id
, "`%s' is not allowed as a constant name", rb_id2name(id
));
1508 if (!OBJ_UNTRUSTED(mod
) && rb_safe_level() >= 4)
1509 rb_raise(rb_eSecurityError
, "Insecure: can't remove constant");
1510 if (OBJ_FROZEN(mod
)) rb_error_frozen("class/module");
1512 if (RCLASS_IV_TBL(mod
) && st_delete(RCLASS_IV_TBL(mod
), (st_data_t
*)&id
, &val
)) {
1513 if (val
== Qundef
) {
1514 autoload_delete(mod
, id
);
1519 if (rb_const_defined_at(mod
, id
)) {
1520 rb_name_error(id
, "cannot remove %s::%s",
1521 rb_class2name(mod
), rb_id2name(id
));
1523 rb_name_error(id
, "constant %s::%s not defined",
1524 rb_class2name(mod
), rb_id2name(id
));
1525 return Qnil
; /* not reached */
1529 sv_i(ID key
, VALUE value
, st_table
*tbl
)
1531 if (rb_is_const_id(key
)) {
1532 if (!st_lookup(tbl
, key
, 0)) {
1533 st_insert(tbl
, key
, key
);
1540 rb_mod_const_at(VALUE mod
, void *data
)
1542 st_table
*tbl
= data
;
1544 tbl
= st_init_numtable();
1546 if (RCLASS_IV_TBL(mod
)) {
1547 st_foreach_safe(RCLASS_IV_TBL(mod
), sv_i
, (st_data_t
)tbl
);
1553 rb_mod_const_of(VALUE mod
, void *data
)
1557 data
= rb_mod_const_at(tmp
, data
);
1558 tmp
= RCLASS_SUPER(tmp
);
1560 if (tmp
== rb_cObject
&& mod
!= rb_cObject
) break;
1566 list_i(ID key
, ID value
, VALUE ary
)
1568 rb_ary_push(ary
, ID2SYM(key
));
1573 rb_const_list(void *data
)
1575 st_table
*tbl
= data
;
1578 if (!tbl
) return rb_ary_new2(0);
1579 ary
= rb_ary_new2(tbl
->num_entries
);
1580 st_foreach_safe(tbl
, list_i
, ary
);
1588 * mod.constants(inherit=true) => array
1590 * Returns an array of the names of the constants accessible in
1591 * <i>mod</i>. This includes the names of constants in any included
1592 * modules (example at start of section), unless the <i>all</i>
1593 * parameter is set to <code>false</code>.
1595 * IO.constants.include?(:SYNC) => true
1596 * IO.constants(false).include?(:SYNC) => false
1598 * Also see <code>Module::const_defined?</code>.
1602 rb_mod_constants(int argc
, VALUE
*argv
, VALUE mod
)
1611 rb_scan_args(argc
, argv
, "01", &inherit
);
1613 if (RTEST(inherit
)) {
1614 tbl
= rb_mod_const_of(mod
, 0);
1617 tbl
= rb_mod_const_at(mod
, 0);
1619 return rb_const_list(tbl
);
1623 rb_const_defined_0(VALUE klass
, ID id
, int exclude
, int recurse
)
1631 if (RCLASS_IV_TBL(tmp
) && st_lookup(RCLASS_IV_TBL(tmp
), id
, &value
)) {
1632 if (value
== Qundef
&& NIL_P(autoload_file(klass
, id
)))
1636 if (!recurse
&& klass
!= rb_cObject
) break;
1637 tmp
= RCLASS_SUPER(tmp
);
1639 if (!exclude
&& !mod_retry
&& BUILTIN_TYPE(klass
) == T_MODULE
) {
1648 rb_const_defined_from(VALUE klass
, ID id
)
1650 return rb_const_defined_0(klass
, id
, Qtrue
, Qtrue
);
1654 rb_const_defined(VALUE klass
, ID id
)
1656 return rb_const_defined_0(klass
, id
, Qfalse
, Qtrue
);
1660 rb_const_defined_at(VALUE klass
, ID id
)
1662 return rb_const_defined_0(klass
, id
, Qtrue
, Qfalse
);
1666 mod_av_set(VALUE klass
, ID id
, VALUE val
, int isconst
)
1668 const char *dest
= isconst
? "constant" : "class variable";
1670 if (!OBJ_UNTRUSTED(klass
) && rb_safe_level() >= 4)
1671 rb_raise(rb_eSecurityError
, "Insecure: can't set %s", dest
);
1672 if (OBJ_FROZEN(klass
)) {
1673 if (BUILTIN_TYPE(klass
) == T_MODULE
) {
1674 rb_error_frozen("module");
1677 rb_error_frozen("class");
1680 if (!RCLASS_IV_TBL(klass
)) {
1681 RCLASS_IV_TBL(klass
) = st_init_numtable();
1684 VALUE value
= Qfalse
;
1686 if (st_lookup(RCLASS_IV_TBL(klass
), id
, &value
)) {
1687 if (value
== Qundef
)
1688 autoload_delete(klass
, id
);
1690 rb_warn("already initialized %s %s", dest
, rb_id2name(id
));
1695 rb_vm_change_state();
1697 st_insert(RCLASS_IV_TBL(klass
), id
, val
);
1701 rb_const_set(VALUE klass
, ID id
, VALUE val
)
1704 rb_raise(rb_eTypeError
, "no class/module to define constant %s",
1707 mod_av_set(klass
, id
, val
, Qtrue
);
1711 rb_define_const(VALUE klass
, const char *name
, VALUE val
)
1713 ID id
= rb_intern(name
);
1715 if (!rb_is_const_id(id
)) {
1716 rb_warn("rb_define_const: invalid name `%s' for constant", name
);
1718 if (klass
== rb_cObject
) {
1721 rb_const_set(klass
, id
, val
);
1725 rb_define_global_const(const char *name
, VALUE val
)
1727 rb_define_const(rb_cObject
, name
, val
);
1731 original_module(VALUE c
)
1733 if (TYPE(c
) == T_ICLASS
)
1734 return RBASIC(c
)->klass
;
1738 #define CVAR_LOOKUP(v,r) do {\
1739 if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),id,(v))) {\
1742 if (FL_TEST(klass, FL_SINGLETON) ) {\
1743 VALUE obj = rb_iv_get(klass, "__attached__");\
1744 switch (TYPE(obj)) {\
1750 klass = RCLASS_SUPER(klass);\
1755 klass = RCLASS_SUPER(klass);\
1758 if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),id,(v))) {\
1761 klass = RCLASS_SUPER(klass);\
1766 rb_cvar_set(VALUE klass
, ID id
, VALUE val
)
1768 VALUE tmp
, front
= 0, target
= 0;
1771 CVAR_LOOKUP(0, {if (!front
) front
= klass
; target
= klass
;});
1773 if (front
&& target
!= front
) {
1776 if (RTEST(ruby_verbose
)) {
1777 rb_warning("class variable %s of %s is overtaken by %s",
1778 rb_id2name(id
), rb_class2name(original_module(front
)),
1779 rb_class2name(original_module(target
)));
1781 if (BUILTIN_TYPE(front
) == T_CLASS
) {
1782 st_delete(RCLASS_IV_TBL(front
),&did
,0);
1789 mod_av_set(target
, id
, val
, Qfalse
);
1793 rb_cvar_get(VALUE klass
, ID id
)
1795 VALUE value
, tmp
, front
= 0, target
= 0;
1798 CVAR_LOOKUP(&value
, {if (!front
) front
= klass
; target
= klass
;});
1800 rb_name_error(id
,"uninitialized class variable %s in %s",
1801 rb_id2name(id
), rb_class2name(tmp
));
1803 if (front
&& target
!= front
) {
1806 if (RTEST(ruby_verbose
)) {
1807 rb_warning("class variable %s of %s is overtaken by %s",
1808 rb_id2name(id
), rb_class2name(original_module(front
)),
1809 rb_class2name(original_module(target
)));
1811 if (BUILTIN_TYPE(front
) == T_CLASS
) {
1812 st_delete(RCLASS_IV_TBL(front
),&did
,0);
1819 rb_cvar_defined(VALUE klass
, ID id
)
1821 if (!klass
) return Qfalse
;
1822 CVAR_LOOKUP(0,return Qtrue
);
1827 rb_cv_set(VALUE klass
, const char *name
, VALUE val
)
1829 ID id
= rb_intern(name
);
1830 if (!rb_is_class_id(id
)) {
1831 rb_name_error(id
, "wrong class variable name %s", name
);
1833 rb_cvar_set(klass
, id
, val
);
1837 rb_cv_get(VALUE klass
, const char *name
)
1839 ID id
= rb_intern(name
);
1840 if (!rb_is_class_id(id
)) {
1841 rb_name_error(id
, "wrong class variable name %s", name
);
1843 return rb_cvar_get(klass
, id
);
1847 rb_define_class_variable(VALUE klass
, const char *name
, VALUE val
)
1849 ID id
= rb_intern(name
);
1851 if (!rb_is_class_id(id
)) {
1852 rb_name_error(id
, "wrong class variable name %s", name
);
1854 rb_cvar_set(klass
, id
, val
);
1858 cv_i(ID key
, VALUE value
, VALUE ary
)
1860 if (rb_is_class_id(key
)) {
1861 VALUE kval
= ID2SYM(key
);
1862 if (!rb_ary_includes(ary
, kval
)) {
1863 rb_ary_push(ary
, kval
);
1871 * mod.class_variables => array
1873 * Returns an array of the names of class variables in <i>mod</i>.
1881 * One.class_variables #=> [:@@var1]
1882 * Two.class_variables #=> [:@@var2]
1886 rb_mod_class_variables(VALUE obj
)
1888 VALUE ary
= rb_ary_new();
1890 if (RCLASS_IV_TBL(obj
)) {
1891 st_foreach_safe(RCLASS_IV_TBL(obj
), cv_i
, ary
);
1898 * remove_class_variable(sym) => obj
1900 * Removes the definition of the <i>sym</i>, returning that
1906 * remove_class_variable(:@@var)
1907 * puts(defined? @@var)
1910 * <em>produces:</em>
1917 rb_mod_remove_cvar(VALUE mod
, VALUE name
)
1919 ID id
= rb_to_id(name
);
1922 if (!rb_is_class_id(id
)) {
1923 rb_name_error(id
, "wrong class variable name %s", rb_id2name(id
));
1925 if (!OBJ_UNTRUSTED(mod
) && rb_safe_level() >= 4)
1926 rb_raise(rb_eSecurityError
, "Insecure: can't remove class variable");
1927 if (OBJ_FROZEN(mod
)) rb_error_frozen("class/module");
1929 if (RCLASS_IV_TBL(mod
) && st_delete(RCLASS_IV_TBL(mod
), (st_data_t
*)&id
, &val
)) {
1932 if (rb_cvar_defined(mod
, id
)) {
1933 rb_name_error(id
, "cannot remove %s for %s",
1934 rb_id2name(id
), rb_class2name(mod
));
1936 rb_name_error(id
, "class variable %s not defined for %s",
1937 rb_id2name(id
), rb_class2name(mod
));
1938 return Qnil
; /* not reached */
1942 rb_iv_get(VALUE obj
, const char *name
)
1944 ID id
= rb_intern(name
);
1946 return rb_ivar_get(obj
, id
);
1950 rb_iv_set(VALUE obj
, const char *name
, VALUE val
)
1952 ID id
= rb_intern(name
);
1954 return rb_ivar_set(obj
, id
, val
);