1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* 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
This commit is contained in:
ko1 2013-05-13 10:49:11 +00:00
parent aacd771046
commit 83aba04862
34 changed files with 190 additions and 112 deletions

View file

@ -1,3 +1,47 @@
Mon May 13 19:29:54 2013 Koichi Sasada <ko1@atdot.net>
* 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 <ko1@atdot.net> Mon May 13 18:44:14 2013 Koichi Sasada <ko1@atdot.net>
* *.c, parse.y, insns.def: use RARRAY_AREF/ASET macro * *.c, parse.y, insns.def: use RARRAY_AREF/ASET macro

34
array.c
View file

@ -2297,7 +2297,7 @@ rb_ary_sort_bang(VALUE ary)
struct ary_sort_data data; struct ary_sort_data data;
long len = RARRAY_LEN(ary); long len = RARRAY_LEN(ary);
RBASIC(tmp)->klass = 0; RBASIC_CLEAR_CLASS(tmp);
data.ary = tmp; data.ary = tmp;
data.opt_methods = 0; data.opt_methods = 0;
data.opt_inited = 0; data.opt_inited = 0;
@ -2343,7 +2343,7 @@ rb_ary_sort_bang(VALUE ary)
FL_SET(tmp, FL_FREEZE); FL_SET(tmp, FL_FREEZE);
} }
/* tmp will be GC'ed. */ /* tmp will be GC'ed. */
RBASIC(tmp)->klass = rb_cArray; RBASIC_SET_CLASS_RAW(tmp, rb_cArray); /* rb_cArray must be marked */
} }
return ary; return ary;
} }
@ -2896,7 +2896,7 @@ rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
} }
if (len == 0) return rb_ary_new2(0); if (len == 0) return rb_ary_new2(0);
arg2 = rb_ary_new4(len, RARRAY_PTR(ary)+pos); 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); rb_ary_splice(ary, pos, len, Qundef);
return arg2; return arg2;
} }
@ -3755,7 +3755,7 @@ ary_tmp_hash_new(void)
{ {
VALUE hash = rb_hash_new(); VALUE hash = rb_hash_new();
RBASIC(hash)->klass = 0; RBASIC_CLEAR_CLASS(hash);
return hash; return hash;
} }
@ -4192,7 +4192,7 @@ flatten(VALUE ary, int level, int *modified)
st_free_table(memo); st_free_table(memo);
RBASIC(result)->klass = rb_class_of(ary); RBASIC_SET_CLASS(result, rb_class_of(ary));
return result; return result;
} }
@ -4461,7 +4461,7 @@ rb_ary_sample(int argc, VALUE *argv, VALUE ary)
else { else {
VALUE *ptr_result; VALUE *ptr_result;
result = rb_ary_new4(len, ptr); result = rb_ary_new4(len, ptr);
RBASIC(result)->klass = 0; RBASIC_CLEAR_CLASS(result);
ptr_result = RARRAY_PTR(result); ptr_result = RARRAY_PTR(result);
RB_GC_GUARD(ary); RB_GC_GUARD(ary);
for (i=0; i<n; i++) { for (i=0; i<n; i++) {
@ -4470,7 +4470,7 @@ rb_ary_sample(int argc, VALUE *argv, VALUE ary)
ptr_result[j] = ptr_result[i]; ptr_result[j] = ptr_result[i];
ptr_result[i] = nv; ptr_result[i] = nv;
} }
RBASIC(result)->klass = rb_cArray; RBASIC_SET_CLASS_RAW(result, rb_cArray);
} }
ARY_SET_LEN(result, n); 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(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(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 * 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)); volatile VALUE t1 = tmpbuf(n,sizeof(char));
char *used = (char*)RSTRING_PTR(t1); char *used = (char*)RSTRING_PTR(t1);
VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */ 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 */ MEMZERO(used, char, n); /* initialize array */
permute0(n, r, p, 0, used, ary0); /* compute and yield permutations */ permute0(n, r, p, 0, used, ary0); /* compute and yield permutations */
tmpbuf_discard(t0); tmpbuf_discard(t0);
tmpbuf_discard(t1); tmpbuf_discard(t1);
RBASIC(ary0)->klass = rb_cArray; RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
} }
return ary; return ary;
} }
@ -4874,11 +4874,11 @@ rb_ary_repeated_permutation(VALUE ary, VALUE num)
volatile VALUE t0 = tmpbuf(r, sizeof(long)); volatile VALUE t0 = tmpbuf(r, sizeof(long));
long *p = (long*)RSTRING_PTR(t0); long *p = (long*)RSTRING_PTR(t0);
VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */ 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 */ rpermute0(n, r, p, 0, ary0); /* compute and yield repeated permutations */
tmpbuf_discard(t0); tmpbuf_discard(t0);
RBASIC(ary0)->klass = rb_cArray; RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
} }
return ary; return ary;
} }
@ -4971,11 +4971,11 @@ rb_ary_repeated_combination(VALUE ary, VALUE num)
volatile VALUE t0 = tmpbuf(n, sizeof(long)); volatile VALUE t0 = tmpbuf(n, sizeof(long));
long *p = (long*)RSTRING_PTR(t0); long *p = (long*)RSTRING_PTR(t0);
VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */ 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 */ rcombinate0(len, n, p, 0, n, ary0); /* compute and yield repeated combinations */
tmpbuf_discard(t0); tmpbuf_discard(t0);
RBASIC(ary0)->klass = rb_cArray; RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
} }
return ary; return ary;
} }
@ -5013,8 +5013,8 @@ rb_ary_product(int argc, VALUE *argv, VALUE ary)
long i,j; long i,j;
long resultlen = 1; long resultlen = 1;
RBASIC(t0)->klass = 0; RBASIC_CLEAR_CLASS(t0);
RBASIC(t1)->klass = 0; RBASIC_CLEAR_CLASS(t1);
/* initialize the arrays of arrays */ /* initialize the arrays of arrays */
ARY_SET_LEN(t0, n); ARY_SET_LEN(t0, n);

