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

ruby-changes:37793

From: ko1 <ko1@a...>
Date: Fri, 6 Mar 2015 21:25:11 +0900 (JST)
Subject: [ruby-changes:37793] ko1:r49874 (trunk): * fix namespace issue on singleton class expressions. [Bug #10943]

ko1	2015-03-06 21:24:58 +0900 (Fri, 06 Mar 2015)

  New Revision: 49874

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

  Log:
    * fix namespace issue on singleton class expressions. [Bug #10943]
    * vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
      to rb_method_definition_t::body.iseq_body.cref.
    * vm_insnhelper.c: modify SVAR usage.
      When calling ISEQ type method, push CREF information onto method
      frame, SVAR located place. Before this fix, SVAR is simply nil.
      After this patch, CREF (or NULL == Qfalse for not iseq methods)
      is stored at the method invocation.
      When SVAR is requierd, then put NODE_IF onto SVAR location,
      and NDOE_IF::nd_reserved points CREF itself.
    * vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
    * vm_insnhelper.c (vm_push_frame): accept CREF.
    * method.h, vm_method.c (rb_add_method_iseq): added. This function
      accepts iseq and CREF.
    * class.c (clone_method): use rb_add_method_iseq().
    * gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
    * iseq.c: remove CREF related codes.
    * insns.def (getinlinecache/setinlinecache): CREF should be cache key
      because a different CREF has a different namespace.
    * node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
    * proc.c: catch up changes.
    * struct.c: ditto.
    * insns.def: ditto.
    * vm_args.c (raise_argument_error): ditto.
    * vm_eval.c: ditto.
    * test/ruby/test_class.rb: add a test.

  Modified files:
    trunk/ChangeLog
    trunk/class.c
    trunk/gc.c
    trunk/insns.def
    trunk/iseq.c
    trunk/method.h
    trunk/node.c
    trunk/proc.c
    trunk/struct.c
    trunk/test/ruby/test_class.rb
    trunk/vm.c
    trunk/vm_args.c
    trunk/vm_core.h
    trunk/vm_eval.c
    trunk/vm_insnhelper.c
    trunk/vm_method.c
Index: method.h
===================================================================
--- method.h	(revision 49873)
+++ method.h	(revision 49874)
@@ -12,6 +12,7 @@ https://github.com/ruby/ruby/blob/trunk/method.h#L12
 #define METHOD_H
 
 #include "internal.h"
+#include "node.h"
 
 #ifndef END_OF_ENUMERATION
 # if defined(__GNUC__) &&! defined(__STRICT_ANSI__)
@@ -79,8 +80,12 @@ typedef struct rb_method_definition_stru https://github.com/ruby/ruby/blob/trunk/method.h#L80
     rb_method_type_t type; /* method type */
     int alias_count;
     ID original_id;
+
     union {
-	rb_iseq_t * const iseq;            /* should be mark */
+	struct {
+	    rb_iseq_t *const iseq;            /* should be mark */
+	    NODE *cref;
+	} iseq_body;
 	rb_method_cfunc_t cfunc;
 	rb_method_attr_t attr;
 	const VALUE proc;                 /* should be mark */
@@ -113,6 +118,7 @@ struct unlinked_method_entry_list_entry https://github.com/ruby/ruby/blob/trunk/method.h#L118
      UNDEFINED_METHOD_ENTRY_P((def)->body.orig_me))
 
 void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_flag_t noex);
+void rb_add_method_iseq(VALUE klass, ID mid, rb_iseq_t *iseq, NODE *cref, rb_method_flag_t noex);
 rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_flag_t noex);
 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);
Index: insns.def
===================================================================
--- insns.def	(revision 49873)
+++ insns.def	(revision 49874)
@@ -159,7 +159,7 @@ getclassvariable https://github.com/ruby/ruby/blob/trunk/insns.def#L159
 ()
 (VALUE val)
 {
-    NODE *cref = rb_vm_get_cref(GET_ISEQ(), GET_EP());
+    NODE *cref = rb_vm_get_cref(GET_EP());
     val = rb_cvar_get(vm_get_cvar_base(cref, GET_CFP()), id);
 }
 
