Project

General

Profile

Feature #3908 ยป 0001-separate-RCLASS_CONST_TBL-from-RCLASS_IV_TBL.patch

mame (Yusuke Endoh), 10/06/2010 12:19 AM

View differences:

class.c
52 52
    OBJSETUP(obj, klass, flags);
53 53
    obj->ptr = ext;
54 54
    RCLASS_IV_TBL(obj) = 0;
55
    RCLASS_CONST_TBL(obj) = 0;
55 56
    RCLASS_M_TBL(obj) = 0;
56 57
    RCLASS_SUPER(obj) = 0;
57 58
    RCLASS_IV_INDEX_TBL(obj) = 0;
......
161 162
	CONST_ID(id, "__classid__");
162 163
	st_delete(RCLASS_IV_TBL(clone), (st_data_t*)&id, 0);
163 164
    }
165
    if (RCLASS_CONST_TBL(orig)) {
166
	if (RCLASS_CONST_TBL(clone)) {
167
	    st_free_table(RCLASS_CONST_TBL(clone));
168
	}
169
	RCLASS_CONST_TBL(clone) = st_copy(RCLASS_CONST_TBL(orig));
170
    }
164 171
    if (RCLASS_M_TBL(orig)) {
165 172
	struct clone_method_data data;
166 173

  
......
216 223
	if (RCLASS_IV_TBL(klass)) {
217 224
	    RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass));
218 225
	}
226
	if (RCLASS_CONST_TBL(klass)) {
227
	    RCLASS_CONST_TBL(clone) = st_copy(RCLASS_CONST_TBL(klass));
228
	}
219 229
	RCLASS_M_TBL(clone) = st_init_numtable();
220 230
	data.tbl = RCLASS_M_TBL(clone);
221 231
	data.klass = (VALUE)clone;
......
605 615
    if (!RCLASS_IV_TBL(module)) {
606 616
	RCLASS_IV_TBL(module) = st_init_numtable();
607 617
    }
618
    if (!RCLASS_CONST_TBL(module)) {
619
	RCLASS_CONST_TBL(module) = st_init_numtable();
620
    }
608 621
    RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
622
    RCLASS_CONST_TBL(klass) = RCLASS_CONST_TBL(module);
609 623
    RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
610 624
    RCLASS_SUPER(klass) = super;
611 625
    if (TYPE(module) == T_ICLASS) {
gc.c
1717 1717
      case T_MODULE:
1718 1718
	mark_m_tbl(objspace, RCLASS_M_TBL(obj), lev);
1719 1719
	mark_tbl(objspace, RCLASS_IV_TBL(obj), lev);
1720
	mark_tbl(objspace, RCLASS_CONST_TBL(obj), lev);
1720 1721
	ptr = RCLASS_SUPER(obj);
1721 1722
	goto again;
1722 1723

  
......
2164 2165
	if (RCLASS_IV_TBL(obj)) {
2165 2166
	    st_free_table(RCLASS_IV_TBL(obj));
2166 2167
	}
2168
	if (RCLASS_CONST_TBL(obj)) {
2169
	    st_free_table(RCLASS_CONST_TBL(obj));
2170
	}
2167 2171
	if (RCLASS_IV_INDEX_TBL(obj)) {
2168 2172
	    st_free_table(RCLASS_IV_INDEX_TBL(obj));
2169 2173
	}
include/ruby/ruby.h
606 606
typedef struct {
607 607
    VALUE super;
608 608
    struct st_table *iv_tbl;
609
    struct st_table *const_tbl;
609 610
} rb_classext_t;
610 611

  
611 612
struct RClass {
......
615 616
    struct st_table *iv_index_tbl;
616 617
};
617 618
#define RCLASS_IV_TBL(c) (RCLASS(c)->ptr->iv_tbl)
619
#define RCLASS_CONST_TBL(c) (RCLASS(c)->ptr->const_tbl)
618 620
#define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
619 621
#define RCLASS_SUPER(c) (RCLASS(c)->ptr->super)
620 622
#define RCLASS_IV_INDEX_TBL(c) (RCLASS(c)->iv_index_tbl)
621 623
#define RMODULE_IV_TBL(m) RCLASS_IV_TBL(m)
624
#define RMODULE_CONST_TBL(m) RCLASS_CONST_TBL(m)
622 625
#define RMODULE_M_TBL(m) RCLASS_M_TBL(m)
623 626
#define RMODULE_SUPER(m) RCLASS_SUPER(m)
624 627

  
object.c
221 221
	    st_free_table(RCLASS_IV_TBL(dest));
222 222
	    RCLASS_IV_TBL(dest) = 0;
223 223
	}
224
	if (RCLASS_CONST_TBL(dest)) {
225
	    st_free_table(RCLASS_CONST_TBL(dest));
226
	    RCLASS_CONST_TBL(dest) = 0;
227
	}
