0001-separate-RCLASS_CONST_TBL-from-RCLASS_IV_TBL.patch
| b/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) {
|
| b/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 |
} |
| b/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 | |
| b/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 |
} |
| b/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 |
| b/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 |
- |
|