rb-threadframe 0.39 → 0.40

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,13 +1,12 @@
1
1
  require 'test/unit'
2
2
 
3
- # require 'thread_frame' # To compare with previous version
4
- require_relative '../../ext/thread_frame'
3
+ require_relative '../../ext/thread_frame' if '1.9.2' == RUBY_VERSION
5
4
 
6
- # Test source_location and source_container.
5
+ # Test accessing and settign RubyVM::Frame stack data
7
6
  class TestSpSize < Test::Unit::TestCase
8
7
 
9
8
  def sizes
10
- tf = RubyVM::ThreadFrame::current
9
+ tf = RubyVM::Frame::current
11
10
  ary = []
12
11
  0.upto(2) do |i|
13
12
  ary << tf.sp_size
@@ -37,7 +36,7 @@ class TestSpSize < Test::Unit::TestCase
37
36
  assert_equal(f1_s[1..-1], f2_s[1..-1])
38
37
 
39
38
  assert_raises ArgumentError do
40
- tf = RubyVM::ThreadFrame.current
39
+ tf = RubyVM::Frame.current
41
40
  tf.sp_set(tf.sp_size, "Should not be able to set this.")
42
41
  end
43
42
  end
@@ -1,6 +1,7 @@
1
1
  # Test of additional tracing flag use to selectively turn on off tracing
2
2
  require 'test/unit'
3
- require_relative '../../ext/thread_frame'
3
+
4
+ require_relative '../../ext/thread_frame' if '1.9.2' == RUBY_VERSION
4
5
 
5
6
  class TestTracingMasks < Test::Unit::TestCase
