* 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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50662 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
4d059bf9f5
commit
6abf7938bf
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
|||||||
|
Fri May 29 04:37:38 2015 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* 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@gmail.com>
|
Thu May 28 06:55:53 2015 Anton Davydov <antondavydov.o@gmail.com>
|
||||||
|
|
||||||
* ext/tk/sample/figmemo_sample.rb (open_file),
|
* ext/tk/sample/figmemo_sample.rb (open_file),
|
||||||
|
2
NEWS
2
NEWS
@ -51,6 +51,8 @@ with all sufficient information, see the ChangeLog file.
|
|||||||
|
|
||||||
* ObjectSpace (objspace)
|
* ObjectSpace (objspace)
|
||||||
* ObjectSpace.count_imemo_objects is added.
|
* ObjectSpace.count_imemo_objects is added.
|
||||||
|
* ObjectSpace.internal_class_of is added.
|
||||||
|
* ObjectSpace.internal_super_of is added.
|
||||||
|
|
||||||
* OpenSSL
|
* OpenSSL
|
||||||
* OpenSSL::SSL::SSLSocket#accept_nonblock and
|
* OpenSSL::SSL::SSLSocket#accept_nonblock and
|
||||||
|
@ -792,6 +792,73 @@ reachable_objects_from_root(VALUE self)
|
|||||||
return hash;
|
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_object_tracing(VALUE rb_mObjSpace);
|
||||||
void Init_objspace_dump(VALUE rb_mObjSpace);
|
void Init_objspace_dump(VALUE rb_mObjSpace);
|
||||||
|
|
||||||
@ -830,6 +897,9 @@ Init_objspace(void)
|
|||||||
rb_define_module_function(rb_mObjSpace, "reachable_objects_from", reachable_objects_from, 1);
|
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, "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
|
* This class is used as a return value from
|
||||||
* ObjectSpace::reachable_objects_from.
|
* ObjectSpace::reachable_objects_from.
|
||||||
|
@ -285,4 +285,55 @@ class TestObjSpace < Test::Unit::TestCase
|
|||||||
assert_not_match /"fd":/, output
|
assert_not_match /"fd":/, output
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user