[前][次][番号順一覧][スレッド一覧]

ruby-changes:39045

From: ko1 <ko1@a...>
Date: Fri, 3 Jul 2015 20:25:16 +0900 (JST)
Subject: [ruby-changes:39045] ko1:r51126 (trunk): * method.h: introduce rb_callable_method_entry_t to remove

ko1	2015-07-03 20:24:50 +0900 (Fri, 03 Jul 2015)

  New Revision: 51126

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=51126

  Log:
    * method.h: introduce rb_callable_method_entry_t to remove
      rb_control_frame_t::klass.
      [Bug #11278], [Bug #11279]
      rb_method_entry_t data belong to modules/classes.
      rb_method_entry_t::owner points defined module or class.
        module M
          def foo; end
        end
      In this case, owner is M.
      rb_callable_method_entry_t data belong to only classes.
      For modules, MRI creates corresponding T_ICLASS internally.
      rb_callable_method_entry_t can also belong to T_ICLASS.
      rb_callable_method_entry_t::defined_class points T_CLASS or
      T_ICLASS.
      rb_method_entry_t data for classes (not for modules) are also
      rb_callable_method_entry_t data because it is completely same data.
      In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
      For example, there are classes C and D, and incldues M,
        class C; include M; end
        class D; include M; end
      then, two T_ICLASS objects for C's super class and D's super class
      will be created.
      When C.new.foo is called, then M#foo is searcheed and
      rb_callable_method_t data is used by VM to invoke M#foo.
      rb_method_entry_t data is only one for M#foo.
      However, rb_callable_method_entry_t data are two (and can be more).
      It is proportional to the number of including (and prepending)
      classes (the number of T_ICLASS which point to the module).
      Now, created rb_callable_method_entry_t are collected when
      the original module M was modified. We can think it is a cache.
      We need to select what kind of method entry data is needed.
      To operate definition, then you need to use rb_method_entry_t.
      You can access them by the following functions.
      * rb_method_entry(VALUE klass, ID id);
      * rb_method_entry_with_refinements(VALUE klass, ID id);
      * rb_method_entry_without_refinements(VALUE klass, ID id);
      * rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
      To invoke methods, then you need to use rb_callable_method_entry_t
      which you can get by the following APIs corresponding to the
      above listed functions.
      * rb_callable_method_entry(VALUE klass, ID id);
      * rb_callable_method_entry_with_refinements(VALUE klass, ID id);
      * rb_callable_method_entry_without_refinements(VALUE klass, ID id);
      * rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
      VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
      returns rb_callable_method_entry_t.
      You can check a super class of current method by
      rb_callable_method_entry_t::defined_class.
    * method.h: renamed from rb_method_entry_t::klass to
      rb_method_entry_t::owner.
    * internal.h: add rb_classext_struct::callable_m_tbl to cache
      rb_callable_method_entry_t data.
      We need to consider abotu this field again because it is only
      active for T_ICLASS.
    * class.c (method_entry_i): ditto.
    * class.c (rb_define_attr): rb_method_entry() does not takes
      defiend_class_ptr.
    * gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
    * cont.c (fiber_init): rb_control_frame_t::klass is removed.
    * proc.c: fix `struct METHOD' data structure because
      rb_callable_method_t has all information.
    * vm_core.h: remove several fields.
      * rb_control_frame_t::klass.
      * rb_block_t::klass.
      And catch up changes.
    * eval.c: catch up changes.
    * gc.c: ditto.
    * insns.def: ditto.
    * vm.c: ditto.
    * vm_args.c: ditto.
    * vm_backtrace.c: ditto.
    * vm_dump.c: ditto.
    * vm_eval.c: ditto.
    * vm_insnhelper.c: ditto.
    * vm_method.c: ditto.

  Modified files:
    trunk/ChangeLog
    trunk/class.c
    trunk/cont.c
    trunk/eval.c
    trunk/gc.c
    trunk/insns.def
    trunk/internal.h
    trunk/method.h
    trunk/proc.c
    trunk/vm.c
    trunk/vm_args.c
    trunk/vm_backtrace.c
    trunk/vm_core.h
    trunk/vm_dump.c
    trunk/vm_eval.c
    trunk/vm_insnhelper.c
    trunk/vm_method.c
Index: method.h
===================================================================
--- method.h	(revision 51125)
+++ method.h	(revision 51126)
@@ -47,12 +47,20 @@ typedef struct rb_cref_struct { https://github.com/ruby/ruby/blob/trunk/method.h#L47
 
 typedef struct rb_method_entry_struct {
     VALUE flags;
-    VALUE dummy;
+    const VALUE defined_class;
     struct rb_method_definition_struct * const def;
     ID called_id;
-    const VALUE klass;    /* should be marked */
+    const VALUE owner;
 } rb_method_entry_t;
 
+typedef struct rb_callable_method_entry_struct { /* same fields with rb_method_entry_t */
+    VALUE flags;
+    const VALUE defined_class;
+    struct rb_method_definition_struct * const def;
+    ID called_id;
+    const VALUE owner;
+} rb_callable_method_entry_t;
+
 #define METHOD_ENTRY_VISI(me)  (rb_method_visibility_t)(((me)->flags & (IMEMO_FL_USER0 | IMEMO_FL_USER1)) >> (IMEMO_FL_USHIFT+0))
 #define METHOD_ENTRY_BASIC(me) (int)                   (((me)->flags & (IMEMO_FL_USER2                 )) >> (IMEMO_FL_USHIFT+2))
 #define METHOD_ENTRY_SAFE(me)  (int)                   (((me)->flags & (IMEMO_FL_USER3 | IMEMO_FL_USER4)) >> (IMEMO_FL_USHIFT+3))
@@ -85,6 +93,13 @@ METHOD_ENTRY_FLAGS_SET(rb_method_entry_t https://github.com/ruby/ruby/blob/trunk/method.h#L93
       (me->flags & ~(IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2|IMEMO_FL_USER3|IMEMO_FL_USER4)) |
 	((visi << IMEMO_FL_USHIFT+0) | (basic << (IMEMO_FL_USHIFT+2)) | (safe << IMEMO_FL_USHIFT+3));
 }
+static inline void
+METHOD_ENTRY_FLAGS_COPY(rb_method_entry_t *dst, const rb_method_entry_t *src)
+{
+    dst->flags =
+      (dst->flags & ~(IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2|IMEMO_FL_USER3|IMEMO_FL_USER4)) |
+	(src->flags & (IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2|IMEMO_FL_USER3|IMEMO_FL_USER4));
+}
 
 typedef enum {
     VM_METHOD_TYPE_ISEQ,
@@ -127,6 +142,7 @@ typedef struct rb_method_alias_struct { https://github.com/ruby/ruby/blob/trunk/method.h#L142
 
 typedef struct rb_method_refined_struct {
     const struct rb_method_entry_struct * const orig_me;
+    const VALUE owner;
 } rb_method_refined_t;
 
 typedef struct rb_method_definition_struct {
@@ -159,20 +175,23 @@ typedef struct rb_method_definition_stru https://github.com/ruby/ruby/blob/trunk/method.h#L175
 
 void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_visibility_t visi);
 void rb_add_method_iseq(VALUE klass, ID mid, VALUE iseqval, rb_cref_t *cref, rb_method_visibility_t visi);
-rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_visibility_t visi);
-rb_method_entry_t *rb_method_entry(VALUE klass, ID id, VALUE *define_class_ptr);
-rb_method_entry_t *rb_method_entry_at(VALUE obj, ID id);
 void rb_add_refined_method_entry(VALUE refined_class, ID mid);
-const rb_method_entry_t *rb_resolve_refined_method(VALUE refinements,
-						   const rb_method_entry_t *me,
-						   VALUE *defined_class_ptr);
-const rb_method_entry_t *rb_method_entry_with_refinements(VALUE klass, ID id,
-							  VALUE *defined_class_ptr);
-const rb_method_entry_t *rb_method_entry_without_refinements(VALUE klass, ID id,
-							     VALUE *defined_class_ptr);
 
-rb_method_entry_t *rb_method_entry_get_without_cache(VALUE klass, ID id, VALUE *define_class_ptr);
+rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_visibility_t visi);
 rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_visibility_t noex);
+rb_method_entry_t *rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, const rb_method_definition_t *def);
+
+const rb_method_entry_t *rb_method_entry_at(VALUE obj, ID id);
+
+const rb_method_entry_t *rb_method_entry(VALUE klass, ID id);
+const rb_method_entry_t *rb_method_entry_with_refinements(VALUE klass, ID id);
+const rb_method_entry_t *rb_method_entry_without_refinements(VALUE klass, ID id);
+const rb_method_entry_t *rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
+
+const rb_callable_method_entry_t *rb_callable_method_entry(VALUE klass, ID id);
+const rb_callable_method_entry_t *rb_callable_method_entry_with_refinements(VALUE klass, ID id);
+const rb_callable_method_entry_t *rb_callable_method_entry_without_refinements(VALUE klass, ID id);
+const rb_callable_method_entry_t *rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
 
 int rb_method_entry_arity(const rb_method_entry_t *me);
 int rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2);
@@ -185,8 +204,8 @@ VALUE rb_obj_method_location(VALUE obj, https://github.com/ruby/ruby/blob/trunk/method.h#L204
 void rb_free_method_entry(const rb_method_entry_t *me);
 void rb_sweep_method_entry(void *vm);
 
-rb_method_entry_t *rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, const rb_method_definition_t *def);
-rb_method_entry_t *rb_method_entry_clone(const rb_method_entry_t *me);
+const rb_method_entry_t *rb_method_entry_clone(const rb_method_entry_t *me);
+const rb_callable_method_entry_t *rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, VALUE defined_class);
 void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src);
 
 void rb_scope_visibility_set(rb_method_visibility_t);
Index: insns.def
===================================================================
--- insns.def	(revision 51125)
+++ insns.def	(revision 51126)
@@ -914,8 +914,7 @@ defineclass https://github.com/ruby/ruby/blob/trunk/insns.def#L914
     }
 
     /* enter scope */
-    vm_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS,
-		  klass, 0,
+    vm_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS, klass,
 		  VM_ENVVAL_BLOCK_PTR(GET_BLOCK_PTR()),
 		  (VALUE)vm_cref_push(th, klass, NULL),
 		  class_iseq->iseq_encoded, GET_SP(),
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 51125)
+++ ChangeLog	(revision 51126)
@@ -1,3 +1,118 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Jul 03 20:05:10 2015  Koichi Sasada  <ko1@a...>
+
+	* method.h: introduce rb_callable_method_entry_t to remove
+	  rb_control_frame_t::klass.
+	  [Bug #11278], [Bug #11279]
+
+	  rb_method_entry_t data belong to modules/classes.
+	  rb_method_entry_t::owner points defined module or class.
+
+	    module M
+	      def foo; end
+	    end
+
+	  In this case, owner is M.
+
+	  rb_callable_method_entry_t data belong to only classes.
+	  For modules, MRI creates corresponding T_ICLASS internally.
+	  rb_callable_method_entry_t can also belong to T_ICLASS.
+
+	  rb_callable_method_entry_t::defined_class points T_CLASS or
+	  T_ICLASS.
+	  rb_method_entry_t data for classes (not for modules) are also
+	  rb_callable_method_entry_t data because it is completely same data.
+	  In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
+
+	  For example, there are classes C and D, and incldues M,
+
+	    class C; include M; end
+	    class D; include M; end
+
+	  then, two T_ICLASS objects for C's super class and D's super class
+	  will be created.
+
+	  When C.new.foo is called, then M#foo is searcheed and
+	  rb_callable_method_t data is used by VM to invoke M#foo.
+
+	  rb_method_entry_t data is only one for M#foo.
+	  However, rb_callable_method_entry_t data are two (and can be more).
+	  It is proportional to the number of including (and prepending)
+	  classes (the number of T_ICLASS which point to the module).
+
+	  Now, created rb_callable_method_entry_t are collected when
+	  the original module M was modified. We can think it is a cache.
+
+	  We need to select what kind of method entry data is needed.
+	  To operate definition, then you need to use rb_method_entry_t.
+
+	  You can access them by the following functions.
+
+	  * rb_method_entry(VALUE klass, ID id);
+	  * rb_method_entry_with_refinements(VALUE klass, ID id);
+	  * rb_method_entry_without_refinements(VALUE klass, ID id);
+	  * rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
+
+	  To invoke methods, then you need to use rb_callable_method_entry_t
+	  which you can get by the following APIs corresponding to the
+	  above listed functions.
+
+	  * rb_callable_method_entry(VALUE klass, ID id);
+	  * rb_callable_method_entry_with_refinements(VALUE klass, ID id);
+	  * rb_callable_method_entry_without_refinements(VALUE klass, ID id);
+	  * rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
+
+	  VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
+	  returns rb_callable_method_entry_t.
+	  You can check a super class of current method by
+	  rb_callable_method_entry_t::defined_class.
+
+	* method.h: renamed from rb_method_entry_t::klass to
+	  rb_method_entry_t::owner.
+
+	* internal.h: add rb_classext_struct::callable_m_tbl to cache
+	  rb_callable_method_entry_t data.
+
+	  We need to consider abotu this field again because it is only
+	  active for T_ICLASS.
+
+	* class.c (method_entry_i): ditto.
+
+	* class.c (rb_define_attr): rb_method_entry() does not takes
+	  defiend_class_ptr.
+
+	* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
+
+	* cont.c (fiber_init): rb_control_frame_t::klass is removed.
+
+	* proc.c: fix `struct METHOD' data structure because
+	  rb_callable_method_t has all information.
+
+	* vm_core.h: remove several fields.
+	  * rb_control_frame_t::klass.
+	  * rb_block_t::klass.
+
+	  And catch up changes.
+
+	* eval.c: catch up changes.
+
+	* gc.c: ditto.
+
+	* insns.def: ditto.
+
+	* vm.c: ditto.
+
+	* vm_args.c: ditto.
+
+	* vm_backtrace.c: ditto.
+
+	* vm_dump.c: ditto.
+
+	* vm_eval.c: ditto.
+
+	* vm_insnhelper.c: ditto.
+
+	* vm_method.c: ditto.
+
 Fri Jul  3 14:30:18 2015  Nobuyoshi Nakada  <nobu@r...>
 
 	* win32/file.c: some mingw compilers need a tweek for the
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 51125)
+++ vm_core.h	(revision 51126)
@@ -183,8 +183,7 @@ typedef struct rb_call_info_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L183
     VALUE klass;
 
     /* inline cache: values */
