18 |
18 |
VALUE recv;
|
19 |
19 |
VALUE rclass;
|
20 |
20 |
ID id;
|
21 |
|
rb_method_entry_t me;
|
|
21 |
rb_method_entry_t *me;
|
22 |
22 |
};
|
23 |
23 |
|
24 |
24 |
VALUE rb_cUnboundMethod;
|
... | ... | |
861 |
861 |
struct METHOD *data = ptr;
|
862 |
862 |
rb_gc_mark(data->rclass);
|
863 |
863 |
rb_gc_mark(data->recv);
|
864 |
|
rb_mark_method_entry(&data->me);
|
|
864 |
rb_mark_method_entry(data->me);
|
865 |
865 |
}
|
866 |
866 |
|
867 |
867 |
static void
|
868 |
868 |
bm_free(void *ptr)
|
869 |
869 |
{
|
870 |
870 |
struct METHOD *data = ptr;
|
871 |
|
rb_method_definition_t *def = data->me.def;
|
872 |
|
if (def->alias_count == 0)
|
873 |
|
xfree(def);
|
874 |
|
else if (def->alias_count > 0)
|
875 |
|
def->alias_count--;
|
|
871 |
rb_unlink_method_entry(data->me);
|
876 |
872 |
xfree(ptr);
|
877 |
873 |
}
|
878 |
874 |
|
... | ... | |
909 |
905 |
VALUE rclass = klass;
|
910 |
906 |
ID rid = id;
|
911 |
907 |
struct METHOD *data;
|
912 |
|
rb_method_entry_t *me, meb;
|
|
908 |
rb_method_entry_t *me, *me2, meb;
|
913 |
909 |
rb_method_definition_t *def = 0;
|
914 |
910 |
rb_method_flag_t flag = NOEX_UNDEF;
|
915 |
911 |
|
... | ... | |
973 |
969 |
}
|
974 |
970 |
|
975 |
971 |
gen_method:
|
|
972 |
me2 = ALLOC(rb_method_entry_t);
|
976 |
973 |
method = TypedData_Make_Struct(mclass, struct METHOD, &method_data_type, data);
|
977 |
974 |
|
978 |
975 |
data->recv = obj;
|
979 |
976 |
data->rclass = rclass;
|
980 |
977 |
data->id = rid;
|
981 |
|
data->me = *me;
|
982 |
|
if (def) def->alias_count++;
|
|
978 |
data->me = me2;
|
|
979 |
*data->me = *me;
|
|
980 |
data->me->def->alias_count++;
|
983 |
981 |
|
984 |
982 |
OBJ_INFECT(method, klass);
|
985 |
983 |
|
... | ... | |
1033 |
1031 |
m1 = (struct METHOD *)DATA_PTR(method);
|
1034 |
1032 |
m2 = (struct METHOD *)DATA_PTR(other);
|
1035 |
1033 |
|
1036 |
|
if (!rb_method_entry_eq(&m1->me, &m2->me) ||
|
|
1034 |
if (!rb_method_entry_eq(m1->me, m2->me) ||
|
1037 |
1035 |
m1->rclass != m2->rclass ||
|
1038 |
1036 |
m1->recv != m2->recv) {
|
1039 |
1037 |
return Qfalse;
|
... | ... | |
1058 |
1056 |
TypedData_Get_Struct(method, struct METHOD, &method_data_type, m);
|
1059 |
1057 |
hash = rb_hash_start((st_index_t)m->rclass);
|
1060 |
1058 |
hash = rb_hash_uint(hash, (st_index_t)m->recv);
|
1061 |
|
hash = rb_hash_uint(hash, (st_index_t)m->me.def);
|
|
1059 |
hash = rb_hash_uint(hash, (st_index_t)m->me->def);
|
1062 |
1060 |
hash = rb_hash_end(hash);
|
1063 |
1061 |
|
1064 |
1062 |
return INT2FIX(hash);
|
... | ... | |
1078 |
1076 |
{
|
1079 |
1077 |
VALUE method;
|
1080 |
1078 |
struct METHOD *orig, *data;
|
|
1079 |
rb_method_entry_t *me2;
|
1081 |
1080 |
|
|
1081 |
me2 = ALLOC(rb_method_entry_t);
|
1082 |
1082 |
TypedData_Get_Struct(obj, struct METHOD, &method_data_type, orig);
|
1083 |
1083 |
method = TypedData_Make_Struct(rb_cUnboundMethod, struct METHOD,
|
1084 |
1084 |
&method_data_type, data);
|
1085 |
1085 |
data->recv = Qundef;
|
1086 |
1086 |
data->id = orig->id;
|
1087 |
|
data->me = orig->me;
|
1088 |
|
if (orig->me.def) orig->me.def->alias_count++;
|
|
1087 |
data->me = me2;
|
|
1088 |
*data->me = *orig->me;
|
|
1089 |
if (orig->me->def) orig->me->def->alias_count++;
|
1089 |
1090 |
data->rclass = orig->rclass;
|
1090 |
1091 |
OBJ_INFECT(method, obj);
|
1091 |
1092 |
|
... | ... | |
1137 |
1138 |
struct METHOD *data;
|
1138 |
1139 |
|
1139 |
1140 |
TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
|
1140 |
|
return data->me.klass;
|
|
1141 |
return data->me->klass;
|
1141 |
1142 |
}
|
1142 |
1143 |
|
1143 |
1144 |
static void
|
... | ... | |
1351 |
1352 |
rb_class2name(rclass));
|
1352 |
1353 |
}
|
1353 |
1354 |
}
|
1354 |
|
rb_method_entry_set(mod, id, &method->me, noex);
|
|
1355 |
rb_method_entry_set(mod, id, method->me, noex);
|
1355 |
1356 |
}
|
1356 |
1357 |
else if (rb_obj_is_proc(body)) {
|
1357 |
1358 |
rb_proc_t *proc;
|
... | ... | |
1417 |
1418 |
{
|
1418 |
1419 |
VALUE clone;
|
1419 |
1420 |
struct METHOD *orig, *data;
|
|
1421 |
rb_method_entry_t *me2;
|
1420 |
1422 |
|
|
1423 |
me2 = ALLOC(rb_method_entry_t);
|
1421 |
1424 |
TypedData_Get_Struct(self, struct METHOD, &method_data_type, orig);
|
1422 |
1425 |
clone = TypedData_Make_Struct(CLASS_OF(self), struct METHOD, &method_data_type, data);
|
1423 |
1426 |
CLONESETUP(clone, self);
|
1424 |
1427 |
*data = *orig;
|
1425 |
|
if (data->me.def) data->me.def->alias_count++;
|
|
1428 |
data->me = me2;
|
|
1429 |
*data->me = *orig->me;
|
|
1430 |
if (data->me->def) data->me->def->alias_count++;
|
1426 |
1431 |
|
1427 |
1432 |
return clone;
|
1428 |
1433 |
}
|
... | ... | |
1463 |
1468 |
rb_thread_t *th = GET_THREAD();
|
1464 |
1469 |
|
1465 |
1470 |
PASS_PASSED_BLOCK_TH(th);
|
1466 |
|
result = rb_vm_call(th, data->recv, data->id, argc, argv, &data->me);
|
|
1471 |
result = rb_vm_call(th, data->recv, data->id, argc, argv, data->me);
|
1467 |
1472 |
}
|
1468 |
1473 |
POP_TAG();
|
1469 |
1474 |
if (safe >= 0)
|
... | ... | |
1568 |
1573 |
umethod_bind(VALUE method, VALUE recv)
|
1569 |
1574 |
{
|
1570 |
1575 |
struct METHOD *data, *bound;
|
|
1576 |
rb_method_entry_t *me2;
|
1571 |
1577 |
|
1572 |
1578 |
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
|
1573 |
1579 |
|
... | ... | |
1582 |
1588 |
}
|
1583 |
1589 |
}
|
1584 |
1590 |
|
|
1591 |
me2 = ALLOC(rb_method_entry_t);
|
1585 |
1592 |
method = TypedData_Make_Struct(rb_cMethod, struct METHOD, &method_data_type, bound);
|
1586 |
1593 |
*bound = *data;
|
1587 |
|
if (bound->me.def) bound->me.def->alias_count++;
|
|
1594 |
bound->me = me2;
|
|
1595 |
*bound->me = *data->me;
|
|
1596 |
if (bound->me->def) bound->me->def->alias_count++;
|
1588 |
1597 |
bound->recv = recv;
|
1589 |
1598 |
bound->rclass = CLASS_OF(recv);
|
1590 |
1599 |
|
... | ... | |
1681 |
1690 |
struct METHOD *data;
|
1682 |
1691 |
|
1683 |
1692 |
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
|
1684 |
|
return rb_method_entry_arity(&data->me);
|
|
1693 |
return rb_method_entry_arity(data->me);
|
1685 |
1694 |
}
|
1686 |
1695 |
|
1687 |
1696 |
int
|
... | ... | |
1703 |
1712 |
struct METHOD *data;
|
1704 |
1713 |
|
1705 |
1714 |
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
|
1706 |
|
return data->me.def;
|
|
1715 |
return data->me->def;
|
1707 |
1716 |
}
|
1708 |
1717 |
|
1709 |
1718 |
static rb_iseq_t *
|
... | ... | |
1786 |
1795 |
rb_str_buf_cat2(str, s);
|
1787 |
1796 |
rb_str_buf_cat2(str, ": ");
|
1788 |
1797 |
|
1789 |
|
if (FL_TEST(data->me.klass, FL_SINGLETON)) {
|
1790 |
|
VALUE v = rb_ivar_get(data->me.klass, attached);
|
|
1798 |
if (FL_TEST(data->me->klass, FL_SINGLETON)) {
|
|
1799 |
VALUE v = rb_ivar_get(data->me->klass, attached);
|
1791 |
1800 |
|
1792 |
1801 |
if (data->recv == Qundef) {
|
1793 |
|
rb_str_buf_append(str, rb_inspect(data->me.klass));
|
|
1802 |
rb_str_buf_append(str, rb_inspect(data->me->klass));
|
1794 |
1803 |
}
|
1795 |
1804 |
else if (data->recv == v) {
|
1796 |
1805 |
rb_str_buf_append(str, rb_inspect(v));
|
... | ... | |
1806 |
1815 |
}
|
1807 |
1816 |
else {
|
1808 |
1817 |
rb_str_buf_cat2(str, rb_class2name(data->rclass));
|
1809 |
|
if (data->rclass != data->me.klass) {
|
|
1818 |
if (data->rclass != data->me->klass) {
|
1810 |
1819 |
rb_str_buf_cat2(str, "(");
|
1811 |
|
rb_str_buf_cat2(str, rb_class2name(data->me.klass));
|
|
1820 |
rb_str_buf_cat2(str, rb_class2name(data->me->klass));
|
1812 |
1821 |
rb_str_buf_cat2(str, ")");
|
1813 |
1822 |
}
|
1814 |
1823 |
}
|
1815 |
1824 |
rb_str_buf_cat2(str, sharp);
|
1816 |
|
rb_str_append(str, rb_id2str(data->me.def->original_id));
|
1817 |
|
if (data->me.def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {
|
|
1825 |
rb_str_append(str, rb_id2str(data->me->def->original_id));
|
|
1826 |
if (data->me->def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) {
|
1818 |
1827 |
rb_str_buf_cat2(str, " (not-implemented)");
|
1819 |
1828 |
}
|
1820 |
1829 |
rb_str_buf_cat2(str, ">");
|