6
7
  @@EVENT2MASK = {
@@ -1,10 +1,10 @@
1
1
  # Test of additional tracing flag use to selectively turn on off tracing
2
2
  require 'test/unit'
3
- require_relative '../../ext/thread_frame'
3
+ require_relative '../../ext/thread_frame' if '1.9.2' == RUBY_VERSION
4
4
 
5
5
  class TestTracing < Test::Unit::TestCase
6
6
  def test_basic_query_set_unset
7
- tf = RubyVM::ThreadFrame::current
7
+ tf = RubyVM::Frame::current
8
8
  # Test default values
9
9
  assert_equal(false, tf.trace_off?)
10
10
  assert_equal(false, tf.return_stop?)
@@ -25,14 +25,14 @@ class TestTracing < Test::Unit::TestCase
25
25
  def test_trace_off
26
26
  @levels = []
27
27
  def trace_hook(event, file, line, id, binding, klass)
28
- @levels << RubyVM::ThreadFrame::current.stack_size
28
+ @levels << RubyVM::Frame::current.stack_size
29
29
  end
30
30
 
31
31
  def baz
32
32
  6
33
33
  end
34
34
  def bar(set_off)
35
- RubyVM::ThreadFrame::current.trace_off = true if set_off
35
+ RubyVM::Frame::current.trace_off = true if set_off
36
36
  baz
37
37
  5
38
38
  end
data/threadframe.rd CHANGED
@@ -1,17 +1,17 @@
1
1
  # = NAME
2
- # +RubyVM+::+ThreadFrame+
2
+ # +RubyVM+::+Frame+
3
3
  #
4
4
  # = SYNOPSES
5
5
  #
6
- # The +RubyVM+::+ThreadFrame+ class gives call-stack frame information
6
+ # The +RubyVM+::+Frame+ class gives call-stack frame information
7
7
  # (controlled access to +rb_control_frame_t+)
8
8
  #
9
9
  #
10
10
  # It is possible that a The +Thread+::+Frame+ may be proposed for
11
- # all Ruby 1.9 implementations. +RubyVM+::+ThreadFrame+
11
+ # all Ruby 1.9 implementations. +RubyVM+::+Frame+
12
12
  # contains routines in the YARV 1.9 implementation.
13
13
  #
14
- # Should there be a +Thread+::+Frame+ +RubyVM+::+ThreadFrame+ would be
14
+ # Should there be a +Thread+::+Frame+ +RubyVM+::+Frame+ would be
15
15
  # a subclass of +Thread+::+Frame+. In code:
16
16
  #
17
17
  # class Thread
@@ -19,11 +19,11 @@
19
19
  # # ...
20
20
  # end
21
21
  # def threadframe
22
- # RubyVM::ThreadFrame.new(self) # or possibly Thread::Frame.new(self)
22
+ # RubyVM::Frame.new(self) # or possibly Thread::Frame.new(self)
23
23
  # end
24
24
  # end
25
25
  #
26
- # class RubyVM::ThreadFrame < Thread::Frame # In YARV
26
+ # class RubyVM::Frame < Thread::Frame # In YARV
27
27
  # def initialize(thread_object)
28
28
  # # implementation-specific code
29
29
  # end
@@ -36,25 +36,25 @@
36
36
  # A +RubyVM+::Thread+Frame+ contains information from a frame running +Thread+
37
37
  # object, and the information may change or disappear in the course of
38
38
  # running that thread. Therefore, it is advisable ensure that the
39
- # threads of the ThreadFrame objects are blocked.
39
+ # threads of the Frame objects are blocked.
40
40
  #
41
41
  #
42
- # === RubyVM::ThreadFrame::new(thread_object)
42
+ # === RubyVM::Frame::new(thread_object)
43
43
  # Creates a thread-frame object for the given thread object.
44
44
  #
45
- # === RubyVM::ThreadFrame::current
46
- # Shorthand for RubyVM::ThreadFrame.new(Thread::current)
45
+ # === RubyVM::Frame::current
46
+ # Shorthand for RubyVM::Frame.new(Thread::current)
47
47
  #
48
48
  # === Thread#threadframe
49
49
  # tf = Thread::current.threadframe()
50
50
  #
51
51
  # Creates a thread-frame object for the given thread object.
52
52
  # Note:
53
- # Thread::current.threadframe() == RubyVM::ThreadFrame.new(Thread::current)
53
+ # Thread::current.threadframe() == RubyVM::Frame.new(Thread::current)
54
54
  #
55
- # == RubyVM::ThreadFrame Instance Methods
55
+ # == RubyVM::Frame Instance Methods
56
56
  #
57
- # === RubyVM::ThreadFrame#prev
57
+ # === RubyVM::Frame#prev
58
58
  # tf.prev(n) -> tf or nil
59
59
  # tf.prev() -> tf or nil # same as tf.prev(1)
60
60
  #
@@ -65,7 +65,7 @@
65
65
  # tf. A negative number of a number greater than the number of frames
66
66
  # returns nil.
67
67
  #
68
- # === RubyVM::ThreadFrame#invalid?
68
+ # === RubyVM::Frame#invalid?
69
69
  # tf.invalid?() -> boolean
70
70
  #
71
71
  # Returns true if the frame is no longer valid. On the other hand,
@@ -78,24 +78,24 @@
78
78
  # variable is active.
79
79
  #
80
80
  #
81
- # === RubyVM::ThreadFrame#thread
81
+ # === RubyVM::Frame#thread
82
82
  # tf.thread() -> Thread
83
- # RubyVM::ThreadFrame.current().thread == Thread.current
83
+ # RubyVM::Frame.current().thread == Thread.current
84
84
  #
85
- # === RubyVM::ThreadFrame#type
85
+ # === RubyVM::Frame#type
86
86
  # tf.type() -> 'C' or 'Ruby'
87
87
  #
88
88
  # Indicates whether the frame is implemented in C or Ruby.
89
89
  #
90
- # === RubyVM::ThreadFrame#source_container
90
+ # === RubyVM::Frame#source_container
91
91
  # RubyVM::Threadframe#source_container() -> [Type, String]
92
92
  #
93
93
  # Returns a tuple representing kind of container, e.g. file
94
94
  # eval'd string object, and the name of the container. If file,
95
95
  # it would be a file name. If an eval'd string it might be the string.
96
96
  #
97
- # === RubyVM::ThreadFrame#source_location
98
- # RubyVM::ThreadFrame#.source_location() -> Array
97
+ # === RubyVM::Frame#source_location
98
+ # RubyVM::Frame#.source_location() -> Array
99
99
  #
100
100
  # Returns an array of source location positions that match
101
101
  # +tf.instruction_offset+. A source location position is left
@@ -103,12 +103,12 @@
103
103
  # and start and end column, or a start line number, start column, end
104
104
  # line number, end column.
105
105
  #
106
- # === RubyVM::ThreadFrame#stack_size
107
- # RubyVM::ThreadFrame#.stack_size -> Fixnum
106
+ # === RubyVM::Frame#stack_size
107
+ # RubyVM::Frame#.stack_size -> Fixnum
108
108
  #
109
109
  # Returns the number of entries
110
110
  #
111
- # === RubyVM::ThreadFrame#binding
111
+ # === RubyVM::Frame#binding
112
112
  # tf.binding() -> binding
113
113
  #
114
114
  #
@@ -117,28 +117,28 @@
117
117
  # execution of the program, variables may spring into existence and
118
118
  # values may change.
119
119
 
120
- # == RubyVM::ThreadFrame
120
+ # == RubyVM::Frame
121
121
  #
122
122
  # === RubyVM::new(thread_object)
123
123
 
124
- # Like RubyVM::ThreadFrame.new(thread_object), but has additional information
124
+ # Like RubyVM::Frame.new(thread_object), but has additional information
125
125
  # available.
126
126
  #
127
- # === RubyVM::ThreadFrame#iseq
127
+ # === RubyVM::Frame#iseq
128
128
  # tf.iseq() -> ISeq
129
129
  #
130
130
  # Returns an instruction sequence object from the instruction sequence
131
- # found inside the +ThreadFrame+ object or +nil+ if there is none.
131
+ # found inside the +Frame+ object or +nil+ if there is none.
132
132
  # But if iseq is +nil+ and tf.type is not C, +binding+, and
133
133
  # +instruction_offset+, and +source_location+ are probably meaningless
134
134
  # and will be +nil+ as well.
135
135
  #
136
136
  #
137
- # === RubyVM::ThreadFrame#instruction_offset
137
+ # === RubyVM::Frame#instruction_offset
138
138
  # tf.instruction_offset -> Fixnum
139
139
  # Offset inside ISeq of instruction that the frame is currently on.
140
140
  #
141
- # === RubyVM::ThreadFrame#instruction_offset=
141
+ # === RubyVM::Frame#instruction_offset=
142
142
  #
143
143
  # tf.instruction_offset=(Fixnum)
144
144
  # Sets the threadframe to a new offset. Some restrictions may apply, e.g.
@@ -147,7 +147,7 @@
147
147
  #
148
148
  # <em>Don't need to implement initially.</em>
149
149
  #
150
- # === RubyVM::ThreadFrame#return_changed?
150
+ # === RubyVM::Frame#return_changed?
151
151
  # tf.return_changed?() -> boolean
152
152
  #
153
153
  # Returns true if tf _may_ be part of tail recursion removal so when
@@ -160,4 +160,4 @@
160
160
  # = THANKS
161
161
  #
162
162
  # Martin Davis for suggesting
163
- # RubyVM::ThreadFrame#new == Thread::current.threadframe
163
+ # RubyVM::Frame#new == Thread::current.threadframe
metadata CHANGED
@@ -1,33 +1,29 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rb-threadframe
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 39
8
- version: "0.39"
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.40'
5
+ prerelease:
9
6
  platform: ruby
10
- authors:
7
+ authors:
11
8
  - R. Bernstein
12
9
  autorequire:
13
10
  bindir: bin
14
11
  cert_chain: []
15
-
16
- date: 2011-10-27 00:00:00 -04:00
17
- default_executable:
12
+ date: 2012-11-25 00:00:00.000000000 Z
18
13
  dependencies: []
14
+ description: ! '
15
+
16
+ rb-threadframe gives introspection access for frames of a thread.
19
17
 
20
- description: "\n\
21
- rb-threadframe gives introspection access for frames of a thread.\n"
18
+ '
22
19
  email: rockyb@rubyforge.net
23
20
  executables: []
24
-
25
- extensions:
21
+ extensions:
26
22
  - ext/extconf.rb
27
- extra_rdoc_files:
23
+ extra_rdoc_files:
28
24
  - README.md
29
25
  - threadframe.rd
30
- files:
26
+ files:
31
27
  - README.md
32
28
  - Rakefile
33
29
  - Makefile
@@ -40,78 +36,56 @@ files:
40
36
  - include/vm_core_mini.h
41
37
  - lib/iseq_extra.rb
42
38
  - lib/thread_frame.rb
43
- - ext/iseq_extra.c
44
- - ext/thread_frame.c
45
- - ext/proc_extra.c
46
- - ext/thread_extra.c
47
- - ext/thread_frame.h
48
- - ext/proc_extra.h
49
- - ext/thread_pthread.h
50
- - ext/node.h
51
- - ext/thread_extra.h
52
- - ext/iseq_extra.h
53
- - ext/iseq_mini.h
39
+ - ext/1.9.3/thread_frame.c
40
+ - ext/version.h
54
41
  - test/unit/test-trace.rb
55
42
  - test/unit/test-iseq-save.rb
56
43
  - test/unit/test-prev.rb
57
44
  - test/unit/test-source.rb
58
45
  - test/unit/test-lib-iseq.rb
59
46
  - test/unit/test-return-stop.rb
47
+ - test/unit/test-frame.rb
60
48
  - test/unit/test-proc.rb
61
49
  - test/unit/test-invalid.rb
62
50
  - test/unit/test-argc.rb
63
51
  - test/unit/cfunc-use.rb
64
52
  - test/unit/test-binding.rb
65
53
  - test/unit/test-lib-iseq-extra.rb
66
- - test/unit/test-thread.rb
67
54
  - test/unit/test-iseq-brkpt.rb
68
55
  - test/unit/test-iseq.rb
69
56
  - test/unit/test-thread-trace-masks.rb
70
57
  - test/unit/test-settracefunc.rb
71
58
  - test/unit/test-sp-size.rb
72
- - test/ruby/test_disasm.rb
73
- - test/ruby/test_iseq.rb
74
- - test/ruby/test_brkpt.rb
75
59
  - test/ruby/test_tracefunc_adds.rb
76
- - test/ruby/test_tracefunc_raise.rb
77
60
  - threadframe.rd
78
61
  - ext/extconf.rb
79
- has_rdoc: true
80
62
  homepage: http://github.com/rocky/rb-threadframe/tree/master
81
- licenses:
63
+ licenses:
82
64
  - MIT
83
65
  post_install_message:
84
- rdoc_options:
66
+ rdoc_options:
85
67
  - --main
86
68
  - README.md
87
69
  - --title
88
- - ThreadFrame 0.39 Documentation
89
- require_paths:
70
+ - ThreadFrame 0.40 Documentation
71
+ require_paths:
90
72
  - lib
91
- required_ruby_version: !ruby/object:Gem::Requirement
73
+ required_ruby_version: !ruby/object:Gem::Requirement
92
74
  none: false
93
- requirements:
94
- - - ~>
95
- - !ruby/object:Gem::Version
96
- segments:
97
- - 1
98
- - 9
99
- - 2frame
100
- version: 1.9.2frame
101
- required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
80
  none: false
103
- requirements:
104
- - - ">="
105
- - !ruby/object:Gem::Version
106
- segments:
107
- - 0
108
- version: "0"
81
+ requirements:
82
+ - - ! '>='
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
109
85
  requirements: []
110
-
111
86
  rubyforge_project:
112
- rubygems_version: 1.3.7
87
+ rubygems_version: 1.8.23
113
88
  signing_key:
114
89
  specification_version: 3
115
90
  summary: Frame introspection
116
91
  test_files: []
117
-
data/ext/iseq_extra.c DELETED
@@ -1,441 +0,0 @@
1
- /*
2
- * Copyright (C) 2010 Rocky Bernstein
3
- */
4
- #if 0 /* The following is to fake out rdoc, until I find a better fix. */
5
- /*
6
- * Additions to the RubyVM::InstructionSequence class
7
- */
8
- VALUE rb_cIseq = rb_define_class_under(rb_cRubyVM, "InstructionSequence",
9
- rb_cObject);
10
- #endif
11
-
12
- #include "../include/vm_core_mini.h" /* Pulls in ruby.h and node.h */
13
- #include "iseq_mini.h" /* Pulls in ruby.h */
14
- #include "../include/ruby19_externs.h"
15
- #include <string.h> /* For strlen() */
16
-
17
- struct iseq_insn_info_entry {
18
- unsigned short position;
19
- unsigned short line_no;
20
- unsigned short sp;
21
- };
22
-
23
- #define COMPILE_OPTS_BOOL_SET_HASH(FIELD) \
24
- rb_hash_aset(hash_opts, rb_str_new2(#FIELD), \
25
- (compile_opts->FIELD) ? Qtrue : Qfalse)
26
-
27
- /*
28
- * Document-method: RubyVM::InstructionSequence::compile_options
29
- *
30
- * call-seq:
31
- * RubyVM::InstructionSequence#compile_options -> Hash
32
- *
33
- * Returns a hash of the compiler options used to create the
34
- * instruction sequence.
35
- */
36
- VALUE
37
- iseq_compile_options(VALUE iseqval)
38
- {
39
- rb_iseq_t *iseq;
40
- if (Qnil == iseqval) return Qnil;
41
- else {
42
- VALUE hash_opts = rb_hash_new();
43
- rb_compile_option_t *compile_opts;
44
- GetISeqPtr(iseqval, iseq);
45
- if (!iseq->compile_data) return Qnil;
46
- compile_opts = iseq->compile_data->option;
47
- COMPILE_OPTS_BOOL_SET_HASH(inline_const_cache);
48
- COMPILE_OPTS_BOOL_SET_HASH(peephole_optimization);
49
- COMPILE_OPTS_BOOL_SET_HASH(tailcall_optimization);
50
- COMPILE_OPTS_BOOL_SET_HASH(specialized_instruction);
51
- COMPILE_OPTS_BOOL_SET_HASH(operands_unification);
52
- COMPILE_OPTS_BOOL_SET_HASH(stack_caching);
53
- COMPILE_OPTS_BOOL_SET_HASH(trace_instruction);
54
- COMPILE_OPTS_BOOL_SET_HASH(debug_level);
55
- COMPILE_OPTS_BOOL_SET_HASH(save_tree_node);
56
- COMPILE_OPTS_BOOL_SET_HASH(save_compile_opts);
57
- return hash_opts;
58
- }
59
- }
60
-
61
- /*
62
- * Document-method: RubyVM::InstructionSequence::encoded
63
- *
64
- * call-seq:
65
- * RubyVM::InstructionSequence#iseq_encoded -> String
66
- *
67
- * Returns a string of the encoded bytes of the instruction
68
- * sequence. Note that this is probably not usable as is, may be useful in
69
- * decoding instructions (using other info) or for getting a sha1
70
- * checksum.
71
- */
72
- VALUE
73
- iseq_iseq_encoded(VALUE iseqval)
74
- {
75
- rb_iseq_t *iseq;
76
- GetISeqPtr(iseqval, iseq);
77
- return rb_str_new((char *) iseq->iseq_encoded, iseq->iseq_size);
78
- }
79
-
80
-
81
- /*
82
- * Document-method: RubyVM::InstructionSequence::equal?
83
- *
84
- * call-seq:
85
- * RubyVM::InstructionSequence#equal?(iseq2) -> bool
86
- *
87
- * Returns true if the instruction sequences are equal.
88
- */
89
- VALUE
90
- iseq_equal(VALUE iseqval1, VALUE iseqval2)
91
- {
92
- rb_iseq_t *iseq1, *iseq2;
93
-
94
- if (Qnil == iseqval2) return Qfalse;
95
- if (!rb_obj_is_kind_of(iseqval2, rb_cISeq)) {
96
- rb_raise(rb_eTypeError,
97
- "comparison argument must be an instance of %s or nil (is %s)",
98
- rb_obj_classname(iseqval1), rb_obj_classname(iseqval2));
99
- }
100
-
101
- if (iseqval1 == iseqval2) return Qtrue;
102
- GetISeqPtr(iseqval1, iseq1);
103
- GetISeqPtr(iseqval2, iseq2);
104
-
105
- /* FIXME: the count 28 below is bogus. I think this should be the fields
106
- from "type" to "mark_ary". Should also include iseq->encoded.
107
- */
108
- if (0 == memcmp(iseq1, iseq2, 28))
109
- return Qtrue;
110
- else
111
- return Qfalse;
112
- }
113
-
114
- VALUE
115
- iseq_parent(VALUE self)
116
- {
117
- rb_iseq_t *piseq;
118
- rb_iseq_t *parent_iseq;
119
- VALUE parent_iseqval;
120
- GetISeqPtr(self, piseq);
121
-
122
- if (!RTEST(piseq->parent_iseq)) return Qnil;
123
- parent_iseqval = iseq_alloc_shared(rb_cISeq);
124
- GetISeqPtr(parent_iseqval, parent_iseq);
125
- memcpy(parent_iseq, piseq->parent_iseq, sizeof(struct rb_iseq_struct));
126
- return parent_iseqval;
127
- }
128
-
129
- VALUE
130
- iseq_local_iseq(VALUE self)
131
- {
132
- rb_iseq_t *piseq;
133
- rb_iseq_t *local_iseq;
134
- VALUE local_iseqval;
135
- GetISeqPtr(self, piseq);
136
-
137
- if (!RTEST(piseq->local_iseq)) return Qnil;
138
- local_iseqval = iseq_alloc_shared(rb_cISeq);
139
- GetISeqPtr(local_iseqval, local_iseq);
140
- memcpy(local_iseq, piseq->local_iseq, sizeof(struct rb_iseq_struct));
141
- return local_iseqval;
142
- }
143
-
144
- /*
145
- * call-seq:
146
- * RubyVM::InstructionSequence#local_name(i) - String
147
- *
148
- * Returns the string name of local variable in i'th position
149
- * of the instruction sequence local table, or nil if i is
150
- * out of range.
151
- */
152
- VALUE
153
- iseq_local_name(VALUE iseqval, VALUE val)
154
- {
155
- rb_iseq_t *iseq;
156
- if (FIXNUM_P(val)) {
157
- long int i = FIX2INT(val);
158
- long int size;
159
-
160
- GetISeqPtr(iseqval, iseq);
161
-
162
- size = iseq->local_table_size;
163
-
164
- if (i < 0) i = size + i;
165
-
166
- if (i >= size)
167
- rb_raise(rb_eIndexError,
168
- "local table index %ld should be in the range -%ld .. %ld",
169
- i, size, size-1);
170
-
171
- return rb_str_new2(rb_id2name(iseq->local_table[i]));
172
- } else {
173
- rb_raise(rb_eTypeError, "type mismatch: %s given, Fixnum expected",
174
- rb_class2name(CLASS_OF(val)));
175
- }
176
- /* not reached. */
177
- return Qnil;
178
- }
179
-
180
- /*
181
- * call-seq:
182
- * RubyVM::InstructionSequence#name -> String
183
- *
184
- * Returns the name if the instruction sequence.
185
- */
186
- VALUE
187
- iseq_name(VALUE iseqval)
188
- {
189
- rb_iseq_t *iseq;
190
- GetISeqPtr(iseqval, iseq);
191
- return(iseq->name);
192
- }
193
-
194
- /*
195
- * call-seq:
196
- * RubyVM::InstructionSequence#offsetlines -> Hash[Fixnum] -> [Fixnum]
197
- *
198
- * Returns an hash. The keys in the hash form the VM offsets of the
199
- * instructions. The value of the hash for a given offset is a list
200
- * of line numbers associated with that offset.
201
- */
202
- VALUE iseq_offsetlines(VALUE iseqval)
203
- {
204
- rb_iseq_t *iseq;
205
- VALUE offsetlines = rb_hash_new();
206
- unsigned long i, size;
207
- struct iseq_insn_info_entry *table;
208
-
209
- GetISeqPtr(iseqval, iseq);
210
-
211
- size = iseq->insn_info_size;
212
- table = iseq->insn_info_table;
213
-
214
- for (i = 0; i < size; i++) {
215
- VALUE ary = rb_ary_new2(1);
216
- rb_ary_push(ary, INT2FIX(table[i].line_no));
217
- rb_hash_aset(offsetlines, INT2FIX(table[i].position), ary);
218
- }
219
- return offsetlines;
220
- }
221
-
222
- /*
223
- * call-seq:
224
- * RubyVM::InstructionSequence#offset2lines(offset) -> [Fixnum]
225
- *
226
- * Returns an Array or nil. If offset is found then return the list of
227
- * lines associated with that offset. If the offset isn't found return nil.
228
- */
229
- VALUE iseq_offset2lines(VALUE iseqval, VALUE offsetval)
230
- {
231
- rb_iseq_t *iseq;
232
-
233
- GetISeqPtr(iseqval, iseq);
234
-
235
- if (FIXNUM_P(offsetval)) {
236
- unsigned long i, size;
237
- int offset = FIX2INT(offsetval);
238
- struct iseq_insn_info_entry *table;
239
-
240
- size = iseq->insn_info_size;
241
- table = iseq->insn_info_table;
242
-
243
- for (i = 0; i < size; i++) {
244
- if (table[i].position == offset) {
245
- VALUE ary = rb_ary_new2(1);
246
- rb_ary_push(ary, INT2FIX(table[i].line_no));
247
- return ary;
248
- }
249
- }
250
- }
251
- return Qnil;
252
- }
253
-
254
- /* FIXME: should return array of destroyed entries */
255
- VALUE iseq_killcache(VALUE iseqval)
256
- {
257
- rb_iseq_t *iseqdat;
258
- VALUE *iseq ;
259
- unsigned long i, size, count = 0;
260
- struct iseq_insn_info_entry *table;
261
-
262
- GetISeqPtr(iseqval, iseqdat);
263
- iseq = iseqdat->iseq;
264
- size = iseqdat->insn_info_size;
265
- table = iseqdat->insn_info_table;
266
- for (i = 0; i < size; i++) {
267
- const unsigned long pos = table[i].position;
268
- const VALUE insn = iseq[pos];
269
- if (0 == strncmp(insn_name(insn), "getinlinecache",
270
- sizeof("getinlinecache")))
271
- {
272
- /* printf("pos: %lu\n", pos); */
273
- count ++;
274
- iseq[pos] = 0;
275
- iseq[pos+1] = 0;
276
- iseq[pos+2] = 0;
277
- }
278
- }
279
- return INT2FIX(count);
280
- }
281
-
282
- const char *
283
- source_container_type(VALUE fileval)
284
- {
285
- const char *filename = RSTRING_PTR(fileval);
286
- size_t len = strlen(filename);
287
-
288
- /* FIXME: Looking for (...) is a hack that I would love to know how
289
- to remove. Probably Ruby has to be changed to record this kind
290
- of information.
291
- */
292
- if (len > 0 &&
293
- ((filename[0] == '(' && filename[len-1] == ')')
294
- || 0 == strncmp(filename, "<compiled>",
295
- sizeof("<compiled>"))))
296
- return "string";
297
- else
298
- return "file";
299
- }
300
-
301
-
302
- VALUE
303
- iseq_source_container_internal(rb_iseq_t *iseq)
304
- {
305
- VALUE fileval = iseq->filename;
306
- const char *contain_type = source_container_type(fileval);
307
-
308
- return rb_ary_new3(2, rb_str_new2(contain_type), fileval);
309
- }
310
-
311
- /*
312
- * call-seq:
313
- * RubyVM::InstructionSequence#source_container() -> [Type, String]
314
- *
315
- * Returns a tuple representing kind of container, e.g. file
316
- * eval'd string object, and the name of the container. If file,
317
- * it would be a file name. If an eval'd string it might be the string.
318
- */
319
- static VALUE
320
- iseq_source_container(VALUE iseqval)
321
- {
322
- rb_iseq_t *iseq;
323
-
324
- if (Qnil == iseqval) return Qnil;
325
- GetISeqPtr(iseqval, iseq);
326
- return iseq_source_container_internal(iseq);
327
- }
328
-
329
-
330
- #if 0
331
- /*
332
- * call-seq:
333
- * RubyVM::InstructionSequence#type() -> Fixnum
334
- *
335
- * Returns instruction-sequence type.
336
- */
337
- static VALUE
338
- iseq_type(VALUE iseqval)
339
- #endif
340
-
341
- #define ISEQ_FIELD_METHOD(FIELD) \
342
- static VALUE \
343
- iseq_##FIELD(VALUE iseqval) \
344
- { \
345
- rb_iseq_t *iseq; \
346
- if (Qnil == iseqval) return Qnil; \
347
- GetISeqPtr(iseqval, iseq); \
348
- return iseq->FIELD; \
349
- }
350
-
351
- ISEQ_FIELD_METHOD(orig) ;
352
- ISEQ_FIELD_METHOD(self) ;
353
- ISEQ_FIELD_METHOD(type) ;
354
-
355
- #define ISEQ_INT_FIELD_METHOD(FIELD) \
356
- extern VALUE \
357
- iseq_##FIELD(VALUE iseqval) \
358
- { \
359
- rb_iseq_t *iseq; \
360
- GetISeqPtr(iseqval, iseq); \
361
- return INT2FIX(iseq->FIELD); \
362
- }
363
-
364
- ISEQ_INT_FIELD_METHOD(arg_block) ;
365
- ISEQ_INT_FIELD_METHOD(arg_opts) ;
366
- ISEQ_INT_FIELD_METHOD(arg_post_len) ;
367
- ISEQ_INT_FIELD_METHOD(arg_rest) ;
368
- ISEQ_INT_FIELD_METHOD(arg_simple) ;
369
- ISEQ_INT_FIELD_METHOD(argc) ;
370
- ISEQ_INT_FIELD_METHOD(iseq_size) ;
371
- ISEQ_INT_FIELD_METHOD(klass) ;
372
- ISEQ_INT_FIELD_METHOD(line_no) ;
373
- ISEQ_INT_FIELD_METHOD(local_size) ;
374
- ISEQ_INT_FIELD_METHOD(local_table_size) ;
375
-
376
- /*
377
- * call-seq:
378
- * RubyVM::InstructionSequence#line_range() -> Range
379
- *
380
- * Returns a range containing the starting line number and the
381
- * ending line of the source code for the instruction-sequence.
382
- */
383
- static VALUE
384
- iseq_line_range(VALUE iseqval)
385
- {
386
- rb_iseq_t *iseq;
387
-
388
- GetISeqPtr(iseqval, iseq);
389
- if (Qnil == iseqval) return Qnil;
390
- else {
391
- unsigned long i, size = iseq->insn_info_size;
392
- struct iseq_insn_info_entry *table = iseq->insn_info_table;
393
- unsigned short min_line = table[0].line_no;
394
- unsigned short max_line = table[0].line_no;
395
-
396
- for (i = 0; i < size; i++) {
397
- if (table[i].line_no < min_line)
398
- min_line = table[i].line_no;
399
- else if (table[i].line_no > max_line)
400
- max_line = table[i].line_no;
401
- }
402
- return rb_range_new(INT2FIX(min_line), INT2FIX(max_line), 0);
403
- }
404
- }
405
-
406
-
407
- /* RDoc can't find methods when we use a definition like this: */
408
- #define RB_DEFINE_ISEQ_METHOD(FIELD, ARGC) \
409
- rb_define_method(rb_cISeq, #FIELD, iseq_##FIELD, ARGC);
410
-
411
- void
412
- Init_iseq_extra(void)
413
- {
414
- rb_define_method(rb_cISeq, "arg_block", iseq_arg_block, 0) ;
415
- rb_define_method(rb_cISeq, "arg_opts", iseq_arg_opts, 0) ;
416
- rb_define_method(rb_cISeq, "arg_post_len", iseq_arg_post_len, 0) ;
417
- rb_define_method(rb_cISeq, "arg_rest", iseq_arg_rest, 0) ;
418
- rb_define_method(rb_cISeq, "arg_simple", iseq_arg_simple, 0) ;
419
- rb_define_method(rb_cISeq, "argc", iseq_argc, 0) ;
420
- rb_define_method(rb_cISeq, "compile_options", iseq_compile_options, 0) ;
421
- rb_define_method(rb_cISeq, "equal?", iseq_equal, 1) ;
422
- rb_define_method(rb_cISeq, "encoded", iseq_iseq_encoded, 0) ;
423
- rb_define_method(rb_cISeq, "iseq_size", iseq_iseq_size, 0) ;
424
- rb_define_method(rb_cISeq, "killcache", iseq_killcache, 0) ;
425
- rb_define_method(rb_cISeq, "klass", iseq_klass, 0) ;
426
- rb_define_method(rb_cISeq, "lineno", iseq_line_no, 0) ;
427
- rb_define_method(rb_cISeq, "line_range", iseq_line_range, 0) ;
428
- rb_define_method(rb_cISeq, "local_iseq", iseq_local_iseq, 0) ;
429
- rb_define_method(rb_cISeq, "local_name", iseq_local_name, 1) ;
430
- rb_define_method(rb_cISeq, "local_size", iseq_local_size, 0) ;
431
- rb_define_method(rb_cISeq, "local_table_size", iseq_local_table_size, 0) ;
432
- rb_define_method(rb_cISeq, "offset2lines", iseq_offset2lines, 1) ;
433
- rb_define_method(rb_cISeq, "offsetlines", iseq_offsetlines, 0) ;
434
- rb_define_method(rb_cISeq, "orig", iseq_orig, 0) ;
435
- rb_define_method(rb_cISeq, "parent", iseq_parent, 0) ;
436
- rb_define_method(rb_cISeq, "name", iseq_name, 0) ;
437
- rb_define_method(rb_cISeq, "self", iseq_self, 0) ;
438
- rb_define_method(rb_cISeq, "source_container", iseq_source_container, 0) ;
439
- rb_define_method(rb_cISeq, "type", iseq_type, 0) ;
440
-
441
- }