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/