224 228
	if (RCLASS_IV_TBL(obj)) {
225 229
	    RCLASS_IV_TBL(dest) = st_copy(RCLASS_IV_TBL(obj));
226 230
	}
variable.c
82 82
    switch (TYPE(value)) {
83 83
      case T_MODULE:
84 84
      case T_CLASS:
85
	if (!RCLASS_IV_TBL(value)) return ST_CONTINUE;
85
	if (!RCLASS_CONST_TBL(value)) return ST_CONTINUE;
86 86
	else {
87 87
	    struct fc_result arg;
88 88
	    struct fc_result *list;
......
98 98
	    arg.klass = res->klass;
99 99
	    arg.track = value;
100 100
	    arg.prev = res;
101
	    st_foreach(RCLASS_IV_TBL(value), fc_i, (st_data_t)&arg);
101
	    st_foreach(RCLASS_CONST_TBL(value), fc_i, (st_data_t)&arg);
102 102
	    if (arg.path) {
103 103
		res->path = arg.path;
104 104
		return ST_STOP;
......
122 122
    arg.klass = klass;
123 123
    arg.track = rb_cObject;
124 124
    arg.prev = 0;
125
    if (RCLASS_IV_TBL(rb_cObject)) {
126
	st_foreach_safe(RCLASS_IV_TBL(rb_cObject), fc_i, (st_data_t)&arg);
125
    if (RCLASS_CONST_TBL(rb_cObject)) {
126
	st_foreach_safe(RCLASS_CONST_TBL(rb_cObject), fc_i, (st_data_t)&arg);
127 127
    }
128 128
    if (arg.path == 0) {
129 129
	st_foreach_safe(rb_class_tbl, fc_i, (st_data_t)&arg);
......
1438 1438
	rb_raise(rb_eArgError, "empty file name");
1439 1439
    }
1440 1440

  
1441
    if ((tbl = RCLASS_IV_TBL(mod)) && st_lookup(tbl, (st_data_t)id, &av) && (VALUE)av != Qundef)
1441
    if ((tbl = RCLASS_CONST_TBL(mod)) && st_lookup(tbl, (st_data_t)id, &av) && (VALUE)av != Qundef)
1442 1442
	return;
1443 1443

  
1444 1444
    rb_const_set(mod, id, Qundef);
......
1462 1462
{
1463 1463
    st_data_t val, load = 0, n = id;
1464 1464

  
1465
    st_delete(RCLASS_IV_TBL(mod), &n, 0);
1465
    st_delete(RCLASS_CONST_TBL(mod), &n, 0);
1466 1466
    if (st_lookup(RCLASS_IV_TBL(mod), (st_data_t)autoload, &val)) {
1467 1467
	struct st_table *tbl = check_autoload_table((VALUE)val);
1468 1468

  
......
1470 1470

  
1471 1471
	if (tbl->num_entries == 0) {
1472 1472
	    n = autoload;
1473
	    st_delete(RCLASS_IV_TBL(mod), &n, &val);
1473
	    st_delete(RCLASS_CONST_TBL(mod), &n, &val);
1474 1474
	}
1475 1475
    }
1476 1476

  
......
1527 1527
static int
1528 1528
autoload_node_id(VALUE mod, ID id)
1529 1529
{
1530
    struct st_table *tbl = RCLASS_IV_TBL(mod);
1530
    struct st_table *tbl = RCLASS_CONST_TBL(mod);
1531 1531
    st_data_t val;
1532 1532

  
1533 1533
    if (!tbl || !st_lookup(tbl, (st_data_t)id, &val) || (VALUE)val != Qundef) {
......
1575 1575
  retry:
1576 1576
    while (RTEST(tmp)) {
1577 1577
	VALUE am = 0;
1578
	while (RCLASS_IV_TBL(tmp) && st_lookup(RCLASS_IV_TBL(tmp), (st_data_t)id, &value)) {
1578
	while (RCLASS_CONST_TBL(tmp) && st_lookup(RCLASS_CONST_TBL(tmp), (st_data_t)id, &value)) {
1579 1579
	    if (value == Qundef) {
1580 1580
		if (am == tmp) break;
1581 1581
		am = tmp;
......
1650 1650
	rb_raise(rb_eSecurityError, "Insecure: can't remove constant");
1651 1651
    if (OBJ_FROZEN(mod)) rb_error_frozen("class/module");
1652 1652

  
1653
    if (!RCLASS_IV_TBL(mod) || !st_delete(RCLASS_IV_TBL(mod), &n, &v)) {
1653
    if (!RCLASS_CONST_TBL(mod) || !st_delete(RCLASS_CONST_TBL(mod), &n, &v)) {
1654 1654
	if (rb_const_defined_at(mod, id)) {
1655 1655
	    rb_name_error(id, "cannot remove %s::%s",
1656 1656
			  rb_class2name(mod), rb_id2name(id));
......
1687 1687
    if (!tbl) {
1688 1688
	tbl = st_init_numtable();
1689 1689
    }
1690
    if (RCLASS_IV_TBL(mod)) {
1691
	st_foreach_safe(RCLASS_IV_TBL(mod), sv_i, (st_data_t)tbl);
1690
    if (RCLASS_CONST_TBL(mod)) {
1691
	st_foreach_safe(RCLASS_CONST_TBL(mod), sv_i, (st_data_t)tbl);
1692 1692
    }
1693 1693
    return tbl;
1694 1694
}
......
1773 1773
    tmp = klass;
1774 1774
  retry:
1775 1775
    while (tmp) {
1776
	if (RCLASS_IV_TBL(tmp) && st_lookup(RCLASS_IV_TBL(tmp), (st_data_t)id, &value)) {
1776
	if (RCLASS_CONST_TBL(tmp) && st_lookup(RCLASS_CONST_TBL(tmp), (st_data_t)id, &value)) {
1777 1777
	    if ((VALUE)value == Qundef && !autoload_node((VALUE)klass, id, 0))
1778 1778
		return (int)Qfalse;
1779 1779
	    return (int)Qtrue;
......
1807 1807
    return rb_const_defined_0(klass, id, TRUE, FALSE);
1808 1808
}
1809 1809

  
1810
static void
1811
mod_av_set(VALUE klass, ID id, VALUE val, int isconst)
1810
void
1811
check_before_mod_set(VALUE klass, ID id, VALUE val, const char *dest)
1812 1812
{
1813
    const char *dest = isconst ? "constant" : "class variable";
1814

  
1815 1813
    if (!OBJ_UNTRUSTED(klass) && rb_safe_level() >= 4)
1816 1814
	rb_raise(rb_eSecurityError, "Insecure: can't set %s", dest);
1817 1815
    if (OBJ_FROZEN(klass)) {
......
1822 1820
	    rb_error_frozen("class");
1823 1821
	}
1824 1822
    }
1825
    if (!RCLASS_IV_TBL(klass)) {
1826
	RCLASS_IV_TBL(klass) = st_init_numtable();
1827
    }
1828
    else if (isconst) {
1829
	st_data_t value;
1830

  
1831
	if (st_lookup(RCLASS_IV_TBL(klass), (st_data_t)id, &value)) {
1832
	    if ((VALUE)value == Qundef)
1833
		autoload_delete(klass, id);
1834
	    else
1835
		rb_warn("already initialized %s %s", dest, rb_id2name(id));
1836
	}
1837
    }
1838

  
1839
    if (isconst){
1840
	rb_vm_change_state();
1841
    }
1842
    st_insert(RCLASS_IV_TBL(klass), (st_data_t)id, (st_data_t)val);
1843 1823
}
1844 1824

  
1845 1825
void
......
1849 1829
	rb_raise(rb_eTypeError, "no class/module to define constant %s",
1850 1830
		 rb_id2name(id));
1851 1831
    }
1852
    mod_av_set(klass, id, val, TRUE);
1832

  
1833
    check_before_mod_set(klass, id, val, "constant");
1834
    if (!RCLASS_CONST_TBL(klass)) {
1835
	RCLASS_CONST_TBL(klass) = st_init_numtable();
1836
    }
1837
    else {
1838
	st_data_t value;
1839

  
1840
	if (st_lookup(RCLASS_CONST_TBL(klass), (st_data_t)id, &value)) {
1841
	    if ((VALUE)value == Qundef)
1842
		autoload_delete(klass, id);
1843
	    else
1844
		rb_warn("already initialized constant %s", rb_id2name(id));
1845
	}
1846
    }
1847

  
1848
    rb_vm_change_state();
1849
    st_insert(RCLASS_CONST_TBL(klass), (st_data_t)id, (st_data_t)val);
1853 1850
}
1854 1851

  
1855 1852
void
......
1931 1928
    else {
1932 1929
	target = tmp;
1933 1930
    }
1934
    mod_av_set(target, id, val, FALSE);
1931

  
1932
    check_before_mod_set(target, id, val, "class variable");
1933
    if (!RCLASS_IV_TBL(target)) {
1934
	RCLASS_IV_TBL(target) = st_init_numtable();
1935
    }
1936

  
1937
    st_insert(RCLASS_IV_TBL(target), (st_data_t)id, (st_data_t)val);
1935 1938
}
1936 1939

  
1937 1940
VALUE
vm_insnhelper.c
1168 1168
	    if (!NIL_P(klass)) {
1169 1169
		VALUE am = 0;
1170 1170
	      search_continue:
1171
		if (RCLASS_IV_TBL(klass) &&
1172
		    st_lookup(RCLASS_IV_TBL(klass), id, &val)) {
1171
		if (RCLASS_CONST_TBL(klass) &&
1172
		    st_lookup(RCLASS_CONST_TBL(klass), id, &val)) {
1173 1173
		    if (val == Qundef) {
1174 1174
			if (am == klass) break;
1175 1175
			am = klass;
1176
-