ruby-changes:2052
From: ko1@a...
Date: 28 Sep 2007 15:22:03 +0900
Subject: [ruby-changes:2052] akr - Ruby:r13543 (trunk): * include/ruby/intern.h: export rb_ivar_foreach.
akr 2007-09-28 15:21:46 +0900 (Fri, 28 Sep 2007)
New Revision: 13543
Modified files:
trunk/ChangeLog
trunk/class.c
trunk/error.c
trunk/eval.c
trunk/eval_method.ci
trunk/ext/digest/digest.c
trunk/gc.c
trunk/include/ruby/intern.h
trunk/include/ruby/ruby.h
trunk/insnhelper.ci
trunk/insns.def
trunk/marshal.c
trunk/object.c
trunk/proc.c
trunk/struct.c
trunk/variable.c
trunk/vm.c
Log:
* include/ruby/intern.h: export rb_ivar_foreach.
* include/ruby/ruby.h: modify struct RObject and RClass for optimizing
T_OBJECT space. [ruby-dev:31853]
(ROBJECT_LEN, ROBJECT_PTR)
(RCLASS_IV_TBL, RCLASS_M_TBL, RCLASS_SUPER, RCLASS_IV_INDEX_TBL)
(RMODULE_IV_TBL, RMODULE_M_TBL, RMODULE_SUPER): abstract accessor
defined.
* variable.c: support the modified RObject and RClass.
* object.c: ditto.
* class.c: ditto.
* gc.c: ditto.
* marshal.c: ditto.
* eval_method.ci: use the abstract accessor.
* insns.def: ditto.
* proc.c: ditto.
* struct.c: ditto.
* eval.c: ditto.
* error.c: ditto.
* vm.c: ditto.
* insnhelper.ci: ditto.
* ext/digest/digest.c: ditto.
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/insnhelper.ci?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/include/ruby/ruby.h?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/class.c?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/variable.c?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/eval_method.ci?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/struct.c?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/gc.c?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ext/digest/digest.c?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/eval.c?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/proc.c?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/marshal.c?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/error.c?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm.c?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/object.c?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/insns.def?r1=13543&r2=13542
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/include/ruby/intern.h?r1=13543&r2=13542
Index: eval_method.ci
===================================================================
--- eval_method.ci (revision 13542)
+++ eval_method.ci (revision 13543)
@@ -143,7 +143,7 @@
st_data_t data;
NODE *old_node;
- if (st_lookup(RCLASS(klass)->m_tbl, mid, &data)) {
+ if (st_lookup(RCLASS_M_TBL(klass), mid, &data)) {
old_node = (NODE *)data;
if (old_node) {
if (nd_type(old_node->nd_body->nd_body) == NODE_CFUNC) {
@@ -166,7 +166,7 @@
}
}
- st_insert(RCLASS(klass)->m_tbl, mid, (st_data_t) body);
+ st_insert(RCLASS_M_TBL(klass), mid, (st_data_t) body);
if (node && mid != ID_ALLOCATOR && ruby_running) {
if (FL_TEST(klass, FL_SINGLETON)) {
@@ -216,8 +216,8 @@
return 0;
}
- while (!st_lookup(RCLASS(klass)->m_tbl, id, &body)) {
- klass = RCLASS(klass)->super;
+ while (!st_lookup(RCLASS_M_TBL(klass), id, &body)) {
+ klass = RCLASS_SUPER(klass);
if (!klass)
return 0;
}
@@ -305,11 +305,11 @@
if (mid == object_id || mid == __send || mid == __send_bang || mid == init) {
rb_warn("removing `%s' may cause serious problem", rb_id2name(mid));
}
- if (st_lookup(RCLASS(klass)->m_tbl, mid, &data)) {
+ if (st_lookup(RCLASS_M_TBL(klass), mid, &data)) {
body = (NODE *)data;
if (!body || !body->nd_body) body = 0;
else {
- st_delete(RCLASS(klass)->m_tbl, &mid, &data);
+ st_delete(RCLASS_M_TBL(klass), &mid, &data);
}
}
if (!body) {
@@ -583,7 +583,7 @@
orig_fbody->nd_cnt++;
- if (st_lookup(RCLASS(klass)->m_tbl, name, &data)) {
+ if (st_lookup(RCLASS_M_TBL(klass), name, &data)) {
node = (NODE *)data;
if (node) {
if (RTEST(ruby_verbose) && node->nd_cnt == 0 && node->nd_body) {
@@ -595,7 +595,7 @@
}
}
- st_insert(RCLASS(klass)->m_tbl, name,
+ st_insert(RCLASS_M_TBL(klass), name,
(st_data_t) NEW_FBODY(
NEW_METHOD(orig_fbody->nd_body->nd_body,
orig_fbody->nd_body->nd_clss,
Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h (revision 13542)
+++ include/ruby/intern.h (revision 13543)
@@ -583,6 +583,7 @@
VALUE rb_ivar_get(VALUE, ID);
VALUE rb_ivar_set(VALUE, ID, VALUE);
VALUE rb_ivar_defined(VALUE, ID);
+void rb_ivar_foreach(VALUE, int (*)(ANYARGS), st_data_t);
VALUE rb_iv_set(VALUE, const char*, VALUE);
VALUE rb_iv_get(VALUE, const char*);
VALUE rb_attr_get(VALUE, ID);
Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h (revision 13542)
+++ include/ruby/ruby.h (revision 13543)
@@ -402,10 +402,26 @@
VALUE klass;
};
+#define ROBJECT_EMBED_LEN_MAX 3
struct RObject {
struct RBasic basic;
- struct st_table *iv_tbl;
+ union {
+ struct {
+ long len;
+ VALUE *ptr;
+ } heap;
+ VALUE ary[ROBJECT_EMBED_LEN_MAX];
+ } as;
};
+#define ROBJECT_EMBED FL_USER1
+#define ROBJECT_LEN(o) \
+ ((RBASIC(o)->flags & ROBJECT_EMBED) ? \
+ ROBJECT_EMBED_LEN_MAX : \
+ ROBJECT(o)->as.heap.len)
+#define ROBJECT_PTR(o) \
+ ((RBASIC(o)->flags & ROBJECT_EMBED) ? \
+ ROBJECT(o)->as.ary : \
+ ROBJECT(o)->as.heap.ptr)
struct RValues {
struct RBasic basic;
@@ -414,12 +430,24 @@
VALUE v3;
};
+typedef struct {
+ struct st_table *iv_tbl;
+ VALUE super;
+} rb_classext_t;
+
struct RClass {
struct RBasic basic;
- struct st_table *iv_tbl;
+ rb_classext_t *ptr;
struct st_table *m_tbl;
- VALUE super;
+ struct st_table *iv_index_tbl;
};
+#define RCLASS_IV_TBL(c) (RCLASS(c)->ptr->iv_tbl)
+#define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
+#define RCLASS_SUPER(c) (RCLASS(c)->ptr->super)
+#define RCLASS_IV_INDEX_TBL(c) (RCLASS(c)->iv_index_tbl)
+#define RMODULE_IV_TBL(m) RCLASS_IV_TBL(m)
+#define RMODULE_M_TBL(m) RCLASS_M_TBL(m)
+#define RMODULE_SUPER(m) RCLASS_SUPER(m)
struct RFloat {
struct RBasic basic;
Index: insns.def
===================================================================
--- insns.def (revision 13542)
+++ insns.def (revision 13543)
@@ -973,7 +973,7 @@
if (super != rb_cObject) {
VALUE tmp;
- tmp = rb_class_real(RCLASS(klass)->super);
+ tmp = rb_class_real(RCLASS_SUPER(klass));
if (tmp != super) {
rb_raise(rb_eTypeError, "superclass mismatch for class %s",
Index: ChangeLog
===================================================================
--- ChangeLog (revision 13542)
+++ ChangeLog (revision 13543)
@@ -1,3 +1,42 @@
+Fri Sep 28 15:05:24 2007 Tanaka Akira <akr@f...>
+
+ * include/ruby/intern.h: export rb_ivar_foreach.
+
+ * include/ruby/ruby.h: modify struct RObject and RClass for optimizing
+ T_OBJECT space. [ruby-dev:31853]
+ (ROBJECT_LEN, ROBJECT_PTR)
+ (RCLASS_IV_TBL, RCLASS_M_TBL, RCLASS_SUPER, RCLASS_IV_INDEX_TBL)
+ (RMODULE_IV_TBL, RMODULE_M_TBL, RMODULE_SUPER): abstract accessor
+ defined.
+
+ * variable.c: support the modified RObject and RClass.
+
+ * object.c: ditto.
+
+ * class.c: ditto.
+
+ * gc.c: ditto.
+
+ * marshal.c: ditto.
+
+ * eval_method.ci: use the abstract accessor.
+
+ * insns.def: ditto.
+
+ * proc.c: ditto.
+
+ * struct.c: ditto.
+
+ * eval.c: ditto.
+
+ * error.c: ditto.
+
+ * vm.c: ditto.
+
+ * insnhelper.ci: ditto.
+
+ * ext/digest/digest.c: ditto.
+
Fri Sep 28 13:20:10 2007 Nobuyoshi Nakada <nobu@r...>
* io.c (rb_io_getline_fast, rb_io_getline_1): set encoding to the
Index: variable.c
===================================================================
--- variable.c (revision 13542)
+++ variable.c (revision 13543)
@@ -48,8 +48,8 @@
path = rb_str_new2(rb_id2name(name));
while (fc) {
if (fc->track == rb_cObject) break;
- if (ROBJECT(fc->track)->iv_tbl &&
- st_lookup(ROBJECT(fc->track)->iv_tbl, classpath, &tmp)) {
+ if (RCLASS_IV_TBL(fc->track) &&
+ st_lookup(RCLASS_IV_TBL(fc->track), classpath, &tmp)) {
tmp = rb_str_dup(tmp);
rb_str_cat2(tmp, "::");
rb_str_append(tmp, path);
@@ -78,7 +78,7 @@
switch (TYPE(value)) {
case T_MODULE:
case T_CLASS:
- if (!RCLASS(value)->iv_tbl) return ST_CONTINUE;
+ if (!RCLASS_IV_TBL(value)) return ST_CONTINUE;
else {
struct fc_result arg;
struct fc_result *list;
@@ -94,7 +94,7 @@
arg.klass = res->klass;
arg.track = value;
arg.prev = res;
- st_foreach(RCLASS(value)->iv_tbl, fc_i, (st_data_t)&arg);
+ st_foreach(RCLASS_IV_TBL(value), fc_i, (st_data_t)&arg);
if (arg.path) {
res->path = arg.path;
return ST_STOP;
@@ -118,18 +118,18 @@
arg.klass = klass;
arg.track = rb_cObject;
arg.prev = 0;
- if (RCLASS(rb_cObject)->iv_tbl) {
- st_foreach_safe(RCLASS(rb_cObject)->iv_tbl, fc_i, (st_data_t)&arg);
+ if (RCLASS_IV_TBL(rb_cObject)) {
+ st_foreach_safe(RCLASS_IV_TBL(rb_cObject), fc_i, (st_data_t)&arg);
}
if (arg.path == 0) {
st_foreach_safe(rb_class_tbl, fc_i, (st_data_t)&arg);
}
if (arg.path) {
- if (!ROBJECT(klass)->iv_tbl) {
- ROBJECT(klass)->iv_tbl = st_init_numtable();
+ if (!RCLASS_IV_TBL(klass)) {
+ RCLASS_IV_TBL(klass) = st_init_numtable();
}
- st_insert(ROBJECT(klass)->iv_tbl, classpath, arg.path);
- st_delete(RCLASS(klass)->iv_tbl, &tmp_classpath, 0);
+ st_insert(RCLASS_IV_TBL(klass), classpath, arg.path);
+ st_delete(RCLASS_IV_TBL(klass), &tmp_classpath, 0);
return arg.path;
}
return Qnil;
@@ -141,17 +141,17 @@
VALUE path = Qnil;
if (!klass) klass = rb_cObject;
- if (ROBJECT(klass)->iv_tbl) {
- if (!st_lookup(ROBJECT(klass)->iv_tbl, classpath, &path)) {
+ if (RCLASS_IV_TBL(klass)) {
+ if (!st_lookup(RCLASS_IV_TBL(klass), classpath, &path)) {
ID classid = rb_intern("__classid__");
- if (!st_lookup(ROBJECT(klass)->iv_tbl, classid, &path)) {
+ if (!st_lookup(RCLASS_IV_TBL(klass), classid, &path)) {
return find_class_path(klass);
}
path = rb_str_new2(rb_id2name(SYM2ID(path)));
OBJ_FREEZE(path);
- st_insert(ROBJECT(klass)->iv_tbl, classpath, path);
- st_delete(RCLASS(klass)->iv_tbl, (st_data_t*)&classid, 0);
+ st_insert(RCLASS_IV_TBL(klass), classpath, path);
+ st_delete(RCLASS_IV_TBL(klass), (st_data_t*)&classid, 0);
}
if (TYPE(path) != T_STRING) {
rb_bug("class path is not set properly");
@@ -183,7 +183,7 @@
VALUE path = classname(klass);
if (!NIL_P(path)) return path;
- if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl,
+ if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),
tmp_classpath, &path)) {
return path;
}
@@ -926,12 +926,22 @@
ivar_get(VALUE obj, ID id, int warn)
{
VALUE val;
+ VALUE klass;
+ st_data_t index;
switch (TYPE(obj)) {
case T_OBJECT:
+ klass = rb_obj_class(obj);
+ if (!RCLASS_IV_INDEX_TBL(klass)) break;
+ if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) break;
+ if (ROBJECT_LEN(obj) <= index) break;
+ val = ROBJECT_PTR(obj)[index];
+ if (val != Qundef)
+ return val;
+ break;
case T_CLASS:
case T_MODULE:
- if (ROBJECT(obj)->iv_tbl && st_lookup(ROBJECT(obj)->iv_tbl, id, &val))
+ if (RCLASS_IV_TBL(obj) && st_lookup(RCLASS_IV_TBL(obj), id, &val))
return val;
break;
default:
@@ -960,16 +970,63 @@
VALUE
rb_ivar_set(VALUE obj, ID id, VALUE val)
{
+ VALUE klass;
+ st_data_t index;
+ long i, len;
+ int ivar_extended;
+
if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
if (OBJ_FROZEN(obj)) rb_error_frozen("object");
switch (TYPE(obj)) {
case T_OBJECT:
+ klass = rb_obj_class(obj);
+ if (!RCLASS_IV_INDEX_TBL(klass))
+ RCLASS_IV_INDEX_TBL(klass) = st_init_numtable();
+ ivar_extended = 0;
+ if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) {
+ index = RCLASS_IV_INDEX_TBL(klass)->num_entries;
+ st_add_direct(RCLASS_IV_INDEX_TBL(klass), id, index);
+ ivar_extended = 1;
+ }
+ len = ROBJECT_LEN(obj);
+ if (len <= index) {
+ VALUE *ptr = ROBJECT_PTR(obj);
+ if (index < ROBJECT_EMBED_LEN_MAX) {
+ RBASIC(obj)->flags |= ROBJECT_EMBED;
+ ptr = ROBJECT(obj)->as.ary;
+ for (i = 0; i < ROBJECT_EMBED_LEN_MAX; i++) {
+ ptr[i] = Qundef;
+ }
+ }
+ else {
+ VALUE *newptr;
+ long newsize = (index+1) + (index+1)/4; /* (index+1)*1.25 */
+ if (!ivar_extended &&
+ RCLASS_IV_INDEX_TBL(klass)->num_entries < newsize) {
+ newsize = RCLASS_IV_INDEX_TBL(klass)->num_entries;
+ }
+ if (RBASIC(obj)->flags & ROBJECT_EMBED) {
+ newptr = ALLOC_N(VALUE, newsize);
+ MEMCPY(newptr, ptr, VALUE, len);
+ RBASIC(obj)->flags &= ~ROBJECT_EMBED;
+ ROBJECT(obj)->as.heap.ptr = newptr;
+ }
+ else {
+ REALLOC_N(ROBJECT(obj)->as.heap.ptr, VALUE, newsize);
+ newptr = ROBJECT(obj)->as.heap.ptr;
+ }
+ for (; len < newsize; len++)
+ newptr[len] = Qundef;
+ ROBJECT(obj)->as.heap.len = newsize;
+ }
+ }
+ ROBJECT_PTR(obj)[index] = val;
+ break;
case T_CLASS:
case T_MODULE:
- if (!ROBJECT(obj)->iv_tbl) ROBJECT(obj)->iv_tbl = st_init_numtable();
- st_insert(ROBJECT(obj)->iv_tbl, id, val);
- break;
+ if (!RCLASS_IV_TBL(obj)) RCLASS_IV_TBL(obj) = st_init_numtable();
+ st_insert(RCLASS_IV_TBL(obj), id, val);
default:
generic_ivar_set(obj, id, val);
break;
@@ -980,11 +1037,21 @@
VALUE
rb_ivar_defined(VALUE obj, ID id)
{
+ VALUE klass, val;
+ st_data_t index;
switch (TYPE(obj)) {
case T_OBJECT:
+ klass = rb_obj_class(obj);
+ if (!RCLASS_IV_INDEX_TBL(klass)) break;
+ if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) break;
+ if (ROBJECT_LEN(obj) <= index) break;
+ val = ROBJECT_PTR(obj)[index];
+ if (val != Qundef)
+ return Qtrue;
+ break;
case T_CLASS:
case T_MODULE:
- if (ROBJECT(obj)->iv_tbl && st_lookup(ROBJECT(obj)->iv_tbl, id, 0))
+ if (RCLASS_IV_TBL(obj) && st_lookup(RCLASS_IV_TBL(obj), id, 0))
return Qtrue;
break;
default:
@@ -995,9 +1062,70 @@
return Qfalse;
}
+struct obj_ivar_tag {
+ VALUE obj;
+ int (*func)(ID key, VALUE val, st_data_t arg);
+ st_data_t arg;
+};
+
static int
-ivar_i(ID key, struct global_entry *entry, VALUE ary)
+obj_ivar_i(ID key, VALUE index, struct obj_ivar_tag *data)
{
+ if (index < ROBJECT_LEN(data->obj)) {
+ VALUE val = ROBJECT_PTR(data->obj)[index];
+ if (val != Qundef) {
+ return (data->func)(key, val, data->arg);
+ }
+ }
+ return ST_CONTINUE;
+}
+
+static void
+obj_ivar_each(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
+{
+ VALUE klass = rb_obj_class(obj);
+ st_table *tbl;
+ struct obj_ivar_tag data;
+
+ tbl = RCLASS_IV_INDEX_TBL(klass);
+ if (!tbl)
+ return;
+
+ data.obj = obj;
+ data.func = func;
+ data.arg = arg;
+
+ st_foreach_safe(tbl, obj_ivar_i, (st_data_t)&data);
+}
+
+void rb_ivar_foreach(VALUE obj, int (*func)(ANYARGS), st_data_t arg)
+{
+ switch (TYPE(obj)) {
+ case T_OBJECT:
+ obj_ivar_each(obj, func, arg);
+ break;
+ case T_CLASS:
+ case T_MODULE:
+ if (RCLASS_IV_TBL(obj)) {
+ st_foreach_safe(RCLASS_IV_TBL(obj), func, arg);
+ }
+ break;
+ default:
+ if (!generic_iv_tbl) break;
+ if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
+ st_data_t tbl;
+
+ if (st_lookup(generic_iv_tbl, obj, &tbl)) {
+ st_foreach_safe((st_table *)tbl, func, arg);
+ }
+ }
+ break;
+ }
+}
+
+static int
+ivar_i(ID key, VALUE val, VALUE ary)
+{
if (rb_is_instance_id(key)) {
rb_ary_push(ary, ID2SYM(key));
}
@@ -1027,25 +1155,7 @@
VALUE ary;
ary = rb_ary_new();
- switch (TYPE(obj)) {
- case T_OBJECT:
- case T_CLASS:
- case T_MODULE:
- if (ROBJECT(obj)->iv_tbl) {
- st_foreach_safe(ROBJECT(obj)->iv_tbl, ivar_i, ary);
- }
- break;
- default:
- if (!generic_iv_tbl) break;
- if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) {
- st_data_t tbl;
-
- if (st_lookup(generic_iv_tbl, obj, &tbl)) {
- st_foreach_safe((st_table *)tbl, ivar_i, ary);
- }
- }
- break;
- }
+ rb_ivar_foreach(obj, ivar_i, ary);
return ary;
}
@@ -1076,6 +1186,8 @@
{
VALUE val = Qnil;
ID id = rb_to_id(name);
+ VALUE klass;
+ st_data_t index;
if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4)
rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable");
@@ -1086,9 +1198,19 @@
switch (TYPE(obj)) {
case T_OBJECT:
+ klass = rb_obj_class(obj);
+ if (!RCLASS_IV_INDEX_TBL(klass)) break;
+ if (!st_lookup(RCLASS_IV_INDEX_TBL(klass), id, &index)) break;
+ if (ROBJECT_LEN(obj) <= index) break;
+ val = ROBJECT_PTR(obj)[index];
+ if (val != Qundef) {
+ ROBJECT_PTR(obj)[index] = Qundef;
+ return val;
+ }
+ break;
case T_CLASS:
case T_MODULE:
- if (ROBJECT(obj)->iv_tbl && st_delete(ROBJECT(obj)->iv_tbl, (st_data_t*)&id, &val)) {
+ if (RCLASS_IV_TBL(obj) && st_delete(RCLASS_IV_TBL(obj), (st_data_t*)&id, &val)) {
return val;
}
break;
@@ -1185,11 +1307,11 @@
rb_raise(rb_eArgError, "empty file name");
}
- if ((tbl = RCLASS(mod)->iv_tbl) && st_lookup(tbl, id, &av) && av != Qundef)
+ if ((tbl = RCLASS_IV_TBL(mod)) && st_lookup(tbl, id, &av) && av != Qundef)
return;
rb_const_set(mod, id, Qundef);
- tbl = RCLASS(mod)->iv_tbl;
+ tbl = RCLASS_IV_TBL(mod);
if (st_lookup(tbl, autoload, &av)) {
tbl = check_autoload_table(av);
}
@@ -1210,8 +1332,8 @@
VALUE val;
st_data_t load = 0;
- st_delete(RCLASS(mod)->iv_tbl, (st_data_t*)&id, 0);
- if (st_lookup(RCLASS(mod)->iv_tbl, autoload, &val)) {
+ st_delete(RCLASS_IV_TBL(mod), (st_data_t*)&id, 0);
+ if (st_lookup(RCLASS_IV_TBL(mod), autoload, &val)) {
struct st_table *tbl = check_autoload_table(val);
st_delete(tbl, (st_data_t*)&id, &load);
@@ -1220,7 +1342,7 @@
DATA_PTR(val) = 0;
st_free_table(tbl);
id = autoload;
- if (st_delete(RCLASS(mod)->iv_tbl, (st_data_t*)&id, &val)) {
+ if (st_delete(RCLASS_IV_TBL(mod), (st_data_t*)&id, &val)) {
rb_gc_force_recycle(val);
}
}
@@ -1248,7 +1370,7 @@
struct st_table *tbl;
st_data_t load;
- if (!st_lookup(RCLASS(mod)->iv_tbl, autoload, &val) ||
+ if (!st_lookup(RCLASS_IV_TBL(mod), autoload, &val) ||
!(tbl = check_autoload_table(val)) || !st_lookup(tbl, id, &load)) {
return Qnil;
}
@@ -1267,7 +1389,7 @@
DATA_PTR(val) = 0;
st_free_table(tbl);
id = autoload;
- if (st_delete(RCLASS(mod)->iv_tbl, (st_data_t*)&id, &val)) {
+ if (st_delete(RCLASS_IV_TBL(mod), (st_data_t*)&id, &val)) {
rb_gc_force_recycle(val);
}
}
@@ -1277,7 +1399,7 @@
VALUE
rb_autoload_p(VALUE mod, ID id)
{
- struct st_table *tbl = RCLASS(mod)->iv_tbl;
+ struct st_table *tbl = RCLASS_IV_TBL(mod);
VALUE val;
if (!tbl || !st_lookup(tbl, id, &val) || val != Qundef) {
@@ -1295,7 +1417,7 @@
tmp = klass;
retry:
while (tmp && !NIL_P(tmp)) {
- while (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {
+ while (RCLASS_IV_TBL(tmp) && st_lookup(RCLASS_IV_TBL(tmp),id,&value)) {
if (value == Qundef) {
if (!RTEST(rb_autoload_load(tmp, id))) break;
continue;
@@ -1307,7 +1429,7 @@
return value;
}
if (!recurse && klass != rb_cObject) break;
- tmp = RCLASS(tmp)->super;
+ tmp = RCLASS_SUPER(tmp);
}
if (!exclude && !mod_retry && BUILTIN_TYPE(klass) == T_MODULE) {
mod_retry = 1;
@@ -1360,7 +1482,7 @@
rb_raise(rb_eSecurityError, "Insecure: can't remove constant");
if (OBJ_FROZEN(mod)) rb_error_frozen("class/module");
- if (RCLASS(mod)->iv_tbl && st_delete(ROBJECT(mod)->iv_tbl, (st_data_t*)&id, &val)) {
+ if (RCLASS_IV_TBL(mod) && st_delete(RCLASS_IV_TBL(mod), (st_data_t*)&id, &val)) {
if (val == Qundef) {
autoload_delete(mod, id);
val = Qnil;
@@ -1394,8 +1516,8 @@
if (!tbl) {
tbl = st_init_numtable();
}
- if (RCLASS(mod)->iv_tbl) {
- st_foreach_safe(RCLASS(mod)->iv_tbl, sv_i, (st_data_t)tbl);
+ if (RCLASS_IV_TBL(mod)) {
+ st_foreach_safe(RCLASS_IV_TBL(mod), sv_i, (st_data_t)tbl);
}
return tbl;
}
@@ -1406,7 +1528,7 @@
VALUE tmp = mod;
for (;;) {
data = rb_mod_const_at(tmp, data);
- tmp = RCLASS(tmp)->super;
+ tmp = RCLASS_SUPER(tmp);
if (!tmp) break;
if (tmp == rb_cObject && mod != rb_cObject) break;
}
@@ -1479,13 +1601,13 @@
tmp = klass;
retry:
while (tmp) {
- if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl, id, &value)) {
+ if (RCLASS_IV_TBL(tmp) && st_lookup(RCLASS_IV_TBL(tmp), id, &value)) {
if (value == Qundef && NIL_P(autoload_file(klass, id)))
return Qfalse;
return Qtrue;
}
if (!recurse && klass != rb_cObject) break;
- tmp = RCLASS(tmp)->super;
+ tmp = RCLASS_SUPER(tmp);
}
if (!exclude && !mod_retry && BUILTIN_TYPE(klass) == T_MODULE) {
mod_retry = 1;
@@ -1528,13 +1650,13 @@
rb_error_frozen("class");
}
}
- if (!RCLASS(klass)->iv_tbl) {
- RCLASS(klass)->iv_tbl = st_init_numtable();
+ if (!RCLASS_IV_TBL(klass)) {
+ RCLASS_IV_TBL(klass) = st_init_numtable();
}
else if (isconst) {
VALUE value = Qfalse;
- if (st_lookup(RCLASS(klass)->iv_tbl, id, &value)) {
+ if (st_lookup(RCLASS_IV_TBL(klass), id, &value)) {
if (value == Qundef)
autoload_delete(klass, id);
else
@@ -1545,7 +1667,7 @@
if(isconst){
rb_vm_change_state();
}
- st_insert(RCLASS(klass)->iv_tbl, id, val);
+ st_insert(RCLASS_IV_TBL(klass), id, val);
}
void
@@ -1585,7 +1707,7 @@
}
#define CVAR_LOOKUP(v,r) do {\
- if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl,id,(v))) {\
+ if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),id,(v))) {\
return (r);\
}\
if (FL_TEST(klass, FL_SINGLETON) ) {\
@@ -1596,18 +1718,18 @@
klass = obj;\
break;\
default:\
- klass = RCLASS(klass)->super;\
+ klass = RCLASS_SUPER(klass);\
break;\
}\
}\
else {\
- klass = RCLASS(klass)->super;\
+ klass = RCLASS_SUPER(klass);\
}\
while (klass) {\
- if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl,id,(v))) {\
+ if (RCLASS_IV_TBL(klass) && st_lookup(RCLASS_IV_TBL(klass),id,(v))) {\
return (r);\
}\
- klass = RCLASS(klass)->super;\
+ klass = RCLASS_SUPER(klass);\
}\
} while(0)
@@ -1695,8 +1817,8 @@
{
VALUE ary = rb_ary_new();
- if (RCLASS(obj)->iv_tbl) {
- st_foreach_safe(RCLASS(obj)->iv_tbl, cv_i, ary);
+ if (RCLASS_IV_TBL(obj)) {
+ st_foreach_safe(RCLASS_IV_TBL(obj), cv_i, ary);
}
return ary;
}
@@ -1734,7 +1856,7 @@
rb_raise(rb_eSecurityError, "Insecure: can't remove class variable");
if (OBJ_FROZEN(mod)) rb_error_frozen("class/module");
- if (RCLASS(mod)->iv_tbl && st_delete(ROBJECT(mod)->iv_tbl, (st_data_t*)&id, &val)) {
+ if (RCLASS_IV_TBL(mod) && st_delete(RCLASS_IV_TBL(mod), (st_data_t*)&id, &val)) {
return val;
}
if (rb_cvar_defined(mod, id)) {
Index: object.c
===================================================================
--- object.c (revision 13542)
+++ object.c (revision 13543)
@@ -100,7 +100,7 @@
rb_class_real(VALUE cl)
{
while (FL_TEST(cl, FL_SINGLETON) || TYPE(cl) == T_ICLASS) {
- cl = RCLASS(cl)->super;
+ cl = RCLASS_SUPER(cl);
}
return cl;
}
@@ -137,15 +137,34 @@
rb_gc_copy_finalizer(dest, obj);
switch (TYPE(obj)) {
case T_OBJECT:
+ if (!(RBASIC(dest)->flags & ROBJECT_EMBED) && ROBJECT_PTR(dest)) {
+ xfree(ROBJECT_PTR(dest));
+ ROBJECT(dest)->as.heap.ptr = 0;
+ ROBJECT(dest)->as.heap.len = 0;
+ }
+ if (RBASIC(obj)->flags & ROBJECT_EMBED) {
+ MEMCPY(ROBJECT(dest)->as.ary, ROBJECT(obj)->as.ary, VALUE, ROBJECT_EMBED_LEN_MAX);
+ RBASIC(dest)->flags |= ROBJECT_EMBED;
+ }
+ else {
+ long len = ROBJECT(obj)->as.heap.len;
+ VALUE *ptr = ALLOC_N(VALUE, len);
+ MEMCPY(ptr, ROBJECT(obj)->as.heap.ptr, VALUE, len);
+ ROBJECT(dest)->as.heap.ptr = ptr;
+ ROBJECT(dest)->as.heap.len = len;
+ RBASIC(dest)->flags &= ~ROBJECT_EMBED;
+ }
+ break;
case T_CLASS:
case T_MODULE:
- if (ROBJECT(dest)->iv_tbl) {
- st_free_table(ROBJECT(dest)->iv_tbl);
- ROBJECT(dest)->iv_tbl = 0;
+ if (RCLASS_IV_TBL(dest)) {
+ st_free_table(RCLASS_IV_TBL(dest));
+ RCLASS_IV_TBL(dest) = 0;
}
- if (ROBJECT(obj)->iv_tbl) {
- ROBJECT(dest)->iv_tbl = st_copy(ROBJECT(obj)->iv_tbl);
+ if (RCLASS_IV_TBL(obj)) {
+ RCLASS_IV_TBL(dest) = st_copy(RCLASS_IV_TBL(obj));
}
+ break;
}
rb_funcall(dest, id_init_copy, 1, obj);
}
@@ -296,7 +315,7 @@
rb_str_cat2(str, " ...");
}
else {
- st_foreach_safe(ROBJECT(obj)->iv_tbl, inspect_i, str);
+ rb_ivar_foreach(obj, inspect_i, str);
}
rb_str_cat2(str, ">");
RSTRING_PTR(str)[0] = '#';
@@ -321,15 +340,28 @@
static VALUE
rb_obj_inspect(VALUE obj)
{
- if (TYPE(obj) == T_OBJECT
- && ROBJECT(obj)->iv_tbl
- && ROBJECT(obj)->iv_tbl->num_entries > 0) {
- VALUE str;
- char *c;
- c = rb_obj_classname(obj);
- str = rb_sprintf("-<%s:%p", c, (void*)obj);
- return rb_exec_recursive(inspect_obj, obj, str);
+ if (TYPE(obj) == T_OBJECT) {
+ int has_ivar = 0;
+ VALUE *ptr = ROBJECT_PTR(obj);
+ long len = ROBJECT_LEN(obj);
+ long i;
+
+ for (i = 0; i < len; i++) {
+ if (ptr[i] != Qundef) {
+ has_ivar = 1;
+ break;
+ }
+ }
+
+ if (has_ivar) {
+ VALUE str;
+ char *c;
+
+ c = rb_obj_classname(obj);
+ str = rb_sprintf("-<%s:%p", c, (void*)obj);
+ return rb_exec_recursive(inspect_obj, obj, str);
+ }
}
return rb_funcall(obj, rb_intern("to_s"), 0, 0);
}
@@ -402,9 +434,9 @@
}
while (cl) {
- if (cl == c || RCLASS(cl)->m_tbl == RCLASS(c)->m_tbl)
+ if (cl == c || RCLASS_M_TBL(cl) == RCLASS_M_TBL(c))
return Qtrue;
- cl = RCLASS(cl)->super;
+ cl = RCLASS_SUPER(cl);
}
return Qfalse;
}
@@ -1104,15 +1136,15 @@
rb_raise(rb_eTypeError, "compared with non class/module");
}
while (mod) {
- if (RCLASS(mod)->m_tbl == RCLASS(arg)->m_tbl)
+ if (RCLASS_M_TBL(mod) == RCLASS_M_TBL(arg))
return Qtrue;
- mod = RCLASS(mod)->super;
+ mod = RCLASS_SUPER(mod);
}
/* not mod < arg; check if mod > arg */
while (arg) {
- if (RCLASS(arg)->m_tbl == RCLASS(start)->m_tbl)
+ if (RCLASS_M_TBL(arg) == RCLASS_M_TBL(start))
return Qfalse;
- arg = RCLASS(arg)->super;
+ arg = RCLASS_SUPER(arg);
}
return Qnil;
}
@@ -1277,7 +1309,7 @@
{
VALUE super;
- if (RCLASS(klass)->super != 0) {
+ if (RCLASS_SUPER(klass) != 0) {
rb_raise(rb_eTypeError, "already initialized class");
}
if (rb_scan_args(argc, argv, "01", &super) == 0) {
@@ -1286,7 +1318,7 @@
else {
rb_check_inheritable(super);
}
- RCLASS(klass)->super = super;
+ RCLASS_SUPER(klass) = super;
rb_make_metaclass(klass, RBASIC(super)->klass);
rb_class_inherited(super, klass);
rb_mod_initialize(klass);
@@ -1308,7 +1340,7 @@
{
VALUE obj;
- if (RCLASS(klass)->super == 0 && klass != rb_cBasicObject) {
+ if (RCLASS_SUPER(klass) == 0 && klass != rb_cBasicObject) {
rb_raise(rb_eTypeError, "can't instantiate uninitialized class");
}
if (FL_TEST(klass, FL_SINGLETON)) {
@@ -1367,13 +1399,13 @@
static VALUE
rb_class_superclass(VALUE klass)
{
- VALUE super = RCLASS(klass)->super;
+ VALUE super = RCLASS_SUPER(klass);
if (!super) {
rb_raise(rb_eTypeError, "uninitialized class");
}
while (TYPE(super) == T_ICLASS) {
- super = RCLASS(super)->super;
+ super = RCLASS_SUPER(super);
}
if (!super) {
return Qnil;
Index: proc.c
===================================================================
--- proc.c (revision 13542)
+++ proc.c (revision 13543)
@@ -620,13 +620,13 @@
body = body->nd_body;
if (nd_type(body) == NODE_ZSUPER) {
- klass = RCLASS(klass)->super;
+ klass = RCLASS_SUPER(klass);
goto again;
}
while (rklass != klass &&
(FL_TEST(rklass, FL_SINGLETON) || TYPE(rklass) == T_ICLASS)) {
- rklass = RCLASS(rklass)->super;
+ rklass = RCLASS_SUPER(rklass);
}
if (TYPE(klass) == T_ICLASS)
klass = RBASIC(klass)->klass;
Index: struct.c
===================================================================
--- struct.c (revision 13542)
+++ struct.c (revision 13543)
@@ -25,7 +25,7 @@
for (;;) {
if (rb_ivar_defined(c, id))
return rb_ivar_get(c, id);
- c = RCLASS(c)->super;
+ c = RCLASS_SUPER(c);
if (c == 0 || c == rb_cStruct)
return Qnil;
}
Index: eval.c
===================================================================
--- eval.c (revision 13542)
+++ eval.c (revision 13543)
@@ -2303,7 +2303,7 @@
if (nd_type(fbody->nd_body->nd_body) != NODE_ZSUPER) {
break; /* normal case: need not to follow 'super' link */
}
- m = RCLASS(m)->super;
+ m = RCLASS_SUPER(m);
if (!m)
break;
}
Index: gc.c
===================================================================
--- gc.c (revision 13542)
+++ gc.c (revision 13543)
@@ -1033,9 +1033,9 @@
case T_ICLASS:
case T_CLASS:
case T_MODULE:
- mark_tbl(obj->as.klass.m_tbl, lev);
- mark_tbl(obj->as.klass.iv_tbl, lev);
- ptr = obj->as.klass.super;
+ mark_tbl(RCLASS_M_TBL(obj), lev);
+ mark_tbl(RCLASS_IV_TBL(obj), lev);
+ ptr = RCLASS_SUPER(obj);
goto again;
case T_ARRAY:
@@ -1070,7 +1070,13 @@
break;
case T_OBJECT:
- mark_tbl(obj->as.object.iv_tbl, lev);
+ {
+ long i, len = ROBJECT_LEN(obj);
+ VALUE *ptr = ROBJECT_PTR(obj);
+ for (i = 0; i < len; i++) {
+ gc_mark(*ptr++, lev);
+ }
+ }
break;
case T_FILE:
@@ -1269,17 +1275,22 @@
switch (RANY(obj)->as.basic.flags & T_MASK) {
case T_OBJECT:
- if (RANY(obj)->as.object.iv_tbl) {
- st_free_table(RANY(obj)->as.object.iv_tbl);
+ if (!(RANY(obj)->as.basic.flags & ROBJECT_EMBED) &&
+ RANY(obj)->as.object.as.heap.ptr) {
+ RUBY_CRITICAL(free(RANY(obj)->as.object.as.heap.ptr));
}
break;
case T_MODULE:
case T_CLASS:
rb_clear_cache_by_class((VALUE)obj);
- st_free_table(RANY(obj)->as.klass.m_tbl);
- if (RANY(obj)->as.object.iv_tbl) {
- st_free_table(RANY(obj)->as.object.iv_tbl);
+ st_free_table(RCLASS_M_TBL(obj));
+ if (RCLASS_IV_TBL(obj)) {
+ st_free_table(RCLASS_IV_TBL(obj));
}
+ if (RCLASS_IV_INDEX_TBL(obj)) {
+ st_free_table(RCLASS_IV_INDEX_TBL(obj));
+ }
+ RUBY_CRITICAL(free(RANY(obj)->as.klass.ptr));
break;
case T_STRING:
rb_str_free(obj);
Index: class.c
===================================================================
--- class.c (revision 13542)
+++ class.c (revision 13543)
@@ -18,16 +18,27 @@
extern st_table *rb_class_tbl;
+static VALUE
+class_alloc(VALUE flags, VALUE klass)
+{
+ rb_classext_t *ext = ALLOC(rb_classext_t);
+ NEWOBJ(obj, struct RClass);
+ OBJSETUP(obj, klass, flags);
+ obj->ptr = ext;
+ RCLASS_IV_TBL(obj) = 0;
+ RCLASS_M_TBL(obj) = 0;
+ RCLASS_SUPER(obj) = 0;
+ RCLASS_IV_INDEX_TBL(obj) = 0;
+ return (VALUE)obj;
+}
+
VALUE
rb_class_boot(VALUE super)
{
- NEWOBJ(klass, struct RClass);
- OBJSETUP(klass, rb_cClass, T_CLASS);
+ VALUE klass = class_alloc(T_CLASS, rb_cClass);
- klass->super = super;
- klass->iv_tbl = 0;
- klass->m_tbl = 0; /* safe GC */
- klass->m_tbl = st_init_numtable();
+ RCLASS_SUPER(klass) = super;
+ RCLASS_M_TBL(klass) = st_init_numtable();
OBJ_INFECT(klass, super);
return (VALUE)klass;
@@ -87,21 +98,21 @@
if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) {
RBASIC(clone)->klass = rb_singleton_class_clone(orig);
}
- RCLASS(clone)->super = RCLASS(orig)->super;
- if (RCLASS(orig)->iv_tbl) {
+ RCLASS_SUPER(clone) = RCLASS_SUPER(orig);
+ if (RCLASS_IV_TBL(orig)) {
ID id;
- RCLASS(clone)->iv_tbl = st_copy(RCLASS(orig)->iv_tbl);
+ RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(orig));
id = rb_intern("__classpath__");
- st_delete(RCLASS(clone)->iv_tbl, (st_data_t*)&id, 0);
+ st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
id = rb_intern("__classid__");
- st_delete(RCLASS(clone)->iv_tbl, (st_data_t*)&id, 0);
+ st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
}
- if (RCLASS(orig)->m_tbl) {
+ if (RCLASS_M_TBL(orig)) {
struct clone_method_data data;
- data.tbl = RCLASS(clone)->m_tbl = st_init_numtable();
+ data.tbl = RCLASS_M_TBL(clone) = st_init_numtable();
data.klass = clone;
- st_foreach(RCLASS(orig)->m_tbl, clone_method,
+ st_foreach(RCLASS_M_TBL(orig), clone_method,
(st_data_t)&data);
}
@@ -112,7 +123,7 @@
VALUE
rb_class_init_copy(VALUE clone, VALUE orig)
{
- if (RCLASS(clone)->super != 0) {
+ if (RCLASS_SUPER(clone) != 0) {
rb_raise(rb_eTypeError, "already initialized class");
}
if (FL_TEST(orig, FL_SINGLETON)) {
@@ -131,8 +142,7 @@
else {
struct clone_method_data data;
/* copy singleton(unnamed) class */
- NEWOBJ(clone, struct RClass);
- OBJSETUP(clone, 0, RBASIC(klass)->flags);
+ VALUE clone = class_alloc(RBASIC(klass)->flags, 0);
if (BUILTIN_TYPE(obj) == T_CLASS) {
RBASIC(clone)->klass = (VALUE)clone;
@@ -141,16 +151,14 @@
RBASIC(clone)->klass = rb_singleton_class_clone(klass);
}
- clone->super = RCLASS(klass)->super;
- clone->iv_tbl = 0;
- clone->m_tbl = 0;
- if (RCLASS(klass)->iv_tbl) {
- clone->iv_tbl = st_copy(RCLASS(klass)->iv_tbl);
+ RCLASS_SUPER(clone) = RCLASS_SUPER(klass);
+ if (RCLASS_IV_TBL(klass)) {
+ RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass));
}
- clone->m_tbl = st_init_numtable();
- data.tbl = clone->m_tbl;
+ RCLASS_M_TBL(clone) = st_init_numtable();
+ data.tbl = RCLASS_M_TBL(clone);
data.klass = (VALUE)clone;
- st_foreach(RCLASS(klass)->m_tbl, clone_method,
+ st_foreach(RCLASS_M_TBL(klass), clone_method,
(st_data_t)&data);
rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone);
FL_SET(clone, FL_SINGLETON);
@@ -162,10 +170,10 @@
rb_singleton_class_attached(VALUE klass, VALUE obj)
{
if (FL_TEST(klass, FL_SINGLETON)) {
- if (!RCLASS(klass)->iv_tbl) {
- RCLASS(klass)->iv_tbl = st_init_numtable();
+ if (!RCLASS_IV_TBL(klass)) {
+ RCLASS_IV_TBL(klass) = st_init_numtable();
}
- st_insert(RCLASS(klass)->iv_tbl, rb_intern("__attached__"), obj);
+ st_insert(RCLASS_IV_TBL(klass), rb_intern("__attached__"), obj);
}
}
@@ -223,7 +231,7 @@
if (TYPE(klass) != T_CLASS) {
rb_raise(rb_eTypeError, "%s is not a class", name);
}
- if (rb_class_real(RCLASS(klass)->super) != super) {
+ if (rb_class_real(RCLASS_SUPER(klass)) != super) {
rb_name_error(id, "%s is already defined", name);
}
return klass;
@@ -252,7 +260,7 @@
if (TYPE(klass) != T_CLASS) {
rb_raise(rb_eTypeError, "%s is not a class", name);
}
- if (rb_class_real(RCLASS(klass)->super) != super) {
+ if (rb_class_real(RCLASS_SUPER(klass)) != super) {
rb_name_error(id, "%s is already defined", name);
}
return klass;
@@ -272,13 +280,9 @@
VALUE
rb_module_new(void)
{
- NEWOBJ(mdl, struct RClass);
- OBJSETUP(mdl, rb_cModule, T_MODULE);
+ VALUE mdl = class_alloc(T_MODULE, rb_cModule);
- mdl->super = 0;
- mdl->iv_tbl = 0;
- mdl->m_tbl = 0;
- mdl->m_tbl = st_init_numtable();
+ RCLASS_M_TBL(mdl) = st_init_numtable();
return (VALUE)mdl;
}
@@ -338,18 +342,17 @@
static VALUE
include_class_new(VALUE module, VALUE super)
{
- NEWOBJ(klass, struct RClass);
- OBJSETUP(klass, rb_cClass, T_ICLASS);
+ VALUE klass = class_alloc(T_ICLASS, rb_cClass);
if (BUILTIN_TYPE(module) == T_ICLASS) {
module = RBASIC(module)->klass;
}
- if (!RCLASS(module)->iv_tbl) {
- RCLASS(module)->iv_tbl = st_init_numtable();
+ if (!RCLASS_IV_TBL(module)) {
+ RCLASS_IV_TBL(module) = st_init_numtable();
}
- klass->iv_tbl = RCLASS(module)->iv_tbl;
- klass->m_tbl = RCLASS(module)->m_tbl;
- klass->super = super;
+ RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
+ RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
+ RCLASS_SUPER(klass) = super;
if (TYPE(module) == T_ICLASS) {
RBASIC(klass)->klass = RBASIC(module)->klass;
}
@@ -382,13 +385,13 @@
while (module) {
int superclass_seen = Qfalse;
- if (RCLASS(klass)->m_tbl == RCLASS(module)->m_tbl)
+ if (RCLASS_M_TBL(klass) == RCLASS_M_TBL(module))
rb_raise(rb_eArgError, "cyclic include detected");
/* ignore if the module included already in superclasses */
- for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {
+ for (p = RCLASS_SUPER(klass); p; p = RCLASS_SUPER(p)) {
switch (BUILTIN_TYPE(p)) {
case T_ICLASS:
- if (RCLASS(p)->m_tbl == RCLASS(module)->m_tbl) {
+ if (RCLASS_M_TBL(p) == RCLASS_M_TBL(module)) {
if (!superclass_seen) {
c = p; /* move insertion point */
}
@@ -400,10 +403,10 @@
break;
}
}
- c = RCLASS(c)->super = include_class_new(module, RCLASS(c)->super);
+ c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
changed = 1;
skip:
- module = RCLASS(module)->super;
+ module = RCLASS_SUPER(module);
}
if (changed) rb_clear_cache();
}
@@ -431,7 +434,7 @@
VALUE ary = rb_ary_new();
VALUE p;
- for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
+ for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
if (BUILTIN_TYPE(p) == T_ICLASS) {
rb_ary_push(ary, RBASIC(p)->klass);
}
@@ -464,7 +467,7 @@
VALUE p;
Check_Type(mod2, T_MODULE);
- for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
+ for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {
if (BUILTIN_TYPE(p) == T_ICLASS) {
if (RBASIC(p)->klass == mod2) return Qtrue;
}
@@ -493,7 +496,7 @@
{
VALUE p, ary = rb_ary_new();
- for (p = mod; p; p = RCLASS(p)->super) {
+ for (p = mod; p; p = RCLASS_SUPER(p)) {
if (FL_TEST(p, FL_SINGLETON))
continue;
if (BUILTIN_TYPE(p) == T_ICLASS) {
@@ -599,8 +602,8 @@
}
list = st_init_numtable();
- for (; mod; mod = RCLASS(mod)->super) {
- st_foreach(RCLASS(mod)->m_tbl, method_entry, (st_data_t)list);
+ for (; mod; mod = RCLASS_SUPER(mod)) {
+ st_foreach(RCLASS_M_TBL(mod), method_entry, (st_data_t)list);
if (BUILTIN_TYPE(mod) == T_ICLASS) continue;
if (FL_TEST(mod, FL_SINGLETON)) continue;
if (!recur) break;
@@ -756,13 +759,13 @@
klass = CLASS_OF(obj);
list = st_init_numtable();
if (klass && FL_TEST(klass, FL_SINGLETON)) {
- st_foreach(RCLASS(klass)->m_tbl, method_entry, (st_data_t)list);
- klass = RCLASS(klass)->super;
+ st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
+ klass = RCLASS_SUPER(klass);
}
if (RTEST(recur)) {
while (klass && (FL_TEST(klass, FL_SINGLETON) || TYPE(klass) == T_ICLASS)) {
- st_foreach(RCLASS(klass)->m_tbl, method_entry, (st_data_t)list);
- klass = RCLASS(klass)->super;
+ st_foreach(RCLASS_M_TBL(klass), method_entry, (st_data_t)list);
+ klass = RCLASS_SUPER(klass);
}
}
ary = rb_ary_new();
Index: ext/digest/digest.c
===================================================================
--- ext/digest/digest.c (revision 13542)
+++ ext/digest/digest.c (revision 13543)
@@ -426,7 +426,7 @@
VALUE obj;
rb_digest_metadata_t *algo;
- for (p = klass; p; p = RCLASS(p)->super) {
+ for (p = klass; p; p = RCLASS_SUPER(p)) {
if (rb_ivar_defined(p, id_metadata)) {
obj = rb_ivar_get(p, id_metadata);
break;
Index: error.c
===================================================================
--- error.c (revision 13542)
+++ error.c (revision 13543)
@@ -971,7 +971,7 @@
VALUE klass = CLASS_OF(exc);
while (TYPE(klass) == T_ICLASS || FL_TEST(klass, FL_SINGLETON)) {
- klass = (VALUE)RCLASS(klass)->super;
+ klass = (VALUE)RCLASS_SUPER(klass);
}
num = rb_const_get(klass, rb_intern("Errno"));
}
Index: vm.c
===================================================================
--- vm.c (revision 13542)
+++ vm.c (revision 13543)
@@ -503,7 +503,7 @@
if (!cfp->iseq) {
klass = cfp->method_klass;
- klass = RCLASS(klass)->super;
+ klass = RCLASS_SUPER(klass);
if (klass == 0) {
klass = vm_search_normal_super_klass(cfp->method_klass, recv);
@@ -1001,7 +1001,7 @@
add_opt_method(VALUE klass, ID mid, VALUE bop)
{
NODE *node;
- if (st_lookup(RCLASS(klass)->m_tbl, mid, (void *)&node) &&
+ if (st_lookup(RCLASS_M_TBL(klass), mid, (void *)&node) &&
nd_type(node->nd_body->nd_body) == NODE_CFUNC) {
st_insert(vm_opt_method_table, (st_data_t)node, (st_data_t)bop);
}
Index: marshal.c
===================================================================
--- marshal.c (revision 13542)
+++ marshal.c (revision 13543)
@@ -404,17 +404,17 @@
char *path;
if (check && FL_TEST(klass, FL_SINGLETON)) {
- if (RCLASS(klass)->m_tbl->num_entries ||
- (RCLASS(klass)->iv_tbl && RCLASS(klass)->iv_tbl->num_entries > 1)) {
+ if (RCLASS_M_TBL(klass)->num_entries ||
+ (RCLASS_IV_TBL(klass) && RCLASS_IV_TBL(klass)->num_entries > 1)) {
rb_raise(rb_eTypeError, "singleton can't be dumped");
}
- klass = RCLASS(klass)->super;
+ klass = RCLASS_SUPER(klass);
}
while (BUILTIN_TYPE(klass) == T_ICLASS) {
path = rb_class2name(RBASIC(klass)->klass);
w_byte(TYPE_EXTENDED, arg);
w_unique(path, arg);
- klass = RCLASS(klass)->super;
+ klass = RCLASS_SUPER(klass);
}
}
@@ -471,6 +471,25 @@
}
static void
+w_objivar(VALUE obj, struct dump_call_arg *arg)
+{
+ VALUE *ptr;
+ long i, len, num;
+
+ len = ROBJECT_LEN(obj);
+ ptr = ROBJECT_PTR(obj);
+ num = 0;
+ for (i = 0; i < len; i++)
+ if (ptr[i] != Qundef)
+ num += 1;
+
+ w_long(num, arg->arg);
+ if (num != 0) {
+ rb_ivar_foreach(obj, w_obj_each, (st_data_t)arg);
+ }
+}
+
+static void
w_object(VALUE obj, struct dump_arg *arg, int limit)
{
struct dump_call_arg c_arg;
@@ -682,7 +701,7 @@
case T_OBJECT:
w_class(TYPE_OBJECT, obj, arg, Qtrue);
- w_ivar(ROBJECT(obj)->iv_tbl, &c_arg);
+ w_objivar(obj, &c_arg);
break;
case T_DATA:
Index: insnhelper.ci
===================================================================
--- insnhelper.ci (revision 13542)
+++ insnhelper.ci (revision 13543)
@@ -507,7 +507,7 @@
break;
}
case NODE_ZSUPER:{
- klass = RCLASS(mn->nd_clss)->super;
+ klass = RCLASS_SUPER(mn->nd_clss);
mn = rb_method_node(klass, id);
if (mn != 0) {
@@ -998,8 +998,8 @@
}
}
search_continue:
- if (RCLASS(klass)->iv_tbl &&
- st_lookup(RCLASS(klass)->iv_tbl, id, &val)) {
+ if (RCLASS_IV_TBL(klass) &&
+ st_lookup(RCLASS_IV_TBL(klass), id, &val)) {
if (val == Qundef) {
rb_autoload_load(klass, id);
goto search_continue;
@@ -1122,16 +1122,16 @@
vm_search_normal_super_klass(VALUE klass, VALUE recv)
{
if (BUILTIN_TYPE(klass) == T_CLASS) {
- klass = RCLASS(klass)->super;
+ klass = RCLASS_SUPER(klass);
}
else if (BUILTIN_TYPE(klass) == T_MODULE) {
VALUE k = CLASS_OF(recv);
while (k) {
if (BUILTIN_TYPE(k) == T_ICLASS && RBASIC(k)->klass == klass) {
- klass = RCLASS(k)->super;
+ klass = RCLASS_SUPER(k);
break;
}
- k = RCLASS(k)->super;
+ k = RCLASS_SUPER(k);
}
}
return klass;
--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml