From 83aba0486298d61b39f3ed3492042690a889807f Mon Sep 17 00:00:00 2001 From: ko1 Date: Mon, 13 May 2013 10:49:11 +0000 Subject: * include/ruby/ruby.h: constify RBasic::klass and add RBASIC_CLASS(obj) macro which returns a class of `obj'. This change is a part of RGENGC branch [ruby-trunk - Feature #8339]. * object.c: add new function rb_obj_reveal(). This function reveal interal (hidden) object by rb_obj_hide(). Note that do not change class before and after hiding. Only permitted example is: klass = RBASIC_CLASS(obj); rb_obj_hide(obj); .... rb_obj_reveal(obj, klass); TODO: API design. rb_obj_reveal() should be replaced with others. TODO: modify constified variables using cast may be harmful for compiler's analysis and optimizaton. Any idea to prohibt inserting RBasic::klass directly? If rename RBasic::klass and force to use RBASIC_CLASS(obj), then all codes such as `RBASIC(obj)->klass' will be compilation error. Is it acceptable? (We have similar experience at Ruby 1.9, for example "RARRAY(ary)->ptr" to "RARRAY_PTR(ary)". * internal.h: add some macros. * RBASIC_CLEAR_CLASS(obj) clear RBasic::klass to make it internal object. * RBASIC_SET_CLASS(obj, cls) set RBasic::klass. * RBASIC_SET_CLASS_RAW(obj, cls) same as RBASIC_SET_CLASS without write barrier (planned). * RCLASS_SET_SUPER(a, b) set super class of a. * array.c, class.c, compile.c, encoding.c, enum.c, error.c, eval.c, file.c, gc.c, hash.c, io.c, iseq.c, marshal.c, object.c, parse.y, proc.c, process.c, random.c, ruby.c, sprintf.c, string.c, thread.c, transcode.c, vm.c, vm_eval.c, win32/file.c: Use above macros and functions to access RBasic::klass. * ext/coverage/coverage.c, ext/readline/readline.c, ext/socket/ancdata.c, ext/socket/init.c, * ext/zlib/zlib.c: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40691 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 44 ++++++++++++++++++++++++++++++++++++++++++++ array.c | 34 +++++++++++++++++----------------- class.c | 49 +++++++++++++++++++++++++------------------------ compile.c | 2 +- encoding.c | 2 +- enum.c | 6 +++--- error.c | 2 +- eval.c | 9 ++++----- ext/coverage/coverage.c | 2 +- ext/readline/readline.c | 4 ++-- ext/socket/ancdata.c | 2 +- ext/socket/init.c | 4 ++-- ext/zlib/zlib.c | 16 ++++++++-------- file.c | 8 ++++---- gc.c | 6 +++--- hash.c | 4 ++-- include/ruby/ruby.h | 7 ++++++- internal.h | 25 ++++++++++++++++++++++--- io.c | 6 +++--- iseq.c | 2 +- marshal.c | 2 +- object.c | 21 +++++++++++++++------ parse.y | 8 ++++---- proc.c | 2 +- process.c | 2 +- random.c | 2 +- ruby.c | 6 +++--- sprintf.c | 8 ++++---- string.c | 6 +++--- thread.c | 2 +- transcode.c | 2 +- vm.c | 2 +- vm_eval.c | 2 +- win32/file.c | 3 ++- 34 files changed, 190 insertions(+), 112 deletions(-) diff --git a/ChangeLog b/ChangeLog index b8bf4f08d5..351565bd71 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,47 @@ +Mon May 13 19:29:54 2013 Koichi Sasada + + * include/ruby/ruby.h: constify RBasic::klass and add + RBASIC_CLASS(obj) macro which returns a class of `obj'. + This change is a part of RGENGC branch [ruby-trunk - Feature #8339]. + + * object.c: add new function rb_obj_reveal(). + This function reveal interal (hidden) object by rb_obj_hide(). + Note that do not change class before and after hiding. + Only permitted example is: + klass = RBASIC_CLASS(obj); + rb_obj_hide(obj); + .... + rb_obj_reveal(obj, klass); + + TODO: API design. rb_obj_reveal() should be replaced with others. + + TODO: modify constified variables using cast may be harmful for + compiler's analysis and optimizaton. + Any idea to prohibt inserting RBasic::klass directly? + If rename RBasic::klass and force to use RBASIC_CLASS(obj), + then all codes such as `RBASIC(obj)->klass' will be + compilation error. Is it acceptable? (We have similar + experience at Ruby 1.9, + for example "RARRAY(ary)->ptr" to "RARRAY_PTR(ary)". + + * internal.h: add some macros. + * RBASIC_CLEAR_CLASS(obj) clear RBasic::klass to make it internal + object. + * RBASIC_SET_CLASS(obj, cls) set RBasic::klass. + * RBASIC_SET_CLASS_RAW(obj, cls) same as RBASIC_SET_CLASS + without write barrier (planned). + * RCLASS_SET_SUPER(a, b) set super class of a. + + * array.c, class.c, compile.c, encoding.c, enum.c, error.c, eval.c, + file.c, gc.c, hash.c, io.c, iseq.c, marshal.c, object.c, + parse.y, proc.c, process.c, random.c, ruby.c, sprintf.c, + string.c, thread.c, transcode.c, vm.c, vm_eval.c, win32/file.c: + Use above macros and functions to access RBasic::klass. + + * ext/coverage/coverage.c, ext/readline/readline.c, + ext/socket/ancdata.c, ext/socket/init.c, + * ext/zlib/zlib.c: ditto. + Mon May 13 18:44:14 2013 Koichi Sasada * *.c, parse.y, insns.def: use RARRAY_AREF/ASET macro diff --git a/array.c b/array.c index 47ff7ac611..f605af264b 100644 --- a/array.c +++ b/array.c @@ -2297,7 +2297,7 @@ rb_ary_sort_bang(VALUE ary) struct ary_sort_data data; long len = RARRAY_LEN(ary); - RBASIC(tmp)->klass = 0; + RBASIC_CLEAR_CLASS(tmp); data.ary = tmp; data.opt_methods = 0; data.opt_inited = 0; @@ -2343,7 +2343,7 @@ rb_ary_sort_bang(VALUE ary) FL_SET(tmp, FL_FREEZE); } /* tmp will be GC'ed. */ - RBASIC(tmp)->klass = rb_cArray; + RBASIC_SET_CLASS_RAW(tmp, rb_cArray); /* rb_cArray must be marked */ } return ary; } @@ -2896,7 +2896,7 @@ rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary) } if (len == 0) return rb_ary_new2(0); arg2 = rb_ary_new4(len, RARRAY_PTR(ary)+pos); - RBASIC(arg2)->klass = rb_obj_class(ary); + RBASIC_SET_CLASS(arg2, rb_obj_class(ary)); rb_ary_splice(ary, pos, len, Qundef); return arg2; } @@ -3755,7 +3755,7 @@ ary_tmp_hash_new(void) { VALUE hash = rb_hash_new(); - RBASIC(hash)->klass = 0; + RBASIC_CLEAR_CLASS(hash); return hash; } @@ -4192,7 +4192,7 @@ flatten(VALUE ary, int level, int *modified) st_free_table(memo); - RBASIC(result)->klass = rb_class_of(ary); + RBASIC_SET_CLASS(result, rb_class_of(ary)); return result; } @@ -4461,7 +4461,7 @@ rb_ary_sample(int argc, VALUE *argv, VALUE ary) else { VALUE *ptr_result; result = rb_ary_new4(len, ptr); - RBASIC(result)->klass = 0; + RBASIC_CLEAR_CLASS(result); ptr_result = RARRAY_PTR(result); RB_GC_GUARD(ary); for (i=0; iklass = rb_cArray; + RBASIC_SET_CLASS_RAW(result, rb_cArray); } ARY_SET_LEN(result, n); @@ -4538,9 +4538,9 @@ rb_ary_cycle(int argc, VALUE *argv, VALUE ary) } #define tmpbuf(n, size) rb_str_tmp_new((n)*(size)) -#define tmpbuf_discard(s) (rb_str_resize((s), 0L), RBASIC(s)->klass = rb_cString) +#define tmpbuf_discard(s) (rb_str_resize((s), 0L), RBASIC_SET_CLASS_RAW(s, rb_cString)) #define tmpary(n) rb_ary_tmp_new(n) -#define tmpary_discard(a) (ary_discard(a), RBASIC(a)->klass = rb_cArray) +#define tmpary_discard(a) (ary_discard(a), RBASIC_SET_CLASS_RAW(a, rb_cArray)) /* * Recursively compute permutations of +r+ elements of the set @@ -4679,14 +4679,14 @@ rb_ary_permutation(int argc, VALUE *argv, VALUE ary) volatile VALUE t1 = tmpbuf(n,sizeof(char)); char *used = (char*)RSTRING_PTR(t1); VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */ - RBASIC(ary0)->klass = 0; + RBASIC_CLEAR_CLASS(ary0); MEMZERO(used, char, n); /* initialize array */ permute0(n, r, p, 0, used, ary0); /* compute and yield permutations */ tmpbuf_discard(t0); tmpbuf_discard(t1); - RBASIC(ary0)->klass = rb_cArray; + RBASIC_SET_CLASS_RAW(ary0, rb_cArray); } return ary; } @@ -4874,11 +4874,11 @@ rb_ary_repeated_permutation(VALUE ary, VALUE num) volatile VALUE t0 = tmpbuf(r, sizeof(long)); long *p = (long*)RSTRING_PTR(t0); VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */ - RBASIC(ary0)->klass = 0; + RBASIC_CLEAR_CLASS(ary0); rpermute0(n, r, p, 0, ary0); /* compute and yield repeated permutations */ tmpbuf_discard(t0); - RBASIC(ary0)->klass = rb_cArray; + RBASIC_SET_CLASS_RAW(ary0, rb_cArray); } return ary; } @@ -4971,11 +4971,11 @@ rb_ary_repeated_combination(VALUE ary, VALUE num) volatile VALUE t0 = tmpbuf(n, sizeof(long)); long *p = (long*)RSTRING_PTR(t0); VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */ - RBASIC(ary0)->klass = 0; + RBASIC_CLEAR_CLASS(ary0); rcombinate0(len, n, p, 0, n, ary0); /* compute and yield repeated combinations */ tmpbuf_discard(t0); - RBASIC(ary0)->klass = rb_cArray; + RBASIC_SET_CLASS_RAW(ary0, rb_cArray); } return ary; } @@ -5013,8 +5013,8 @@ rb_ary_product(int argc, VALUE *argv, VALUE ary) long i,j; long resultlen = 1; - RBASIC(t0)->klass = 0; - RBASIC(t1)->klass = 0; + RBASIC_CLEAR_CLASS(t0); + RBASIC_CLEAR_CLASS(t1); /* initialize the arrays of arrays */ ARY_SET_LEN(t0, n); diff --git a/class.c b/class.c index a37a153d77..eeca4102af 100644 --- a/class.c +++ b/class.c @@ -54,7 +54,7 @@ class_alloc(VALUE flags, VALUE klass) RCLASS_IV_TBL(obj) = 0; RCLASS_CONST_TBL(obj) = 0; RCLASS_M_TBL(obj) = 0; - RCLASS_SUPER(obj) = 0; + RCLASS_SET_SUPER((VALUE)obj, 0); RCLASS_ORIGIN(obj) = (VALUE)obj; RCLASS_IV_INDEX_TBL(obj) = 0; RCLASS_REFINED_CLASS(obj) = Qnil; @@ -77,7 +77,7 @@ rb_class_boot(VALUE super) { VALUE klass = class_alloc(T_CLASS, rb_cClass); - RCLASS_SUPER(klass) = super; + RCLASS_SET_SUPER(klass, super); RCLASS_M_TBL(klass) = st_init_numtable(); OBJ_INFECT(klass, super); @@ -200,10 +200,10 @@ rb_mod_init_copy(VALUE clone, VALUE orig) } rb_obj_init_copy(clone, orig); if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) { - RBASIC(clone)->klass = rb_singleton_class_clone(orig); + RBASIC_SET_CLASS(clone, rb_singleton_class_clone(orig)); rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone); } - RCLASS_SUPER(clone) = RCLASS_SUPER(orig); + RCLASS_SET_SUPER(clone, RCLASS_SUPER(orig)); RCLASS_EXT(clone)->allocator = RCLASS_EXT(orig)->allocator; if (RCLASS_IV_TBL(orig)) { st_data_t id; @@ -255,13 +255,13 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach) VALUE clone = class_alloc(RBASIC(klass)->flags, 0); if (BUILTIN_TYPE(obj) == T_CLASS) { - RBASIC(clone)->klass = clone; + RBASIC_SET_CLASS(clone, clone); } else { - RBASIC(clone)->klass = rb_singleton_class_clone(klass); + RBASIC_SET_CLASS(clone, rb_singleton_class_clone(klass)); } - RCLASS_SUPER(clone) = RCLASS_SUPER(klass); + RCLASS_SET_SUPER(clone, RCLASS_SUPER(klass)); RCLASS_EXT(clone)->allocator = RCLASS_EXT(klass)->allocator; if (RCLASS_IV_TBL(klass)) { RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass)); @@ -299,6 +299,7 @@ rb_singleton_class_attached(VALUE klass, VALUE obj) #define METACLASS_OF(k) RBASIC(k)->klass +#define SET_METACLASS_OF(k, cls) RBASIC_SET_CLASS(k, cls) /*! * whether k is a meta^(n)-class of Class class @@ -346,17 +347,18 @@ make_metaclass(VALUE klass) rb_singleton_class_attached(metaclass, klass); if (META_CLASS_OF_CLASS_CLASS_P(klass)) { - METACLASS_OF(klass) = METACLASS_OF(metaclass) = metaclass; + SET_METACLASS_OF(klass, metaclass); + SET_METACLASS_OF(metaclass, metaclass); } else { VALUE tmp = METACLASS_OF(klass); /* for a meta^(n)-class klass, tmp is meta^(n)-class of Class class */ - METACLASS_OF(klass) = metaclass; - METACLASS_OF(metaclass) = ENSURE_EIGENCLASS(tmp); + SET_METACLASS_OF(klass, metaclass); + SET_METACLASS_OF(metaclass, ENSURE_EIGENCLASS(tmp)); } super = RCLASS_SUPER(klass); while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super); - RCLASS_SUPER(metaclass) = super ? ENSURE_EIGENCLASS(super) : rb_cClass; + RCLASS_SET_SUPER(metaclass, super ? ENSURE_EIGENCLASS(super) : rb_cClass); OBJ_INFECT(metaclass, RCLASS_SUPER(metaclass)); @@ -376,10 +378,10 @@ make_singleton_class(VALUE obj) VALUE klass = rb_class_boot(orig_class); FL_SET(klass, FL_SINGLETON); - RBASIC(obj)->klass = klass; + RBASIC_SET_CLASS(obj, klass); rb_singleton_class_attached(klass, obj); - METACLASS_OF(klass) = METACLASS_OF(rb_class_real(orig_class)); + SET_METACLASS_OF(klass, METACLASS_OF(rb_class_real(orig_class))); return klass; } @@ -406,11 +408,10 @@ Init_class_hierarchy(void) rb_cClass = boot_defclass("Class", rb_cModule); rb_const_set(rb_cObject, rb_intern("BasicObject"), rb_cBasicObject); - RBASIC(rb_cClass)->klass - = RBASIC(rb_cModule)->klass - = RBASIC(rb_cObject)->klass - = RBASIC(rb_cBasicObject)->klass - = rb_cClass; + RBASIC_SET_CLASS(rb_cClass, rb_cClass); + RBASIC_SET_CLASS(rb_cModule, rb_cClass); + RBASIC_SET_CLASS(rb_cObject, rb_cClass); + RBASIC_SET_CLASS(rb_cBasicObject, rb_cClass); } @@ -674,12 +675,12 @@ rb_include_class_new(VALUE module, VALUE super) RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module); RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module); RCLASS_M_TBL(klass) = RCLASS_M_TBL(RCLASS_ORIGIN(module)); - RCLASS_SUPER(klass) = super; + RCLASS_SET_SUPER(klass, super); if (RB_TYPE_P(module, T_ICLASS)) { - RBASIC(klass)->klass = RBASIC(module)->klass; + RBASIC_SET_CLASS(klass, RBASIC(module)->klass); } else { - RBASIC(klass)->klass = module; + RBASIC_SET_CLASS(klass, module); } OBJ_INFECT(klass, module); OBJ_INFECT(klass, super); @@ -748,7 +749,7 @@ include_modules_at(const VALUE klass, VALUE c, VALUE module) break; } } - c = RCLASS_SUPER(c) = rb_include_class_new(module, RCLASS_SUPER(c)); + c = RCLASS_SET_SUPER(c, rb_include_class_new(module, RCLASS_SUPER(c))); if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) { VALUE refined_class = rb_refinement_module_get_refined_class(klass); @@ -812,8 +813,8 @@ rb_prepend_module(VALUE klass, VALUE module) origin = RCLASS_ORIGIN(klass); if (origin == klass) { origin = class_alloc(T_ICLASS, klass); - RCLASS_SUPER(origin) = RCLASS_SUPER(klass); - RCLASS_SUPER(klass) = origin; + RCLASS_SET_SUPER(origin, RCLASS_SUPER(klass)); + RCLASS_SET_SUPER(klass, origin); RCLASS_ORIGIN(klass) = origin; RCLASS_M_TBL(origin) = RCLASS_M_TBL(klass); RCLASS_M_TBL(klass) = st_init_numtable(); diff --git a/compile.c b/compile.c index 1a911f1f4d..c079c03c50 100644 --- a/compile.c +++ b/compile.c @@ -299,7 +299,7 @@ r_value(VALUE value) #define INIT_ANCHOR(name) \ (name##_body__.last = &name##_body__.anchor, name = &name##_body__) -#define hide_obj(obj) do {OBJ_FREEZE(obj); RBASIC(obj)->klass = 0;} while (0) +#define hide_obj(obj) do {OBJ_FREEZE(obj); RBASIC_CLEAR_CLASS(obj);} while (0) #include "optinsn.inc" #if OPT_INSTRUCTIONS_UNIFICATION diff --git a/encoding.c b/encoding.c index 3d89d52ea6..a9a224430d 100644 --- a/encoding.c +++ b/encoding.c @@ -1866,7 +1866,7 @@ Init_Encoding(void) rb_define_singleton_method(rb_cEncoding, "locale_charmap", rb_locale_charmap, 0); list = rb_ary_new2(enc_table.count); - RBASIC(list)->klass = 0; + RBASIC_CLEAR_CLASS(list); rb_encoding_list = list; rb_gc_register_mark_object(list); diff --git a/enum.c b/enum.c index cd03f41951..1a30897ee6 100644 --- a/enum.c +++ b/enum.c @@ -931,7 +931,7 @@ enum_sort_by(VALUE obj) else { ary = rb_ary_new(); } - RBASIC(ary)->klass = 0; + RBASIC_CLEAR_CLASS(ary); buf = rb_ary_tmp_new(SORT_BY_BUFSIZE*2); rb_ary_store(buf, SORT_BY_BUFSIZE*2-1, Qnil); memo = NEW_MEMO(0, 0, 0); @@ -958,7 +958,7 @@ enum_sort_by(VALUE obj) RARRAY_ASET(ary, i/2, RARRAY_AREF(ary, i)); } rb_ary_resize(ary, RARRAY_LEN(ary)/2); - RBASIC(ary)->klass = rb_cArray; + RBASIC_SET_CLASS_RAW(ary, rb_cArray); OBJ_INFECT(ary, memo); return ary; @@ -2309,7 +2309,7 @@ enum_cycle(int argc, VALUE *argv, VALUE obj) if (n <= 0) return Qnil; } ary = rb_ary_new(); - RBASIC(ary)->klass = 0; + RBASIC_CLEAR_CLASS(ary); rb_block_call(obj, id_each, 0, 0, cycle_i, ary); len = RARRAY_LEN(ary); if (len == 0) return Qnil; diff --git a/error.c b/error.c index 2dbcd817c4..ea8c3cfc2f 100644 --- a/error.c +++ b/error.c @@ -1261,7 +1261,7 @@ syserr_initialize(int argc, VALUE *argv, VALUE self) if (!RB_TYPE_P(self, T_OBJECT)) { /* insurance to avoid type crash */ rb_raise(rb_eTypeError, "invalid instance type"); } - RBASIC(self)->klass = klass; + RBASIC_SET_CLASS(self, klass); } } else { diff --git a/eval.c b/eval.c index 3880a0edce..53d6d14328 100644 --- a/eval.c +++ b/eval.c @@ -1060,7 +1060,7 @@ hidden_identity_hash_new() VALUE hash = rb_hash_new(); rb_funcall(hash, rb_intern("compare_by_identity"), 0); - RBASIC(hash)->klass = 0; /* hide from ObjectSpace */ + RBASIC_CLEAR_CLASS(hash); /* hide from ObjectSpace */ return hash; } @@ -1097,7 +1097,7 @@ rb_using_refinement(NODE *cref, VALUE klass, VALUE module) module = RCLASS_SUPER(module); while (module && module != klass) { FL_SET(module, RMODULE_IS_OVERLAID); - c = RCLASS_SUPER(c) = rb_include_class_new(module, RCLASS_SUPER(c)); + c = RCLASS_SET_SUPER(c, rb_include_class_new(module, RCLASS_SUPER(c))); RCLASS_REFINED_CLASS(c) = klass; module = RCLASS_SUPER(module); } @@ -1156,8 +1156,7 @@ add_activated_refinement(VALUE activated_refinements, refinement = RCLASS_SUPER(refinement); while (refinement) { FL_SET(refinement, RMODULE_IS_OVERLAID); - c = RCLASS_SUPER(c) = - rb_include_class_new(refinement, RCLASS_SUPER(c)); + c = RCLASS_SET_SUPER(c, rb_include_class_new(refinement, RCLASS_SUPER(c))); RCLASS_REFINED_CLASS(c) = klass; refinement = RCLASS_SUPER(refinement); } @@ -1210,7 +1209,7 @@ rb_mod_refine(VALUE module, VALUE klass) refinement = rb_hash_lookup(refinements, klass); if (NIL_P(refinement)) { refinement = rb_module_new(); - RCLASS_SUPER(refinement) = klass; + RCLASS_SET_SUPER(refinement, klass); FL_SET(refinement, RMODULE_IS_REFINEMENT); CONST_ID(id_refined_class, "__refined_class__"); rb_ivar_set(refinement, id_refined_class, klass); diff --git a/ext/coverage/coverage.c b/ext/coverage/coverage.c index d2cdb357e0..93cb2a5c9e 100644 --- a/ext/coverage/coverage.c +++ b/ext/coverage/coverage.c @@ -25,7 +25,7 @@ rb_coverage_start(VALUE klass) if (!RTEST(rb_get_coverages())) { if (rb_coverages == Qundef) { rb_coverages = rb_hash_new(); - RBASIC(rb_coverages)->klass = 0; + rb_obj_hide(rb_coverages); } rb_set_coverages(rb_coverages); } diff --git a/ext/readline/readline.c b/ext/readline/readline.c index fe5c7234e5..a4c51c646a 100644 --- a/ext/readline/readline.c +++ b/ext/readline/readline.c @@ -1217,7 +1217,7 @@ readline_s_set_special_prefixes(VALUE self, VALUE str) if (!NIL_P(str)) { OutputStringValue(str); str = rb_str_dup_frozen(str); - RBASIC(str)->klass = 0; + rb_obj_hide(str); } rb_ivar_set(mReadline, id_special_prefixes, str); if (NIL_P(str)) { @@ -1252,7 +1252,7 @@ readline_s_get_special_prefixes(VALUE self) str = rb_ivar_get(mReadline, id_special_prefixes); if (!NIL_P(str)) { str = rb_str_dup_frozen(str); - RBASIC(str)->klass = rb_cString; + rb_obj_reveal(str, rb_cString); } return str; } diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c index 3e6431ebbf..7fe965918d 100644 --- a/ext/socket/ancdata.c +++ b/ext/socket/ancdata.c @@ -1677,7 +1677,7 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock) else { rb_str_resize(dat_str, ss); OBJ_TAINT(dat_str); - RBASIC(dat_str)->klass = rb_cString; + rb_obj_reveal(dat_str, rb_cString); } ret = rb_ary_new3(3, dat_str, diff --git a/ext/socket/init.c b/ext/socket/init.c index a5ffe7bfa5..6d98a66d6e 100644 --- a/ext/socket/init.c +++ b/ext/socket/init.c @@ -132,7 +132,7 @@ rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from) arg.str = str = rb_tainted_str_new(0, buflen); klass = RBASIC(str)->klass; - RBASIC(str)->klass = 0; + rb_obj_hide(str); while (rb_io_check_closed(fptr), rb_thread_wait_fd(arg.fd), @@ -145,7 +145,7 @@ rsock_s_recvfrom(VALUE sock, int argc, VALUE *argv, enum sock_recv_type from) } } - RBASIC(str)->klass = klass; + rb_obj_reveal(str, klass); if (slen < RSTRING_LEN(str)) { rb_str_set_len(str, slen); } diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 64a3e697c6..db153e3694 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -633,7 +633,7 @@ zstream_expand_buffer(struct zstream *z) VALUE self = (VALUE)z->stream.opaque; rb_str_resize(z->buf, z->buf_filled); - RBASIC(z->buf)->klass = rb_cString; + rb_obj_reveal(z->buf, rb_cString); OBJ_INFECT(z->buf, self); rb_protect(rb_yield, z->buf, &state); @@ -678,7 +678,7 @@ zstream_expand_buffer_into(struct zstream *z, unsigned long size) z->buf_filled = 0; z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf); z->stream.avail_out = MAX_UINT(size); - RBASIC(z->buf)->klass = 0; + rb_obj_hide(z->buf); } else if (z->stream.avail_out != size) { rb_str_resize(z->buf, z->buf_filled + size); @@ -740,7 +740,7 @@ zstream_append_buffer(struct zstream *z, const Bytef *src, long len) z->buf_filled = len; z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf); z->stream.avail_out = 0; - RBASIC(z->buf)->klass = 0; + rb_obj_hide(z->buf); return; } @@ -782,7 +782,7 @@ zstream_detach_buffer(struct zstream *z) else { dst = z->buf; rb_str_resize(dst, z->buf_filled); - RBASIC(dst)->klass = rb_cString; + rb_obj_reveal(dst, rb_cString); } OBJ_INFECT(dst, self); @@ -811,7 +811,7 @@ zstream_shift_buffer(struct zstream *z, long len) } dst = rb_str_subseq(z->buf, 0, len); - RBASIC(dst)->klass = rb_cString; + rb_obj_reveal(dst, rb_cString); z->buf_filled -= len; memmove(RSTRING_PTR(z->buf), RSTRING_PTR(z->buf) + len, z->buf_filled); @@ -866,7 +866,7 @@ zstream_append_input(struct zstream *z, const Bytef *src, long len) if (NIL_P(z->input)) { z->input = rb_str_buf_new(len); rb_str_buf_cat(z->input, (const char*)src, len); - RBASIC(z->input)->klass = 0; + rb_obj_hide(z->input); } else { rb_str_buf_cat(z->input, (const char*)src, len); @@ -915,10 +915,10 @@ zstream_detach_input(struct zstream *z) } else { dst = z->input; - RBASIC(dst)->klass = rb_cString; + rb_obj_reveal(dst, rb_cString); } z->input = Qnil; - RBASIC(dst)->klass = rb_cString; + rb_obj_reveal(dst, rb_cString); return dst; } diff --git a/file.c b/file.c index 55d4792e7d..2628cb5e5f 100644 --- a/file.c +++ b/file.c @@ -4013,7 +4013,7 @@ rb_file_join(VALUE ary, VALUE sep) len += RSTRING_LEN(sep) * (RARRAY_LEN(ary) - 1); } result = rb_str_buf_new(len); - RBASIC(result)->klass = 0; + RBASIC_CLEAR_CLASS(result); OBJ_INFECT(result, ary); for (i=0; iklass = rb_cString; + RBASIC_SET_CLASS_RAW(result, rb_cString); return result; } @@ -5304,7 +5304,7 @@ is_explicit_relative(const char *path) static VALUE copy_path_class(VALUE path, VALUE orig) { - RBASIC(path)->klass = rb_obj_class(orig); + RBASIC_SET_CLASS(path, rb_obj_class(orig)); OBJ_FREEZE(path); return path; } @@ -5360,7 +5360,7 @@ rb_find_file_ext_safe(VALUE *filep, const char *const *ext, int safe_level) if (!load_path) return 0; fname = rb_str_dup(*filep); - RBASIC(fname)->klass = 0; + RBASIC_CLEAR_CLASS(fname); fnlen = RSTRING_LEN(fname); tmp = rb_str_tmp_new(MAXPATHLEN + 2); rb_enc_associate_index(tmp, rb_usascii_encindex()); diff --git a/gc.c b/gc.c index 8283e581c0..679a727ed2 100644 --- a/gc.c +++ b/gc.c @@ -1330,7 +1330,7 @@ define_final0(VALUE obj, VALUE block) } else { table = rb_ary_new3(1, block); - RBASIC(table)->klass = 0; + RBASIC_CLEAR_CLASS(table); st_add_direct(finalizer_table, obj, table); } return block; @@ -1405,7 +1405,7 @@ run_final(rb_objspace_t *objspace, VALUE obj) objspace->heap.final_num--; - RBASIC(obj)->klass = 0; + RBASIC_CLEAR_CLASS(obj); if (RTYPEDDATA_P(obj)) { free_func = RTYPEDDATA_TYPE(obj)->function.dfree; @@ -2796,7 +2796,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr) if (!RCLASS_EXT(obj)) break; mark_tbl(objspace, RCLASS_IV_TBL(obj)); mark_const_tbl(objspace, RCLASS_CONST_TBL(obj)); - ptr = RCLASS_SUPER(obj); + ptr = RCLASS_SUPER((VALUE)obj); goto again; case T_ARRAY: diff --git a/hash.c b/hash.c index e990f53d3e..f51da37001 100644 --- a/hash.c +++ b/hash.c @@ -2708,7 +2708,7 @@ env_reject_bang(VALUE ehash) RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size); keys = env_keys(); /* rb_secure(4); */ - RBASIC(keys)->klass = 0; + RBASIC_CLEAR_CLASS(keys); for (i=0; iklass = 0; + RBASIC_CLEAR_CLASS(keys); for (i=0; iklass) + #define ROBJECT_EMBED_LEN_MAX 3 struct RObject { struct RBasic basic; diff --git a/internal.h b/internal.h index 89a0e3ed2b..6f2091cdac 100644 --- a/internal.h +++ b/internal.h @@ -64,9 +64,7 @@ struct rb_classext_struct { rb_alloc_func_t allocator; }; -#undef RCLASS_SUPER #define RCLASS_EXT(c) (RCLASS(c)->ptr) -#define RCLASS_SUPER(c) (RCLASS_EXT(c)->super) #define RCLASS_IV_TBL(c) (RCLASS_EXT(c)->iv_tbl) #define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl) #define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl) @@ -74,6 +72,19 @@ struct rb_classext_struct { #define RCLASS_ORIGIN(c) (RCLASS_EXT(c)->origin) #define RCLASS_REFINED_CLASS(c) (RCLASS_EXT(c)->refined_class) +#undef RCLASS_SUPER +static inline VALUE +RCLASS_SUPER(VALUE c) +{ + return RCLASS_EXT(c)->super; +} + +static inline VALUE +RCLASS_SET_SUPER(VALUE a, VALUE b) { + RCLASS_EXT(a)->super = b; + return b; +} + struct vtm; /* defined by timev.h */ /* array.c */ @@ -220,7 +231,15 @@ VALUE rb_int_pred(VALUE num); /* object.c */ VALUE rb_obj_equal(VALUE obj1, VALUE obj2); -VALUE rb_obj_hide(VALUE obj); + +struct RBasicRaw { + VALUE flags; + VALUE klass; +}; + +#define RBASIC_CLEAR_CLASS(obj) (((struct RBasicRaw *)((VALUE)(obj)))->klass = 0) +#define RBASIC_SET_CLASS_RAW(obj, cls) (((struct RBasicRaw *)((VALUE)(obj)))->klass = (cls)) +#define RBASIC_SET_CLASS(obj, cls) do {((struct RBasicRaw *)(obj))->klass = cls; } while (0) /* parse.y */ VALUE rb_parser_get_yydebug(VALUE); diff --git a/io.c b/io.c index 1aa043efae..b5aa6c6e32 100644 --- a/io.c +++ b/io.c @@ -6061,7 +6061,7 @@ rb_io_s_popen(int argc, VALUE *argv, VALUE klass) } #endif tmp = rb_ary_dup(tmp); - RBASIC(tmp)->klass = 0; + RBASIC_CLEAR_CLASS(tmp); execarg_obj = rb_execarg_new((int)len, RARRAY_PTR(tmp), FALSE); rb_ary_clear(tmp); } @@ -6091,7 +6091,7 @@ rb_io_s_popen(int argc, VALUE *argv, VALUE klass) } return Qnil; } - RBASIC(port)->klass = klass; + RBASIC_SET_CLASS(port, klass); if (rb_block_given_p()) { return rb_ensure(rb_yield, port, io_close, port); } @@ -6487,7 +6487,7 @@ io_reopen(VALUE io, VALUE nfile) rb_io_binmode(io); } - RBASIC(io)->klass = rb_obj_class(nfile); + RBASIC_SET_CLASS(io, rb_obj_class(nfile)); return io; } diff --git a/iseq.c b/iseq.c index 1e32bc31d6..a7f50970c2 100644 --- a/iseq.c +++ b/iseq.c @@ -246,7 +246,7 @@ rb_iseq_add_mark_object(rb_iseq_t *iseq, VALUE obj) if (!RTEST(iseq->mark_ary)) { iseq->mark_ary = rb_ary_tmp_new(3); OBJ_UNTRUST(iseq->mark_ary); - RBASIC(iseq->mark_ary)->klass = 0; + RBASIC_CLEAR_CLASS(iseq->mark_ary); } rb_ary_push(iseq->mark_ary, obj); } diff --git a/marshal.c b/marshal.c index 79fd94880e..c948a1d54d 100644 --- a/marshal.c +++ b/marshal.c @@ -1554,7 +1554,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod) if (TYPE(v) != TYPE(tmp)) goto format_error; } - RBASIC(v)->klass = c; + RBASIC_SET_CLASS(v, c); } break; diff --git a/object.c b/object.c index d999c8c313..e15d89f99b 100644 --- a/object.c +++ b/object.c @@ -53,7 +53,16 @@ VALUE rb_obj_hide(VALUE obj) { if (!SPECIAL_CONST_P(obj)) { - RBASIC(obj)->klass = 0; + RBASIC_CLEAR_CLASS(obj); + } + return obj; +} + +VALUE +rb_obj_reveal(VALUE obj, VALUE klass) +{ + if (!SPECIAL_CONST_P(obj)) { + RBASIC_SET_CLASS(obj, klass); } return obj; } @@ -62,7 +71,7 @@ VALUE rb_obj_setup(VALUE obj, VALUE klass, VALUE type) { RBASIC(obj)->flags = type; - RBASIC(obj)->klass = klass; + RBASIC_SET_CLASS(obj, klass); if (rb_safe_level() >= 3) FL_SET((obj), FL_TAINT | FL_UNTRUSTED); return obj; } @@ -327,7 +336,7 @@ rb_obj_clone(VALUE obj) } clone = rb_obj_alloc(rb_obj_class(obj)); singleton = rb_singleton_class_clone_and_attach(obj, clone); - RBASIC(clone)->klass = singleton; + RBASIC_SET_CLASS(clone, singleton); if (FL_TEST(singleton, FL_SINGLETON)) { rb_singleton_class_attached(singleton, clone); } @@ -1630,7 +1639,7 @@ rb_module_s_alloc(VALUE klass) { VALUE mod = rb_module_new(); - RBASIC(mod)->klass = klass; + RBASIC_SET_CLASS(mod, klass); return mod; } @@ -1723,7 +1732,7 @@ rb_class_initialize(int argc, VALUE *argv, VALUE klass) rb_raise(rb_eTypeError, "can't inherit uninitialized class"); } } - RCLASS_SUPER(klass) = super; + RCLASS_SET_SUPER(klass, super); rb_make_metaclass(klass, RBASIC(super)->klass); rb_class_inherited(super, klass); rb_mod_initialize(klass); @@ -1858,7 +1867,7 @@ rb_class_superclass(VALUE klass) VALUE rb_class_get_superclass(VALUE klass) { - return RCLASS_SUPER(klass); + return RCLASS_EXT(klass)->super; } #define id_for_setter(name, type, message) \ diff --git a/parse.y b/parse.y index c86649736e..b02de5ca02 100644 --- a/parse.y +++ b/parse.y @@ -5298,7 +5298,7 @@ coverage(const char *f, int n) VALUE fname = rb_external_str_new_with_enc(f, strlen(f), rb_filesystem_encoding()); VALUE lines = rb_ary_new2(n); int i; - RBASIC(lines)->klass = 0; + RBASIC_CLEAR_CLASS(lines); for (i = 0; i < n; i++) RARRAY_ASET(lines, i, Qnil); RARRAY(lines)->as.heap.len = n; rb_hash_aset(coverages, fname, lines); @@ -10238,7 +10238,7 @@ static VALUE setup_fake_str(struct RString *fake_str, const char *name, long len) { fake_str->basic.flags = T_STRING|RSTRING_NOEMBED; - fake_str->basic.klass = rb_cString; + RBASIC_SET_CLASS((VALUE)fake_str, rb_cString); fake_str->as.heap.len = len; fake_str->as.heap.ptr = (char *)name; fake_str->as.heap.aux.capa = len; @@ -10426,7 +10426,7 @@ rb_id2str(ID id) if (st_lookup(global_symbols.id_str, id, &data)) { VALUE str = (VALUE)data; if (RBASIC(str)->klass == 0) - RBASIC(str)->klass = rb_cString; + RBASIC_SET_CLASS_RAW(str, rb_cString); return str; } @@ -10444,7 +10444,7 @@ rb_id2str(ID id) if (st_lookup(global_symbols.id_str, id, &data)) { VALUE str = (VALUE)data; if (RBASIC(str)->klass == 0) - RBASIC(str)->klass = rb_cString; + RBASIC_SET_CLASS_RAW(str, rb_cString); return str; } } diff --git a/proc.c b/proc.c index f4ce8382b8..32b7ef8c44 100644 --- a/proc.c +++ b/proc.c @@ -427,7 +427,7 @@ proc_new(VALUE klass, int is_lambda) } else { VALUE newprocval = proc_dup(procval); - RBASIC(newprocval)->klass = klass; + RBASIC_SET_CLASS(newprocval, klass); return newprocval; } } diff --git a/process.c b/process.c index f741d28089..afb2885c15 100644 --- a/process.c +++ b/process.c @@ -1435,7 +1435,7 @@ proc_spawn_sh(char *str) static VALUE hide_obj(VALUE obj) { - RBASIC(obj)->klass = 0; + RBASIC_CLEAR_CLASS(obj); return obj; } diff --git a/random.c b/random.c index 8f8a7f33a8..cb5fd57822 100644 --- a/random.c +++ b/random.c @@ -1435,7 +1435,7 @@ Init_RandomSeed2(void) VALUE seed = default_rand.seed; if (RB_TYPE_P(seed, T_BIGNUM)) { - RBASIC(seed)->klass = rb_cBignum; + rb_obj_reveal(seed, rb_cBignum); } } diff --git a/ruby.c b/ruby.c index fc298878ee..669e8024f6 100644 --- a/ruby.c +++ b/ruby.c @@ -542,10 +542,10 @@ add_modules(VALUE *req_list, const char *mod) if (!list) { *req_list = list = rb_ary_new(); - RBASIC(list)->klass = 0; + RBASIC_CLEAR_CLASS(list); } feature = rb_str_new2(mod); - RBASIC(feature)->klass = 0; + RBASIC_CLEAR_CLASS(feature); rb_ary_push(list, feature); } @@ -565,7 +565,7 @@ require_libraries(VALUE *req_list) while (list && RARRAY_LEN(list) > 0) { VALUE feature = rb_ary_shift(list); rb_enc_associate(feature, extenc); - RBASIC(feature)->klass = rb_cString; + RBASIC_SET_CLASS_RAW(feature, rb_cString); OBJ_FREEZE(feature); rb_funcall2(self, require, 1, &feature); } diff --git a/sprintf.c b/sprintf.c index 77fd7bc940..c818eb5dfa 100644 --- a/sprintf.c +++ b/sprintf.c @@ -1239,12 +1239,12 @@ rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap) } f._bf._base = (unsigned char *)result; f._p = (unsigned char *)RSTRING_PTR(result); - RBASIC(result)->klass = 0; + RBASIC_CLEAR_CLASS(result); f.vwrite = ruby__sfvwrite; f.vextra = ruby__sfvextra; buffer.value = 0; BSD_vfprintf(&f, fmt, ap); - RBASIC(result)->klass = rb_cString; + RBASIC_SET_CLASS_RAW(result, rb_cString); rb_str_resize(result, (char *)f._p - RSTRING_PTR(result)); #undef f @@ -1298,12 +1298,12 @@ rb_str_vcatf(VALUE str, const char *fmt, va_list ap) f._bf._base = (unsigned char *)str; f._p = (unsigned char *)RSTRING_END(str); klass = RBASIC(str)->klass; - RBASIC(str)->klass = 0; + RBASIC_CLEAR_CLASS(str); f.vwrite = ruby__sfvwrite; f.vextra = ruby__sfvextra; buffer.value = 0; BSD_vfprintf(&f, fmt, ap); - RBASIC(str)->klass = klass; + RBASIC_SET_CLASS_RAW(str, klass); rb_str_resize(str, (char *)f._p - RSTRING_PTR(str)); #undef f diff --git a/string.c b/string.c index 11e974ea32..b6adfefaea 100644 --- a/string.c +++ b/string.c @@ -519,7 +519,7 @@ rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags, olen = len; econv_wrapper = rb_obj_alloc(rb_cEncodingConverter); - RBASIC(econv_wrapper)->klass = 0; + RBASIC_CLEAR_CLASS(econv_wrapper); ec = rb_econv_open_opts(from->name, to->name, ecflags, ecopts); if (!ec) return str; DATA_PTR(econv_wrapper) = ec; @@ -1446,7 +1446,7 @@ rb_str_associate(VALUE str, VALUE add) RESIZE_CAPA(str, RSTRING_LEN(str)); } FL_SET(str, STR_ASSOC); - RBASIC(add)->klass = 0; + RBASIC_CLEAR_CLASS(add); RSTRING(str)->as.heap.aux.shared = add; } } @@ -3931,7 +3931,7 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang) rb_str_shared_replace(str, dest); } else { - RBASIC(dest)->klass = rb_obj_class(str); + RBASIC_SET_CLASS(dest, rb_obj_class(str)); OBJ_INFECT(dest, str); str = dest; } diff --git a/thread.c b/thread.c index f1f3e3050c..c2edb7e273 100644 --- a/thread.c +++ b/thread.c @@ -622,7 +622,7 @@ thread_create_core(VALUE thval, VALUE args, VALUE (*fn)(ANYARGS)) th->pending_interrupt_queue = rb_ary_tmp_new(0); th->pending_interrupt_queue_checked = 0; th->pending_interrupt_mask_stack = rb_ary_dup(current_th->pending_interrupt_mask_stack); - RBASIC(th->pending_interrupt_mask_stack)->klass = 0; + RBASIC_CLEAR_CLASS(th->pending_interrupt_mask_stack); th->interrupt_mask = 0; diff --git a/transcode.c b/transcode.c index 58a4265e0e..badb8460f3 100644 --- a/transcode.c +++ b/transcode.c @@ -2892,7 +2892,7 @@ encoded_dup(VALUE newstr, VALUE str, int encidx) return newstr; } else { - RBASIC(newstr)->klass = rb_obj_class(str); + RBASIC_SET_CLASS(newstr, rb_obj_class(str)); } return str_encode_associate(newstr, encidx); } diff --git a/vm.c b/vm.c index bd38d2d640..c8124a35b0 100644 --- a/vm.c +++ b/vm.c @@ -1730,7 +1730,7 @@ vm_init2(rb_vm_t *vm) MEMZERO(vm, rb_vm_t, 1); vm->src_encoding_index = -1; vm->at_exit.basic.flags = (T_ARRAY | RARRAY_EMBED_FLAG) & ~RARRAY_EMBED_LEN_MASK; /* len set 0 */ - vm->at_exit.basic.klass = 0; + rb_obj_hide((VALUE)&vm->at_exit); vm_default_params_setup(vm); } diff --git a/vm_eval.c b/vm_eval.c index 7b8aafeb63..783bbfe3b5 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -750,7 +750,7 @@ rb_apply(VALUE recv, ID mid, VALUE args) argc = RARRAY_LENINT(args); if (argc >= 0x100) { args = rb_ary_subseq(args, 0, argc); - RBASIC(args)->klass = 0; + RBASIC_CLEAR_CLASS(args); OBJ_FREEZE(args); ret = rb_call(recv, mid, argc, RARRAY_PTR(args), CALL_FCALL); RB_GC_GUARD(args); diff --git a/win32/file.c b/win32/file.c index 96fe61bad2..78e7331188 100644 --- a/win32/file.c +++ b/win32/file.c @@ -1,5 +1,6 @@ #include "ruby/ruby.h" #include "ruby/encoding.h" +#include "internal.h" #include #include #include @@ -193,7 +194,7 @@ code_page(rb_encoding *enc) enc_name = (char *)rb_enc_name(enc); fake_str.basic.flags = T_STRING|RSTRING_NOEMBED; - fake_str.basic.klass = rb_cString; + RBASIC_SET_CLASS_RAW((VALUE)&fake_str, rb_cString); fake_str.as.heap.len = strlen(enc_name); fake_str.as.heap.ptr = enc_name; fake_str.as.heap.aux.capa = fake_str.as.heap.len; -- cgit v1.2.3