@@ -174,7 +174,7 @@ setclassvariable https://github.com/ruby/ruby/blob/trunk/insns.def#L174
 (VALUE val)
 ()
 {
-    NODE *cref = rb_vm_get_cref(GET_ISEQ(), GET_EP());
+    NODE *cref = rb_vm_get_cref(GET_EP());
     rb_cvar_set(vm_get_cvar_base(cref, GET_CFP()), id, val);
 }
 
@@ -196,7 +196,7 @@ getconstant https://github.com/ruby/ruby/blob/trunk/insns.def#L196
 (VALUE klass)
 (VALUE val)
 {
-    val = vm_get_ev_const(th, GET_ISEQ(), klass, id, 0);
+    val = vm_get_ev_const(th, klass, id, 0);
 }
 
 /**
@@ -318,10 +318,10 @@ putspecialobject https://github.com/ruby/ruby/blob/trunk/insns.def#L318
 	val = rb_mRubyVMFrozenCore;
 	break;
       case VM_SPECIAL_OBJECT_CBASE:
-	val = vm_get_cbase(GET_ISEQ(), GET_EP());
+	val = vm_get_cbase(GET_EP());
 	break;
       case VM_SPECIAL_OBJECT_CONST_BASE:
-	val = vm_get_const_base(GET_ISEQ(), GET_EP());
+	val = vm_get_const_base(GET_EP());
 	break;
       default:
 	rb_bug("putspecialobject insn: unknown value_type");
@@ -730,7 +730,7 @@ defined https://github.com/ruby/ruby/blob/trunk/insns.def#L730
 	}
 	break;
       case DEFINED_IVAR2:
-	klass = vm_get_cbase(GET_ISEQ(), GET_EP());
+	klass = vm_get_cbase(GET_EP());
 	break;
       case DEFINED_GVAR:
 	if (rb_gvar_defined(rb_global_entry(SYM2ID(obj)))) {
@@ -738,7 +738,7 @@ defined https://github.com/ruby/ruby/blob/trunk/insns.def#L738
 	}
 	break;
       case DEFINED_CVAR: {
-	NODE *cref = rb_vm_get_cref(GET_ISEQ(), GET_EP());
+	NODE *cref = rb_vm_get_cref(GET_EP());
 	klass = vm_get_cvar_base(cref, GET_CFP());
 	if (rb_cvar_defined(klass, SYM2ID(obj))) {
 	    expr_type = DEFINED_CVAR;
@@ -747,7 +747,7 @@ defined https://github.com/ruby/ruby/blob/trunk/insns.def#L747
       }
       case DEFINED_CONST:
 	klass = v;
-	if (vm_get_ev_const(th, GET_ISEQ(), klass, SYM2ID(obj), 1)) {
+	if (vm_get_ev_const(th, klass, SYM2ID(obj), 1)) {
 	    expr_type = DEFINED_CONST;
 	}
 	break;
@@ -1013,13 +1013,14 @@ defineclass https://github.com/ruby/ruby/blob/trunk/insns.def#L1013
 	rb_bug("unknown defineclass type: %d", (int)type);
     }
 
-    COPY_CREF(class_iseq->cref_stack, vm_cref_push(th, klass, NOEX_PUBLIC, NULL));
-
     /* enter scope */
     vm_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS,
-		  klass, 0, VM_ENVVAL_BLOCK_PTR(GET_BLOCK_PTR()),
+		  klass, 0,
+		  VM_ENVVAL_BLOCK_PTR(GET_BLOCK_PTR()),
+		  vm_cref_push(th, klass, NOEX_PUBLIC, NULL),
 		  class_iseq->iseq_encoded, GET_SP(),
 		  class_iseq->local_size, 0, class_iseq->stack_max);
+
     RESTORE_REGS();
     NEXT_INSN();
 }
