Project

General

Profile

refinement-r29837-20101124.diff

shugo (Shugo Maeda), 11/24/2010 10:12 PM

View differences:

bootstraptest/test_method.rb
287 287
assert_equal '1',       %q( class C
288 288
                              def m
289 289
                                def mm() 1 end
290
                                mm
290 291
                              end
291 292
                            end
292
                            C.new.m
293
                            C.new.mm )
293
                            C.new.m )
294 294
assert_equal '1',       %q( class C
295 295
                              def m
296 296
                                def mm() 1 end
297
                                mm
297 298
                              end
298 299
                            end
299
                            instance_eval "C.new.m; C.new.mm" )
300
                            instance_eval "C.new.m" )
300 301

  
301 302
# method_missing
302 303
assert_equal ':m',      %q( class C
class.c
617 617
    return module;
618 618
}
619 619

  
620
static VALUE
621
include_class_new(VALUE module, VALUE super)
620
VALUE
621
rb_include_class_new(VALUE module, VALUE super)
622 622
{
623 623
    VALUE klass = class_alloc(T_ICLASS, rb_cClass);
624 624

  
......
685 685
		break;
686 686
	    }
687 687
	}
688
	c = RCLASS_SUPER(c) = include_class_new(module, RCLASS_SUPER(c));
688
	c = RCLASS_SUPER(c) = rb_include_class_new(module, RCLASS_SUPER(c));
689 689
	if (RMODULE_M_TBL(module) && RMODULE_M_TBL(module)->num_entries)
690 690
	    changed = 1;
691 691
      skip:
......
1387 1387
int
1388 1388
rb_obj_basic_to_s_p(VALUE obj)
1389 1389
{
1390
    const rb_method_entry_t *me = rb_method_entry(CLASS_OF(obj), rb_intern("to_s"));
1390
    const rb_method_entry_t *me = rb_method_entry(CLASS_OF(obj), rb_intern("to_s"), 0);
1391 1391
    if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC &&
1392 1392
	me->def->body.cfunc.func == rb_any_to_s)
1393 1393
	return 1;
compile.c
4575 4575
	ADD_INSN1(ret, nd_line(node), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE));
4576 4576
	ADD_INSN1(ret, nd_line(node), putobject, ID2SYM(node->nd_mid));
4577 4577
	ADD_INSN1(ret, nd_line(node), putiseq, iseqval);
4578
	ADD_SEND (ret, nd_line(node), ID2SYM(id_core_define_method), INT2FIX(3));
4578
	ADD_INSN1(ret, nd_line(node), putobject,
4579
		  node->flags & NODE_FL_NESTED_DEF ? Qtrue : Qfalse);
4580
	ADD_SEND (ret, nd_line(node), ID2SYM(id_core_define_method), INT2FIX(4));
4579 4581

  
4580 4582
	if (poped) {
4581 4583
	    ADD_INSN(ret, nd_line(node), pop);
eval.c
23 23
VALUE rb_binding_new(void);
24 24
NORETURN(void rb_raise_jump(VALUE));
25 25

  
26
NODE *rb_vm_get_cref(const rb_iseq_t *, const VALUE *, const VALUE *);
27

  
26 28
ID rb_frame_callee(void);
27 29
VALUE rb_eLocalJumpError;
28 30
VALUE rb_eSysStackError;
......
858 860
}
859 861

  
860 862
void
863
rb_overlay_module(NODE *cref, VALUE klass, VALUE module)
864
{
865
    VALUE iclass, c, superclass = klass;
866

  
867
    Check_Type(klass, T_CLASS);
868
    Check_Type(module, T_MODULE);
869
    if (NIL_P(cref->nd_omod)) {
870
	cref->nd_omod = rb_hash_new();
871
	rb_funcall(cref->nd_omod, rb_intern("compare_by_identity"), 0);
872
    }
873
    else {
874
	if (cref->flags & NODE_FL_CREF_OMOD_SHARED) {
875
	    cref->nd_omod = rb_hash_dup(cref->nd_omod);
876
	    cref->flags &= ~NODE_FL_CREF_OMOD_SHARED;
877
	}
878
	if (!NIL_P(c = rb_hash_lookup(cref->nd_omod, klass))) {
879
	    superclass = c;
880
	    while (c && TYPE(c) == T_ICLASS) {
881
		if (RBASIC(c)->klass == module) {
882
		    /* already overlayed module */
883
		    return;
884
		}
885
		c = RCLASS_SUPER(c);
886
	    }
887
	}
888
    }
889
    FL_SET(module, RMODULE_IS_OVERLAYED);
890
    c = iclass = rb_include_class_new(module, superclass);
891
    module = RCLASS_SUPER(module);
892
    while (module) {
893
	FL_SET(module, RMODULE_IS_OVERLAYED);
894
	c = RCLASS_SUPER(c) = rb_include_class_new(module, RCLASS_SUPER(c));
895
	module = RCLASS_SUPER(module);
896
    }
897
    rb_hash_aset(cref->nd_omod, klass, iclass);
898
    rb_clear_cache_by_class(klass);
899
}
900

  
901
static int
902
using_module_i(VALUE klass, VALUE module, VALUE arg)
903
{
904
    NODE *cref = (NODE *) arg;
905
    int i;
906

  
907
    rb_overlay_module(cref, klass, module);
908
    return ST_CONTINUE;
909
}
910

  
911
void
912
rb_using_module(NODE *cref, VALUE module)
913
{
914
    ID id_overlayed_modules;
915
    VALUE overlayed_modules;
916

  
917
    Check_Type(module, T_MODULE);
918
    CONST_ID(id_overlayed_modules, "__overlayed_modules__");
919
    overlayed_modules = rb_attr_get(module, id_overlayed_modules);
920
    if (NIL_P(overlayed_modules)) return;
921
    rb_hash_foreach(overlayed_modules, using_module_i, (VALUE) cref);
922
}
923

  
924
/*
925
 *  call-seq:
926
 *     using(module)    -> self
927
 *
928
 *  Import class refinements from <i>module</i> into the receiver.
929
 */
930

  
931
static VALUE
932
rb_mod_using(VALUE self, VALUE module)
933
{
934
    NODE *cref = rb_vm_cref();
935
    ID id_using_modules;
936
    VALUE using_modules;
937

  
938
    CONST_ID(id_using_modules, "__using_modules__");
939
    using_modules = rb_attr_get(self, id_using_modules);
940
    if (NIL_P(using_modules)) {
941
	using_modules = rb_hash_new();
942
	rb_funcall(using_modules, rb_intern("compare_by_identity"), 0);
943
	rb_ivar_set(self, id_using_modules, using_modules);
944
    }
945
    rb_hash_aset(using_modules, module, Qtrue);
946
    rb_using_module(cref, module);
947
    rb_funcall(module, rb_intern("used"), 1, self);
948
    return self;
949
}
950

  
951
void rb_redefine_opt_method(VALUE, ID);
952

  
953
static VALUE
954
refinement_module_method_added(VALUE mod, VALUE mid)
955
{
956
    ID id = SYM2ID(mid);
957
    ID id_refined_class;
958
    VALUE klass;
959

  
960
    CONST_ID(id_refined_class, "__refined_class__");
961
    klass = rb_ivar_get(mod, id_refined_class);
962
    rb_redefine_opt_method(klass, id);
963
}
964

  
965
/*
966
 *  call-seq:
967
 *     refine(klass) { block }   -> self
968
 *
969
 *  Refine <i>klass</i> in the receiver.
970
 */