49
class.c
View file

@ -54,7 +54,7 @@ class_alloc(VALUE flags, VALUE klass)
RCLASS_IV_TBL(obj) = 0; RCLASS_IV_TBL(obj) = 0;
RCLASS_CONST_TBL(obj) = 0; RCLASS_CONST_TBL(obj) = 0;
RCLASS_M_TBL(obj) = 0; RCLASS_M_TBL(obj) = 0;
RCLASS_SUPER(obj) = 0; RCLASS_SET_SUPER((VALUE)obj, 0);
RCLASS_ORIGIN(obj) = (VALUE)obj; RCLASS_ORIGIN(obj) = (VALUE)obj;
RCLASS_IV_INDEX_TBL(obj) = 0; RCLASS_IV_INDEX_TBL(obj) = 0;
RCLASS_REFINED_CLASS(obj) = Qnil; RCLASS_REFINED_CLASS(obj) = Qnil;
@ -77,7 +77,7 @@ rb_class_boot(VALUE super)
{ {
VALUE klass = class_alloc(T_CLASS, rb_cClass); VALUE klass = class_alloc(T_CLASS, rb_cClass);
RCLASS_SUPER(klass) = super; RCLASS_SET_SUPER(klass, super);
RCLASS_M_TBL(klass) = st_init_numtable(); RCLASS_M_TBL(klass) = st_init_numtable();
OBJ_INFECT(klass, super); OBJ_INFECT(klass, super);
@ -200,10 +200,10 @@ rb_mod_init_copy(VALUE clone, VALUE orig)
} }
rb_obj_init_copy(clone, orig); rb_obj_init_copy(clone, orig);
if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) { 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); 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; RCLASS_EXT(clone)->allocator = RCLASS_EXT(orig)->allocator;
if (RCLASS_IV_TBL(orig)) { if (RCLASS_IV_TBL(orig)) {
st_data_t id; 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); VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
if (BUILTIN_TYPE(obj) == T_CLASS) { if (BUILTIN_TYPE(obj) == T_CLASS) {
RBASIC(clone)->klass = clone; RBASIC_SET_CLASS(clone, clone);
} }
else { 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; RCLASS_EXT(clone)->allocator = RCLASS_EXT(klass)->allocator;
if (RCLASS_IV_TBL(klass)) { if (RCLASS_IV_TBL(klass)) {
RCLASS_IV_TBL(clone) = st_copy(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 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 * whether k is a meta^(n)-class of Class class
@ -346,17 +347,18 @@ make_metaclass(VALUE klass)
rb_singleton_class_attached(metaclass, klass); rb_singleton_class_attached(metaclass, klass);
if (META_CLASS_OF_CLASS_CLASS_P(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 { else {
VALUE tmp = METACLASS_OF(klass); /* for a meta^(n)-class klass, tmp is meta^(n)-class of Class class */ VALUE tmp = METACLASS_OF(klass); /* for a meta^(n)-class klass, tmp is meta^(n)-class of Class class */
METACLASS_OF(klass) = metaclass; SET_METACLASS_OF(klass, metaclass);
METACLASS_OF(metaclass) = ENSURE_EIGENCLASS(tmp); SET_METACLASS_OF(metaclass, ENSURE_EIGENCLASS(tmp));
} }
super = RCLASS_SUPER(klass); super = RCLASS_SUPER(klass);
while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super); 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)); OBJ_INFECT(metaclass, RCLASS_SUPER(metaclass));
@ -376,10 +378,10 @@ make_singleton_class(VALUE obj)
VALUE klass = rb_class_boot(orig_class); VALUE klass = rb_class_boot(orig_class);
FL_SET(klass, FL_SINGLETON); FL_SET(klass, FL_SINGLETON);
RBASIC(obj)->klass = klass; RBASIC_SET_CLASS(obj, klass);
rb_singleton_class_attached(klass, obj); 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; return klass;
} }
@ -406,11 +408,10 @@ Init_class_hierarchy(void)
rb_cClass = boot_defclass("Class", rb_cModule); rb_cClass = boot_defclass("Class", rb_cModule);
rb_const_set(rb_cObject, rb_intern("BasicObject"), rb_cBasicObject); rb_const_set(rb_cObject, rb_intern("BasicObject"), rb_cBasicObject);
RBASIC(rb_cClass)->klass RBASIC_SET_CLASS(rb_cClass, rb_cClass);
= RBASIC(rb_cModule)->klass RBASIC_SET_CLASS(rb_cModule, rb_cClass);
= RBASIC(rb_cObject)->klass RBASIC_SET_CLASS(rb_cObject, rb_cClass);
= RBASIC(rb_cBasicObject)->klass RBASIC_SET_CLASS(rb_cBasicObject, rb_cClass);
= rb_cClass;
} }
@ -674,12 +675,12 @@ rb_include_class_new(VALUE module, VALUE super)
RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module); RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module); RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module);
RCLASS_M_TBL(klass) = RCLASS_M_TBL(RCLASS_ORIGIN(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)) { if (RB_TYPE_P(module, T_ICLASS)) {
RBASIC(klass)->klass = RBASIC(module)->klass; RBASIC_SET_CLASS(klass, RBASIC(module)->klass);
} }
else { else {
RBASIC(klass)->klass = module; RBASIC_SET_CLASS(klass, module);
} }
OBJ_INFECT(klass, module); OBJ_INFECT(klass, module);
OBJ_INFECT(klass, super); OBJ_INFECT(klass, super);
@ -748,7 +749,7 @@ include_modules_at(const VALUE klass, VALUE c, VALUE module)
break; 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)) { if (FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
VALUE refined_class = VALUE refined_class =
rb_refinement_module_get_refined_class(klass); rb_refinement_module_get_refined_class(klass);
@ -812,8 +813,8 @@ rb_prepend_module(VALUE klass, VALUE module)
origin = RCLASS_ORIGIN(klass); origin = RCLASS_ORIGIN(klass);
if (origin == klass) { if (origin == klass) {
origin = class_alloc(T_ICLASS, klass); origin = class_alloc(T_ICLASS, klass);
RCLASS_SUPER(origin) = RCLASS_SUPER(klass); RCLASS_SET_SUPER(origin, RCLASS_SUPER(klass));
RCLASS_SUPER(klass) = origin; RCLASS_SET_SUPER(klass, origin);
RCLASS_ORIGIN(klass) = origin; RCLASS_ORIGIN(klass) = origin;
RCLASS_M_TBL(origin) = RCLASS_M_TBL(klass); RCLASS_M_TBL(origin) = RCLASS_M_TBL(klass);
RCLASS_M_TBL(klass) = st_init_numtable(); RCLASS_M_TBL(klass) = st_init_numtable();

View file

@ -299,7 +299,7 @@ r_value(VALUE value)
#define INIT_ANCHOR(name) \ #define INIT_ANCHOR(name) \
(name##_body__.last = &name##_body__.anchor, name = &name##_body__) (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" #include "optinsn.inc"
#if OPT_INSTRUCTIONS_UNIFICATION #if OPT_INSTRUCTIONS_UNIFICATION

View file

@ -1866,7 +1866,7 @@ Init_Encoding(void)
rb_define_singleton_method(rb_cEncoding, "locale_charmap", rb_locale_charmap, 0); rb_define_singleton_method(rb_cEncoding, "locale_charmap", rb_locale_charmap, 0);
list = rb_ary_new2(enc_table.count); list = rb_ary_new2(enc_table.count);
RBASIC(list)->klass = 0; RBASIC_CLEAR_CLASS(list);
rb_encoding_list = list; rb_encoding_list = list;
rb_gc_register_mark_object(list); rb_gc_register_mark_object(list);

6
enum.c
View file

@ -931,7 +931,7 @@ enum_sort_by(VALUE obj)
else { else {
ary = rb_ary_new(); ary = rb_ary_new();
} }
RBASIC(ary)->klass = 0; RBASIC_CLEAR_CLASS(ary);
buf = rb_ary_tmp_new(SORT_BY_BUFSIZE*2); buf = rb_ary_tmp_new(SORT_BY_BUFSIZE*2);
rb_ary_store(buf, SORT_BY_BUFSIZE*2-1, Qnil); rb_ary_store(buf, SORT_BY_BUFSIZE*2-1, Qnil);
memo = NEW_MEMO(0, 0, 0); memo = NEW_MEMO(0, 0, 0);
@ -958,7 +958,7 @@ enum_sort_by(VALUE obj)
RARRAY_ASET(ary, i/2, RARRAY_AREF(ary, i)); RARRAY_ASET(ary, i/2, RARRAY_AREF(ary, i));
} }
rb_ary_resize(ary, RARRAY_LEN(ary)/2); rb_ary_resize(ary, RARRAY_LEN(ary)/2);
RBASIC(ary)->klass = rb_cArray; RBASIC_SET_CLASS_RAW(ary, rb_cArray);
OBJ_INFECT(ary, memo); OBJ_INFECT(ary, memo);
return ary; return ary;
@ -2309,7 +2309,7 @@ enum_cycle(int argc, VALUE *argv, VALUE obj)
if (n <= 0) return Qnil; if (n <= 0) return Qnil;
} }
ary = rb_ary_new(); ary = rb_ary_new();
RBASIC(ary)->klass = 0; RBASIC_CLEAR_CLASS(ary);
rb_block_call(obj, id_each, 0, 0, cycle_i, ary); rb_block_call(obj, id_each, 0, 0, cycle_i, ary);
len = RARRAY_LEN(ary); len = RARRAY_LEN(ary);
if (len == 0) return Qnil; if (len == 0) return Qnil;

View file

@ -1261,7 +1261,7 @@ syserr_initialize(int argc, VALUE *argv, VALUE self)
if (!RB_TYPE_P(self, T_OBJECT)) { /* insurance to avoid type crash */ if (!RB_TYPE_P(self, T_OBJECT)) { /* insurance to avoid type crash */
rb_raise(rb_eTypeError, "invalid instance type"); rb_raise(rb_eTypeError, "invalid instance type");
} }
RBASIC(self)->klass = klass; RBASIC_SET_CLASS(self, klass);
} }
} }
else { else {

9
eval.c
View file

@ -1060,7 +1060,7 @@ hidden_identity_hash_new()
VALUE hash = rb_hash_new(); VALUE hash = rb_hash_new();
rb_funcall(hash, rb_intern("compare_by_identity"), 0); 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; return hash;
} }
@ -1097,7 +1097,7 @@ rb_using_refinement(NODE *cref, VALUE klass, VALUE module)
module = RCLASS_SUPER(module); module = RCLASS_SUPER(module);
while (module && module != klass) { while (module && module != klass) {
FL_SET(module, RMODULE_IS_OVERLAID); 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; RCLASS_REFINED_CLASS(c) = klass;
module = RCLASS_SUPER(module); module = RCLASS_SUPER(module);
} }
@ -1156,8 +1156,7 @@ add_activated_refinement(VALUE activated_refinements,
refinement = RCLASS_SUPER(refinement); refinement = RCLASS_SUPER(refinement);
while (refinement) { while (refinement) {
FL_SET(refinement, RMODULE_IS_OVERLAID); FL_SET(refinement, RMODULE_IS_OVERLAID);
c = RCLASS_SUPER(c) = c = RCLASS_SET_SUPER(c, rb_include_class_new(refinement, RCLASS_SUPER(c)));
rb_include_class_new(refinement, RCLASS_SUPER(c));
RCLASS_REFINED_CLASS(c) = klass; RCLASS_REFINED_CLASS(c) = klass;
refinement = RCLASS_SUPER(refinement); refinement = RCLASS_SUPER(refinement);
} }
@ -1210,7 +1209,7 @@ rb_mod_refine(VALUE module, VALUE klass)
refinement = rb_hash_lookup(refinements, klass); refinement = rb_hash_lookup(refinements, klass);
if (NIL_P(refinement)) { if (NIL_P(refinement)) {
refinement = rb_module_new(); refinement = rb_module_new();
RCLASS_SUPER(refinement) = klass; RCLASS_SET_SUPER(refinement, klass);
FL_SET(refinement, RMODULE_IS_REFINEMENT); FL_SET(refinement, RMODULE_IS_REFINEMENT);
CONST_ID(id_refined_class, "__refined_class__"); CONST_ID(id_refined_class, "__refined_class__");
rb_ivar_set(refinement, id_refined_class, klass); rb_ivar_set(refinement, id_refined_class, klass);

View file

@ -25,7 +25,7 @@ rb_coverage_start(VALUE klass)
if (!RTEST(rb_get_coverages())) { if (!RTEST(rb_get_coverages())) {
if (rb_coverages == Qundef) { if (rb_coverages == Qundef) {
rb_coverages = rb_hash_new(); rb_coverages = rb_hash_new();
RBASIC(rb_coverages)->klass = 0; rb_obj_hide(rb_coverages);
} }
rb_set_coverages(rb_coverages); rb_set_coverages(rb_coverages);
} }

View file

@ -1217,7 +1217,7 @@ readline_s_set_special_prefixes(VALUE self, VALUE str)
if (!NIL_P(str)) { if (!NIL_P(str)) {
OutputStringValue(str); OutputStringValue(str);
str = rb_str_dup_frozen(str); str = rb_str_dup_frozen(str);
RBASIC(str)->klass = 0; rb_obj_hide(str);
} }
rb_ivar_set(mReadline, id_special_prefixes, str); rb_ivar_set(mReadline, id_special_prefixes, str);
if (NIL_P(str)) { if (NIL_P(str)) {
@ -1252,7 +1252,7 @@ readline_s_get_special_prefixes(VALUE self)
str = rb_ivar_get(mReadline, id_special_prefixes); str = rb_ivar_get(mReadline, id_special_prefixes);
if (!NIL_P(str)) { if (!NIL_P(str)) {
str = rb_str_dup_frozen(str); str = rb_str_dup_frozen(str);
RBASIC(str)->klass = rb_cString; rb_obj_reveal(str, rb_cString);
} }
return str; return str;
} }

View file

@ -1677,7 +1677,7 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
else { else {
rb_str_resize(dat_str, ss); rb_str_resize(dat_str, ss);
OBJ_TAINT(dat_str); OBJ_TAINT(dat_str);
RBASIC(dat_str)->klass = rb_cString; rb_obj_reveal(dat_str, rb_cString);
} }
ret = rb_ary_new3(3, dat_str, ret = rb_ary_new3(3, dat_str,

View file

@ -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); arg.str = str = rb_tainted_str_new(0, buflen);
klass = RBASIC(str)->klass; klass = RBASIC(str)->klass;
RBASIC(str)->klass = 0; rb_obj_hide(str);
while (rb_io_check_closed(fptr), while (rb_io_check_closed(fptr),
rb_thread_wait_fd(arg.fd), 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)) { if (slen < RSTRING_LEN(str)) {
rb_str_set_len(str, slen); rb_str_set_len(str, slen);
} }

View file

@ -633,7 +633,7 @@ zstream_expand_buffer(struct zstream *z)
VALUE self = (VALUE)z->stream.opaque; VALUE self = (VALUE)z->stream.opaque;
rb_str_resize(z->buf, z->buf_filled); 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); OBJ_INFECT(z->buf, self);
rb_protect(rb_yield, z->buf, &state); 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->buf_filled = 0;
z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf); z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
z->stream.avail_out = MAX_UINT(size); z->stream.avail_out = MAX_UINT(size);
RBASIC(z->buf)->klass = 0; rb_obj_hide(z->buf);
} }
else if (z->stream.avail_out != size) { else if (z->stream.avail_out != size) {
rb_str_resize(z->buf, z->buf_filled + 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->buf_filled = len;
z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf); z->stream.next_out = (Bytef*)RSTRING_PTR(z->buf);
z->stream.avail_out = 0; z->stream.avail_out = 0;
RBASIC(z->buf)->klass = 0; rb_obj_hide(z->buf);
return; return;
} }
@ -782,7 +782,7 @@ zstream_detach_buffer(struct zstream *z)
else { else {
dst = z->buf; dst = z->buf;
rb_str_resize(dst, z->buf_filled); rb_str_resize(dst, z->buf_filled);
RBASIC(dst)->klass = rb_cString; rb_obj_reveal(dst, rb_cString);
} }
OBJ_INFECT(dst, self); OBJ_INFECT(dst, self);
@ -811,7 +811,7 @@ zstream_shift_buffer(struct zstream *z, long len)
} }
dst = rb_str_subseq(z->buf, 0, len); dst = rb_str_subseq(z->buf, 0, len);
RBASIC(dst)->klass = rb_cString; rb_obj_reveal(dst, rb_cString);
z->buf_filled -= len; z->buf_filled -= len;
memmove(RSTRING_PTR(z->buf), RSTRING_PTR(z->buf) + len, memmove(RSTRING_PTR(z->buf), RSTRING_PTR(z->buf) + len,
z->buf_filled); z->buf_filled);
@ -866,7 +866,7 @@ zstream_append_input(struct zstream *z, const Bytef *src, long len)
if (NIL_P(z->input)) { if (NIL_P(z->input)) {
z->input = rb_str_buf_new(len); z->input = rb_str_buf_new(len);
rb_str_buf_cat(z->input, (const char*)src, len); rb_str_buf_cat(z->input, (const char*)src, len);
RBASIC(z->input)->klass = 0; rb_obj_hide(z->input);
} }
else { else {
rb_str_buf_cat(z->input, (const char*)src, len); rb_str_buf_cat(z->input, (const char*)src, len);
@ -915,10 +915,10 @@ zstream_detach_input(struct zstream *z)
} }
else { else {
dst = z->input; dst = z->input;
RBASIC(dst)->klass = rb_cString; rb_obj_reveal(dst, rb_cString);
} }
z->input = Qnil; z->input = Qnil;
RBASIC(dst)->klass = rb_cString; rb_obj_reveal(dst, rb_cString);
return dst; return dst;
} }

