pline 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README +134 -0
- data/ext/pline/depend +55 -0
- data/ext/pline/extconf.rb +14 -0
- data/ext/pline/iseq.c +124 -0
- data/ext/pline/minfo.c +167 -0
- data/ext/pline/pline.c.rb +68 -0
- data/ext/pline/profiler.c +125 -0
- data/ext/pline/ruby_source/1.9.2/debug.h +36 -0
- data/ext/pline/ruby_source/1.9.2/eval_intern.h +232 -0
- data/ext/pline/ruby_source/1.9.2/gc.h +77 -0
- data/ext/pline/ruby_source/1.9.2/id.h +170 -0
- data/ext/pline/ruby_source/1.9.2/insns.inc +179 -0
- data/ext/pline/ruby_source/1.9.2/insns_info.inc +695 -0
- data/ext/pline/ruby_source/1.9.2/iseq.h +104 -0
- data/ext/pline/ruby_source/1.9.2/manual_update.h +19 -0
- data/ext/pline/ruby_source/1.9.2/method.h +103 -0
- data/ext/pline/ruby_source/1.9.2/node.h +483 -0
- data/ext/pline/ruby_source/1.9.2/thread_pthread.h +27 -0
- data/ext/pline/ruby_source/1.9.2/thread_win32.h +33 -0
- data/ext/pline/ruby_source/1.9.2/vm_core.h +706 -0
- data/ext/pline/ruby_source/1.9.2/vm_exec.h +184 -0
- data/ext/pline/ruby_source/1.9.2/vm_insnhelper.c +1734 -0
- data/ext/pline/ruby_source/1.9.2/vm_insnhelper.h +208 -0
- data/ext/pline/ruby_source/1.9.2/vm_opts.h +51 -0
- data/ext/pline/ruby_source/1.9.3/atomic.h +56 -0
- data/ext/pline/ruby_source/1.9.3/constant.h +34 -0
- data/ext/pline/ruby_source/1.9.3/debug.h +41 -0
- data/ext/pline/ruby_source/1.9.3/eval_intern.h +234 -0
- data/ext/pline/ruby_source/1.9.3/gc.h +98 -0
- data/ext/pline/ruby_source/1.9.3/id.h +175 -0
- data/ext/pline/ruby_source/1.9.3/insns.inc +179 -0
- data/ext/pline/ruby_source/1.9.3/insns_info.inc +695 -0
- data/ext/pline/ruby_source/1.9.3/internal.h +227 -0
- data/ext/pline/ruby_source/1.9.3/iseq.h +125 -0
- data/ext/pline/ruby_source/1.9.3/manual_update.h +19 -0
- data/ext/pline/ruby_source/1.9.3/method.h +105 -0
- data/ext/pline/ruby_source/1.9.3/node.h +503 -0
- data/ext/pline/ruby_source/1.9.3/thread_pthread.h +51 -0
- data/ext/pline/ruby_source/1.9.3/thread_win32.h +40 -0
- data/ext/pline/ruby_source/1.9.3/vm_core.h +756 -0
- data/ext/pline/ruby_source/1.9.3/vm_exec.h +184 -0
- data/ext/pline/ruby_source/1.9.3/vm_insnhelper.c +1749 -0
- data/ext/pline/ruby_source/1.9.3/vm_insnhelper.h +220 -0
- data/ext/pline/ruby_source/1.9.3/vm_opts.h +51 -0
- data/ext/pline/sinfo.c +311 -0
- data/lib/pline.rb +11 -0
- data/lib/pline/minfo.rb +22 -0
- data/lib/pline/summarize.rb +127 -0
- data/lib/pline/util.rb +54 -0
- data/pline.gemspec +28 -0
- metadata +102 -0
data/README
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
* About PLine
|
2
|
+
PLine is a profiler for Ruby1.9.3 and Ruby1.9.2.
|
3
|
+
PLine profiles each line of Ruby method (method written in Ruby) you specified.
|
4
|
+
Using PLine, you can profile each line of Ruby method easily.
|
5
|
+
|
6
|
+
This README document introduces basic functionality of PLine.
|
7
|
+
If you have any questions or comments, please send email to shiba@rvm.jp,
|
8
|
+
or use http://github.com/soba1104/PLine/issues.
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
* License
|
13
|
+
Same as the license of Ruby runtime.
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
* Installation
|
18
|
+
$gem install pline
|
19
|
+
|
20
|
+
Currently, PLine supports Ruby1.9.3 and Ruby1.9.2 only.
|
21
|
+
So, if you want to use PLine, please install PLine
|
22
|
+
under Ruby1.9.3 or Ruby1.9.2 runtime.
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
* Usage
|
27
|
+
############### sample code ###############
|
28
|
+
require 'pline'
|
29
|
+
|
30
|
+
# Target method of profiling
|
31
|
+
def sum(a, b)
|
32
|
+
a + b
|
33
|
+
end
|
34
|
+
|
35
|
+
# Specify unit of measurement to PLine
|
36
|
+
PLine.show_msec()
|
37
|
+
|
38
|
+
# Specify profiling to PLine
|
39
|
+
PLine.profile(self, :sum, true)
|
40
|
+
|
41
|
+
1000000.times{|i| sum(i, i)}
|
42
|
+
|
43
|
+
################## result ##################
|
44
|
+
-----------------------------------------
|
45
|
+
| main.sum: tmp/sample.rb(4 - 6) |
|
46
|
+
|-----------------------------------------|
|
47
|
+
| Line | Time(msec) | Source |
|
48
|
+
|-----------------------------------------|
|
49
|
+
| 4 | 0 | def sum(a, b) |
|
50
|
+
| 5 | 625 | a + b | < You can know that
|
51
|
+
| 6 | 0 | end | 'a + b' takes 625 microseconds.
|
52
|
+
-----------------------------------------
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
* Attention
|
57
|
+
Currently, PLine is alpha version. So, you must not use PLine in critical mission.
|
58
|
+
This section introduces some attentions about PLine.
|
59
|
+
|
60
|
+
** Recursive call profiling
|
61
|
+
PLine cannot profile recursive call statements correctly.
|
62
|
+
Profiling results of recursive call statements may become short.
|
63
|
+
|
64
|
+
** Block invocation profiling
|
65
|
+
PLine cannot profile exit points of block invocation.
|
66
|
+
Profiling results of exit points of block invocation may become significantly short.
|
67
|
+
|
68
|
+
------------------------ example ------------------------
|
69
|
+
# sample code
|
70
|
+
require 'pline'
|
71
|
+
|
72
|
+
def foo
|
73
|
+
sum = 0
|
74
|
+
100000.times{|i|
|
75
|
+
sum += i
|
76
|
+
sum += i
|
77
|
+
}
|
78
|
+
sum
|
79
|
+
end
|
80
|
+
|
81
|
+
PLine.profile(self, :foo, true)
|
82
|
+
foo()
|
83
|
+
|
84
|
+
# result
|
85
|
+
----------------------------------------
|
86
|
+
| main.foo: tmp/test2.rb(3 - 10) |
|
87
|
+
|----------------------------------------|
|
88
|
+
| Line | Time(usec) | Source |
|
89
|
+
|----------------------------------------|
|
90
|
+
| 3 | 0 | def foo |
|
91
|
+
| 4 | 2 | sum = 0 |
|
92
|
+
| 5 | 2 | 100000.times{|i| |
|
93
|
+
| 6 | 81190 | sum += i |
|
94
|
+
| 7 | 3 | sum += i | <= this
|
95
|
+
| 8 | 0 | } |
|
96
|
+
| 9 | 1 | sum |
|
97
|
+
| 10 | 0 | end |
|
98
|
+
----------------------------------------
|
99
|
+
---------------------------------------------------------
|
100
|
+
|
101
|
+
** Using together with other profiler
|
102
|
+
PLine rewrites RUBY_EVENT_LINE event to RUBY_EVENT_END event.
|
103
|
+
So, when you use PLine, above events become incompatible.
|
104
|
+
You should not use PLine together with other profilers which use above events.
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
* PLine APIs
|
109
|
+
This section introduces PLine APIs.
|
110
|
+
|
111
|
+
** A API of specifying profiling
|
112
|
+
- PLine.profile(object, method_id, singleton_p = false)
|
113
|
+
Specify profiling to PLine.
|
114
|
+
When singleton_p argument(third argument) is false, PLine searches object#method_id (instance method).
|
115
|
+
Otherwise, PLine searches object.method_id (singleton_method).
|
116
|
+
|
117
|
+
** APIs of specifying output
|
118
|
+
- PLine.output=(io)
|
119
|
+
Specify output io object.
|
120
|
+
Default output of PLine is STDERR.
|
121
|
+
|
122
|
+
- PLine.show_sec()
|
123
|
+
Specify sec as the unit of measurement.
|
124
|
+
|
125
|
+
- PLine.show_msec()
|
126
|
+
Specify millisec as the unit of measurement.
|
127
|
+
|
128
|
+
- PLine.show_usec()
|
129
|
+
Specify microsec as the unit of measurement.
|
130
|
+
Microsec is the default unit of measurement.
|
131
|
+
|
132
|
+
- PLine.show_nsec()
|
133
|
+
Specify nanosec as the unit of measurement.
|
134
|
+
|
data/ext/pline/depend
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
HEADERS = \
|
2
|
+
$(arch_hdrdir)/ruby/config.h \
|
3
|
+
$(hdrdir)/ruby/defines.h \
|
4
|
+
$(hdrdir)/ruby/intern.h \
|
5
|
+
$(hdrdir)/ruby/missing.h \
|
6
|
+
$(hdrdir)/ruby/ruby.h \
|
7
|
+
$(hdrdir)/ruby/st.h \
|
8
|
+
$(srcdir)/ruby_source/1.9.3/eval_intern.h \
|
9
|
+
$(srcdir)/ruby_source/1.9.3/iseq.h \
|
10
|
+
$(srcdir)/ruby_source/1.9.3/method.h \
|
11
|
+
$(srcdir)/ruby_source/1.9.3/node.h \
|
12
|
+
$(srcdir)/ruby_source/1.9.3/thread_pthread.h \
|
13
|
+
$(srcdir)/ruby_source/1.9.3/thread_win32.h \
|
14
|
+
$(srcdir)/ruby_source/1.9.3/vm_core.h \
|
15
|
+
$(srcdir)/ruby_source/1.9.3/vm_exec.h \
|
16
|
+
$(srcdir)/ruby_source/1.9.3/vm_insnhelper.c \
|
17
|
+
$(srcdir)/ruby_source/1.9.3/vm_insnhelper.h \
|
18
|
+
$(srcdir)/ruby_source/1.9.3/vm_opts.h \
|
19
|
+
$(srcdir)/ruby_source/1.9.3/insns_info.inc \
|
20
|
+
$(srcdir)/ruby_source/1.9.3/insns.inc \
|
21
|
+
$(srcdir)/ruby_source/1.9.3/constant.h \
|
22
|
+
$(srcdir)/ruby_source/1.9.3/atomic.h \
|
23
|
+
$(srcdir)/ruby_source/1.9.3/internal.h \
|
24
|
+
$(srcdir)/ruby_source/1.9.3/manual_update.h \
|
25
|
+
$(srcdir)/ruby_source/1.9.2/debug.h \
|
26
|
+
$(srcdir)/ruby_source/1.9.2/gc.h \
|
27
|
+
$(srcdir)/ruby_source/1.9.2/id.h \
|
28
|
+
$(srcdir)/ruby_source/1.9.2/eval_intern.h \
|
29
|
+
$(srcdir)/ruby_source/1.9.2/iseq.h \
|
30
|
+
$(srcdir)/ruby_source/1.9.2/method.h \
|
31
|
+
$(srcdir)/ruby_source/1.9.2/node.h \
|
32
|
+
$(srcdir)/ruby_source/1.9.2/thread_pthread.h \
|
33
|
+
$(srcdir)/ruby_source/1.9.2/thread_win32.h \
|
34
|
+
$(srcdir)/ruby_source/1.9.2/vm_core.h \
|
35
|
+
$(srcdir)/ruby_source/1.9.2/vm_exec.h \
|
36
|
+
$(srcdir)/ruby_source/1.9.2/vm_insnhelper.c \
|
37
|
+
$(srcdir)/ruby_source/1.9.2/vm_insnhelper.h \
|
38
|
+
$(srcdir)/ruby_source/1.9.2/vm_opts.h \
|
39
|
+
$(srcdir)/ruby_source/1.9.2/insns_info.inc \
|
40
|
+
$(srcdir)/ruby_source/1.9.2/insns.inc \
|
41
|
+
$(srcdir)/ruby_source/1.9.2/manual_update.h \
|
42
|
+
$(srcdir)/extconf.h
|
43
|
+
|
44
|
+
$(srcdir)/pline.c: \
|
45
|
+
$(srcdir)/pline.c.rb
|
46
|
+
$(RUBY) -- $(srcdir)/pline.c.rb > $@
|
47
|
+
|
48
|
+
$(srcdir)/pline.o: \
|
49
|
+
$(HEADERS) \
|
50
|
+
$(srcdir)/profiler.c \
|
51
|
+
$(srcdir)/sinfo.c \
|
52
|
+
$(srcdir)/minfo.c \
|
53
|
+
$(srcdir)/iseq.c \
|
54
|
+
$(srcdir)/pline.c
|
55
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# coding=utf-8
|
2
|
+
|
3
|
+
require 'mkmf'
|
4
|
+
require 'rbconfig'
|
5
|
+
extend RbConfig
|
6
|
+
|
7
|
+
$defs.push '-DCABI_OPERANDS' if enable_config 'cabi-operands', true
|
8
|
+
$defs.push '-DCABI_PASS_CFP' if enable_config 'cabi-pass-cfp', true
|
9
|
+
|
10
|
+
$INCFLAGS << ' -I$(srcdir)/ruby_source'
|
11
|
+
$objs = %w'$(srcdir)/pline.o'
|
12
|
+
create_header
|
13
|
+
create_makefile 'pline'
|
14
|
+
|
data/ext/pline/iseq.c
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
static rb_iseq_t *iseq_find(VALUE obj, VALUE mid, VALUE singleton_p)
|
2
|
+
{
|
3
|
+
rb_method_entry_t *me;
|
4
|
+
rb_method_definition_t *def;
|
5
|
+
VALUE km;
|
6
|
+
int class;
|
7
|
+
const char *msg = NULL;
|
8
|
+
VALUE name;
|
9
|
+
const char *sep = RTEST(singleton_p) ? "." : "#";
|
10
|
+
|
11
|
+
if (RTEST(singleton_p)) {
|
12
|
+
class = 1;
|
13
|
+
km = rb_class_of(obj);
|
14
|
+
} else {
|
15
|
+
VALUE c = rb_obj_class(obj);
|
16
|
+
if (c == rb_cClass) {
|
17
|
+
class = 1;
|
18
|
+
} else if (c == rb_cModule) {
|
19
|
+
class = 0;
|
20
|
+
} else {
|
21
|
+
rb_raise(rb_eArgError, "expected class or module");
|
22
|
+
}
|
23
|
+
km = obj;
|
24
|
+
}
|
25
|
+
|
26
|
+
me = search_method(km, SYM2ID(mid));
|
27
|
+
if (!me) {
|
28
|
+
if (class) {
|
29
|
+
name = rb_class_path(km);
|
30
|
+
} else {
|
31
|
+
name = rb_mod_name(km);
|
32
|
+
}
|
33
|
+
rb_raise(rb_eArgError, "method not found (%s%s%s)",
|
34
|
+
RSTRING_PTR(name), sep, rb_id2name(SYM2ID(mid)));
|
35
|
+
}
|
36
|
+
|
37
|
+
def = me->def;
|
38
|
+
switch (def->type) {
|
39
|
+
case VM_METHOD_TYPE_ISEQ:
|
40
|
+
return def->body.iseq;
|
41
|
+
case VM_METHOD_TYPE_CFUNC:
|
42
|
+
msg = "PLine cannot handle C method";
|
43
|
+
break;
|
44
|
+
case VM_METHOD_TYPE_ATTRSET:
|
45
|
+
msg = "PLine cannot handle attr_writer";
|
46
|
+
break;
|
47
|
+
case VM_METHOD_TYPE_IVAR:
|
48
|
+
msg = "PLine cannot handle attr_reader";
|
49
|
+
break;
|
50
|
+
case VM_METHOD_TYPE_BMETHOD:
|
51
|
+
msg = "Currently, PLine cannot handle method defined by define_method";
|
52
|
+
break;
|
53
|
+
case VM_METHOD_TYPE_ZSUPER:
|
54
|
+
msg = "Unsupported method type zsuper";
|
55
|
+
break;
|
56
|
+
case VM_METHOD_TYPE_UNDEF:
|
57
|
+
msg = "Unsupported method type undef";
|
58
|
+
break;
|
59
|
+
case VM_METHOD_TYPE_NOTIMPLEMENTED:
|
60
|
+
msg = "Unsupported method type notimplemented";
|
61
|
+
break;
|
62
|
+
case VM_METHOD_TYPE_OPTIMIZED:
|
63
|
+
msg = "Unsupported method type optimized";
|
64
|
+
break;
|
65
|
+
case VM_METHOD_TYPE_MISSING:
|
66
|
+
msg = "Unsupported method type missing";
|
67
|
+
break;
|
68
|
+
default:
|
69
|
+
msg = NULL;
|
70
|
+
}
|
71
|
+
|
72
|
+
if (!msg) {
|
73
|
+
rb_bug("pline_find_iseq: should not be reached(1)");
|
74
|
+
}
|
75
|
+
|
76
|
+
if (class) {
|
77
|
+
name = rb_class_path(km);
|
78
|
+
} else {
|
79
|
+
name = rb_mod_name(km);
|
80
|
+
}
|
81
|
+
rb_raise(rb_eArgError, "%s (%s%s%s)",
|
82
|
+
msg, RSTRING_PTR(name), sep, rb_id2name(SYM2ID(mid)));
|
83
|
+
}
|
84
|
+
|
85
|
+
static void iseq_inject(rb_iseq_t *iseq)
|
86
|
+
{
|
87
|
+
int idx, len = iseq->iseq_size;
|
88
|
+
VALUE *seq = iseq->iseq;
|
89
|
+
VALUE *enc = iseq->iseq_encoded;
|
90
|
+
|
91
|
+
for (idx = 0; idx < len; idx += insn_len(seq[idx])) {
|
92
|
+
VALUE insn = seq[idx];
|
93
|
+
VALUE *op0 = &seq[idx] + 1;
|
94
|
+
VALUE *op1 = &enc[idx] + 1;
|
95
|
+
rb_num_t nf;
|
96
|
+
rb_iseq_t *child = NULL;
|
97
|
+
|
98
|
+
switch(insn) {
|
99
|
+
case BIN(trace):
|
100
|
+
nf = op0[0];
|
101
|
+
if (nf == RUBY_EVENT_LINE || nf == RUBY_EVENT_RETURN) {
|
102
|
+
op0[0] = RUBY_EVENT_END;
|
103
|
+
op1[0] = RUBY_EVENT_END;
|
104
|
+
}
|
105
|
+
break;
|
106
|
+
case BIN(putiseq):
|
107
|
+
child = (rb_iseq_t *)op0[0];
|
108
|
+
break;
|
109
|
+
case BIN(defineclass):
|
110
|
+
child = (rb_iseq_t *)op0[1];
|
111
|
+
break;
|
112
|
+
case BIN(send):
|
113
|
+
child = (rb_iseq_t *)op0[2];
|
114
|
+
break;
|
115
|
+
case BIN(invokesuper):
|
116
|
+
child = (rb_iseq_t *)op0[1];
|
117
|
+
break;
|
118
|
+
}
|
119
|
+
if (child) {
|
120
|
+
iseq_inject(child);
|
121
|
+
}
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
data/ext/pline/minfo.c
ADDED
@@ -0,0 +1,167 @@
|
|
1
|
+
typedef struct pline_method_info {
|
2
|
+
VALUE obj;
|
3
|
+
VALUE mid;
|
4
|
+
VALUE spath;
|
5
|
+
VALUE sline;
|
6
|
+
VALUE eline;
|
7
|
+
VALUE singleton_p;
|
8
|
+
} pline_method_info_t;
|
9
|
+
|
10
|
+
static void minfo_mark(void *ptr)
|
11
|
+
{
|
12
|
+
pline_method_info_t *m = ptr;
|
13
|
+
|
14
|
+
if (!m) return;
|
15
|
+
rb_gc_mark(m->obj);
|
16
|
+
rb_gc_mark(m->mid);
|
17
|
+
rb_gc_mark(m->spath);
|
18
|
+
rb_gc_mark(m->sline);
|
19
|
+
rb_gc_mark(m->eline);
|
20
|
+
rb_gc_mark(m->singleton_p);
|
21
|
+
}
|
22
|
+
|
23
|
+
static void minfo_free(void *p)
|
24
|
+
{
|
25
|
+
if (p) xfree(p);
|
26
|
+
}
|
27
|
+
|
28
|
+
static const rb_data_type_t minfo_data_type = {
|
29
|
+
"pline_method_info",
|
30
|
+
{minfo_mark, minfo_free, NULL,},
|
31
|
+
};
|
32
|
+
|
33
|
+
static VALUE minfo_s_alloc(VALUE klass)
|
34
|
+
{
|
35
|
+
VALUE obj;
|
36
|
+
pline_method_info_t *m;
|
37
|
+
|
38
|
+
obj = TypedData_Make_Struct(klass, pline_method_info_t, &minfo_data_type, m);
|
39
|
+
m->spath = Qnil;
|
40
|
+
m->sline = Qnil;
|
41
|
+
m->eline = Qnil;
|
42
|
+
|
43
|
+
return obj;
|
44
|
+
}
|
45
|
+
|
46
|
+
static void minfo_source_information_error(void)
|
47
|
+
{
|
48
|
+
rb_raise(rb_eArgError, "unexpected source information");
|
49
|
+
}
|
50
|
+
|
51
|
+
static void check_line_information(VALUE line)
|
52
|
+
{
|
53
|
+
if (rb_class_of(line) != rb_cFixnum || FIX2LONG(line) < 0) {
|
54
|
+
minfo_source_information_error();
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
static VALUE minfo_spath_from_iseq(VALUE iseqval)
|
59
|
+
{
|
60
|
+
rb_iseq_t *iseq = DATA_PTR(iseqval);
|
61
|
+
VALUE spath = iseq->filename;
|
62
|
+
VALUE valid = rb_funcall(rb_cFile, rb_intern("exist?"), 1, spath);
|
63
|
+
|
64
|
+
if (!RTEST(valid)) {
|
65
|
+
minfo_source_information_error();
|
66
|
+
}
|
67
|
+
|
68
|
+
return spath;
|
69
|
+
}
|
70
|
+
|
71
|
+
static VALUE minfo_sline_from_iseq(VALUE iseqval)
|
72
|
+
{
|
73
|
+
rb_iseq_t *iseq = DATA_PTR(iseqval);
|
74
|
+
VALUE sline = iseq->line_no;
|
75
|
+
|
76
|
+
check_line_information(sline);
|
77
|
+
|
78
|
+
return sline;
|
79
|
+
}
|
80
|
+
|
81
|
+
static VALUE minfo_eline_from_iseq(VALUE iseqval)
|
82
|
+
{
|
83
|
+
rb_iseq_t *iseq = DATA_PTR(iseqval);
|
84
|
+
VALUE eline = iseq->line_no;
|
85
|
+
unsigned int i;
|
86
|
+
|
87
|
+
check_line_information(eline);
|
88
|
+
|
89
|
+
for (i = 0; i < iseq->insn_info_size; i++) {
|
90
|
+
VALUE l = LONG2FIX(iseq->insn_info_table[i].line_no);
|
91
|
+
if (l > eline) {
|
92
|
+
eline = l;
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
return eline;
|
97
|
+
}
|
98
|
+
|
99
|
+
static VALUE minfo_m_init(VALUE self, VALUE iseq, VALUE obj, VALUE mid, VALUE singleton_p)
|
100
|
+
{
|
101
|
+
pline_method_info_t *m = DATA_PTR(self);
|
102
|
+
VALUE spath, sline, eline;
|
103
|
+
|
104
|
+
if (rb_obj_class(mid) != rb_cSymbol ||
|
105
|
+
rb_obj_class(iseq) != rb_cISeq) {
|
106
|
+
rb_raise(rb_eArgError, "invalid arguments");
|
107
|
+
}
|
108
|
+
|
109
|
+
m->obj = obj;
|
110
|
+
m->mid = mid;
|
111
|
+
m->spath = minfo_spath_from_iseq(iseq);
|
112
|
+
m->sline = minfo_sline_from_iseq(iseq);
|
113
|
+
m->eline = minfo_eline_from_iseq(iseq);
|
114
|
+
m->singleton_p = singleton_p;
|
115
|
+
|
116
|
+
return Qnil;
|
117
|
+
}
|
118
|
+
|
119
|
+
static VALUE minfo_m_obj(VALUE self)
|
120
|
+
{
|
121
|
+
pline_method_info_t *m = DATA_PTR(self);
|
122
|
+
return m->obj;
|
123
|
+
}
|
124
|
+
|
125
|
+
static VALUE minfo_m_mid(VALUE self)
|
126
|
+
{
|
127
|
+
pline_method_info_t *m = DATA_PTR(self);
|
128
|
+
return m->mid;
|
129
|
+
}
|
130
|
+
|
131
|
+
static VALUE minfo_m_spath(VALUE self)
|
132
|
+
{
|
133
|
+
pline_method_info_t *m = DATA_PTR(self);
|
134
|
+
return m->spath;
|
135
|
+
}
|
136
|
+
|
137
|
+
static VALUE minfo_m_sline(VALUE self)
|
138
|
+
{
|
139
|
+
pline_method_info_t *m = DATA_PTR(self);
|
140
|
+
return m->sline;
|
141
|
+
}
|
142
|
+
|
143
|
+
static VALUE minfo_m_eline(VALUE self)
|
144
|
+
{
|
145
|
+
pline_method_info_t *m = DATA_PTR(self);
|
146
|
+
return m->eline;
|
147
|
+
}
|
148
|
+
|
149
|
+
static VALUE minfo_m_singleton_p(VALUE self)
|
150
|
+
{
|
151
|
+
pline_method_info_t *m = DATA_PTR(self);
|
152
|
+
return RTEST(m->singleton_p) ? Qtrue : Qfalse;
|
153
|
+
}
|
154
|
+
|
155
|
+
static void pline_minfo_init(void)
|
156
|
+
{
|
157
|
+
cMethodInfo = rb_define_class_under(mPLine, "MethodInfo", rb_cObject);
|
158
|
+
rb_define_method(cMethodInfo, "obj", minfo_m_obj, 0);
|
159
|
+
rb_define_method(cMethodInfo, "mid", minfo_m_mid, 0);
|
160
|
+
rb_define_method(cMethodInfo, "spath", minfo_m_spath, 0);
|
161
|
+
rb_define_method(cMethodInfo, "sline", minfo_m_sline, 0);
|
162
|
+
rb_define_method(cMethodInfo, "eline", minfo_m_eline, 0);
|
163
|
+
rb_define_method(cMethodInfo, "singleton?", minfo_m_singleton_p, 0);
|
164
|
+
rb_define_method(cMethodInfo, "initialize", minfo_m_init, 4);
|
165
|
+
rb_define_alloc_func(cMethodInfo, minfo_s_alloc);
|
166
|
+
}
|
167
|
+
|