971

  
972
static VALUE
973
rb_mod_refine(VALUE module, VALUE klass)
974
{
975
    NODE *cref = rb_vm_cref();
976
    VALUE mod;
977
    ID id_overlayed_modules, id_refined_class;
978
    VALUE overlayed_modules, modules;
979

  
980
    Check_Type(klass, T_CLASS);
981
    CONST_ID(id_overlayed_modules, "__overlayed_modules__");
982
    overlayed_modules = rb_attr_get(module, id_overlayed_modules);
983
    if (NIL_P(overlayed_modules)) {
984
	overlayed_modules = rb_hash_new();
985
	rb_funcall(overlayed_modules, rb_intern("compare_by_identity"), 0);
986
	rb_ivar_set(module, id_overlayed_modules, overlayed_modules);
987
    }
988
    mod = rb_hash_aref(overlayed_modules, klass);
989
    if (NIL_P(mod)) {
990
	mod = rb_module_new();
991
	CONST_ID(id_refined_class, "__refined_class__");
992
	rb_ivar_set(mod, id_refined_class, klass);
993
	rb_define_singleton_method(mod, "method_added",
994
				   refinement_module_method_added, 1);
995
	rb_overlay_module(cref, klass, mod);
996
	rb_hash_aset(overlayed_modules, klass, mod);
997
    }
998
    rb_mod_module_eval(0, NULL, mod);
999
    return mod;
1000
}
1001

  
1002
void
861 1003
rb_obj_call_init(VALUE obj, int argc, VALUE *argv)
862 1004
{
863 1005
    PASS_PASSED_BLOCK();
......
969 1111
    return rb_mod_include(argc, argv, rb_cObject);
970 1112
}
971 1113

  
1114
/*
1115
 *  call-seq:
1116
 *     using(module)    -> self
1117
 *
1118
 *  Import class refinements from <i>module</i> into the scope where <code>use</code> is called.
1119
 */
1120

  
1121
static VALUE
1122
f_using(VALUE self, VALUE module)
1123
{
1124
    NODE *cref = rb_vm_cref();
1125

  
1126
    rb_using_module(cref, module);
1127
    return self;
1128
}
1129

  
972 1130
VALUE rb_f_trace_var();
973 1131
VALUE rb_f_untrace_var();
974 1132

  
......
1121 1279
    rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
1122 1280
    rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
1123 1281
    rb_define_private_method(rb_cModule, "include", rb_mod_include, -1);
1282
    rb_define_private_method(rb_cModule, "using", rb_mod_using, 1);
1283
    rb_define_private_method(rb_cModule, "refine", rb_mod_refine, 1);
1124 1284

  
1125 1285
    rb_undef_method(rb_cClass, "module_function");
1126 1286

  
......
1136 1296

  
1137 1297
    rb_define_singleton_method(rb_vm_top_self(), "include", top_include, -1);
1138 1298

  
1299
    rb_define_global_function("using", f_using, 1);
1300

  
1139 1301
    rb_define_method(rb_mKernel, "extend", rb_obj_extend, -1);
1140 1302

  
1141 1303
    rb_define_global_function("trace_var", rb_f_trace_var, -1);	/* in variable.c */
gc.c
1684 1684
	    ptr = (VALUE)obj->as.node.u2.node;
1685 1685
	    goto again;
1686 1686

  
1687
	  case NODE_CREF:
1688
	    gc_mark(objspace, obj->as.node.u0.value, lev);
1689
	    gc_mark(objspace, (VALUE)obj->as.node.u1.node, lev);
1690
	    ptr = (VALUE)obj->as.node.u3.node;
1691
	    goto again;
1692

  
1687 1693
	  default:		/* unlisted NODE */