8
file.c
View file

@ -4013,7 +4013,7 @@ rb_file_join(VALUE ary, VALUE sep)
len += RSTRING_LEN(sep) * (RARRAY_LEN(ary) - 1); len += RSTRING_LEN(sep) * (RARRAY_LEN(ary) - 1);
} }
result = rb_str_buf_new(len); result = rb_str_buf_new(len);
RBASIC(result)->klass = 0; RBASIC_CLEAR_CLASS(result);
OBJ_INFECT(result, ary); OBJ_INFECT(result, ary);
for (i=0; i<RARRAY_LEN(ary); i++) { for (i=0; i<RARRAY_LEN(ary); i++) {
tmp = RARRAY_AREF(ary, i); tmp = RARRAY_AREF(ary, i);
@ -4057,7 +4057,7 @@ rb_file_join(VALUE ary, VALUE sep)
rb_str_buf_append(result, tmp); rb_str_buf_append(result, tmp);
rb_enc_associate(result, enc); rb_enc_associate(result, enc);
} }
RBASIC(result)->klass = rb_cString; RBASIC_SET_CLASS_RAW(result, rb_cString);
return result; return result;
} }
@ -5304,7 +5304,7 @@ is_explicit_relative(const char *path)
static VALUE static VALUE
copy_path_class(VALUE path, VALUE orig) 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); OBJ_FREEZE(path);
return 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; if (!load_path) return 0;
fname = rb_str_dup(*filep); fname = rb_str_dup(*filep);
RBASIC(fname)->klass = 0; RBASIC_CLEAR_CLASS(fname);
fnlen = RSTRING_LEN(fname); fnlen = RSTRING_LEN(fname);
tmp = rb_str_tmp_new(MAXPATHLEN + 2); tmp = rb_str_tmp_new(MAXPATHLEN + 2);
rb_enc_associate_index(tmp, rb_usascii_encindex()); rb_enc_associate_index(tmp, rb_usascii_encindex());

