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

ruby-changes:35551

From: nobu <ko1@a...>
Date: Fri, 19 Sep 2014 10:46:01 +0900 (JST)
Subject: [ruby-changes:35551] nobu:r47633 (trunk): class.c: do not freeze meta-meta-class

nobu	2014-09-19 10:45:45 +0900 (Fri, 19 Sep 2014)

  New Revision: 47633

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

  Log:
    class.c: do not freeze meta-meta-class
    
    * class.c (rb_freeze_singleton_class): should not propagate to
      meta-meta-class, and so on, which is shared with the original
      class.  fix occational exceptions.

  Modified files:
    trunk/class.c
    trunk/include/ruby/ruby.h
    trunk/test/ruby/test_module.rb
Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h	(revision 47632)
+++ include/ruby/ruby.h	(revision 47633)
@@ -1108,14 +1108,15 @@ struct RStruct { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1108
 #define OBJ_FREEZE_RAW(x) (RBASIC(x)->flags |= FL_FREEZE)
 #define OBJ_FREEZE(x) rb_obj_freeze_inline((VALUE)x)
 
+void rb_freeze_singleton_class(VALUE klass);
+
 static inline void
 rb_obj_freeze_inline(VALUE x)
 {
     if (FL_ABLE(x)) {
-	VALUE klass = RBASIC_CLASS(x);
 	OBJ_FREEZE_RAW(x);
-	if (FL_TEST(klass, (FL_SINGLETON|FL_FREEZE)) == FL_SINGLETON) {
-	    OBJ_FREEZE_RAW(klass);
+	if (!(RBASIC(x)->flags & FL_SINGLETON)) {
+	    rb_freeze_singleton_class(x);
 	}
     }
 }
Index: class.c
===================================================================
--- class.c	(revision 47632)
+++ class.c	(revision 47633)
@@ -1578,6 +1578,19 @@ singleton_class_of(VALUE obj) https://github.com/ruby/ruby/blob/trunk/class.c#L1578
     return klass;
 }
 
+void
+rb_freeze_singleton_class(VALUE x)
+{
+    /* should not propagate to meta-meta-class, and so on */
+    if (!(RBASIC(x)->flags & FL_SINGLETON)) {
+	VALUE klass = RBASIC_CLASS(x);
+	klass = RCLASS_ORIGIN(klass);
+	if (FL_TEST(klass, (FL_SINGLETON|FL_FREEZE)) == FL_SINGLETON) {
+	    OBJ_FREEZE_RAW(klass);
+	}
+    }
+}
+
 /*!
  * Returns the singleton class of \a obj, or nil if obj is not a
  * singleton object.
Index: test/ruby/test_module.rb
===================================================================
--- test/ruby/test_module.rb	(revision 47632)
+++ test/ruby/test_module.rb	(revision 47633)
@@ -914,25 +914,34 @@ class TestModule < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_module.rb#L914
     assert_include(c.constants(false), :Foo, bug9413)
   end
 
-  def test_frozen_class
+  def test_frozen_module
     m = Module.new
     m.freeze
     assert_raise(RuntimeError) do
       m.instance_eval { undef_method(:foo) }
     end
+  end
 
+  def test_frozen_class
     c = Class.new
     c.freeze
     assert_raise(RuntimeError) do
       c.instance_eval { undef_method(:foo) }
     end
+  end
 
-    o = Object.new
+  def test_frozen_singleton_class
+    klass = Class.new
+    o = klass.new
     c = class << o; self; end
     c.freeze
-    assert_raise(RuntimeError) do
+    assert_raise_with_message(RuntimeError, /frozen/) do
       c.instance_eval { undef_method(:foo) }
     end
+    klass.class_eval do
+      def self.foo
+      end
+    end
   end
 
   def test_method_defined

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

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