1688 1694
	    if (is_pointer_to_heap(objspace, obj->as.node.u1.node)) {
1689 1695
		gc_mark(objspace, (VALUE)obj->as.node.u1.node, lev);
include/ruby/intern.h
164 164
VALUE rb_make_metaclass(VALUE, VALUE);
165 165
void rb_check_inheritable(VALUE);
166 166
VALUE rb_class_inherited(VALUE, VALUE);
167
VALUE rb_mod_opened(VALUE);
167 168
VALUE rb_define_class_id(ID, VALUE);
168 169
VALUE rb_define_class_id_under(VALUE, ID, VALUE);
169 170
VALUE rb_module_new(void);
170 171
VALUE rb_define_module_id(ID);
171 172
VALUE rb_define_module_id_under(VALUE, ID);
173
VALUE rb_include_class_new(VALUE, VALUE);
172 174
VALUE rb_mod_included_modules(VALUE);
173 175
VALUE rb_mod_include_p(VALUE, VALUE);
174 176
VALUE rb_mod_ancestors(VALUE);
include/ruby/ruby.h
629 629
#define RMODULE_CONST_TBL(m) RCLASS_CONST_TBL(m)
630 630
#define RMODULE_M_TBL(m) RCLASS_M_TBL(m)
631 631
#define RMODULE_SUPER(m) RCLASS_SUPER(m)
632
#define RMODULE_HAS_NESTED_METHODS FL_USER2
633
#define RMODULE_IS_OVERLAYED FL_USER3
632 634

  
633 635
struct RFloat {
634 636
    struct RBasic basic;
insns.def
183 183
()
184 184
(VALUE val)
185 185
{
186
    NODE * const cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
187
    val = rb_cvar_get(vm_get_cvar_base(cref), id);
186
    NODE * const cref = rb_vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
187
    val = rb_cvar_get(vm_get_cvar_base(cref, GET_CFP()), id);
188 188
}
189 189

  
190 190
/**
......
198 198
(VALUE val)
199 199
()
200 200
{
201
    NODE * const cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
202
    rb_cvar_set(vm_get_cvar_base(cref), id, val);
201
    NODE * const cref = rb_vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
202
    rb_cvar_set(vm_get_cvar_base(cref, GET_CFP()), id, val);
203 203
}
204 204

  
205 205
/**
......
792 792
	break;
793 793
      case DEFINED_METHOD:{
794 794
	VALUE klass = CLASS_OF(v);
795
	const rb_method_entry_t *me = rb_method_entry(klass, SYM2ID(obj));
795
	const rb_method_entry_t *me = rb_method_entry(klass, SYM2ID(obj), 0);
796 796

  
797 797
	if (me) {
798 798
	    if (!(me->flag & NOEX_PRIVATE)) {
......
964 964

  
965 965
    /* enter scope */
966 966
    vm_push_frame(th, class_iseq,
967
		  VM_FRAME_MAGIC_CLASS, klass, (VALUE) GET_BLOCK_PTR(),
967
		  VM_FRAME_MAGIC_CLASS, klass, 0, (VALUE) GET_BLOCK_PTR(),
968 968
		  class_iseq->iseq_encoded, GET_SP(), 0,
969 969
		  class_iseq->local_size);
970
    rb_vm_using_modules(class_iseq->cref_stack, klass);
970 971
    RESTORE_REGS();
971 972

  
972 973
    INC_VM_STATE_VERSION();
......
996 997
(VALUE val) // inc += - (int)(op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
997 998
{
998 999
    const rb_method_entry_t *me;
999
    VALUE recv, klass;
1000
    VALUE recv, klass, defined_class;
1000 1001
    rb_block_t *blockptr = 0;
1001 1002
    VALUE flag = op_flag;
1002 1003
    int num = caller_setup_args(th, GET_CFP(), flag, (int)op_argc,
......
1006 1007
    /* get receiver */
1007 1008
    recv = (flag & VM_CALL_FCALL_BIT) ? GET_SELF() : TOPN(num);
1008 1009
    klass = CLASS_OF(recv);
1009
    me = vm_method_search(id, klass, ic);
1010
    CALL_METHOD(num, blockptr, flag, id, me, recv);
1010
    me = vm_method_search(id, klass, ic, &defined_class);
1011
    CALL_METHOD(num, blockptr, flag, id, me, recv, defined_class);
1011 1012
}
1012 1013

  
1013 1014
/**
......
1030 1031
    VALUE recv, klass;
1031 1032
    ID id;
1032 1033
    const rb_method_entry_t *me;
1034
    rb_iseq_t *ip;
1033 1035

  
1034 1036
    flag = VM_CALL_SUPER_BIT | VM_CALL_FCALL_BIT;
1035 1037

  
1036 1038
    recv = GET_SELF();
1037 1039
    vm_search_superclass(GET_CFP(), GET_ISEQ(), recv, TOPN(num), &id, &klass);
1038 1040

  
1039
    /* temporary measure for [Bug #2402] [Bug #2502] [Bug #3136] */
1040
    if (!rb_obj_is_kind_of(recv, klass)) {
1041
	rb_raise(rb_eNotImpError, "super from singleton method that is defined to multiple classes is not supported; this will be fixed in 1.9.3 or later");
1041
    ip = GET_ISEQ();
1042
    while (ip && !ip->klass) {
1043
	ip = ip->parent_iseq;
1044
    }
1045
    me = rb_method_entry(klass, id, &klass);
1046
    if (me && me->def->type == VM_METHOD_TYPE_ISEQ &&
1047
	me->def->body.iseq == ip) {
1048
	klass = RCLASS_SUPER(klass);
1049
	me = rb_method_entry_get_with_omod(Qnil, klass, id, &klass);
1042 1050
    }
1043 1051

  
1044
    me = rb_method_entry(klass, id);
1045

  
1046
    CALL_METHOD(num, blockptr, flag, id, me, recv);
1052
    CALL_METHOD(num, blockptr, flag, id, me, recv, klass);
1047 1053
}
1048 1054

  
1049 1055
/**
......
1668 1674
(VALUE val)
1669 1675
{
1670 1676
    extern VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
1671
    const rb_method_entry_t *me = vm_method_search(idNeq, CLASS_OF(recv), ic);
1677
    const rb_method_entry_t *me = vm_method_search(idNeq, CLASS_OF(recv), ic, 0);
1672 1678
    val = Qundef;
1673 1679

  
1674 1680
    if (check_cfunc(me, rb_obj_not_equal)) {
......
2069 2075
(VALUE val)
2070 2076
{
2071 2077
    extern VALUE rb_obj_not(VALUE obj);
2072
    const rb_method_entry_t *me = vm_method_search(idNot, CLASS_OF(recv), ic);
2078
    const rb_method_entry_t *me = vm_method_search(idNot, CLASS_OF(recv), ic, 0);
2073 2079

  
2074 2080
    if (check_cfunc(me, rb_obj_not)) {
2075 2081
	val = RTEST(recv) ? Qfalse : Qtrue;
iseq.c
182 182
    /* set class nest stack */
183 183
    if (type == ISEQ_TYPE_TOP) {
184 184
	/* toplevel is private */
185
	iseq->cref_stack = NEW_BLOCK(rb_cObject);
186
	iseq->cref_stack->nd_file = 0;
185
	iseq->cref_stack = NEW_CREF(rb_cObject);
186
	iseq->cref_stack->nd_omod = Qnil;
187 187
	iseq->cref_stack->nd_visi = NOEX_PRIVATE;
188 188
	if (th->top_wrapper) {
189
	    NODE *cref = NEW_BLOCK(th->top_wrapper);
190
	    cref->nd_file = 0;
189
	    NODE *cref = NEW_CREF(th->top_wrapper);
190
	    cref->nd_omod = Qnil;
191 191
	    cref->nd_visi = NOEX_PRIVATE;
192 192
	    cref->nd_next = iseq->cref_stack;
193 193
	    iseq->cref_stack = cref;
194 194
	}
195 195
    }
196 196
    else if (type == ISEQ_TYPE_METHOD || type == ISEQ_TYPE_CLASS) {
197
	iseq->cref_stack = NEW_BLOCK(0); /* place holder */
198
	iseq->cref_stack->nd_file = 0;
197
	iseq->cref_stack = NEW_CREF(0); /* place holder */
198
	iseq->cref_stack->nd_omod = Qnil;
199 199
    }
200 200
    else if (RTEST(parent)) {
201 201
	rb_iseq_t *piseq;
......
1368 1368
	iseq1->local_iseq = iseq1;
1369 1369
    }
1370 1370
    if (newcbase) {
1371
	iseq1->cref_stack = NEW_BLOCK(newcbase);
1371
	iseq1->cref_stack = NEW_CREF(newcbase);
1372
	iseq1->cref_stack->nd_omod = iseq0->cref_stack->nd_omod;
1373
	iseq1->cref_stack->nd_visi = iseq0->cref_stack->nd_visi;
1372 1374
	if (iseq0->cref_stack->nd_next) {
1373 1375
	    iseq1->cref_stack->nd_next = iseq0->cref_stack->nd_next;
1374 1376
	}
lex.c.blt
1
/* C code produced by gperf version 3.0.4 */
2
/* Command-line: gperf -C -p -j1 -i 1 -g -o -t -N rb_reserved_word -k'1,3,$' defs/keywords  */
1
/* C code produced by gperf version 3.0.3 */
2
/* Command-line: gperf -C -p -j1 -i 1 -g -o -t -N rb_reserved_word -k'1,3,$' ../defs/keywords  */
3 3

  
4 4
#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
5 5
      && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
......
28 28
error "gperf generated tables don't work with this execution character set. Please report a bug to <bug-gnu-gperf@gnu.org>."
29 29
#endif
30 30

  
31
#line 1 "defs/keywords"
31
#line 1 "../defs/keywords"
32 32

  
33 33
struct kwtable {const char *name; int id[2]; enum lex_state_e state;};
34 34
const struct kwtable *rb_reserved_word(const char *, unsigned int);
35 35
#ifndef RIPPER
36 36
static const struct kwtable *reserved_word(const char *, unsigned int);
37 37
#define rb_reserved_word(str, len) reserved_word(str, len)
38
#line 9 "defs/keywords"
38
#line 9 "../defs/keywords"
39 39
struct kwtable;
40 40

  
41 41
#define TOTAL_KEYWORDS 41
......
103 103

  
104 104
#ifdef __GNUC__
105 105
__inline
106
#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
106
#ifdef __GNUC_STDC_INLINE__
107 107
__attribute__ ((__gnu_inline__))
108 108
#endif
109 109
#endif
......
115 115
  static const struct kwtable wordlist[] =
116 116
    {
117 117
      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
118
#line 19 "defs/keywords"
118
#line 19 "../defs/keywords"
119 119
      {"break", {keyword_break, keyword_break}, EXPR_MID},
120
#line 25 "defs/keywords"
120
#line 25 "../defs/keywords"
121 121
      {"else", {keyword_else, keyword_else}, EXPR_BEG},
122
#line 35 "defs/keywords"
122
#line 35 "../defs/keywords"
123 123
      {"nil", {keyword_nil, keyword_nil}, EXPR_END},
124
#line 28 "defs/keywords"
124
#line 28 "../defs/keywords"
125 125
      {"ensure", {keyword_ensure, keyword_ensure}, EXPR_BEG},
126
#line 27 "defs/keywords"
126
#line 27 "../defs/keywords"
127 127
      {"end", {keyword_end, keyword_end}, EXPR_END},
128
#line 44 "defs/keywords"
128
#line 44 "../defs/keywords"
129 129
      {"then", {keyword_then, keyword_then}, EXPR_BEG},
130
#line 36 "defs/keywords"
130
#line 36 "../defs/keywords"
131 131
      {"not", {keyword_not, keyword_not}, EXPR_ARG},
132
#line 29 "defs/keywords"
132
#line 29 "../defs/keywords"
133 133
      {"false", {keyword_false, keyword_false}, EXPR_END},
134
#line 42 "defs/keywords"
134
#line 42 "../defs/keywords"
135 135
      {"self", {keyword_self, keyword_self}, EXPR_END},
136
#line 26 "defs/keywords"
136
#line 26 "../defs/keywords"
137 137
      {"elsif", {keyword_elsif, keyword_elsif}, EXPR_VALUE},
138
#line 39 "defs/keywords"
138
#line 39 "../defs/keywords"
139 139
      {"rescue", {keyword_rescue, modifier_rescue}, EXPR_MID},
140
#line 45 "defs/keywords"
140
#line 45 "../defs/keywords"
141 141
      {"true", {keyword_true, keyword_true}, EXPR_END},
142
#line 48 "defs/keywords"
142
#line 48 "../defs/keywords"
143 143
      {"until", {keyword_until, modifier_until}, EXPR_VALUE},
144
#line 47 "defs/keywords"
144
#line 47 "../defs/keywords"
145 145
      {"unless", {keyword_unless, modifier_unless}, EXPR_VALUE},
146
#line 41 "defs/keywords"
146
#line 41 "../defs/keywords"
147 147
      {"return", {keyword_return, keyword_return}, EXPR_MID},
148
#line 22 "defs/keywords"
148
#line 22 "../defs/keywords"
149 149
      {"def", {keyword_def, keyword_def}, EXPR_FNAME},
150
#line 17 "defs/keywords"
150
#line 17 "../defs/keywords"
151 151
      {"and", {keyword_and, keyword_and}, EXPR_VALUE},
152
#line 24 "defs/keywords"
152
#line 24 "../defs/keywords"
153 153
      {"do", {keyword_do, keyword_do}, EXPR_BEG},
154
#line 51 "defs/keywords"
154
#line 51 "../defs/keywords"
155 155
      {"yield", {keyword_yield, keyword_yield}, EXPR_ARG},
156
#line 30 "defs/keywords"
156
#line 30 "../defs/keywords"
157 157
      {"for", {keyword_for, keyword_for}, EXPR_VALUE},
158
#line 46 "defs/keywords"
158
#line 46 "../defs/keywords"
159 159
      {"undef", {keyword_undef, keyword_undef}, EXPR_FNAME},
160
#line 37 "defs/keywords"
160
#line 37 "../defs/keywords"
161 161
      {"or", {keyword_or, keyword_or}, EXPR_VALUE},
162
#line 32 "defs/keywords"
162
#line 32 "../defs/keywords"
163 163
      {"in", {keyword_in, keyword_in}, EXPR_VALUE},
164
#line 49 "defs/keywords"
164
#line 49 "../defs/keywords"
165 165
      {"when", {keyword_when, keyword_when}, EXPR_VALUE},
166
#line 40 "defs/keywords"
166
#line 40 "../defs/keywords"
167 167
      {"retry", {keyword_retry, keyword_retry}, EXPR_END},
168
#line 31 "defs/keywords"
168
#line 31 "../defs/keywords"
169 169
      {"if", {keyword_if, modifier_if}, EXPR_VALUE},
170
#line 20 "defs/keywords"
170
#line 20 "../defs/keywords"
171 171
      {"case", {keyword_case, keyword_case}, EXPR_VALUE},
172
#line 38 "defs/keywords"
172
#line 38 "../defs/keywords"
173 173
      {"redo", {keyword_redo, keyword_redo}, EXPR_END},
174
#line 34 "defs/keywords"
174
#line 34 "../defs/keywords"
175 175
      {"next", {keyword_next, keyword_next}, EXPR_MID},
176
#line 43 "defs/keywords"
176
#line 43 "../defs/keywords"
177 177
      {"super", {keyword_super, keyword_super}, EXPR_ARG},
178
#line 33 "defs/keywords"
178
#line 33 "../defs/keywords"
179 179
      {"module", {keyword_module, keyword_module}, EXPR_VALUE},
180
#line 18 "defs/keywords"
180
#line 18 "../defs/keywords"
181 181
      {"begin", {keyword_begin, keyword_begin}, EXPR_BEG},
182
#line 12 "defs/keywords"
182
#line 12 "../defs/keywords"
183 183
      {"__LINE__", {keyword__LINE__, keyword__LINE__}, EXPR_END},
184
#line 13 "defs/keywords"
184
#line 13 "../defs/keywords"
185 185
      {"__FILE__", {keyword__FILE__, keyword__FILE__}, EXPR_END},
186
#line 11 "defs/keywords"
186
#line 11 "../defs/keywords"
187 187
      {"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END},
188
#line 15 "defs/keywords"
188
#line 15 "../defs/keywords"
189 189
      {"END", {keyword_END, keyword_END}, EXPR_END},
190
#line 16 "defs/keywords"
190
#line 16 "../defs/keywords"
191 191
      {"alias", {keyword_alias, keyword_alias}, EXPR_FNAME},
192
#line 14 "defs/keywords"
192
#line 14 "../defs/keywords"
193 193
      {"BEGIN", {keyword_BEGIN, keyword_BEGIN}, EXPR_END},
194
#line 23 "defs/keywords"
194
#line 23 "../defs/keywords"
195 195
      {"defined?", {keyword_defined, keyword_defined}, EXPR_ARG},
196
#line 21 "defs/keywords"
196
#line 21 "../defs/keywords"
197 197
      {"class", {keyword_class, keyword_class}, EXPR_CLASS},
198 198
      {""}, {""},
199
#line 50 "defs/keywords"
199
#line 50 "../defs/keywords"
200 200
      {"while", {keyword_while, modifier_while}, EXPR_VALUE}
201 201
    };
202 202

  
......
214 214
    }
215 215
  return 0;
216 216
}
217
#line 52 "defs/keywords"
217
#line 52 "../defs/keywords"
218 218

  
219 219
#endif
method.h
89 89

  
90 90
void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_flag_t noex);
91 91
rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_flag_t noex);
92
rb_method_entry_t *rb_method_entry(VALUE klass, ID id);
92
rb_method_entry_t *rb_method_entry(VALUE klass, ID id, VALUE *define_class_ptr);
93 93

  
94
rb_method_entry_t *rb_method_entry_get_without_cache(VALUE klass, ID id);
94
rb_method_entry_t *rb_method_entry_get_with_omod(VALUE omod, VALUE klass, ID id, VALUE *define_class_ptr);
95
rb_method_entry_t *rb_method_entry_get_without_cache(VALUE klass, VALUE omod, ID id, VALUE *define_class_ptr);
95 96
rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_flag_t noex);
96 97

  
97 98
int rb_method_entry_arity(const rb_method_entry_t *me);
node.h
188 188
#define NODE_COLON2      NODE_COLON2
189 189
    NODE_COLON3,
