Reduce diff to proc.c @ b0b9f7201acab05c2a3ad92c3043a1f01df3e17f
* So it's easy to review https://github.com/ruby/ruby/pull/6242 + https://github.com/ruby/ruby/pull/6467 and there are less changes overall.
This commit is contained in:
parent
c6319026ca
commit
aa490f9442
76
proc.c
76
proc.c
@ -1681,42 +1681,16 @@ mnew_missing_by_name(VALUE klass, VALUE obj, VALUE *name, int scope, VALUE mclas
|
|||||||
return mnew_missing(klass, obj, SYM2ID(vid), mclass);
|
return mnew_missing(klass, obj, SYM2ID(vid), mclass);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline VALUE
|
|
||||||
method_entry_defined_class(const rb_method_entry_t *me)
|
|
||||||
{
|
|
||||||
VALUE defined_class = me->defined_class;
|
|
||||||
return defined_class ? defined_class : me->owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const rb_method_entry_t*
|
|
||||||
zsuper_resolve(const rb_method_entry_t *me, VALUE *iclass_ptr)
|
|
||||||
{
|
|
||||||
const rb_method_entry_t *super_me;
|
|
||||||
while (me->def->type == VM_METHOD_TYPE_ZSUPER) {
|
|
||||||
VALUE defined_class = method_entry_defined_class(me);
|
|
||||||
VALUE super_class = RCLASS_SUPER(RCLASS_ORIGIN(defined_class));
|
|
||||||
if (!super_class) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ID id = me->def->original_id;
|
|
||||||
super_me = (rb_method_entry_t *)rb_callable_method_entry_with_refinements(super_class, id, iclass_ptr);
|
|
||||||
if (!super_me) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
me = super_me;
|
|
||||||
}
|
|
||||||
return me;
|
|
||||||
}
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
mnew_internal(const rb_method_entry_t *me, VALUE klass, VALUE iclass,
|
mnew_internal(const rb_method_entry_t *me, VALUE klass, VALUE iclass,
|
||||||
VALUE obj, ID id, VALUE mclass, int scope, int error)
|
VALUE obj, ID id, VALUE mclass, int scope, int error)
|
||||||
{
|
{
|
||||||
struct METHOD *data;
|
struct METHOD *data;
|
||||||
VALUE method;
|
VALUE method;
|
||||||
const rb_method_entry_t *zsuper_resolved_me;
|
const rb_method_entry_t *original_me = me;
|
||||||
rb_method_visibility_t visi = METHOD_VISI_UNDEF;
|
rb_method_visibility_t visi = METHOD_VISI_UNDEF;
|
||||||
|
|
||||||
|
again:
|
||||||
if (UNDEFINED_METHOD_ENTRY_P(me)) {
|
if (UNDEFINED_METHOD_ENTRY_P(me)) {
|
||||||
if (respond_to_missing_p(klass, obj, ID2SYM(id), scope)) {
|
if (respond_to_missing_p(klass, obj, ID2SYM(id), scope)) {
|
||||||
return mnew_missing(klass, obj, id, mclass);
|
return mnew_missing(klass, obj, id, mclass);
|
||||||
@ -1732,15 +1706,27 @@ mnew_internal(const rb_method_entry_t *me, VALUE klass, VALUE iclass,
|
|||||||
rb_print_inaccessible(klass, id, visi);
|
rb_print_inaccessible(klass, id, visi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zsuper_resolved_me = zsuper_resolve(me, &iclass);
|
if (me->def->type == VM_METHOD_TYPE_ZSUPER) {
|
||||||
|
if (me->defined_class) {
|
||||||
|
VALUE klass = RCLASS_SUPER(RCLASS_ORIGIN(me->defined_class));
|
||||||
|
id = me->def->original_id;
|
||||||
|
me = (rb_method_entry_t *)rb_callable_method_entry_with_refinements(klass, id, &iclass);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
VALUE klass = RCLASS_SUPER(RCLASS_ORIGIN(me->owner));
|
||||||
|
id = me->def->original_id;
|
||||||
|
me = rb_method_entry_without_refinements(klass, id, &iclass);
|
||||||
|
}
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
|
||||||
method = TypedData_Make_Struct(mclass, struct METHOD, &method_data_type, data);
|
method = TypedData_Make_Struct(mclass, struct METHOD, &method_data_type, data);
|
||||||
|
|
||||||
RB_OBJ_WRITE(method, &data->recv, obj);
|
RB_OBJ_WRITE(method, &data->recv, obj);
|
||||||
RB_OBJ_WRITE(method, &data->klass, klass);
|
RB_OBJ_WRITE(method, &data->klass, klass);
|
||||||
RB_OBJ_WRITE(method, &data->iclass, iclass);
|
RB_OBJ_WRITE(method, &data->iclass, iclass);
|
||||||
RB_OBJ_WRITE(method, &data->owner, me->owner);
|
RB_OBJ_WRITE(method, &data->owner, original_me->owner);
|
||||||
RB_OBJ_WRITE(method, &data->me, zsuper_resolved_me);
|
RB_OBJ_WRITE(method, &data->me, me);
|
||||||
|
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
@ -1773,6 +1759,13 @@ mnew_unbound(VALUE klass, ID id, VALUE mclass, int scope)
|
|||||||
return mnew_from_me(me, klass, iclass, Qundef, id, mclass, scope);
|
return mnew_from_me(me, klass, iclass, Qundef, id, mclass, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline VALUE
|
||||||
|
method_entry_defined_class(const rb_method_entry_t *me)
|
||||||
|
{
|
||||||
|
VALUE defined_class = me->defined_class;
|
||||||
|
return defined_class ? defined_class : me->owner;
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
*
|
*
|
||||||
* Document-class: Method
|
* Document-class: Method
|
||||||
@ -1826,13 +1819,10 @@ method_eq(VALUE method, VALUE other)
|
|||||||
m1 = (struct METHOD *)DATA_PTR(method);
|
m1 = (struct METHOD *)DATA_PTR(method);
|
||||||
m2 = (struct METHOD *)DATA_PTR(other);
|
m2 = (struct METHOD *)DATA_PTR(other);
|
||||||
|
|
||||||
const rb_method_entry_t *m1_me = m1->me;
|
klass1 = method_entry_defined_class(m1->me);
|
||||||
const rb_method_entry_t *m2_me = m2->me;
|
klass2 = method_entry_defined_class(m2->me);
|
||||||
|
|
||||||
klass1 = method_entry_defined_class(m1_me);
|
if (!rb_method_entry_eq(m1->me, m2->me) ||
|
||||||
klass2 = method_entry_defined_class(m2_me);
|
|
||||||
|
|
||||||
if (!rb_method_entry_eq(m1_me, m2_me) ||
|
|
||||||
klass1 != klass2 ||
|
klass1 != klass2 ||
|
||||||
m1->klass != m2->klass ||
|
m1->klass != m2->klass ||
|
||||||
m1->recv != m2->recv) {
|
m1->recv != m2->recv) {
|
||||||
@ -2979,14 +2969,6 @@ rb_method_entry_location(const rb_method_entry_t *me)
|
|||||||
return method_def_location(me->def);
|
return method_def_location(me->def);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const rb_method_definition_t *
|
|
||||||
zsuper_ref_method_def(VALUE method)
|
|
||||||
{
|
|
||||||
const struct METHOD *data;
|
|
||||||
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
|
|
||||||
return data->me->def;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* meth.source_location -> [String, Integer]
|
* meth.source_location -> [String, Integer]
|
||||||
@ -2998,7 +2980,7 @@ zsuper_ref_method_def(VALUE method)
|
|||||||
VALUE
|
VALUE
|
||||||
rb_method_location(VALUE method)
|
rb_method_location(VALUE method)
|
||||||
{
|
{
|
||||||
return method_def_location(zsuper_ref_method_def(method));
|
return method_def_location(rb_method_def(method));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const rb_method_definition_t *
|
static const rb_method_definition_t *
|
||||||
@ -3086,7 +3068,7 @@ method_def_parameters(const rb_method_definition_t *def)
|
|||||||
static VALUE
|
static VALUE
|
||||||
rb_method_parameters(VALUE method)
|
rb_method_parameters(VALUE method)
|
||||||
{
|
{
|
||||||
return method_def_parameters(zsuper_ref_method_def(method));
|
return method_def_parameters(rb_method_def(method));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1063,7 +1063,7 @@ class TestMethod < Test::Unit::TestCase
|
|||||||
c1.class_eval {undef foo}
|
c1.class_eval {undef foo}
|
||||||
m = c3.instance_method(:foo)
|
m = c3.instance_method(:foo)
|
||||||
m = assert_nothing_raised(NameError, Feature9781) {break m.super_method}
|
m = assert_nothing_raised(NameError, Feature9781) {break m.super_method}
|
||||||
assert_equal c2, m.owner
|
assert_nil(m, Feature9781)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_super_method_removed_regular
|
def test_super_method_removed_regular
|
||||||
@ -1248,7 +1248,10 @@ class TestMethod < Test::Unit::TestCase
|
|||||||
assert_equal 1, unbound.bind_call(obj)
|
assert_equal 1, unbound.bind_call(obj)
|
||||||
|
|
||||||
assert_include b.instance_methods(false), :foo
|
assert_include b.instance_methods(false), :foo
|
||||||
assert_equal "#<UnboundMethod: B#foo(*)>", b.instance_method(:foo).inspect
|
link = 'https://github.com/ruby/ruby/pull/6467#issuecomment-1262159088'
|
||||||
|
assert_raise(NameError, link) { b.instance_method(:foo) }
|
||||||
|
# For #test_method_list below, otherwise we get the same error as just above
|
||||||
|
b.remove_method(:foo)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_zsuper_method_removed_higher_method
|
def test_zsuper_method_removed_higher_method
|
||||||
|
Loading…
x
Reference in New Issue
Block a user