6
gc.c
View file

@ -1330,7 +1330,7 @@ define_final0(VALUE obj, VALUE block)
} }
else { else {
table = rb_ary_new3(1, block); table = rb_ary_new3(1, block);
RBASIC(table)->klass = 0; RBASIC_CLEAR_CLASS(table);
st_add_direct(finalizer_table, obj, table); st_add_direct(finalizer_table, obj, table);
} }
return block; return block;
@ -1405,7 +1405,7 @@ run_final(rb_objspace_t *objspace, VALUE obj)
objspace->heap.final_num--; objspace->heap.final_num--;
RBASIC(obj)->klass = 0; RBASIC_CLEAR_CLASS(obj);
if (RTYPEDDATA_P(obj)) { if (RTYPEDDATA_P(obj)) {
free_func = RTYPEDDATA_TYPE(obj)->function.dfree; 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; if (!RCLASS_EXT(obj)) break;
mark_tbl(objspace, RCLASS_IV_TBL(obj)); mark_tbl(objspace, RCLASS_IV_TBL(obj));
mark_const_tbl(objspace, RCLASS_CONST_TBL(obj)); mark_const_tbl(objspace, RCLASS_CONST_TBL(obj));
ptr = RCLASS_SUPER(obj); ptr = RCLASS_SUPER((VALUE)obj);
goto again; goto again;
case T_ARRAY: case T_ARRAY:

4
hash.c
View file

@ -2708,7 +2708,7 @@ env_reject_bang(VALUE ehash)
RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size); RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
keys = env_keys(); /* rb_secure(4); */ keys = env_keys(); /* rb_secure(4); */
RBASIC(keys)->klass = 0; RBASIC_CLEAR_CLASS(keys);
for (i=0; i<RARRAY_LEN(keys); i++) { for (i=0; i<RARRAY_LEN(keys); i++) {
VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i)); VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
if (!NIL_P(val)) { if (!NIL_P(val)) {
@ -2812,7 +2812,7 @@ env_select_bang(VALUE ehash)
RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size); RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
keys = env_keys(); /* rb_secure(4); */ keys = env_keys(); /* rb_secure(4); */
RBASIC(keys)->klass = 0; RBASIC_CLEAR_CLASS(keys);
for (i=0; i<RARRAY_LEN(keys); i++) { for (i=0; i<RARRAY_LEN(keys); i++) {
VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i)); VALUE val = rb_f_getenv(Qnil, RARRAY_AREF(keys, i));
if (!NIL_P(val)) { if (!NIL_P(val)) {

View file

@ -683,13 +683,18 @@ VALUE rb_obj_setup(VALUE obj, VALUE klass, VALUE type);
struct RBasic { struct RBasic {
VALUE flags; VALUE flags;
VALUE klass; const VALUE klass;
} }
#ifdef __GNUC__ #ifdef __GNUC__
__attribute__((aligned(sizeof(VALUE)))) __attribute__((aligned(sizeof(VALUE))))
#endif #endif
; ;
VALUE rb_obj_hide(VALUE obj);
VALUE rb_obj_reveal(VALUE obj, VALUE klass); /* do not use this API to change klass information */
#define RBASIC_CLASS(obj) (RBASIC(obj)->klass)
#define ROBJECT_EMBED_LEN_MAX 3 #define ROBJECT_EMBED_LEN_MAX 3
struct RObject { struct RObject {
struct RBasic basic; struct RBasic basic;

View file

@ -64,9 +64,7 @@ struct rb_classext_struct {
rb_alloc_func_t allocator; rb_alloc_func_t allocator;
}; };
#undef RCLASS_SUPER
#define RCLASS_EXT(c) (RCLASS(c)->ptr) #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_IV_TBL(c) (RCLASS_EXT(c)->iv_tbl)
#define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl) #define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl)
#define RCLASS_M_TBL(c) (RCLASS(c)->m_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_ORIGIN(c) (RCLASS_EXT(c)->origin)
#define RCLASS_REFINED_CLASS(c) (RCLASS_EXT(c)->refined_class) #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 */ struct vtm; /* defined by timev.h */
/* array.c */ /* array.c */
@ -220,7 +231,15 @@ VALUE rb_int_pred(VALUE num);
/* object.c */ /* object.c */
VALUE rb_obj_equal(VALUE obj1, VALUE obj2); 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 */ /* parse.y */
VALUE rb_parser_get_yydebug(VALUE); VALUE rb_parser_get_yydebug(VALUE);

6
io.c
View file

@ -6061,7 +6061,7 @@ rb_io_s_popen(int argc, VALUE *argv, VALUE klass)
} }
#endif #endif
tmp = rb_ary_dup(tmp); tmp = rb_ary_dup(tmp);
RBASIC(tmp)->klass = 0; RBASIC_CLEAR_CLASS(tmp);
execarg_obj = rb_execarg_new((int)len, RARRAY_PTR(tmp), FALSE); execarg_obj = rb_execarg_new((int)len, RARRAY_PTR(tmp), FALSE);
rb_ary_clear(tmp); rb_ary_clear(tmp);
} }
@ -6091,7 +6091,7 @@ rb_io_s_popen(int argc, VALUE *argv, VALUE klass)
} }
return Qnil; return Qnil;
} }
RBASIC(port)->klass = klass; RBASIC_SET_CLASS(port, klass);
if (rb_block_given_p()) { if (rb_block_given_p()) {
return rb_ensure(rb_yield, port, io_close, port); return rb_ensure(rb_yield, port, io_close, port);
} }
@ -6487,7 +6487,7 @@ io_reopen(VALUE io, VALUE nfile)
rb_io_binmode(io); rb_io_binmode(io);
} }
RBASIC(io)->klass = rb_obj_class(nfile); RBASIC_SET_CLASS(io, rb_obj_class(nfile));
return io; return io;
} }