@@ -1241,7 +1242,8 @@ getinlinecache https://github.com/ruby/ruby/blob/trunk/insns.def#L1242
 ()
 (VALUE val)
 {
-    if (ic->ic_serial == GET_GLOBAL_CONSTANT_STATE()) {
+    if (ic->ic_serial == GET_GLOBAL_CONSTANT_STATE() &&
+	ic->ic_cref == rb_vm_get_cref(GET_EP())) {
 	val = ic->ic_value.value;
 	JUMP(dst);
     }
@@ -1267,6 +1269,7 @@ setinlinecache https://github.com/ruby/ruby/blob/trunk/insns.def#L1269
     }
     ic->ic_value.value = val;
     ic->ic_serial = GET_GLOBAL_CONSTANT_STATE() - ruby_vm_const_missing_count;
+    ic->ic_cref = rb_vm_get_cref(GET_EP());
     ruby_vm_const_missing_count = 0;
 }
 
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 49873)
+++ ChangeLog	(revision 49874)
@@ -1,3 +1,49 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri Mar  6 20:18:38 2015  Koichi Sasada  <ko1@a...>
+
+	* fix namespace issue on singleton class expressions. [Bug #10943]
+
+	* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
+	  to rb_method_definition_t::body.iseq_body.cref.
+
+	* vm_insnhelper.c: modify SVAR usage.
+	  When calling ISEQ type method, push CREF information onto method
+	  frame, SVAR located place. Before this fix, SVAR is simply nil.
+	  After this patch, CREF (or NULL == Qfalse for not iseq methods)
+	  is stored at the method invocation.
+
+	  When SVAR is requierd, then put NODE_IF onto SVAR location,
+	  and NDOE_IF::nd_reserved points CREF itself.
+
+	* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
+
+	* vm_insnhelper.c (vm_push_frame): accept CREF.
+
+	* method.h, vm_method.c (rb_add_method_iseq): added. This function
+	  accepts iseq and CREF.
+
+	* class.c (clone_method): use rb_add_method_iseq().
+
+	* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
+
+	* iseq.c: remove CREF related codes.
+
+	* insns.def (getinlinecache/setinlinecache): CREF should be cache key
+	  because a different CREF has a different namespace.
+
+	* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
+
+	* proc.c: catch up changes.
+
+	* struct.c: ditto.
+
+	* insns.def: ditto.
+
+	* vm_args.c (raise_argument_error): ditto.
+
+	* vm_eval.c: ditto.
+
+	* test/ruby/test_class.rb: add a test.
+
 Fri Mar  6 18:19:13 2015  Koichi Sasada  <ko1@a...>
 
 	* test/webrick/test_filehandler.rb: on vboxsf (on VirtualBox
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 49873)
+++ vm_core.h	(revision 49874)
@@ -117,6 +117,7 @@ typedef struct rb_compile_option_struct https://github.com/ruby/ruby/blob/trunk/vm_core.h#L117
 
 struct iseq_inline_cache_entry {
     rb_serial_t ic_serial;
+    NODE *ic_cref;
     union {
 	size_t index;
 	VALUE value;
@@ -322,17 +323,6 @@ struct rb_iseq_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L323
 
     VALUE self;
     const VALUE orig;			/* non-NULL if its data have origin */
-
-    /* block inlining */
-    /*
-     * NODE *node;
-     * void *special_block_builder;
-     * void *cached_special_block_builder;
-     * VALUE cached_special_block;
-     */
-
-    /* klass/module nest information stack (cref) */
-    NODE * const cref_stack;
     const VALUE klass;
 
     /* misc */
@@ -416,7 +406,6 @@ typedef struct rb_vm_struct { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L406
 
     /* object management */
     VALUE mark_object_ary;
-
     const VALUE special_exceptions[ruby_special_error_count];
 
     /* load */
Index: iseq.c
===================================================================
--- iseq.c	(revision 49873)
+++ iseq.c	(revision 49874)
@@ -121,7 +121,6 @@ iseq_mark(void *ptr) https://github.com/ruby/ruby/blob/trunk/iseq.c#L121
 	RUBY_MARK_UNLESS_NULL(iseq->location.path);
 	RUBY_MARK_UNLESS_NULL(iseq->location.absolute_path);
 
-	RUBY_MARK_UNLESS_NULL((VALUE)iseq->cref_stack);
 	RUBY_MARK_UNLESS_NULL(iseq->klass);
 	RUBY_MARK_UNLESS_NULL(iseq->coverage);
 	RUBY_MARK_UNLESS_NULL(iseq->orig);
@@ -213,38 +212,21 @@ iseq_location_setup(rb_iseq_t *iseq, VAL https://github.com/ruby/ruby/blob/trunk/iseq.c#L212
     return loc;
 }
 
-#define ISEQ_SET_CREF(iseq, cref) RB_OBJ_WRITE((iseq)->self, &(iseq)->cref_stack, (cref))
-
 static void
 set_relation(rb_iseq_t *iseq, const VALUE parent)
 {
     const VALUE type = iseq->type;
-    rb_thread_t *th = GET_THREAD();
     rb_iseq_t *piseq;
 
     /* set class nest stack */
     if (type == ISEQ_TYPE_TOP) {
-	/* toplevel is private */
-	RB_OBJ_WRITE(iseq->self, &iseq->cref_stack, NEW_CREF(rb_cObject));
-	iseq->cref_stack->nd_refinements = Qnil;
-	iseq->cref_stack->nd_visi = NOEX_PRIVATE;
-	if (th->top_wrapper) {
-	    NODE *cref = NEW_CREF(th->top_wrapper);
-	    cref->nd_refinements = Qnil;
-	    cref->nd_visi = NOEX_PRIVATE;
-	    RB_OBJ_WRITE(cref, &cref->nd_next, iseq->cref_stack);
-	    ISEQ_SET_CREF(iseq, cref);
-	}
 	iseq->local_iseq = iseq;
     }
     else if (type == ISEQ_TYPE_METHOD || type == ISEQ_TYPE_CLASS) {
-	ISEQ_SET_CREF(iseq, NEW_CREF(0)); /* place holder */
-	iseq->cref_stack->nd_refinements = Qnil;
 	iseq->local_iseq = iseq;
     }
     else if (RTEST(parent)) {
 	GetISeqPtr(parent, piseq);
-	ISEQ_SET_CREF(iseq, piseq->cref_stack);
 	iseq->local_iseq = piseq->local_iseq;
     }
 
@@ -1973,13 +1955,8 @@ rb_iseq_clone(VALUE iseqval, VALUE newcb https://github.com/ruby/ruby/blob/trunk/iseq.c#L1955
     if (iseq0->local_iseq == iseq0) {
 	iseq1->local_iseq = iseq1;
     }
+
     if (newcbase) {
-	ISEQ_SET_CREF(iseq1, NEW_CREF(newcbase));
-	RB_OBJ_WRITE(iseq1->cref_stack, &iseq1->cref_stack->nd_refinements, iseq0->cref_stack->nd_refinements);
-	iseq1->cref_stack->nd_visi = iseq0->cref_stack->nd_visi;
-	if (iseq0->cref_stack->nd_next) {
-	    RB_OBJ_WRITE(iseq1->cref_stack, &iseq1->cref_stack->nd_next, iseq0->cref_stack->nd_next);
-	}
 	RB_OBJ_WRITE(iseq1->self, &iseq1->klass, newcbase);
     }
 
Index: vm_eval.c
===================================================================
--- vm_eval.c	(revision 49873)
+++ vm_eval.c	(revision 49874)
@@ -119,7 +119,8 @@ vm_call0_cfunc_with_frame(rb_thread_t* t https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L119
 	rb_control_frame_t *reg_cfp = th->cfp;
 
 	vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC, recv, defined_class,
-		      VM_ENVVAL_BLOCK_PTR(blockptr), 0, reg_cfp->sp, 1, me, 0);
+		      VM_ENVVAL_BLOCK_PTR(blockptr), NULL /* cref */,
+		      0, reg_cfp->sp, 1, me, 0);
 
 	if (len >= 0) rb_check_arity(argc, len, len);
 
@@ -1306,13 +1307,13 @@ eval_string_with_cref(VALUE self, VALUE https://github.com/ruby/ruby/blob/trunk/vm_eval.c#L1307
 
 	if (!cref && base_block->iseq) {
 	    if (NIL_P(scope)) {
-		orig_cref = rb_vm_get_cref(base_block->iseq, base_block->ep);
+		orig_cref = rb_vm_get_cref(base_block->ep);
 		cref = NEW_CREF(Qnil);
 		crefval = (VALUE) cref;
 		COPY_CREF(cref, orig_cref);
 	    }
 	    else {
-		cref = rb_vm_get_cref(base_block->iseq, base_block->ep);
+		cref = rb_vm_get_cref(base_block->ep);
 	    }
 	}
 	vm_set_eval_stack(th, iseqval, cref, base_block);
Index: proc.c
===================================================================
--- proc.c	(revision 49873)
+++ proc.c	(revision 49874)
@@ -1208,7 +1208,6 @@ mnew_internal(rb_method_entry_t *me, VAL https://github.com/ruby/ruby/blob/trunk/proc.c#L1208
 	def->type = VM_METHOD_TYPE_MISSING;
 	def->original_id = id;
 	def->alias_count = 0;
-
     }
     data->ume = ALLOC(struct unlinked_method_entry_list_entry);
     data->me->def->alias_count++;
@@ -2025,7 +2024,7 @@ rb_method_entry_min_max_arity(const rb_m https://github.com/ruby/ruby/blob/trunk/proc.c#L2024
       case VM_METHOD_TYPE_BMETHOD:
 	return rb_proc_min_max_arity(def->body.proc, max);
       case VM_METHOD_TYPE_ISEQ: {
-	rb_iseq_t *iseq = def->body.iseq;
+	rb_iseq_t *iseq = def->body.iseq_body.iseq;
 	return rb_iseq_min_max_arity(iseq, max);
       }
       case VM_METHOD_TYPE_UNDEF:
@@ -2162,12 +2161,24 @@ method_get_iseq(rb_method_definition_t * https://github.com/ruby/ruby/blob/trunk/proc.c#L2161
       case VM_METHOD_TYPE_BMETHOD:
 	return get_proc_iseq(def->body.proc, 0);
       case VM_METHOD_TYPE_ISEQ:
-	return def->body.iseq;
+	return def->body.iseq_body.iseq;
       default:
-	return 0;
+	return NULL;
+    }
+}
+
+static NODE *
+method_get_cref(rb_method_definition_t *def)
+{
+    switch (def->type) {
+      case VM_METHOD_TYPE_ISEQ:
+	return def->body.iseq_body.cref;
+      default:
+	return NULL;
     }
 }
 
+
 rb_iseq_t *
 rb_method_get_iseq(VALUE method)
 {
@@ -2376,6 +2387,7 @@ method_proc(VALUE method) https://github.com/ruby/ruby/blob/trunk/proc.c#L2387
     env->block.self = meth->recv;
     env->block.klass = meth->defined_class;
     env->block.iseq = method_get_iseq(meth->me->def);
+    env->block.ep[-1] = (VALUE)method_get_cref(meth->me->def);
     return procval;
 }
 
Index: vm_method.c
===================================================================
--- vm_method.c	(revision 49873)
+++ vm_method.c	(revision 49874)
@@ -245,8 +245,7 @@ rb_add_refined_method_entry(VALUE refine https://github.com/ruby/ruby/blob/trunk/vm_method.c#L245
 	rb_clear_method_cache_by_class(refined_class);
     }
     else {
-	rb_add_method(refined_class, mid, VM_METHOD_TYPE_REFINED, 0,
-		      NOEX_PUBLIC);
+	rb_add_method(refined_class, mid, VM_METHOD_TYPE_REFINED, 0, NOEX_PUBLIC);
     }
 }
 
@@ -325,7 +324,7 @@ rb_method_entry_make(VALUE klass, ID mid https://github.com/ruby/ruby/blob/trunk/vm_method.c#L324
 	    rb_warning("method redefined; discarding old %"PRIsVALUE, rb_id2str(mid));
 	    switch (old_def->type) {
 	      case VM_METHOD_TYPE_ISEQ:
-		iseq = old_def->body.iseq;
+		iseq = old_def->body.iseq_body.iseq;
 		break;
 	      case VM_METHOD_TYPE_BMETHOD:
 		iseq = rb_proc_get_iseq(old_def->body.proc, 0);
@@ -359,7 +358,8 @@ rb_method_entry_make(VALUE klass, ID mid https://github.com/ruby/ruby/blob/trunk/vm_method.c#L358
 
 	switch(def->type) {
 	  case VM_METHOD_TYPE_ISEQ:
-	    RB_OBJ_WRITTEN(klass, Qundef, def->body.iseq->self);
+	    RB_OBJ_WRITTEN(klass, Qundef, def->body.iseq_body.iseq->self);
+	    RB_OBJ_WRITTEN(klass, Qundef, def->body.iseq_body.cref);
 	    break;
 	  case VM_METHOD_TYPE_IVAR:
 	    RB_OBJ_WRITTEN(klass, Qundef, def->body.attr.location);
@@ -447,27 +447,40 @@ setup_method_cfunc_struct(rb_method_cfun https://github.com/ruby/ruby/blob/trunk/vm_method.c#L447
 }
 
 rb_method_entry_t *
-rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_flag_t noex)
+rb_add_method0(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_flag_t noex, NODE *cref)
 {
     rb_thread_t *th;
     rb_control_frame_t *cfp;
     int line;
     rb_method_entry_t *me = rb_method_entry_make(klass, mid, type, 0, noex, klass);
     rb_method_definition_t *def = ALLOC(rb_method_definition_t);
+
     if (me->def && me->def->type == VM_METHOD_TYPE_REFINED) {
 	me->def->body.orig_me->def = def;
     }
     else {
 	me->def = def;
     }
+
+    if (0 && cref) vm_cref_dump("rb_add_method0", cref);
+
     def->type = type;
     def->original_id = mid;
     def->alias_count = 0;
+
     switch (type) {
       case VM_METHOD_TYPE_ISEQ: {
 	  rb_iseq_t *iseq = (rb_iseq_t *)opts;
-	  *(rb_iseq_t **)&def->body.iseq = iseq;
-	  RB_OBJ_WRITTEN(klass, Qundef, iseq->self);
+	  NODE *private_cref;
+
+	  *(rb_iseq_t **)&def->body.iseq_body.iseq = iseq;
+	  RB_OBJ_WRITTEN(klass, Qundef, iseq->self); /* should be set iseq before newobj */
+	  def->body.iseq_body.cref = NULL;
+
+	  private_cref = vm_cref_new_toplevel(GET_THREAD()); /* TODO: CREF should be shared with other methods */
+	  if (cref) COPY_CREF(private_cref, cref);
+	  private_cref->nd_visi = NOEX_PUBLIC;
+	  RB_OBJ_WRITE(klass, &def->body.iseq_body.cref, private_cref);
 	  break;
       }
       case VM_METHOD_TYPE_CFUNC:
@@ -511,13 +524,24 @@ rb_add_method(VALUE klass, ID mid, rb_me https://github.com/ruby/ruby/blob/trunk/vm_method.c#L524
     return me;
 }
 
+rb_method_entry_t *
+rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_flag_t noex)
+{
+    return rb_add_method0(klass, mid, type, opts, noex, NULL);
+}
+
+void
+rb_add_method_iseq(VALUE klass, ID mid, rb_iseq_t *iseq, NODE *cref, rb_method_flag_t noex)
+{
+    rb_add_method0(klass, mid, VM_METHOD_TYPE_ISEQ, iseq, noex, cref);
+}
+
 static rb_method_entry_t *
 method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me,
 		 rb_method_flag_t noex, VALUE defined_class)
 {
     rb_method_type_t type = me->def ? me->def->type : VM_METHOD_TYPE_UNDEF;
-    rb_method_entry_t *newme = rb_method_entry_make(klass, mid, type, me->def, noex,
-						    defined_class);
+    rb_method_entry_t *newme = rb_method_entry_make(klass, mid, type, me->def, noex, defined_class);
     method_added(klass, mid);
     return newme;
 }
@@ -1195,7 +1219,7 @@ rb_method_definition_eq(const rb_method_ https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1219
     }
     switch (d1->type) {
       case VM_METHOD_TYPE_ISEQ:
-	return d1->body.iseq == d2->body.iseq;
+	return d1->body.iseq_body.iseq == d2->body.iseq_body.iseq;
       case VM_METHOD_TYPE_CFUNC:
 	return
 	  d1->body.cfunc.func == d2->body.cfunc.func &&
@@ -1226,7 +1250,7 @@ rb_hash_method_definition(st_index_t has https://github.com/ruby/ruby/blob/trunk/vm_method.c#L1250
     hash = rb_hash_uint(hash, def->type);
     switch (def->type) {
       case VM_METHOD_TYPE_ISEQ:
-	return rb_hash_uint(hash, (st_index_t)def->body.iseq);
+	return rb_hash_uint(hash, (st_index_t)def->body.iseq_body.iseq);
       case VM_METHOD_TYPE_CFUNC:
 	hash = rb_hash_uint(hash, (st_index_t)def->body.cfunc.func);
 	return rb_hash_uint(hash, def->body.cfunc.argc);
Index: struct.c
===================================================================
--- struct.c	(revision 49873)
+++ struct.c	(revision 49874)
@@ -179,7 +179,7 @@ define_aref_method(VALUE nstr, VALUE nam https://github.com/ruby/ruby/blob/trunk/struct.c#L179
     VALUE iseqval = rb_method_for_self_aref(name, off, rb_vm_opt_struct_aref);
     rb_iseq_t *iseq = DATA_PTR(iseqval);
 
-    rb_add_method(nstr, SYM2ID(name), VM_METHOD_TYPE_ISEQ, iseq, NOEX_PUBLIC);
+    rb_add_method_iseq(nstr, SYM2ID(name), iseq, NULL, NOEX_PUBLIC);
     RB_GC_GUARD(iseqval);
 }
 
@@ -190,7 +190,7 @@ define_aset_method(VALUE nstr, VALUE nam https://github.com/ruby/ruby/blob/trunk/struct.c#L190
     VALUE iseqval = rb_method_for_self_aset(name, off, rb_vm_opt_struct_aset);
     rb_iseq_t *iseq = DATA_PTR(iseqval);
 
-    rb_add_method(nstr, SYM2ID(name), VM_METHOD_TYPE_ISEQ, iseq, NOEX_PUBLIC);
+    rb_add_method_iseq(nstr, SYM2ID(name), iseq, NULL, NOEX_PUBLIC);
     RB_GC_GUARD(iseqval);
 }
 
Index: gc.c
===================================================================
--- gc.c	(revision 49873)
+++ gc.c	(revision 49874)
@@ -3786,11 +3786,14 @@ mark_method_entry(rb_objspace_t *objspac https://github.com/ruby/ruby/blob/trunk/gc.c#L3786
     const rb_method_definition_t *def = me->def;
 
     gc_mark(objspace, me->klass);
+
   again:
     if (!def) return;
+
     switch (def->type) {
       case VM_METHOD_TYPE_ISEQ:
-	gc_mark(objspace, def->body.iseq->self);
+	gc_mark(objspace, def->body.iseq_body.iseq->self);
+	gc_mark(objspace, (VALUE)def->body.iseq_body.cref);
 	break;
       case VM_METHOD_TYPE_BMETHOD:
 	gc_mark(objspace, def->body.proc);
Index: class.c
===================================================================
--- class.c	(revision 49873)
+++ class.c	(revision 49874)
@@ -247,11 +247,10 @@ clone_method(VALUE klass, ID mid, const https://github.com/rub (... truncated)

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

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