-    const rb_method_entry_t *me;
-    VALUE defined_class;
+    const rb_callable_method_entry_t *me;
 
     /* temporary values for method calling */
     struct rb_block_struct *blockptr;
@@ -524,7 +523,7 @@ typedef struct rb_vm_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L523
 #endif
 
 #ifndef VM_DEBUG_VERIFY_METHOD_CACHE
-#define VM_DEBUG_VERIFY_METHOD_CACHE 0
+#define VM_DEBUG_VERIFY_METHOD_CACHE (VM_DEBUG_MODE != 0)
 #endif
 
 typedef struct rb_control_frame_struct {
@@ -533,10 +532,9 @@ typedef struct rb_control_frame_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L532
     rb_iseq_t *iseq;		/* cfp[2] */
     VALUE flag;			/* cfp[3] */
     VALUE self;			/* cfp[4] / block[0] */
-    VALUE klass;		/* cfp[5] / block[1] */
-    VALUE *ep;			/* cfp[6] / block[2] */
-    rb_iseq_t *block_iseq;	/* cfp[7] / block[3] */
-    VALUE proc;			/* cfp[8] / block[4] */
+    VALUE *ep;			/* cfp[6] / block[1] */
+    rb_iseq_t *block_iseq;	/* cfp[7] / block[2] */
+    VALUE proc;			/* cfp[8] / block[3] */
 
 #if VM_DEBUG_BP_CHECK
     VALUE *bp_check;		/* cfp[9] */
@@ -545,7 +543,6 @@ typedef struct rb_control_frame_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L543
 
 typedef struct rb_block_struct {
     VALUE self;			/* share with method frame if it's only block */
-    VALUE klass;		/* share with method frame if it's only block */
     VALUE *ep;			/* share with method frame if it's only block */
     rb_iseq_t *iseq;
     VALUE proc;
@@ -631,7 +628,7 @@ typedef struct rb_thread_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L628
     const rb_block_t *passed_block;
 
     /* for bmethod */
-    const rb_method_entry_t *passed_bmethod_me;
+    const rb_callable_method_entry_t *passed_bmethod_me;
 
     /* for cfunc */
     rb_call_info_t *passed_ci;
@@ -976,8 +973,7 @@ VALUE *rb_binding_add_dynavars(rb_bindin https://github.com/ruby/ruby/blob/trunk/vm_core.h#L973
 void rb_vm_inc_const_missing_count(void);
 void rb_vm_gvl_destroy(rb_vm_t *vm);
 VALUE rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc,
-		 const VALUE *argv, const rb_method_entry_t *me,
-		 VALUE defined_class);
+		 const VALUE *argv, const rb_callable_method_entry_t *me);
 
 void rb_thread_start_timer_thread(void);
 void rb_thread_stop_timer_thread(int);
@@ -1024,7 +1020,7 @@ int rb_autoloading_value(VALUE mod, ID i https://github.com/ruby/ruby/blob/trunk/vm_core.h#L1020
 
 void rb_vm_rewrite_cref(rb_cref_t *node, VALUE old_klass, VALUE new_klass, rb_cref_t **new_cref_ptr);
 
-const rb_method_entry_t *rb_vm_frame_method_entry(const rb_control_frame_t *cfp);
+const rb_callable_method_entry_t *rb_vm_frame_method_entry(const rb_control_frame_t *cfp);
 
 #define sysstack_error GET_VM()->special_exceptions[ruby_error_sysstack]
 
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 51125)
+++ vm_eval.c	(revision 51126)
@@ -42,15 +42,13 @@ static VALUE send_internal(int argc, con https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L42
 static VALUE vm_call0_body(rb_thread_t* th, rb_call_info_t *ci, const VALUE *argv);
 
 static VALUE
-vm_call0(rb_thread_t* th, VALUE recv, ID id, int argc, const VALUE *argv,
-	 const rb_method_entry_t *me, VALUE defined_class)
+vm_call0(rb_thread_t* th, VALUE recv, ID id, int argc, const VALUE *argv, const rb_callable_method_entry_t *me)
 {
     rb_call_info_t ci_entry, *ci = &ci_entry;
 
     ci->flag = 0;
     ci->mid = id;
     ci->recv = recv;
-    ci->defined_class = defined_class;
     ci->argc = argc;
     ci->me = me;
     ci->kw_arg = NULL;
@@ -64,11 +62,11 @@ vm_call0_cfunc(rb_thread_t* th, rb_call_ https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L62
 {
     VALUE val;
 
-    RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, ci->defined_class, ci->mid);
-    EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, ci->recv, ci->mid, ci->defined_class, Qnil);
+    RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, ci->me->owner, ci->mid);
+    EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, ci->recv, ci->mid, ci->me->owner, Qnil);
     {
 	rb_control_frame_t *reg_cfp = th->cfp;
-	const rb_method_entry_t *me = ci->me;
+	const rb_callable_method_entry_t *me = ci->me;
 	const rb_method_cfunc_t *cfunc = &me->def->body.cfunc;
 	int len = cfunc->argc;
 	VALUE recv = ci->recv;
@@ -95,8 +93,8 @@ vm_call0_cfunc(rb_thread_t* th, rb_call_ https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L93
 	    vm_pop_frame(th);
 	}
     }
-    EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, ci->recv, ci->mid, ci->defined_class, val);
-    RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, ci->defined_class, ci->mid);
+    EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, ci->recv, ci->mid, ci->me->owner, val);
+    RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, ci->me->owner, ci->mid);
 
     return val;
 }