2
iseq.c
View file

@ -246,7 +246,7 @@ rb_iseq_add_mark_object(rb_iseq_t *iseq, VALUE obj)
if (!RTEST(iseq->mark_ary)) { if (!RTEST(iseq->mark_ary)) {
iseq->mark_ary = rb_ary_tmp_new(3); iseq->mark_ary = rb_ary_tmp_new(3);
OBJ_UNTRUST(iseq->mark_ary); OBJ_UNTRUST(iseq->mark_ary);
RBASIC(iseq->mark_ary)->klass = 0; RBASIC_CLEAR_CLASS(iseq->mark_ary);
} }
rb_ary_push(iseq->mark_ary, obj); rb_ary_push(iseq->mark_ary, obj);
} }

View file

@ -1554,7 +1554,7 @@ r_object0(struct load_arg *arg, int *ivp, VALUE extmod)
if (TYPE(v) != TYPE(tmp)) goto format_error; if (TYPE(v) != TYPE(tmp)) goto format_error;
} }
RBASIC(v)->klass = c; RBASIC_SET_CLASS(v, c);
} }
break; break;

View file

@ -53,7 +53,16 @@ VALUE
rb_obj_hide(VALUE obj) rb_obj_hide(VALUE obj)
{ {
if (!SPECIAL_CONST_P(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; return obj;
} }
@ -62,7 +71,7 @@ VALUE
rb_obj_setup(VALUE obj, VALUE klass, VALUE type) rb_obj_setup(VALUE obj, VALUE klass, VALUE type)
{ {
RBASIC(obj)->flags = 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); if (rb_safe_level() >= 3) FL_SET((obj), FL_TAINT | FL_UNTRUSTED);
return obj; return obj;
} }
@ -327,7 +336,7 @@ rb_obj_clone(VALUE obj)
} }
clone = rb_obj_alloc(rb_obj_class(obj)); clone = rb_obj_alloc(rb_obj_class(obj));
singleton = rb_singleton_class_clone_and_attach(obj, clone); singleton = rb_singleton_class_clone_and_attach(obj, clone);
RBASIC(clone)->klass = singleton; RBASIC_SET_CLASS(clone, singleton);
if (FL_TEST(singleton, FL_SINGLETON)) { if (FL_TEST(singleton, FL_SINGLETON)) {
rb_singleton_class_attached(singleton, clone); rb_singleton_class_attached(singleton, clone);
} }
@ -1630,7 +1639,7 @@ rb_module_s_alloc(VALUE klass)
{ {
VALUE mod = rb_module_new(); VALUE mod = rb_module_new();
RBASIC(mod)->klass = klass; RBASIC_SET_CLASS(mod, klass);
return mod; return mod;
} }
@ -1723,7 +1732,7 @@ rb_class_initialize(int argc, VALUE *argv, VALUE klass)
rb_raise(rb_eTypeError, "can't inherit uninitialized class"); 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_make_metaclass(klass, RBASIC(super)->klass);
rb_class_inherited(super, klass); rb_class_inherited(super, klass);
rb_mod_initialize(klass); rb_mod_initialize(klass);
@ -1858,7 +1867,7 @@ rb_class_superclass(VALUE klass)
VALUE VALUE
rb_class_get_superclass(VALUE klass) rb_class_get_superclass(VALUE klass)
{ {
return RCLASS_SUPER(klass); return RCLASS_EXT(klass)->super;
} }
#define id_for_setter(name, type, message) \ #define id_for_setter(name, type, message) \