190 190
#define NODE_COLON3      NODE_COLON3
191
    NODE_CREF,
192
#define NODE_CREF        NODE_CREF
191 193
    NODE_DOT2,
192 194
#define NODE_DOT2        NODE_DOT2
193 195
    NODE_DOT3,
......
234 236

  
235 237
typedef struct RNode {
236 238
    unsigned long flags;
237
    char *nd_file;
239
    union {
240
	char *file;
241
	VALUE value;
242
    } u0;
238 243
    union {
239 244
	struct RNode *node;
240 245
	ID id;
......
260 265

  
261 266
#define RNODE(obj)  (R_CAST(RNode)(obj))
262 267

  
263
/* 0..4:T_TYPES, 5:FL_MARK, 6:reserved, 7:NODE_FL_NEWLINE */
268
/* 0..4:T_TYPES, 5:FL_MARK, 6:NODE_FL_NESTED_DEF, 7:NODE_FL_NEWLINE */
264 269
#define NODE_FL_NEWLINE (((VALUE)1)<<7)
270
#define NODE_FL_NESTED_DEF (((VALUE)1)<<6)
265 271
#define NODE_FL_CREF_PUSHED_BY_EVAL NODE_FL_NEWLINE
272
#define NODE_FL_CREF_OMOD_SHARED NODE_FL_NESTED_DEF
266 273

  
267 274
#define NODE_TYPESHIFT 8
268 275
#define NODE_TYPEMASK  (((VALUE)0x7f)<<NODE_TYPESHIFT)
......
277 284
#define nd_set_line(n,l) \
278 285
    RNODE(n)->flags=((RNODE(n)->flags&~(-1<<NODE_LSHIFT))|(((l)&NODE_LMASK)<<NODE_LSHIFT))
279 286

  
287
#define nd_file  u0.file
288
#define nd_omod  u0.value
289

  
280 290
#define nd_head  u1.node
281 291
#define nd_alen  u2.argc
282 292
#define nd_next  u3.node
......
433 443
#define NEW_MODULE(n,b) NEW_NODE(NODE_MODULE,n,NEW_SCOPE(0,b),0)
434 444
#define NEW_COLON2(c,i) NEW_NODE(NODE_COLON2,c,i,0)
435 445
#define NEW_COLON3(i) NEW_NODE(NODE_COLON3,0,i,0)
446
#define NEW_CREF(a) NEW_NODE(NODE_CREF,a,0,0)
436 447
#define NEW_DOT2(b,e) NEW_NODE(NODE_DOT2,b,e,0)
437 448
#define NEW_DOT3(b,e) NEW_NODE(NODE_DOT3,b,e,0)
438 449
#define NEW_SELF() NEW_NODE(NODE_SELF,0,0,0)
object.c
2531 2531
    rb_define_private_method(rb_cClass, "inherited", rb_obj_dummy, 1);
2532 2532
    rb_define_private_method(rb_cModule, "included", rb_obj_dummy, 1);
2533 2533
    rb_define_private_method(rb_cModule, "extended", rb_obj_dummy, 1);
2534
    rb_define_private_method(rb_cModule, "used", rb_obj_dummy, 1);
2534 2535
    rb_define_private_method(rb_cModule, "method_added", rb_obj_dummy, 1);
2535 2536
    rb_define_private_method(rb_cModule, "method_removed", rb_obj_dummy, 1);
2536 2537
    rb_define_private_method(rb_cModule, "method_undefined", rb_obj_dummy, 1);
parse.y
2967 2967
			reduce_nodes(&body);
2968 2968
			$$ = NEW_DEFN($2, $4, body, NOEX_PRIVATE);
2969 2969
			nd_set_line($$, $<num>1);
2970
			if (in_def > 1 || in_single > 0)
2971
			    $$->flags |= NODE_FL_NESTED_DEF;
2970 2972
		    /*%
2971 2973
			$$ = dispatch3(def, $2, $4, $5);
2972 2974
		    %*/
proc.c
15 15
struct METHOD {
16 16
    VALUE recv;
17 17
    VALUE rclass;
18
    VALUE defined_class;
18 19
    ID id;
19 20
    rb_method_entry_t me;
20 21
};
......
861 862
bm_mark(void *ptr)
862 863
{
863 864
    struct METHOD *data = ptr;
865
    rb_gc_mark(data->defined_class);
864 866
    rb_gc_mark(data->rclass);
865 867
    rb_gc_mark(data->recv);
866 868
    rb_mark_method_entry(&data->me);
......
903 905
mnew(VALUE klass, VALUE obj, ID id, VALUE mclass, int scope)
904 906
{
905 907
    VALUE method;
906
    VALUE rclass = klass;
908
    VALUE rclass = klass, defined_class;
907 909
    ID rid = id;
908 910
    struct METHOD *data;
909 911
    rb_method_entry_t *me, meb;
......
911 913
    rb_method_flag_t flag = NOEX_UNDEF;
912 914

  
913 915
  again:
914
    me = rb_method_entry(klass, id);
916
    me = rb_method_entry(klass, id, &defined_class);
915 917
    if (UNDEFINED_METHOD_ENTRY_P(me)) {
916 918
	ID rmiss = rb_intern("respond_to_missing?");
917 919
	VALUE sym = ID2SYM(id);
......
953 955
	}
954 956
    }
955 957
    if (def && def->type == VM_METHOD_TYPE_ZSUPER) {
956
	klass = RCLASS_SUPER(me->klass);
958
	klass = RCLASS_SUPER(defined_class);
957 959
	id = def->original_id;
958 960
	goto again;
959 961
    }
960 962

  
961
    klass = me->klass;
963
    klass = defined_class;
962 964

  
963 965
    while (rclass != klass &&
964 966
	   (FL_TEST(rclass, FL_SINGLETON) || TYPE(rclass) == T_ICLASS)) {
......
974 976

  
975 977
    data->recv = obj;
976 978
    data->rclass = rclass;
979
    data->defined_class = defined_class;
977 980
    data->id = rid;
978 981
    data->me = *me;
979 982
    if (def) def->alias_count++;
......
1085 1088
    data->me = orig->me;
1086 1089
    if (orig->me.def) orig->me.def->alias_count++;
1087 1090
    data->rclass = orig->rclass;
1091
    data->defined_class = orig->defined_class;
1088 1092
    OBJ_INFECT(method, obj);
1089 1093

  
1090 1094
    return method;
......
1421 1425
    if ((state = EXEC_TAG()) == 0) {
1422 1426
	rb_thread_t *th = GET_THREAD();
1423 1427
	VALUE rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc, const VALUE *argv,
1424
			 const rb_method_entry_t *me);
1428
			 const rb_method_entry_t *me, VALUE defined_class);
1425 1429

  
1426 1430
	PASS_PASSED_BLOCK_TH(th);
1427
	result = rb_vm_call(th, data->recv, data->id,  argc, argv, &data->me);
1431
	result = rb_vm_call(th, data->recv, data->id,  argc, argv, &data->me, data->defined_class);
1428 1432
    }
1429 1433
    POP_TAG();
1430 1434
    if (safe >= 0)
......
1648 1652
int
1649 1653
rb_mod_method_arity(VALUE mod, ID id)
1650 1654
{
1651
    rb_method_entry_t *me = rb_method_entry(mod, id);
1655
    rb_method_entry_t *me = rb_method_entry(mod, id, 0);
1652 1656
    return rb_method_entry_arity(me);
1653 1657
}
1654 1658

  
test/rdoc/test_rdoc_text.rb
62 62
    assert_equal expected, flush_left(text)
63 63
  end
64 64

  
65
  def formatter() RDoc::Markup::ToHtml.new end
65 66
  def test_markup
66
    def formatter() RDoc::Markup::ToHtml.new end
67 67

  
68 68
    assert_equal "<p>\nhi\n</p>\n", markup('hi')
69 69
  end
test/ruby/test_nested_method.rb
1
require 'test/unit'
2

  
3
class TestNestedMethod < Test::Unit::TestCase
4
  def call_nested_method
5
    def foo
6
      return "foo"
7
    end
8

  
9
    return foo
10
  end
11

  
12
  def test_nested_method
13
    assert_equal("foo", call_nested_method)
14
    assert_raise(NoMethodError) { foo() }
15
  end
16

  
17
  def test_doubly_nested_method
18
    def call_doubly_nested_method
19
      def foo
20
        return "foo"
21
      end
22

  
23
      return foo
24
    end
25

  
26
    assert_equal("foo", call_doubly_nested_method)
27
    assert_raise(NoMethodError) { foo() }
28
  end
29
end
test/ruby/test_refinement.rb
1
require 'test/unit'
2

  
3
class TestRefinement < Test::Unit::TestCase
4
  class Foo
5
    def x
6
      return "Foo#x"
7
    end
8

  
9
    def y
10
      return "Foo#y"
11
    end
12

  
13
    def call_x
14
      return x
15
    end
16
  end
17

  
18
  module FooExt
19
    refine Foo do
20
      def x
21
        return "FooExt#x"
22
      end
23

  
24
      def y
25
        return "FooExt#y " + super
26
      end
27

  
28
      def z
29
        return "FooExt#z"
30
      end
31
    end
32
  end
33

  
34
  module FooExt2
35
    refine Foo do
36
      def x
37
        return "FooExt2#x"
38
      end
39

  
40
      def y
41
        return "FooExt2#y " + super
42
      end
43

  
44
      def z
45
        return "FooExt2#z"
46
      end
47
    end
48
  end
49

  
50
  class FooSub < Foo
51
    def x
52
      return "FooSub#x"
53
    end
54

  
55
    def y
56
      return "FooSub#y " + super
57
    end
58
  end
59

  
60
  class FooExtClient
61
    using FooExt
62

  
63
    def self.invoke_x_on(foo)
64
      return foo.x
65
    end
66

  
67
    def self.invoke_y_on(foo)
68
      return foo.y
69
    end
70

  
71
    def self.invoke_z_on(foo)
72
      return foo.z
73
    end
74

  
75
    def self.invoke_call_x_on(foo)
76
      return foo.call_x
77
    end
78
  end
79

  
80
  class FooExtClient2
81
    using FooExt
82
    using FooExt2
83

  
84
    def self.invoke_y_on(foo)
85
      return foo.y
86
    end
87
  end
88

  
89
  def test_override
90
    foo = Foo.new
91
    assert_equal("Foo#x", foo.x)
92
    assert_equal("FooExt#x", FooExtClient.invoke_x_on(foo))
93
    assert_equal("Foo#x", foo.x)
94
  end
95

  
96
  def test_super
97
    foo = Foo.new
98
    assert_equal("Foo#y", foo.y)
99
    assert_equal("FooExt#y Foo#y", FooExtClient.invoke_y_on(foo))
100
    assert_equal("Foo#y", foo.y)
101
  end
102

  
103
  def test_super_chain
104
    foo = Foo.new
105
    assert_equal("Foo#y", foo.y)
106
    assert_equal("FooExt2#y FooExt#y Foo#y", FooExtClient2.invoke_y_on(foo))
107
    assert_equal("Foo#y", foo.y)
108
  end
109

  
110
  def test_new_method
111
    foo = Foo.new
112
    assert_raise(NoMethodError) { foo.z }
113
    assert_equal("FooExt#z", FooExtClient.invoke_z_on(foo))
114
    assert_raise(NoMethodError) { foo.z }
115
  end
116

  
117
  def test_no_local_rebinding
118
    foo = Foo.new
119
    assert_equal("Foo#x", foo.call_x)
120
    assert_equal("Foo#x", FooExtClient.invoke_call_x_on(foo))
121
    assert_equal("Foo#x", foo.call_x)
122
  end
123

  
124
  def test_subclass_is_prior
125
    sub = FooSub.new
126
    assert_equal("FooSub#x", sub.x)
127
    assert_equal("FooSub#x", FooExtClient.invoke_x_on(sub))
128
    assert_equal("FooSub#x", sub.x)
129
  end
130

  
131
  def test_subclass_is_prior
132
    sub = FooSub.new
133
    assert_equal("FooSub#x", sub.x)
134
    assert_equal("FooSub#x", FooExtClient.invoke_x_on(sub))
135
    assert_equal("FooSub#x", sub.x)
136
  end
137

  
138
  def test_super_in_subclass
139
    sub = FooSub.new
140
    assert_equal("FooSub#y Foo#y", sub.y)
141
    # not "FooSub#y FooExt#y Foo#y"
142
    assert_equal("FooSub#y Foo#y", FooExtClient.invoke_y_on(sub))
143
    assert_equal("FooSub#y Foo#y", sub.y)
144
  end
145

  
146
  def test_new_method_on_subclass
147
    sub = FooSub.new
148
    assert_raise(NoMethodError) { sub.z }
149
    assert_equal("FooExt#z", FooExtClient.invoke_z_on(sub))
150
    assert_raise(NoMethodError) { sub.z }
151
  end
152

  
153
  def test_module_eval
154
    foo = Foo.new
155
    assert_equal("Foo#x", foo.x)
156
    assert_equal("FooExt#x", FooExt.module_eval { foo.x })
157
    assert_equal("Foo#x", foo.x)
158
  end
159

  
160
  def test_instance_eval
161
    foo = Foo.new
162
    ext_client = FooExtClient.new
163
    assert_equal("Foo#x", foo.x)
164
    assert_equal("FooExt#x", ext_client.instance_eval { foo.x })
165
    assert_equal("Foo#x", foo.x)
166
  end
167

  
168
  def test_override_builtin_method
169
    m = Module.new {
170
      refine Fixnum do
171
        def /(other) quo(other) end
172
      end
173
    }
174
    assert_equal(0, 1 / 2)
175
    assert_equal(Rational(1, 2), m.module_eval { 1 / 2 })
176
    assert_equal(0, 1 / 2)
177
  end
178

  
179
  def test_return_value_of_refine
180
    mod = nil
181
    result = nil
182
    m = Module.new {
183
      result = refine(Object) {
184
        mod = self
185
      }
186
    }
187
    assert_equal mod, result
188
  end
189

  
190
  def test_refine_same_class_twice
191
    result1 = nil
192
    result2 = nil
193
    result3 = nil
194
    m = Module.new {
195
      result1 = refine(Fixnum) {
196
        def foo; return "foo" end
197
      }
198
      result2 = refine(Fixnum) {
199
        def bar; return "bar" end
200
      }
201
      result3 = refine(String) {
202
        def baz; return "baz" end
203
      }
204
    }
205
    assert_equal("foo", m.module_eval { 1.foo })
206
    assert_equal("bar", m.module_eval { 1.bar })
207
    assert_equal(result1, result2)
208
    assert_not_equal(result1, result3)
209
  end
210
end
vm.c
70 70
rb_vm_set_finish_env(rb_thread_t * th)
71 71
{
72 72
    vm_push_frame(th, 0, VM_FRAME_MAGIC_FINISH,
73
		  Qnil, th->cfp->lfp[0], 0,
73
		  Qnil, Qnil, th->cfp->lfp[0], 0,
74 74
		  th->cfp->sp, 0, 1);
75 75
    th->cfp->pc = (VALUE *)&finish_insn_seq[0];
76 76
    return Qtrue;
......
90 90
    rb_vm_set_finish_env(th);
91 91

  
92 92
    vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP,
93
		  th->top_self, 0, iseq->iseq_encoded,
93
		  th->top_self, rb_cObject, 0, iseq->iseq_encoded,
94 94
		  th->cfp->sp, 0, iseq->local_size);
95 95

  
96 96
    CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max);
......
105 105

  
106 106
    /* for return */
107 107
    rb_vm_set_finish_env(th);
108
    vm_push_frame(th, iseq, VM_FRAME_MAGIC_EVAL, block->self,
108
    vm_push_frame(th, iseq, VM_FRAME_MAGIC_EVAL, block->self, block->klass,
109 109
		  GC_GUARDED_PTR(block->dfp), iseq->iseq_encoded,
110 110
		  th->cfp->sp, block->lfp, iseq->local_size);
111 111

  
......
490 490
    GetProcPtr(procval, proc);
491 491
    proc->blockprocval = blockprocval;
492 492
    proc->block.self = block->self;
493
    proc->block.klass = block->klass;
493 494
    proc->block.lfp = block->lfp;
494 495
    proc->block.dfp = block->dfp;
495 496
    proc->block.iseq = block->iseq;
......
539 540
				     type == VM_FRAME_MAGIC_LAMBDA);
540 541

  
541 542
	ncfp = vm_push_frame(th, iseq, type,
542
			     self, GC_GUARDED_PTR(block->dfp),
543
			     self, th->passed_defined_class,
544
			     GC_GUARDED_PTR(block->dfp),
543 545
			     iseq->iseq_encoded + opt_pc, cfp->sp + arg_size, block->lfp,
544 546
			     iseq->local_size - arg_size);
547
	th->passed_defined_class = 0;
545 548
	ncfp->me = th->passed_me;
546 549
	th->passed_me = 0;
547 550
	th->passed_block = blockptr;
......
816 819
{
817 820
    rb_thread_t *th = GET_THREAD();
818 821
    rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp);
819
    return vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
822
    if (!cfp) return NULL;
823
    return rb_vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
820 824
}
821 825

  
822 826
#if 0
......
1317 1321
	    /* push block frame */
