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

ruby-changes:38581

From: ko1 <ko1@a...>
Date: Fri, 29 May 2015 04:40:49 +0900 (JST)
Subject: [ruby-changes:38581] ko1:r50662 (trunk): * ext/objspace/objspace.c: add two methods to debug internals.

ko1	2015-05-29 04:40:04 +0900 (Fri, 29 May 2015)

  New Revision: 50662

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

  Log:
    * ext/objspace/objspace.c: add two methods to debug internals.
      * ObjectSpace.internal_class_of: return RBASIC_CLASS(obj).
      * ObjectSpace.internal_super_of: return RCLASS_SUPER(cls).
    * NEWS: add information about both methods.
    * test/objspace/test_objspace.rb: add tests for both methods.

  Modified files:
    trunk/ChangeLog
    trunk/NEWS
    trunk/ext/objspace/objspace.c
    trunk/test/objspace/test_objspace.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 50661)
+++ ChangeLog	(revision 50662)
@@ -1,3 +1,14 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Fri May 29 04:37:38 2015  Koichi Sasada  <ko1@a...>
+
+	* ext/objspace/objspace.c: add two methods to debug internals.
+
+	  * ObjectSpace.internal_class_of: return RBASIC_CLASS(obj).
+	  * ObjectSpace.internal_super_of: return RCLASS_SUPER(cls).
+
+	* NEWS: add information about both methods.
+
+	* test/objspace/test_objspace.rb: add tests for both methods.
+
 Thu May 28 06:55:53 2015  Anton Davydov  <antondavydov.o@g...>
 
 	* ext/tk/sample/figmemo_sample.rb (open_file),
Index: ext/objspace/objspace.c
===================================================================
--- ext/objspace/objspace.c	(revision 50661)
+++ ext/objspace/objspace.c	(revision 50662)
@@ -792,6 +792,73 @@ reachable_objects_from_root(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L792
     return hash;
 }
 
+static VALUE
+wrap_klass_iow(VALUE klass)
+{
+    if (!RTEST(klass)) {
+	return Qnil;
+    }
+    else if (RB_TYPE_P(klass, T_ICLASS)) {
+	return iow_newobj(klass);
+    }
+    else {
+	return klass;
+    }
+}
+
+/*
+ *  call-seq:
+ *     ObjectSpace.internal_class_of(obj) -> Class or Module
+ *
+ *  [MRI specific feature] Return internal class of obj.
+ *  obj can be an instance of InternalObjectWrapper.
+ *
+ *  Note that you should not use this method in your application.
+ */
+static VALUE
+objspace_internal_class_of(VALUE self, VALUE obj)
+{
+    VALUE klass;
+
+    if (rb_typeddata_is_kind_of(obj, &iow_data_type)) {
+	obj = (VALUE)DATA_PTR(obj);
+    }
+
+    klass = CLASS_OF(obj);
+    return wrap_klass_iow(klass);
+}
+
+/*
+ *  call-seq:
+ *     ObjectSpace.internal_super_of(cls) -> Class or Module
+ *
+ *  [MRI specific feature] Return internal super class of cls (Class or Module).
+ *  obj can be an instance of InternalObjectWrapper.
+ *
+ *  Note that you should not use this method in your application.
+ */
+static VALUE
+objspace_internal_super_of(VALUE self, VALUE obj)
+{
+    VALUE super;
+
+    if (rb_typeddata_is_kind_of(obj, &iow_data_type)) {
+	obj = (VALUE)DATA_PTR(obj);
+    }
+
+    switch (TYPE(obj)) {
+      case T_MODULE:
+      case T_CLASS:
+      case T_ICLASS:
+	super = RCLASS_SUPER(obj);
+	break;
+      default:
+	rb_raise(rb_eArgError, "class or module is expected");
+    }
+
+    return wrap_klass_iow(super);
+}
+
 void Init_object_tracing(VALUE rb_mObjSpace);
 void Init_objspace_dump(VALUE rb_mObjSpace);
 
@@ -830,6 +897,9 @@ Init_objspace(void) https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L897
     rb_define_module_function(rb_mObjSpace, "reachable_objects_from", reachable_objects_from, 1);
     rb_define_module_function(rb_mObjSpace, "reachable_objects_from_root", reachable_objects_from_root, 0);
 
+    rb_define_module_function(rb_mObjSpace, "internal_class_of", objspace_internal_class_of, 1);
+    rb_define_module_function(rb_mObjSpace, "internal_super_of", objspace_internal_super_of, 1);
+
     /*
      * This class is used as a return value from
      * ObjectSpace::reachable_objects_from.
Index: NEWS
===================================================================
--- NEWS	(revision 50661)
+++ NEWS	(revision 50662)
@@ -51,6 +51,8 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/NEWS#L51
 
 * ObjectSpace (objspace)
   * ObjectSpace.count_imemo_objects is added.
+  * ObjectSpace.internal_class_of is added.
+  * ObjectSpace.internal_super_of is added.
 
 * OpenSSL
   * OpenSSL::SSL::SSLSocket#accept_nonblock and
Index: test/objspace/test_objspace.rb
===================================================================
--- test/objspace/test_objspace.rb	(revision 50661)
+++ test/objspace/test_objspace.rb	(revision 50662)
@@ -285,4 +285,55 @@ class TestObjSpace < Test::Unit::TestCas https://github.com/ruby/ruby/blob/trunk/test/objspace/test_objspace.rb#L285
       assert_not_match /"fd":/, output
     end
   end
+
+  def traverse_classes klass
+    h = {}
+    while klass && !h.has_key?(klass)
+      h[klass] = true
+      klass = ObjectSpace.internal_class_of(klass)
+    end
+  end
+
+  def test_internal_class_of
+    i = 0
+    ObjectSpace.each_object{|o|
+      traverse_classes ObjectSpace.internal_class_of(o)
+      i += 1
+    }
+    assert_operator i, :>, 0
+  end
+
+  def traverse_super_classes klass
+    while klass
+      klass = ObjectSpace.internal_super_of(klass)
+    end
+  end
+
+  def all_super_classes klass
+    klasses = []
+    while klass
+      klasses << klass
+      klass = ObjectSpace.internal_super_of(klass)
+    end
+    klasses
+  end
+
+  def test_internal_super_of
+    klasses = all_super_classes(String)
+    String.ancestors.each{|k|
+      case k
+      when Class
+        assert_equal(true, klasses.include?(k), k.inspect)
+      when Module
+        assert_equal(false, klasses.include?(k), k.inspect) # Internal object (T_ICLASS)
+      end
+    }
+
+    i = 0
+    ObjectSpace.each_object(Module){|o|
+      traverse_super_classes ObjectSpace.internal_super_of(o)
+      i += 1
+    }
+    assert_operator i, :>, 0
+  end
 end

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

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