ruby-changes:73796
From: Benoit <ko1@a...>
Date: Thu, 29 Sep 2022 22:48:52 +0900 (JST)
Subject: [ruby-changes:73796] aa490f9442 (master): Reduce diff to proc.c @ b0b9f7201acab05c2a3ad92c3043a1f01df3e17f
https://git.ruby-lang.org/ruby.git/commit/?id=aa490f9442 From aa490f9442c32cd0e1e449ac817f410bd5924c8b Mon Sep 17 00:00:00 2001 From: Benoit Daloze <eregontp@g...> Date: Thu, 29 Sep 2022 12:09:01 +0200 Subject: 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. --- proc.c | 76 ++++++++++++++++++------------------------------ test/ruby/test_method.rb | 7 +++-- 2 files changed, 34 insertions(+), 49 deletions(-) diff --git a/proc.c b/proc.c index 6362efc28e..307535720e 100644 --- a/proc.c +++ b/proc.c @@ -1681,42 +1681,16 @@ mnew_missing_by_name(VALUE klass, VALUE obj, VALUE *name, int scope, VALUE mclas https://github.com/ruby/ruby/blob/trunk/proc.c#L1681 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 mnew_internal(const rb_method_entry_t *me, VALUE klass, VALUE iclass, VALUE obj, ID id, VALUE mclass, int scope, int error) { struct METHOD *data; 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; + again: if (UNDEFINED_METHOD_ENTRY_P(me)) { if (respond_to_missing_p(klass, obj, ID2SYM(id), scope)) { return mnew_missing(klass, obj, id, mclass); @@ -1732,15 +1706,27 @@ mnew_internal(const rb_method_entry_t *me, VALUE klass, VALUE iclass, https://github.com/ruby/ruby/blob/trunk/proc.c#L1706 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); RB_OBJ_WRITE(method, &data->recv, obj); RB_OBJ_WRITE(method, &data->klass, klass); RB_OBJ_WRITE(method, &data->iclass, iclass); - RB_OBJ_WRITE(method, &data->owner, me->owner); - RB_OBJ_WRITE(method, &data->me, zsuper_resolved_me); + RB_OBJ_WRITE(method, &data->owner, original_me->owner); + RB_OBJ_WRITE(method, &data->me, me); return method; } @@ -1773,6 +1759,13 @@ mnew_unbound(VALUE klass, ID id, VALUE mclass, int scope) https://github.com/ruby/ruby/blob/trunk/proc.c#L1759 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 @@ -1826,13 +1819,10 @@ method_eq(VALUE method, VALUE other) https://github.com/ruby/ruby/blob/trunk/proc.c#L1819 m1 = (struct METHOD *)DATA_PTR(method); m2 = (struct METHOD *)DATA_PTR(other); - const rb_method_entry_t *m1_me = m1->me; - const rb_method_entry_t *m2_me = m2->me; - - klass1 = method_entry_defined_class(m1_me); - klass2 = method_entry_defined_class(m2_me); + klass1 = method_entry_defined_class(m1->me); + klass2 = method_entry_defined_class(m2->me); - if (!rb_method_entry_eq(m1_me, m2_me) || + if (!rb_method_entry_eq(m1->me, m2->me) || klass1 != klass2 || m1->klass != m2->klass || m1->recv != m2->recv) { @@ -2979,14 +2969,6 @@ rb_method_entry_location(const rb_method_entry_t *me) https://github.com/ruby/ruby/blob/trunk/proc.c#L2969 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: * meth.source_location -> [String, Integer] @@ -2998,7 +2980,7 @@ zsuper_ref_method_def(VALUE method) https://github.com/ruby/ruby/blob/trunk/proc.c#L2980 VALUE 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 * @@ -3086,7 +3068,7 @@ method_def_parameters(const rb_method_definition_t *def) https://github.com/ruby/ruby/blob/trunk/proc.c#L3068 static VALUE rb_method_parameters(VALUE method) { - return method_def_parameters(zsuper_ref_method_def(method)); + return method_def_parameters(rb_method_def(method)); } /* diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb index 0b838f5e40..b1eee7381a 100644 --- a/test/ruby/test_method.rb +++ b/test/ruby/test_method.rb @@ -1063,7 +1063,7 @@ class TestMethod < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_method.rb#L1063 c1.class_eval {undef foo} m = c3.instance_method(:foo) m = assert_nothing_raised(NameError, Feature9781) {break m.super_method} - assert_equal c2, m.owner + assert_nil(m, Feature9781) end def test_super_method_removed_regular @@ -1248,7 +1248,10 @@ class TestMethod < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_method.rb#L1248 assert_equal 1, unbound.bind_call(obj) 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 def test_zsuper_method_removed_higher_method -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/