1318 1322
	    cfp->sp[0] = err;
1319 1323
	    vm_push_frame(th, catch_iseq, VM_FRAME_MAGIC_BLOCK,
1320
			  cfp->self, (VALUE)cfp->dfp, catch_iseq->iseq_encoded,
1324
			  cfp->self, cfp->klass,
1325
			  (VALUE)cfp->dfp, catch_iseq->iseq_encoded,
1321 1326
			  cfp->sp + 1 /* push value */, cfp->lfp, catch_iseq->local_size - 1);
1322 1327

  
1323 1328
	    state = 0;
......
1455 1460
    VALUE val;
1456 1461

  
1457 1462
    vm_push_frame(th, DATA_PTR(iseqval), VM_FRAME_MAGIC_TOP,
1458
		  recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
1463
		  recv, CLASS_OF(recv), (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
1459 1464

  
1460 1465
    val = (*func)(arg);
1461 1466

  
......
1667 1672
	RUBY_MARK_UNLESS_NULL(th->root_fiber);
1668 1673
	RUBY_MARK_UNLESS_NULL(th->stat_insn_usage);
1669 1674
	RUBY_MARK_UNLESS_NULL(th->last_status);
1675
	RUBY_MARK_UNLESS_NULL(th->passed_defined_class);
1670 1676

  
1671 1677
	RUBY_MARK_UNLESS_NULL(th->locking_mutex);
1672 1678

  
......
1778 1784

  
1779 1785
    th->cfp = (void *)(th->stack + th->stack_size);
1780 1786

  
1781
    vm_push_frame(th, 0, VM_FRAME_MAGIC_TOP, Qnil, 0, 0,
1787
    vm_push_frame(th, 0, VM_FRAME_MAGIC_TOP, Qnil, Qnil, 0, 0,
1782 1788
		  th->stack, 0, 1);
1783 1789

  
1784 1790
    th->status = THREAD_RUNNABLE;
......
1815 1821
    return self;
1816 1822
}
1817 1823

  
1824
static VALUE
1825
find_module_for_nested_methods(NODE *cref, VALUE klass)
1826
{
1827
    VALUE iclass;
1828

  
1829
    if (NIL_P(cref->nd_omod))
1830
	return Qnil;
1831
    iclass = rb_hash_lookup(cref->nd_omod, klass);
1832
    if (NIL_P(iclass))
1833
	return Qnil;
1834
    while (iclass) {
1835
	VALUE module = RBASIC(iclass)->klass;
1836
	if (FL_TEST(module, RMODULE_HAS_NESTED_METHODS)) {
1837
	    return module;
1838
	}
1839
	iclass = RCLASS_SUPER(iclass);
1840
    }
1841
    return Qnil;
1842
}
1843

  
1818 1844
VALUE rb_iseq_clone(VALUE iseqval, VALUE newcbase);
1819 1845

  
1820 1846
static void
1821
vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval,
1847
vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval, VALUE nested,
1822 1848
		 rb_num_t is_singleton, NODE *cref)
1823 1849
{
1824 1850
    VALUE klass = cref->nd_clss;
1851
    VALUE target, defined_class;
1852
    rb_method_entry_t *me;
1825 1853
    int noex = (int)cref->nd_visi;
1854
    int is_nested = RTEST(nested);
1826 1855
    rb_iseq_t *miseq;
1827 1856
    GetISeqPtr(iseqval, miseq);
1828 1857

  
......
1847 1876
	noex = NOEX_PUBLIC;
1848 1877
    }
1849 1878

  
1879
    if (is_nested && th->cfp->lfp == th->cfp->dfp) {
1880
	VALUE c;
1881
       	if (TYPE(klass) == T_MODULE) {
1882
	    c = rb_obj_class(th->cfp->self);
1883
	}
1884
	else {
1885
	    c = klass;
1886
	}
1887
	if (cref->flags & NODE_FL_CREF_OMOD_SHARED) {
1888
	    target = Qnil;
1889
	}
1890
	else {
1891
	    target = find_module_for_nested_methods(cref, c);
1892
	}
1893
	if (NIL_P(target)) {
1894
	    target = rb_module_new();
1895
	    FL_SET(target, RMODULE_HAS_NESTED_METHODS);
1896
	    rb_overlay_module(cref, c, target);
1897
	}
1898
	else {
1899
	    me = search_method(target, id, Qnil, &defined_class);
1900
	    if (me && me->def->type == VM_METHOD_TYPE_ISEQ &&
1901
		me->def->body.iseq == miseq) {
1902
		return;
1903
	    }
1904
	}
1905
	noex = NOEX_PRIVATE;
1906
    }
1907
    else {
1908
	target = klass;
1909
    }
1850 1910
    /* dup */
1851 1911
    COPY_CREF(miseq->cref_stack, cref);
1852 1912
    miseq->cref_stack->nd_visi = NOEX_PUBLIC;
1853
    miseq->klass = klass;
1913
    miseq->klass = target;
1854 1914
    miseq->defined_method_id = id;
1855
    rb_add_method(klass, id, VM_METHOD_TYPE_ISEQ, miseq, noex);
1915
    rb_add_method(target, id, VM_METHOD_TYPE_ISEQ, miseq, noex);
1856 1916

  
1857 1917
    if (!is_singleton && noex == NOEX_MODFUNC) {
1858 1918
	rb_add_method(rb_singleton_class(klass), id, VM_METHOD_TYPE_ISEQ, miseq, NOEX_PUBLIC);
......
1866 1926
} while (0)
1867 1927

  
1868 1928
static VALUE
1869
m_core_define_method(VALUE self, VALUE cbase, VALUE sym, VALUE iseqval)
1929
m_core_define_method(VALUE self, VALUE cbase, VALUE sym, VALUE iseqval, VALUE nested)
1870 1930
{
1871 1931
    REWIND_CFP({
1872
	vm_define_method(GET_THREAD(), cbase, SYM2ID(sym), iseqval, 0, rb_vm_cref());
1932
	vm_define_method(GET_THREAD(), cbase, SYM2ID(sym), iseqval, nested, 0, rb_vm_cref());
1873 1933
    });
1874 1934
    return Qnil;
1875 1935
}
......
1878 1938
m_core_define_singleton_method(VALUE self, VALUE cbase, VALUE sym, VALUE iseqval)
1879 1939
{
1880 1940
    REWIND_CFP({
1881
	vm_define_method(GET_THREAD(), cbase, SYM2ID(sym), iseqval, 1, rb_vm_cref());
1941
	vm_define_method(GET_THREAD(), cbase, SYM2ID(sym), iseqval, Qfalse, 1, rb_vm_cref());
1882 1942
    });
1883 1943
    return Qnil;
1884 1944
}
......
1994 2054
    rb_define_method_id(klass, id_core_set_method_alias, m_core_set_method_alias, 3);
1995 2055
    rb_define_method_id(klass, id_core_set_variable_alias, m_core_set_variable_alias, 2);
1996 2056
    rb_define_method_id(klass, id_core_undef_method, m_core_undef_method, 2);
1997
    rb_define_method_id(klass, id_core_define_method, m_core_define_method, 3);
2057
    rb_define_method_id(klass, id_core_define_method, m_core_define_method, 4);
1998 2058
    rb_define_method_id(klass, id_core_define_singleton_method, m_core_define_singleton_method, 3);
1999 2059
    rb_define_method_id(klass, id_core_set_postexe, m_core_set_postexe, 1);
2000 2060
    rb_obj_freeze(fcore);
vm_core.h
132 132
	rb_method_entry_t *method;
133 133
	long index;
134 134
    } ic_value;
