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

ruby-changes:40534

From: ko1 <ko1@a...>
Date: Tue, 17 Nov 2015 18:43:09 +0900 (JST)
Subject: [ruby-changes:40534] ko1:r52614 (trunk): * method.h: introduce rb_method_definition_t::complemented_count.

ko1	2015-11-17 18:42:39 +0900 (Tue, 17 Nov 2015)

  New Revision: 52614

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

  Log:
    * method.h: introduce rb_method_definition_t::complemented_count.
    
    * vm_method.c (method_definition_addref_complement): introduced.
    
      def->alias_count is used to decide warn or do not warn at method
      redefinition. Complented methods should not prevent redefiniton
      warnings.
    
    * vm_method.c (rb_method_definition_release): release def iff
      alias_count == 0 && complemented_count == 0.
    
    * test/ruby/test_module.rb: add a test.

  Modified files:
    trunk/ChangeLog
    trunk/method.h
    trunk/test/ruby/test_module.rb
    trunk/vm_method.c
Index: method.h
===================================================================
--- method.h	(revision 52613)
+++ method.h	(revision 52614)
@@ -143,8 +143,9 @@ typedef struct rb_method_refined_struct https://github.com/ruby/ruby/blob/trunk/method.h#L143
 } rb_method_refined_t;
 
 typedef struct rb_method_definition_struct {
-    rb_method_type_t type; /* method type */
-    int alias_count;
+    rb_method_type_t type :  8; /* method type */
+    int alias_count       : 28;
+    int complemented_count: 28;
 
     union {
 	rb_method_iseq_t iseq;
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 52613)
+++ ChangeLog	(revision 52614)
@@ -1,3 +1,18 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Nov 17 18:36:52 2015  Koichi Sasada  <ko1@a...>
+
+	* method.h: introduce rb_method_definition_t::complemented_count.
+
+	* vm_method.c (method_definition_addref_complement): introduced.
+
+	  def->alias_count is used to decide warn or do not warn at method
+	  redefinition. Complented methods should not prevent redefiniton
+	  warnings.
+
+	* vm_method.c (rb_method_definition_release): release def iff
+	  alias_count == 0 && complemented_count == 0.
+
+	* test/ruby/test_module.rb: add a test.
+
 Tue Nov 17 15:34:34 2015  Martin Duerst  <duerst@i...>
 	* NEWS: Added update from Unicode 7.0.0 to 8.0.0 [ci skip]
 
Index: vm_method.c
===================================================================
--- vm_method.c	(revision 52613)
+++ vm_method.c	(revision 52614)
@@ -135,19 +135,24 @@ rb_add_method_cfunc(VALUE klass, ID mid, https://github.com/ruby/ruby/blob/trunk/vm_method.c#L135
 }
 
 static void
-rb_method_definition_release(rb_method_definition_t *def)
+rb_method_definition_release(rb_method_definition_t *def, int complemented)
 {
     if (def != NULL) {
-	const int count = def->alias_count;
-	VM_ASSERT(count >= 0);
+	const int alias_count = def->alias_count;
+	const int complemented_count = def->complemented_count;
+	VM_ASSERT(alias_count >= 0);
+	VM_ASSERT(complemented_count >= 0);
 
-	if (count == 0) {
-	    if (METHOD_DEBUG) fprintf(stderr, "-%p-%s:%d\n", def, rb_id2name(def->original_id), count);
+	if (alias_count + complemented_count == 0) {
+	    if (METHOD_DEBUG) fprintf(stderr, "-%p-%s:%d,%d (remove)\n", def, rb_id2name(def->original_id), alias_count, complemented_count);
 	    xfree(def);
 	}
 	else {
-	    if (METHOD_DEBUG) fprintf(stderr, "-%p-%s:%d->%d\n", def, rb_id2name(def->original_id), count, count-1);
-	    def->alias_count--;
+	    if (complemented) def->complemented_count--;
+	    else if (def->alias_count > 0) def->alias_count--;
+
+	    if (METHOD_DEBUG) fprintf(stderr, "-%p-%s:%d->%d,%d->%d (dec)\n", def, rb_id2name(def->original_id),
+				      alias_count, def->alias_count, complemented_count, def->complemented_count);
 	}
     }
 }
@@ -155,7 +160,7 @@ rb_method_definition_release(rb_method_d https://github.com/ruby/ruby/blob/trunk/vm_method.c#L160
 void
 rb_free_method_entry(const rb_method_entry_t *me)
 {
-    rb_method_definition_release(me->def);
+    rb_method_definition_release(me->def, RB_TYPE_P(me->owner, T_MODULE) && RB_TYPE_P(me->defined_class, T_ICLASS));
 }
 
 static inline rb_method_entry_t *search_method(VALUE klass, ID id, VALUE *defined_class_ptr);
@@ -342,6 +347,14 @@ method_definition_addref(rb_method_defin https://github.com/ruby/ruby/blob/trunk/vm_method.c#L347
     return def;
 }
 
+static rb_method_definition_t *
+method_definition_addref_complement(rb_method_definition_t *def)
+{
+    def->complemented_count++;
+    if (METHOD_DEBUG) fprintf(stderr, "+%p-%s:%d\n", def, rb_id2name(def->original_id), def->alias_count);
+    return def;
+}
+
 static rb_method_entry_t *
 rb_method_entry_alloc(ID called_id, VALUE owner, VALUE defined_class, const rb_method_definition_t *def)
 {
@@ -385,8 +398,12 @@ const rb_callable_method_entry_t * https://github.com/ruby/ruby/blob/trunk/vm_method.c#L398
 rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, VALUE defined_class)
 {
     rb_method_entry_t *me = rb_method_entry_alloc(src_me->called_id, src_me->owner, defined_class,
-						  method_definition_addref(src_me->def));
+						  method_definition_addref_complement(src_me->def));
     METHOD_ENTRY_FLAGS_COPY(me, src_me);
+
+    VM_ASSERT(RB_TYPE_P(me->owner, T_MODULE));
+    VM_ASSERT(RB_TYPE_P(me->defined_class, T_ICLASS));
+
     return (rb_callable_method_entry_t *)me;
 }
 
Index: test/ruby/test_module.rb
===================================================================
--- test/ruby/test_module.rb	(revision 52613)
+++ test/ruby/test_module.rb	(revision 52614)
@@ -1280,6 +1280,20 @@ class TestModule < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_module.rb#L1280
         undef foo
       end
     end
+
+    stderr = EnvUtil.verbose_warning do
+      Module.new do
+        def foo; end
+        mod = self
+        c = Class.new do
+          include mod
+        end
+        c.new.foo
+        def foo; end
+      end
+    end
+    assert_match(/: warning: method redefined; discarding old foo/, stderr)
+    assert_match(/: warning: previous definition of foo/, stderr)
   end
 
   def test_protected_singleton_method

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

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