@@ -105,21 +103,20 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L103
 vm_call0_cfunc_with_frame(rb_thread_t* th, rb_call_info_t *ci, const VALUE *argv)
 {
     VALUE val;
-    const rb_method_entry_t *me = ci->me;
+    const rb_callable_method_entry_t *me = ci->me;
     const rb_method_cfunc_t *cfunc = &me->def->body.cfunc;
     int len = cfunc->argc;
     VALUE recv = ci->recv;
-    VALUE defined_class = ci->defined_class;
     int argc = ci->argc;
     ID mid = ci->mid;
     rb_block_t *blockptr = ci->blockptr;
 
-    RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, defined_class, mid);
-    EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, mid, defined_class, Qnil);
+    RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, me->owner, mid);
+    EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, mid, me->owner, Qnil);
     {
 	rb_control_frame_t *reg_cfp = th->cfp;
 
-	vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC, recv, defined_class,
+	vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC, recv, 
 		      VM_ENVVAL_BLOCK_PTR(blockptr), (VALUE)me,
 		      0, reg_cfp->sp, 1, 0);
 
@@ -134,8 +131,8 @@ vm_call0_cfunc_with_frame(rb_thread_t* t https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L131
 	VM_PROFILE_UP(3);
 	vm_pop_frame(th);
     }
