rb-threadframe 0.39 → 0.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
- }