View file

@ -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 fname = rb_external_str_new_with_enc(f, strlen(f), rb_filesystem_encoding());
VALUE lines = rb_ary_new2(n); VALUE lines = rb_ary_new2(n);
int i; int i;
RBASIC(lines)->klass = 0; RBASIC_CLEAR_CLASS(lines);
for (i = 0; i < n; i++) RARRAY_ASET(lines, i, Qnil); for (i = 0; i < n; i++) RARRAY_ASET(lines, i, Qnil);
RARRAY(lines)->as.heap.len = n; RARRAY(lines)->as.heap.len = n;
rb_hash_aset(coverages, fname, lines); rb_hash_aset(coverages, fname, lines);
@ -10238,7 +10238,7 @@ static VALUE
setup_fake_str(struct RString *fake_str, const char *name, long len) setup_fake_str(struct RString *fake_str, const char *name, long len)
{ {
fake_str->basic.flags = T_STRING|RSTRING_NOEMBED; 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.len = len;
fake_str->as.heap.ptr = (char *)name; fake_str->as.heap.ptr = (char *)name;
fake_str->as.heap.aux.capa = len; fake_str->as.heap.aux.capa = len;
@ -10426,7 +10426,7 @@ rb_id2str(ID id)
if (st_lookup(global_symbols.id_str, id, &data)) { if (st_lookup(global_symbols.id_str, id, &data)) {
VALUE str = (VALUE)data; VALUE str = (VALUE)data;
if (RBASIC(str)->klass == 0) if (RBASIC(str)->klass == 0)
RBASIC(str)->klass = rb_cString; RBASIC_SET_CLASS_RAW(str, rb_cString);
return str; return str;
} }
@ -10444,7 +10444,7 @@ rb_id2str(ID id)
if (st_lookup(global_symbols.id_str, id, &data)) { if (st_lookup(global_symbols.id_str, id, &data)) {
VALUE str = (VALUE)data; VALUE str = (VALUE)data;
if (RBASIC(str)->klass == 0) if (RBASIC(str)->klass == 0)
RBASIC(str)->klass = rb_cString; RBASIC_SET_CLASS_RAW(str, rb_cString);
return str; return str;
} }
} }