135
    union {
136
	VALUE defined_class;
137
    } ic_value2;
135 138
};
136 139

  
137 140
#if 1
......
325 328
    VALUE *bp;			/* cfp[2] */
326 329
    rb_iseq_t *iseq;		/* cfp[3] */
327 330
    VALUE flag;			/* cfp[4] */
328
    VALUE self;			/* cfp[5] / block[0] */
329
    VALUE *lfp;			/* cfp[6] / block[1] */
330
    VALUE *dfp;			/* cfp[7] / block[2] */
331
    rb_iseq_t *block_iseq;	/* cfp[8] / block[3] */
332
    VALUE proc;			/* cfp[9] / block[4] */
333
    const rb_method_entry_t *me;/* cfp[10] */
331
    VALUE self;			/* cfp[5]  / block[0] */
332
    VALUE klass;		/* cfp[6]  / block[1] */
333
    VALUE *lfp;			/* cfp[7]  / block[2] */
334
    VALUE *dfp;			/* cfp[8]  / block[3] */
335
    rb_iseq_t *block_iseq;	/* cfp[9]  / block[4] */
336
    VALUE proc;			/* cfp[10] / block[5] */
337
    const rb_method_entry_t *me;/* cfp[11] */
334 338
} rb_control_frame_t;
335 339

  
336 340
typedef struct rb_block_struct {
337 341
    VALUE self;			/* share with method frame if it's only block */
342
    VALUE klass;		/* share with method frame if it's only block */
338 343
    VALUE *lfp;			/* share with method frame if it's only block */
339 344
    VALUE *dfp;			/* share with method frame if it's only block */
340 345
    rb_iseq_t *iseq;
......
392 397

  
393 398
    /* for bmethod */
394 399
    const rb_method_entry_t *passed_me;
400
    VALUE passed_defined_class;
395 401

  
396 402
    /* for load(true) */
397 403
    VALUE top_self;
......
711 717
    } \