-    EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, mid, defined_class, val);
-    RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, defined_class, mid);
+    EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, mid, me->owner, val);
+    RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, me->owner, mid);
 
     return val;
 }
@@ -198,14 +195,16 @@ vm_call0_body(rb_thread_t* th, rb_call_i https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L195
       case VM_METHOD_TYPE_REFINED:
 	{
 	    const rb_method_type_t type = ci->me->def->type;
+	    VALUE super_class;
+
 	    if (type == VM_METHOD_TYPE_REFINED && ci->me->def->body.refined.orig_me) {
-		ci->me = ci->me->def->body.refined.orig_me;
+		ci->me = refined_method_callable_without_refinement(ci->me);
 		goto again;
 	    }
 
-	    ci->defined_class = RCLASS_SUPER(ci->defined_class);
+	    super_class = RCLASS_SUPER(ci->me->defined_class);
 
-	    if (!ci->defined_class || !(ci->me = rb_method_entry(ci->defined_class, ci->mid, &ci->defined_class))) {
+	    if (!super_class || !(ci->me = rb_callable_method_entry(super_class, ci->mid))) {
 		enum method_missing_reason ex = (type == VM_METHOD_TYPE_ZSUPER) ? MISSING_SUPER : 0;
 		ret = method_missing(ci->recv, ci->mid, ci->argc, argv, ex);
 		goto success;
@@ -214,11 +213,8 @@ vm_call0_body(rb_thread_t* th, rb_call_i https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L213
 	    goto again;
 	}
       case VM_METHOD_TYPE_ALIAS:
-	{
-	    ci->me = ci->me->def->body.alias.original_me;
-	    ci->defined_class = find_defined_class_by_owner(ci->defined_class, ci->me->klass);
-	    goto again;
-	}
+	ci->me = aliased_callable_method_entry(ci->me);
+	goto again;
       case VM_METHOD_TYPE_MISSING:
 	{
 	    VALUE new_args = rb_ary_new4(ci->argc, argv);
@@ -258,10 +254,9 @@ vm_call0_body(rb_thread_t* th, rb_call_i https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L254
 }
 
 VALUE
-rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc, const VALUE *argv,
-	   const rb_method_entry_t *me, VALUE defined_class)
+rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc, const VALUE *argv, const rb_callable_method_entry_t *me)
 {
-    return vm_call0(th, recv, id, argc, argv, me, defined_class);
+    return vm_call0(th, recv, id, argc, argv, me);
 }
 
 static inline VALUE
@@ -270,22 +265,24 @@ vm_call_super(rb_thread_t *th, int argc, https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L265
     VALUE recv = th->cfp->self;
     VALUE klass;
     ID id;
-    rb_method_entry_t *me;
     rb_control_frame_t *cfp = th->cfp;
+    const rb_callable_method_entry_t *me = rb_vm_frame_method_entry(cfp);
 
-    if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq) || NIL_P(cfp->klass)) {
+    if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
 	rb_bug("vm_call_super: should not be reached");
     }
 
-    klass = RCLASS_ORIGIN(cfp->klass);
+    klass = RCLASS_ORIGIN(me->defined_class);
     klass = RCLASS_SUPER(klass);
-    id = rb_vm_frame_method_entry(cfp)->def->original_id;
-    me = rb_method_entry(klass, id, &klass);
+    id = me->def->original_id;
+    me = rb_callable_method_entry(klass, id);
+
     if (!me) {
 	return method_missing(recv, id, argc, argv, MISSING_SUPER);
     }
-
-    return vm_call0(th, recv, id, argc, argv, me, klass);
+    else {
+	return vm_call0(th, recv, id, argc, argv, me);
+    }
 }
 
 VALUE
@@ -316,9 +313,8 @@ stack_check(void) https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L313
     }
 }
 
-static inline rb_method_entry_t *
-    rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr);
-static inline enum method_missing_reason rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type scope, VALUE se (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]