2
proc.c
View file

@ -427,7 +427,7 @@ proc_new(VALUE klass, int is_lambda)
} }
else { else {
VALUE newprocval = proc_dup(procval); VALUE newprocval = proc_dup(procval);
RBASIC(newprocval)->klass = klass; RBASIC_SET_CLASS(newprocval, klass);
return newprocval; return newprocval;
} }
} }

View file

@ -1435,7 +1435,7 @@ proc_spawn_sh(char *str)
static VALUE static VALUE
hide_obj(VALUE obj) hide_obj(VALUE obj)
{ {
RBASIC(obj)->klass = 0; RBASIC_CLEAR_CLASS(obj);
return obj; return obj;
} }

View file

@ -1435,7 +1435,7 @@ Init_RandomSeed2(void)
VALUE seed = default_rand.seed; VALUE seed = default_rand.seed;
if (RB_TYPE_P(seed, T_BIGNUM)) { if (RB_TYPE_P(seed, T_BIGNUM)) {
RBASIC(seed)->klass = rb_cBignum; rb_obj_reveal(seed, rb_cBignum);
} }
} }

6
ruby.c
View file

@ -542,10 +542,10 @@ add_modules(VALUE *req_list, const char *mod)
if (!list) { if (!list) {
*req_list = list = rb_ary_new(); *req_list = list = rb_ary_new();
RBASIC(list)->klass = 0; RBASIC_CLEAR_CLASS(list);
} }
feature = rb_str_new2(mod); feature = rb_str_new2(mod);
RBASIC(feature)->klass = 0; RBASIC_CLEAR_CLASS(feature);
rb_ary_push(list, feature); rb_ary_push(list, feature);
} }
@ -565,7 +565,7 @@ require_libraries(VALUE *req_list)
while (list && RARRAY_LEN(list) > 0) { while (list && RARRAY_LEN(list) > 0) {
VALUE feature = rb_ary_shift(list); VALUE feature = rb_ary_shift(list);
rb_enc_associate(feature, extenc); rb_enc_associate(feature, extenc);
RBASIC(feature)->klass = rb_cString; RBASIC_SET_CLASS_RAW(feature, rb_cString);
OBJ_FREEZE(feature); OBJ_FREEZE(feature);
rb_funcall2(self, require, 1, &feature); rb_funcall2(self, require, 1, &feature);
} }

