Project

General

Profile

Bug #15629 ยป super_method-bind-unbind-clone-15629.patch

jeremyevans0 (Jeremy Evans), 10/02/2019 10:23 PM

View differences:

proc.c
1678 1678
				   &method_data_type, data);
1679 1679
    RB_OBJ_WRITE(method, &data->recv, Qundef);
1680 1680
    RB_OBJ_WRITE(method, &data->klass, orig->klass);
1681
    RB_OBJ_WRITE(method, &data->iclass, orig->iclass);
1681 1682
    RB_OBJ_WRITE(method, &data->me, rb_method_entry_clone(orig->me));
1682 1683
    OBJ_INFECT(method, obj);
1683 1684

  
......
2191 2192
    CLONESETUP(clone, self);
2192 2193
    RB_OBJ_WRITE(clone, &data->recv, orig->recv);
2193 2194
    RB_OBJ_WRITE(clone, &data->klass, orig->klass);
2195
    RB_OBJ_WRITE(clone, &data->iclass, orig->iclass);
2194 2196
    RB_OBJ_WRITE(clone, &data->me, rb_method_entry_clone(orig->me));
2195 2197
    return clone;
2196 2198
}
......
2367 2369
 */
2368 2370

  
2369 2371
static void
2370
convert_umethod_to_method_components(VALUE method, VALUE recv, VALUE *methclass_out, VALUE *klass_out, const rb_method_entry_t **me_out)
2372
convert_umethod_to_method_components(VALUE method, VALUE recv, VALUE *methclass_out, VALUE *klass_out, VALUE *iclass_out, const rb_method_entry_t **me_out)
2371 2373
{
2372 2374
    struct METHOD *data;
2373 2375

  
2374 2376
    TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
2375 2377

  
2376 2378
    VALUE methclass = data->me->owner;
2379
    VALUE iclass = data->me->defined_class;
2377 2380
    VALUE klass = CLASS_OF(recv);
2378 2381

  
2379 2382
    if (!RB_TYPE_P(methclass, T_MODULE) &&
......
2394 2397
	VALUE ic = rb_class_search_ancestor(klass, me->owner);
2395 2398
	if (ic) {
2396 2399
	    klass = ic;
2400
            iclass = ic;
2397 2401
	}
2398 2402
	else {
2399 2403
	    klass = rb_include_class_new(methclass, klass);
......
2403 2407

  
2404 2408
    *methclass_out = methclass;
2405 2409
    *klass_out = klass;
2410
    *iclass_out = iclass;
2406 2411
    *me_out = me;
2407 2412
}
2408 2413

  
......
2444 2449
static VALUE
2445 2450
umethod_bind(VALUE method, VALUE recv)
2446 2451
{
2447
    VALUE methclass, klass;
2452
    VALUE methclass, klass, iclass;
2448 2453
    const rb_method_entry_t *me;
2449
    convert_umethod_to_method_components(method, recv, &methclass, &klass, &me);
2454
    convert_umethod_to_method_components(method, recv, &methclass, &klass, &iclass, &me);
2450 2455

  
2451 2456
    struct METHOD *bound;
2452 2457
    method = TypedData_Make_Struct(rb_cMethod, struct METHOD, &method_data_type, bound);
2453 2458
    RB_OBJ_WRITE(method, &bound->recv, recv);
2454 2459
    RB_OBJ_WRITE(method, &bound->klass, klass);
2460
    RB_OBJ_WRITE(method, &bound->iclass, iclass);
2455 2461
    RB_OBJ_WRITE(method, &bound->me, me);
2456 2462

  
2457 2463
    return method;
......
2473 2479
    argc--;
2474 2480
    argv++;
2475 2481

  
2476
    VALUE methclass, klass;
2482
    VALUE methclass, klass, iclass;
2477 2483
    const rb_method_entry_t *me;
2478
    convert_umethod_to_method_components(method, recv, &methclass, &klass, &me);
2484
    convert_umethod_to_method_components(method, recv, &methclass, &klass, &iclass, &me);
2479 2485
    struct METHOD bound = { recv, klass, 0, me };
2480 2486

  
2481 2487
    VALUE passed_procval = rb_block_given_p() ? rb_block_proc() : Qnil;
test/ruby/test_method.rb
930 930
    assert_nil(m.super_method)
931 931
  end
932 932

  
933
  def test_super_method_bind_unbind_clone
934
    bug15629_m1 = Module.new do
935
      def foo; end
936
    end
937

  
938
    bug15629_m2 = Module.new do
939
      def foo; end
940
    end
941

  
942
    bug15629_c = Class.new do
943
      include bug15629_m1
944
      include bug15629_m2
945
    end
946

  
947
    o  = bug15629_c.new
948
    m = o.:foo
949
    sm = m.super_method
950
    im = bug15629_c.instance_method(:foo)
951
    sim = im.super_method
952

  
953
    assert_equal(sm, m.clone.super_method)
954
    assert_equal(sim, m.unbind.super_method)
955
    assert_equal(sim, m.unbind.clone.super_method)
956
    assert_equal(sim, im.clone.super_method)
957
    assert_equal(sm, m.unbind.bind(o).super_method)
958
    assert_equal(sm, m.unbind.clone.bind(o).super_method)
959
    assert_equal(sm, im.bind(o).super_method)
960
    assert_equal(sm, im.clone.bind(o).super_method)
961
  end
962

  
933 963
  def test_super_method_removed
934 964
    c1 = Class.new {private def foo; end}
935 965
    c2 = Class.new(c1) {public :foo}
936
-