712 718
} while (0)
713 719

  
720
void rb_overlay_module(NODE*, VALUE, VALUE);
721

  
714 722
#if defined __GNUC__ && __GNUC__ >= 4
715 723
#pragma GCC visibility push(default)
716 724
#endif
vm_eval.c
33 33

  
34 34
static inline VALUE
35 35
vm_call0(rb_thread_t* th, VALUE recv, VALUE id, int argc, const VALUE *argv,
36
	 const rb_method_entry_t *me)
36
	 const rb_method_entry_t *me, VALUE defined_class)
37 37
{
38 38
    const rb_method_definition_t *def = me->def;
39 39
    VALUE val;
40
    VALUE klass = me->klass;
40
    VALUE klass = defined_class;
41 41
    const rb_block_t *blockptr = 0;
42 42

  
43 43
    if (!def) return Qnil;
......
62 62
	    *reg_cfp->sp++ = argv[i];
63 63
	}
64 64

  
65
	vm_setup_method(th, reg_cfp, recv, argc, blockptr, 0 /* flag */, me);
65
	vm_setup_method(th, reg_cfp, recv, argc, blockptr, 0 /* flag */, me, klass);
66 66
	val = vm_exec(th);
67 67
	break;
68 68
      }
......
73 73
	    rb_control_frame_t *reg_cfp = th->cfp;
