summaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-10-29 05:32:19 (GMT)
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-10-29 05:32:19 (GMT)
commit38094dd7f4987a9335ba9a666465ba4a8a27968a (patch)
treed112dcdc0f34898811f8a1db6be9cc83390d092e /vm.c
parent56eee285be2e18f727ef15d58e338b134c3ab210 (diff)
vm.c: ruby_th_dtrace_setup
* vm.c (ruby_th_dtrace_setup): extract setup for calling dtrace hook from RUBY_DTRACE_HOOK macro. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52338 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/vm.c b/vm.c
index d22e696..3b684f1 100644
--- a/vm.c
+++ b/vm.c
@@ -179,6 +179,46 @@ rb_vm_inc_const_missing_count(void)
ruby_vm_const_missing_count +=1;
}
+VALUE rb_class_path_no_cache(VALUE _klass);
+
+int
+ruby_th_dtrace_setup(rb_thread_t *th, VALUE klass, ID id,
+ struct ruby_dtrace_method_hook_args *args)
+{
+ enum ruby_value_type type;
+ if (!klass) {
+ if (!th) th = GET_THREAD();
+ if (!rb_thread_method_id_and_class(th, &id, &klass) || !klass)
+ return FALSE;
+ }
+ if (RB_TYPE_P(klass, T_ICLASS)) {
+ klass = RBASIC(klass)->klass;
+ }
+ else if (FL_TEST(klass, FL_SINGLETON)) {
+ klass = rb_attr_get(klass, id__attached__);
+ if (NIL_P(klass)) return FALSE;
+ }
+ type = BUILTIN_TYPE(klass);
+ if (type == T_CLASS || type == T_ICLASS || type == T_MODULE) {
+ VALUE name = rb_class_path_no_cache(klass);
+ const char *classname;
+ const char *methodname = rb_id2name(id);
+ const char *filename = rb_sourcefile();
+ if (methodname && filename) {
+ if (NIL_P(name) || !(classname = StringValuePtr(name)))
+ classname = "<unknown>";
+ args->classname = classname;
+ args->methodname = methodname;
+ args->filename = filename;
+ args->line_no = rb_sourceline();
+ args->klass = klass;
+ args->name = name;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
/*
* call-seq:
* RubyVM.stat -> Hash