View file

@ -1239,12 +1239,12 @@ rb_enc_vsprintf(rb_encoding *enc, const char *fmt, va_list ap)
} }
f._bf._base = (unsigned char *)result; f._bf._base = (unsigned char *)result;
f._p = (unsigned char *)RSTRING_PTR(result); f._p = (unsigned char *)RSTRING_PTR(result);
RBASIC(result)->klass = 0; RBASIC_CLEAR_CLASS(result);
f.vwrite = ruby__sfvwrite; f.vwrite = ruby__sfvwrite;
f.vextra = ruby__sfvextra; f.vextra = ruby__sfvextra;
buffer.value = 0; buffer.value = 0;
BSD_vfprintf(&f, fmt, ap); 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)); rb_str_resize(result, (char *)f._p - RSTRING_PTR(result));
#undef f #undef f
@ -1298,12 +1298,12 @@ rb_str_vcatf(VALUE str, const char *fmt, va_list ap)
f._bf._base = (unsigned char *)str; f._bf._base = (unsigned char *)str;
f._p = (unsigned char *)RSTRING_END(str); f._p = (unsigned char *)RSTRING_END(str);
klass = RBASIC(str)->klass; klass = RBASIC(str)->klass;
RBASIC(str)->klass = 0; RBASIC_CLEAR_CLASS(str);
f.vwrite = ruby__sfvwrite; f.vwrite = ruby__sfvwrite;
f.vextra = ruby__sfvextra; f.vextra = ruby__sfvextra;
buffer.value = 0; buffer.value = 0;
BSD_vfprintf(&f, fmt, ap); 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)); rb_str_resize(str, (char *)f._p - RSTRING_PTR(str));
#undef f #undef f

View file

@ -519,7 +519,7 @@ rb_str_conv_enc_opts(VALUE str, rb_encoding *from, rb_encoding *to, int ecflags,
olen = len; olen = len;
econv_wrapper = rb_obj_alloc(rb_cEncodingConverter); 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); ec = rb_econv_open_opts(from->name, to->name, ecflags, ecopts);
if (!ec) return str; if (!ec) return str;
DATA_PTR(econv_wrapper) = ec; DATA_PTR(econv_wrapper) = ec;
@ -1446,7 +1446,7 @@ rb_str_associate(VALUE str, VALUE add)
RESIZE_CAPA(str, RSTRING_LEN(str)); RESIZE_CAPA(str, RSTRING_LEN(str));
} }
FL_SET(str, STR_ASSOC); FL_SET(str, STR_ASSOC);
RBASIC(add)->klass = 0; RBASIC_CLEAR_CLASS(add);
RSTRING(str)->as.heap.aux.shared = 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); rb_str_shared_replace(str, dest);
} }
else { else {
RBASIC(dest)->klass = rb_obj_class(str); RBASIC_SET_CLASS(dest, rb_obj_class(str));
OBJ_INFECT(dest, str); OBJ_INFECT(dest, str);
str = dest; str = dest;
} }

View file

@ -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 = rb_ary_tmp_new(0);
th->pending_interrupt_queue_checked = 0; th->pending_interrupt_queue_checked = 0;
th->pending_interrupt_mask_stack = rb_ary_dup(current_th->pending_interrupt_mask_stack); 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; th->interrupt_mask = 0;

View file

@ -2892,7 +2892,7 @@ encoded_dup(VALUE newstr, VALUE str, int encidx)
return newstr; return newstr;
} }
else { else {
RBASIC(newstr)->klass = rb_obj_class(str); RBASIC_SET_CLASS(newstr, rb_obj_class(str));
} }
return str_encode_associate(newstr, encidx); return str_encode_associate(newstr, encidx);
} }

2
vm.c
View file

@ -1730,7 +1730,7 @@ vm_init2(rb_vm_t *vm)
MEMZERO(vm, rb_vm_t, 1); MEMZERO(vm, rb_vm_t, 1);
vm->src_encoding_index = -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.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); vm_default_params_setup(vm);
} }

View file

@ -750,7 +750,7 @@ rb_apply(VALUE recv, ID mid, VALUE args)
argc = RARRAY_LENINT(args); argc = RARRAY_LENINT(args);
if (argc >= 0x100) { if (argc >= 0x100) {
args = rb_ary_subseq(args, 0, argc); args = rb_ary_subseq(args, 0, argc);
RBASIC(args)->klass = 0; RBASIC_CLEAR_CLASS(args);
OBJ_FREEZE(args); OBJ_FREEZE(args);
ret = rb_call(recv, mid, argc, RARRAY_PTR(args), CALL_FCALL); ret = rb_call(recv, mid, argc, RARRAY_PTR(args), CALL_FCALL);
RB_GC_GUARD(args); RB_GC_GUARD(args);

View file

@ -1,5 +1,6 @@
#include "ruby/ruby.h" #include "ruby/ruby.h"
#include "ruby/encoding.h" #include "ruby/encoding.h"
#include "internal.h"
#include <winbase.h> #include <winbase.h>
#include <wchar.h> #include <wchar.h>
#include <shlwapi.h> #include <shlwapi.h>
@ -193,7 +194,7 @@ code_page(rb_encoding *enc)
enc_name = (char *)rb_enc_name(enc); enc_name = (char *)rb_enc_name(enc);
fake_str.basic.flags = T_STRING|RSTRING_NOEMBED; 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.len = strlen(enc_name);
fake_str.as.heap.ptr = enc_name; fake_str.as.heap.ptr = enc_name;
fake_str.as.heap.aux.capa = fake_str.as.heap.len; fake_str.as.heap.aux.capa = fake_str.as.heap.len;