74 74
	    rb_control_frame_t *cfp =
75 75
		vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC,
76
			      recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
76
			      recv, klass, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
77 77

  
78 78
	    cfp->me = me;
79 79
	    val = call_cfunc(def->body.cfunc.func, recv, def->body.cfunc.argc, argc, argv);
......
101 101
	break;
102 102
      }
103 103
      case VM_METHOD_TYPE_BMETHOD: {
104
	val = vm_call_bmethod(th, recv, argc, argv, blockptr, me);
104
	val = vm_call_bmethod(th, recv, argc, argv, blockptr, me, klass);
105 105
	break;
106 106
      }
107 107
      case VM_METHOD_TYPE_ZSUPER: {
108 108
	klass = RCLASS_SUPER(klass);
109
	if (!klass || !(me = rb_method_entry(klass, id))) {
109
	if (!klass || !(me = rb_method_entry(klass, id, &klass))) {
110 110
	    return method_missing(recv, id, argc, argv, NOEX_SUPER);
111 111
	}
112 112
	RUBY_VM_CHECK_INTS();
......
149 149

  
150 150
VALUE
151 151
rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc, const VALUE *argv,
152
	   const rb_method_entry_t *me)
152
	   const rb_method_entry_t *me, VALUE defined_class)
153 153
{
154
    return vm_call0(th, recv, id, argc, argv, me);
154
    return vm_call0(th, recv, id, argc, argv, me, defined_class);
155 155
}
156 156

  
157 157
static inline VALUE
......
163 163
    rb_method_entry_t *me;
164 164
    rb_control_frame_t *cfp = th->cfp;
165 165

  
166
    if (!cfp->iseq) {
167
	klass = cfp->me->klass;
168
	klass = RCLASS_SUPER(klass);
166
    if (!cfp->iseq && !NIL_P(cfp->klass)) {
167
	klass = RCLASS_SUPER(cfp->klass);
169 168

  
170 169
	if (klass == 0) {
171 170
	    klass = vm_search_normal_superclass(cfp->me->klass, recv);
......
176 175
	rb_bug("vm_call_super: should not be reached");
177 176
    }
178 177

  
179
    me = rb_method_entry(klass, id);
178
    me = rb_method_entry(klass, id, &klass);
180 179
    if (!me) {
181 180
	return method_missing(recv, id, argc, argv, NOEX_SUPER);
182 181
    }
183 182

  
184
    return vm_call0(th, recv, id, argc, argv, me);
183
    return vm_call0(th, recv, id, argc, argv, me, klass);
185 184
}
186 185

  
187 186
VALUE
......
202 201
    }
203 202
}
204 203

  
205
static inline rb_method_entry_t *rb_search_method_entry(VALUE recv, ID mid);
204
static inline rb_method_entry_t *rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr);
206 205
static inline int rb_method_call_status(rb_thread_t *th, rb_method_entry_t *me, call_type scope, VALUE self);
207 206
#define NOEX_OK NOEX_NOSUPER
208 207

  
......
224 223
rb_call0(VALUE recv, ID mid, int argc, const VALUE *argv,
225 224
	 call_type scope, VALUE self)
226 225
{
227
    rb_method_entry_t *me = rb_search_method_entry(recv, mid);
226
    VALUE defined_class;
227
    rb_method_entry_t *me = rb_search_method_entry(recv, mid, &defined_class);
228 228
    rb_thread_t *th = GET_THREAD();
229 229
    int call_status = rb_method_call_status(th, me, scope, self);
230 230

  
......
232 232
	return method_missing(recv, mid, argc, argv, call_status);
233 233
    }
234 234
    stack_check();
235
    return vm_call0(th, recv, mid, argc, argv, me);
235
    return vm_call0(th, recv, mid, argc, argv, me, defined_class);
236 236
}
237 237

  
238 238
struct rescue_funcall_args {
......
265 265
static VALUE
... This diff was truncated because it exceeds the maximum size that can be displayed.