flaw_detector 0.0.1 → 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: af3e76154f18c212c10a2a6a3d4d107f64618255
4
+ data.tar.gz: 42d43bb6c926ad0ee08e07a4fda53b841613eef3
5
+ SHA512:
6
+ metadata.gz: 9bc4863341aeb50d5ee24209ae6997ab84ec155a9800d1adc5a150746e64f7cb12c5a0d962765526c3f833b808a940042377abbd835be22b3a78390392e0476e
7
+ data.tar.gz: 51a0e99b72ba5e61984856e288874431269ae84e32220f90bea7c843d44ab21d1a2c8ae74a487e276472ee2d5d0d7f93e470d93738101ba42425a3199ec7dd75
data/README.md CHANGED
@@ -1,4 +1,64 @@
1
- flaw_detector
1
+ FlawDetector [![Build Status](https://secure.travis-ci.org/ginriki/flaw_detector.png)][Continuous Integration]
2
2
  =============
3
+ FlawDetector is a tool to detect ruby code's flaw with static analysis.
4
+ In static analysis, it analyze RubyVM bytecode which is compiled from ruby code.
3
5
 
4
- The tool to detect code's flaw with static analysis
6
+ FlawDetector is similer to FindBugs which is a tool to detect java code's flaw.
7
+ For details of FindBugs, refer to references section in this text file.
8
+
9
+ [Continuous Integration]: http://travis-ci.org/ginriki/flaw_detector
10
+
11
+ Getting Started
12
+ -------
13
+ ```shell
14
+ $ gem install flaw_detector
15
+ ```
16
+
17
+ Usage
18
+ -------
19
+ ```shell
20
+ flaw_detector [-f outfille] [--help] rbfile ...
21
+ ```
22
+
23
+ Example
24
+ -------
25
+ ```shell
26
+ $ flaw_detector -f result.csv sample/flaw_in_code.rb
27
+ ```
28
+
29
+ Command Result
30
+ -------
31
+ Currently, FlawDetector supports only CSV format result.
32
+ Result example is as follows:
33
+ ```file
34
+ $ cat result.csv
35
+ msgid,file,line,short_desc,long_desc,details
36
+ RCN_REDUNDANT_FALSECHECK_OF_FALSE_VALUE,sample/flaw_in_code.rb,4,Redundant falsecheck of value known to be false,Redundant falsecheck of a which is known to be false in LINE:2,This method contains a redundant check of a known false value against the constant false.
37
+ NP_ALWAYS_FALSE,sample/flaw_in_code.rb,7,False value missing method received,False value missing method received in a,"A false value, which is NilClass or FalseClass, is received missing method here. This will lead to a NoMethodError when the code is executed."
38
+ ```
39
+
40
+ Each line represents a flaw.
41
+ If you want to know how flaw can be shown in result,
42
+ refer to [message.rb](https://github.com/ginriki/flaw_detector/blob/master/lib/flaw_detector/message.rb)
43
+
44
+ Fix and Recheck
45
+ ------
46
+ According to the result, you should fix source code and recheck it by FlawDetector until "OK" is displaied
47
+ ```file
48
+ $ emacs sample/flaw_in_code.rb
49
+ $ cat sample/flaw_in_code.rb
50
+ def no_flaw(a)
51
+ if a
52
+ rl = a + 1
53
+ else
54
+ rl = a.to_i + 1
55
+ end
56
+ end
57
+ $ flaw_detector sample/flaw_in_code.rb
58
+ OK
59
+ $
60
+ ```
61
+
62
+ References
63
+ ------
64
+ * http://findbugs.sourceforge.net/findbugs2.html
@@ -1,2 +1,2 @@
1
1
  require 'mkmf'
2
- create_makefile("insns_ext")
2
+ create_makefile("insns_ext", "insns/#{RUBY_VERSION[0..2]}")
@@ -3,5 +3,37 @@ module InsnExt
3
3
  def insn_num(insn_name)
4
4
  return RubyVM::INSTRUCTION_NAMES.index(insn_name.to_s)
5
5
  end
6
- module_function :insn_num
6
+
7
+ # @todo refactoring from c-function to pure ruby function
8
+ alias :_insn_stack_increase :insn_stack_increase
9
+
10
+ if RUBY_VERSION =~ /^2.0/
11
+ VM_CALL_ARGS_BLOCKARG = (0x01 ** 2)
12
+
13
+ # Override for substitution of CALL_INFO cast
14
+ # in c-function@insns_info.inc
15
+ def insn_stack_increase(opcode_index, ary)
16
+ call_info = [:send, :invokesuper, :opt_send_simple, :invokeblock]
17
+ name = RubyVM::INSTRUCTION_NAMES[opcode_index].to_sym
18
+ unless call_info.include?(name)
19
+ return _insn_stack_increase(opcode_index, ary)
20
+ else
21
+ case name
22
+ when :opt_send_simple
23
+ inc = -ary[0][:orig_argc]
24
+ when :invokeblock
25
+ inc = 1-ary[0][:orig_argc]
26
+ when :send, :invokesuper
27
+ inc = -ary[0][:orig_argc]
28
+ inc += -1 if (ary[0][:flag] & VM_CALL_ARGS_BLOCKARG) != 0
29
+ else
30
+ raise "unknown state"
31
+ end
32
+ return inc
33
+ end
34
+ end
35
+ else
36
+ #don't need to override insn_stack_increase
37
+ end
38
+ module_function :insn_num, :insn_stack_increase, :_insn_stack_increase
7
39
  end
@@ -0,0 +1,22 @@
1
+ Copyright (C) 1993-2010 Yukihiro Matsumoto. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+ 1. Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ 2. Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ SUCH DAMAGE.
File without changes
@@ -9,18 +9,18 @@
9
9
  or insns2vm.rb
10
10
  */
11
11
 
12
+ #define TS_ISEQ 'S'
13
+ #define TS_GENTRY 'G'
12
14
  #define TS_OFFSET 'O'
13
- #define TS_NUM 'N'
14
- #define TS_LINDEX 'L'
15
15
  #define TS_DINDEX 'D'
16
- #define TS_VALUE 'V'
17
- #define TS_ID 'I'
18
- #define TS_GENTRY 'G'
19
- #define TS_IC 'C'
20
- #define TS_CDHASH 'H'
21
- #define TS_ISEQ 'S'
22
16
  #define TS_VARIABLE '.'
17
+ #define TS_CDHASH 'H'
18
+ #define TS_IC 'C'
19
+ #define TS_ID 'I'
23
20
  #define TS_FUNCPTR 'F'
21
+ #define TS_VALUE 'V'
22
+ #define TS_LINDEX 'L'
23
+ #define TS_NUM 'N'
24
24
 
25
25
  static const char *const insn_name_info[] = {
26
26
  "nop",
@@ -110,8 +110,8 @@ static const char *const insn_operand_info[] = {
110
110
  "",
111
111
  "L",
112
112
  "L",
113
- "VN",
114
- "V",
113
+ "NN",
114
+ "N",
115
115
  "DN",
116
116
  "DN",
117
117
  "IC",
@@ -0,0 +1,22 @@
1
+ Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+ 1. Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ 2. Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
13
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
14
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
15
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
21
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
22
+ SUCH DAMAGE.
@@ -0,0 +1,187 @@
1
+ /** -*-c-*-
2
+ This file contains YARV instructions list.
3
+
4
+ ----
5
+ This file is auto generated by insns2vm.rb
6
+ DO NOT TOUCH!
7
+
8
+ If you want to fix something, you must edit 'template/insns.inc.tmpl'
9
+ or insns2vm.rb
10
+ */
11
+
12
+
13
+ /* BIN : Basic Instruction Name */
14
+ #define BIN(n) YARVINSN_##n
15
+
16
+ enum ruby_vminsn_type {
17
+ BIN(nop) = 0,
18
+
19
+ BIN(getlocal) = 1,
20
+
21
+ BIN(setlocal) = 2,
22
+
23
+ BIN(getspecial) = 3,
24
+
25
+ BIN(setspecial) = 4,
26
+
27
+ BIN(getinstancevariable) = 5,
28
+
29
+ BIN(setinstancevariable) = 6,
30
+
31
+ BIN(getclassvariable) = 7,
32
+
33
+ BIN(setclassvariable) = 8,
34
+
35
+ BIN(getconstant) = 9,
36
+
37
+ BIN(setconstant) = 10,
38
+
39
+ BIN(getglobal) = 11,
40
+
41
+ BIN(setglobal) = 12,
42
+
43
+ BIN(putnil) = 13,
44
+
45
+ BIN(putself) = 14,
46
+
47
+ BIN(putobject) = 15,
48
+
49
+ BIN(putspecialobject) = 16,
50
+
51
+ BIN(putiseq) = 17,
52
+
53
+ BIN(putstring) = 18,
54
+
55
+ BIN(concatstrings) = 19,
56
+
57
+ BIN(tostring) = 20,
58
+
59
+ BIN(toregexp) = 21,
60
+
61
+ BIN(newarray) = 22,
62
+
63
+ BIN(duparray) = 23,
64
+
65
+ BIN(expandarray) = 24,
66
+
67
+ BIN(concatarray) = 25,
68
+
69
+ BIN(splatarray) = 26,
70
+
71
+ BIN(newhash) = 27,
72
+
73
+ BIN(newrange) = 28,
74
+
75
+ BIN(pop) = 29,
76
+
77
+ BIN(dup) = 30,
78
+
79
+ BIN(dupn) = 31,
80
+
81
+ BIN(swap) = 32,
82
+
83
+ BIN(reput) = 33,
84
+
85
+ BIN(topn) = 34,
86
+
87
+ BIN(setn) = 35,
88
+
89
+ BIN(adjuststack) = 36,
90
+
91
+ BIN(defined) = 37,
92
+
93
+ BIN(checkmatch) = 38,
94
+
95
+ BIN(trace) = 39,
96
+
97
+ BIN(defineclass) = 40,
98
+
99
+ BIN(send) = 41,
100
+
101
+ BIN(opt_send_simple) = 42,
102
+
103
+ BIN(invokesuper) = 43,
104
+
105
+ BIN(invokeblock) = 44,
106
+
107
+ BIN(leave) = 45,
108
+
109
+ BIN(throw) = 46,
110
+
111
+ BIN(jump) = 47,
112
+
113
+ BIN(branchif) = 48,
114
+
115
+ BIN(branchunless) = 49,
116
+
117
+ BIN(getinlinecache) = 50,
118
+
119
+ BIN(onceinlinecache) = 51,
120
+
121
+ BIN(setinlinecache) = 52,
122
+
123
+ BIN(opt_case_dispatch) = 53,
124
+
125
+ BIN(opt_plus) = 54,
126
+
127
+ BIN(opt_minus) = 55,
128
+
129
+ BIN(opt_mult) = 56,
130
+
131
+ BIN(opt_div) = 57,
132
+
133
+ BIN(opt_mod) = 58,
134
+
135
+ BIN(opt_eq) = 59,
136
+
137
+ BIN(opt_neq) = 60,
138
+
139
+ BIN(opt_lt) = 61,
140
+
141
+ BIN(opt_le) = 62,
142
+
143
+ BIN(opt_gt) = 63,
144
+
145
+ BIN(opt_ge) = 64,
146
+
147
+ BIN(opt_ltlt) = 65,
148
+
149
+ BIN(opt_aref) = 66,
150
+
151
+ BIN(opt_aset) = 67,
152
+
153
+ BIN(opt_length) = 68,
154
+
155
+ BIN(opt_size) = 69,
156
+
157
+ BIN(opt_empty_p) = 70,
158
+
159
+ BIN(opt_succ) = 71,
160
+
161
+ BIN(opt_not) = 72,
162
+
163
+ BIN(opt_regexpmatch1) = 73,
164
+
165
+ BIN(opt_regexpmatch2) = 74,
166
+
167
+ BIN(opt_call_c_function) = 75,
168
+
169
+ BIN(bitblt) = 76,
170
+
171
+ BIN(answer) = 77,
172
+
173
+ BIN(getlocal_OP__WC__0) = 78,
174
+
175
+ BIN(getlocal_OP__WC__1) = 79,
176
+
177
+ BIN(setlocal_OP__WC__0) = 80,
178
+
179
+ BIN(setlocal_OP__WC__1) = 81,
180
+
181
+ BIN(putobject_OP_INT2FIX_O_0_C_) = 82,
182
+
183
+ BIN(putobject_OP_INT2FIX_O_1_C_) = 83,
184
+
185
+ VM_INSTRUCTION_SIZE = 84
186
+ };
187
+
@@ -0,0 +1,36 @@
1
+ #define USE_INSN_STACK_INCREASE
2
+ #define USE_INSN_RET_NUM
3
+ #include "ruby.h"
4
+
5
+ #include "vm_core_subset.h"
6
+ #include "insns.inc"
7
+ #include "insns_info.inc"
8
+
9
+ VALUE wrap_insn_len(VALUE self, VALUE insn)
10
+ {
11
+ int len = insn_len(FIX2INT(insn));
12
+ return INT2FIX(len);
13
+ }
14
+
15
+ VALUE wrap_insn_stack_increase(VALUE self, VALUE insn, VALUE ope_ary)
16
+ {
17
+ int inc = insn_stack_increase(0, FIX2INT(insn), RARRAY_PTR(ope_ary));
18
+ return INT2FIX(inc);
19
+ }
20
+
21
+ VALUE wrap_insn_ret_num(VALUE self, VALUE insn)
22
+ {
23
+ int ret_num = insn_ret_num(FIX2INT(insn));
24
+ return INT2FIX(ret_num);
25
+ }
26
+
27
+ void Init_insns_ext()
28
+ {
29
+ VALUE module;
30
+
31
+ module = rb_define_module("InsnExt");
32
+ rb_define_module_function(module, "insn_len", wrap_insn_len, 1);
33
+ rb_define_module_function(module, "insn_stack_increase", wrap_insn_stack_increase, 2);
34
+ rb_define_module_function(module, "insn_ret_num", wrap_insn_ret_num, 1);
35
+ }
36
+
@@ -0,0 +1,724 @@
1
+ /** -*-c-*-
2
+ This file contains instruction information for yarv instruction sequence.
3
+
4
+ ----
5
+ This file is auto generated by insns2vm.rb
6
+ DO NOT TOUCH!
7
+
8
+ If you want to fix something, you must edit 'template/insns_info.inc.tmpl'
9
+ or insns2vm.rb
10
+ */
11
+
12
+ #define TS_ISEQ 'S'
13
+ #define TS_GENTRY 'G'
14
+ #define TS_OFFSET 'O'
15
+ #define TS_CALLINFO 'C'
16
+ #define TS_VARIABLE '.'
17
+ #define TS_CDHASH 'H'
18
+ #define TS_IC 'K'
19
+ #define TS_ID 'I'
20
+ #define TS_FUNCPTR 'F'
21
+ #define TS_VALUE 'V'
22
+ #define TS_LINDEX 'L'
23
+ #define TS_NUM 'N'
24
+
25
+ static const char *const insn_name_info[] = {
26
+ "nop",
27
+ "getlocal",
28
+ "setlocal",
29
+ "getspecial",
30
+ "setspecial",
31
+ "getinstancevariable",
32
+ "setinstancevariable",
33
+ "getclassvariable",
34
+ "setclassvariable",
35
+ "getconstant",
36
+ "setconstant",
37
+ "getglobal",
38
+ "setglobal",
39
+ "putnil",
40
+ "putself",
41
+ "putobject",
42
+ "putspecialobject",
43
+ "putiseq",
44
+ "putstring",
45
+ "concatstrings",
46
+ "tostring",
47
+ "toregexp",
48
+ "newarray",
49
+ "duparray",
50
+ "expandarray",
51
+ "concatarray",
52
+ "splatarray",
53
+ "newhash",
54
+ "newrange",
55
+ "pop",
56
+ "dup",
57
+ "dupn",
58
+ "swap",
59
+ "reput",
60
+ "topn",
61
+ "setn",
62
+ "adjuststack",
63
+ "defined",
64
+ "checkmatch",
65
+ "trace",
66
+ "defineclass",
67
+ "send",
68
+ "opt_send_simple",
69
+ "invokesuper",
70
+ "invokeblock",
71
+ "leave",
72
+ "throw",
73
+ "jump",
74
+ "branchif",
75
+ "branchunless",
76
+ "getinlinecache",
77
+ "onceinlinecache",
78
+ "setinlinecache",
79
+ "opt_case_dispatch",
80
+ "opt_plus",
81
+ "opt_minus",
82
+ "opt_mult",
83
+ "opt_div",
84
+ "opt_mod",
85
+ "opt_eq",
86
+ "opt_neq",
87
+ "opt_lt",
88
+ "opt_le",
89
+ "opt_gt",
90
+ "opt_ge",
91
+ "opt_ltlt",
92
+ "opt_aref",
93
+ "opt_aset",
94
+ "opt_length",
95
+ "opt_size",
96
+ "opt_empty_p",
97
+ "opt_succ",
98
+ "opt_not",
99
+ "opt_regexpmatch1",
100
+ "opt_regexpmatch2",
101
+ "opt_call_c_function",
102
+ "bitblt",
103
+ "answer",
104
+ "getlocal_OP__WC__0",
105
+ "getlocal_OP__WC__1",
106
+ "setlocal_OP__WC__0",
107
+ "setlocal_OP__WC__1",
108
+ "putobject_OP_INT2FIX_O_0_C_",
109
+ "putobject_OP_INT2FIX_O_1_C_",
110
+
111
+ };
112
+
113
+ static const char *const insn_operand_info[] = {
114
+ "",
115
+ "LN",
116
+ "LN",
117
+ "NN",
118
+ "N",
119
+ "IK",
120
+ "IK",
121
+ "I",
122
+ "I",
123
+ "I",
124
+ "I",
125
+ "G",
126
+ "G",
127
+ "",
128
+ "",
129
+ "V",
130
+ "N",
131
+ "S",
132
+ "V",
133
+ "N",
134
+ "",
135
+ "NN",
136
+ "N",
137
+ "V",
138
+ "NN",
139
+ "",
140
+ "V",
141
+ "N",
142
+ "N",
143
+ "",
144
+ "",
145
+ "N",
146
+ "",
147
+ "",
148
+ "N",
149
+ "N",
150
+ "N",
151
+ "NVV",
152
+ "N",
153
+ "N",
154
+ "ISN",
155
+ "C",
156
+ "C",
157
+ "C",
158
+ "C",
159
+ "",
160
+ "N",
161
+ "O",
162
+ "O",
163
+ "O",
164
+ "OK",
165
+ "OK",
166
+ "K",
167
+ "HO",
168
+ "C",
169
+ "C",
170
+ "C",
171
+ "C",
172
+ "C",
173
+ "C",
174
+ "CC",
175
+ "C",
176
+ "C",
177
+ "C",
178
+ "C",
179
+ "C",
180
+ "C",
181
+ "C",
182
+ "C",
183
+ "C",
184
+ "C",
185
+ "C",
186
+ "C",
187
+ "V",
188
+ "",
189
+ "F",
190
+ "",
191
+ "",
192
+ "L",
193
+ "L",
194
+ "L",
195
+ "L",
196
+ "",
197
+ "",
198
+
199
+ };
200
+
201
+ static const int insn_len_info[] = {
202
+ 1,
203
+ 3,
204
+ 3,
205
+ 3,
206
+ 2,
207
+ 3,
208
+ 3,
209
+ 2,
210
+ 2,
211
+ 2,
212
+ 2,
213
+ 2,
214
+ 2,
215
+ 1,
216
+ 1,
217
+ 2,
218
+ 2,
219
+ 2,
220
+ 2,
221
+ 2,
222
+ 1,
223
+ 3,
224
+ 2,
225
+ 2,
226
+ 3,
227
+ 1,
228
+ 2,
229
+ 2,
230
+ 2,
231
+ 1,
232
+ 1,
233
+ 2,
234
+ 1,
235
+ 1,
236
+ 2,
237
+ 2,
238
+ 2,
239
+ 4,
240
+ 2,
241
+ 2,
242
+ 4,
243
+ 2,
244
+ 2,
245
+ 2,
246
+ 2,
247
+ 1,
248
+ 2,
249
+ 2,
250
+ 2,
251
+ 2,
252
+ 3,
253
+ 3,
254
+ 2,
255
+ 3,
256
+ 2,
257
+ 2,
258
+ 2,
259
+ 2,
260
+ 2,
261
+ 2,
262
+ 3,
263
+ 2,
264
+ 2,
265
+ 2,
266
+ 2,
267
+ 2,
268
+ 2,
269
+ 2,
270
+ 2,
271
+ 2,
272
+ 2,
273
+ 2,
274
+ 2,
275
+ 2,
276
+ 1,
277
+ 2,
278
+ 1,
279
+ 1,
280
+ 2,
281
+ 2,
282
+ 2,
283
+ 2,
284
+ 1,
285
+ 1,
286
+
287
+ };
288
+
289
+ #ifdef USE_INSN_RET_NUM
290
+ static const int insn_stack_push_num_info[] = {
291
+ 0,
292
+ 1,
293
+ 0,
294
+ 1,
295
+ 0,
296
+ 1,
297
+ 0,
298
+ 1,
299
+ 0,
300
+ 1,
301
+ 0,
302
+ 1,
303
+ 0,
304
+ 1,
305
+ 1,
306
+ 1,
307
+ 1,
308
+ 1,
309
+ 1,
310
+ 1,
311
+ 1,
312
+ 1,
313
+ 1,
314
+ 1,
315
+ 1,
316
+ 1,
317
+ 1,
318
+ 1,
319
+ 1,
320
+ 0,
321
+ 2,
322
+ 1,
323
+ 2,
324
+ 1,
325
+ 1,
326
+ 1,
327
+ 1,
328
+ 1,
329
+ 1,
330
+ 0,
331
+ 1,
332
+ 1,
333
+ 1,
334
+ 1,
335
+ 1,
336
+ 1,
337
+ 1,
338
+ 0,
339
+ 0,
340
+ 0,
341
+ 1,
342
+ 1,
343
+ 1,
344
+ 0,
345
+ 1,
346
+ 1,
347
+ 1,
348
+ 1,
349
+ 1,
350
+ 1,
351
+ 1,
352
+ 1,
353
+ 1,
354
+ 1,
355
+ 1,
356
+ 1,
357
+ 1,
358
+ 1,
359
+ 1,
360
+ 1,
361
+ 1,
362
+ 1,
363
+ 1,
364
+ 1,
365
+ 1,
366
+ 0,
367
+ 1,
368
+ 1,
369
+ 1,
370
+ 1,
371
+ 0,
372
+ 0,
373
+ 1,
374
+ 1,
375
+
376
+ };
377
+ #endif
378
+
379
+ #ifdef USE_INSN_STACK_INCREASE
380
+ static int
381
+ insn_stack_increase(int depth, int insn, VALUE *opes)
382
+ {
383
+ switch(insn){
384
+ case BIN(nop):{
385
+ return depth + 0;
386
+ }
387
+ case BIN(getlocal):{
388
+ return depth + 1;
389
+ }
390
+ case BIN(setlocal):{
391
+ return depth + -1;
392
+ }
393
+ case BIN(getspecial):{
394
+ return depth + 1;
395
+ }
396
+ case BIN(setspecial):{
397
+ return depth + -1;
398
+ }
399
+ case BIN(getinstancevariable):{
400
+ return depth + 1;
401
+ }
402
+ case BIN(setinstancevariable):{
403
+ return depth + -1;
404
+ }
405
+ case BIN(getclassvariable):{
406
+ return depth + 1;
407
+ }
408
+ case BIN(setclassvariable):{
409
+ return depth + -1;
410
+ }
411
+ case BIN(getconstant):{
412
+ return depth + 0;
413
+ }
414
+ case BIN(setconstant):{
415
+ return depth + -2;
416
+ }
417
+ case BIN(getglobal):{
418
+ return depth + 1;
419
+ }
420
+ case BIN(setglobal):{
421
+ return depth + -1;
422
+ }
423
+ case BIN(putnil):{
424
+ return depth + 1;
425
+ }
426
+ case BIN(putself):{
427
+ return depth + 1;
428
+ }
429
+ case BIN(putobject):{
430
+ return depth + 1;
431
+ }
432
+ case BIN(putspecialobject):{
433
+ return depth + 1;
434
+ }
435
+ case BIN(putiseq):{
436
+ return depth + 1;
437
+ }
438
+ case BIN(putstring):{
439
+ return depth + 1;
440
+ }
441
+ case BIN(concatstrings):{
442
+ int inc = 0;
443
+ int num = FIX2INT(opes[0]);
444
+ inc += 1 - num;;
445
+ return depth + inc;
446
+ }
447
+ case BIN(tostring):{
448
+ return depth + 0;
449
+ }
450
+ case BIN(toregexp):{
451
+ int inc = 0;
452
+ int cnt = FIX2INT(opes[1]);
453
+ inc += 1 - cnt;;
454
+ return depth + inc;
455
+ }
456
+ case BIN(newarray):{
457
+ int inc = 0;
458
+ int num = FIX2INT(opes[0]);
459
+ inc += 1 - num;;
460
+ return depth + inc;
461
+ }
462
+ case BIN(duparray):{
463
+ return depth + 1;
464
+ }
465
+ case BIN(expandarray):{
466
+ int inc = 0;
467
+ int num = FIX2INT(opes[0]);
468
+ int flag = FIX2INT(opes[1]);
469
+ inc += num - 1 + (flag & 1 ? 1 : 0);;
470
+ return depth + inc;
471
+ }
472
+ case BIN(concatarray):{
473
+ return depth + -1;
474
+ }
475
+ case BIN(splatarray):{
476
+ return depth + 0;
477
+ }
478
+ case BIN(newhash):{
479
+ int inc = 0;
480
+ int num = FIX2INT(opes[0]);
481
+ inc += 1 - num;;
482
+ return depth + inc;
483
+ }
484
+ case BIN(newrange):{
485
+ return depth + -1;
486
+ }
487
+ case BIN(pop):{
488
+ return depth + -1;
489
+ }
490
+ case BIN(dup):{
491
+ return depth + 1;
492
+ }
493
+ case BIN(dupn):{
494
+ int inc = 0;
495
+ int n = FIX2INT(opes[0]);
496
+ inc += n;;
497
+ return depth + inc;
498
+ }
499
+ case BIN(swap):{
500
+ return depth + 0;
501
+ }
502
+ case BIN(reput):{
503
+ int inc = 0;
504
+ inc += 0;;
505
+ return depth + inc;
506
+ }
507
+ case BIN(topn):{
508
+ int inc = 0;
509
+ inc += 1;;
510
+ return depth + inc;
511
+ }
512
+ case BIN(setn):{
513
+ int inc = 0;
514
+ inc += 0;
515
+ return depth + inc;
516
+ }
517
+ case BIN(adjuststack):{
518
+ int inc = 0;
519
+ int n = FIX2INT(opes[0]);
520
+ inc -= n;
521
+ return depth + inc;
522
+ }
523
+ case BIN(defined):{
524
+ return depth + 0;
525
+ }
526
+ case BIN(checkmatch):{
527
+ return depth + -1;
528
+ }
529
+ case BIN(trace):{
530
+ return depth + 0;
531
+ }
532
+ case BIN(defineclass):{
533
+ return depth + -1;
534
+ }
535
+ case BIN(send):{
536
+ int inc = 0;
537
+ CALL_INFO ci = (CALL_INFO)(opes[0]);
538
+ inc += - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG) ? 1 : 0));;
539
+ return depth + inc;
540
+ }
541
+ case BIN(opt_send_simple):{
542
+ int inc = 0;
543
+ CALL_INFO ci = (CALL_INFO)(opes[0]);
544
+ inc += -ci->orig_argc;;
545
+ return depth + inc;
546
+ }
547
+ case BIN(invokesuper):{
548
+ int inc = 0;
549
+ CALL_INFO ci = (CALL_INFO)(opes[0]);
550
+ inc += - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG) ? 1 : 0));;
551
+ return depth + inc;
552
+ }
553
+ case BIN(invokeblock):{
554
+ int inc = 0;
555
+ CALL_INFO ci = (CALL_INFO)(opes[0]);
556
+ inc += 1 - ci->orig_argc;;
557
+ return depth + inc;
558
+ }
559
+ case BIN(leave):{
560
+ return depth + 0;
561
+ }
562
+ case BIN(throw):{
563
+ return depth + 0;
564
+ }
565
+ case BIN(jump):{
566
+ return depth + 0;
567
+ }
568
+ case BIN(branchif):{
569
+ return depth + -1;
570
+ }
571
+ case BIN(branchunless):{
572
+ return depth + -1;
573
+ }
574
+ case BIN(getinlinecache):{
575
+ return depth + 1;
576
+ }
577
+ case BIN(onceinlinecache):{
578
+ return depth + 1;
579
+ }
580
+ case BIN(setinlinecache):{
581
+ return depth + 0;
582
+ }
583
+ case BIN(opt_case_dispatch):{
584
+ int inc = 0;
585
+ inc += -1;;
586
+ return depth + inc;
587
+ }
588
+ case BIN(opt_plus):{
589
+ return depth + -1;
590
+ }
591
+ case BIN(opt_minus):{
592
+ return depth + -1;
593
+ }
594
+ case BIN(opt_mult):{
595
+ return depth + -1;
596
+ }
597
+ case BIN(opt_div):{
598
+ return depth + -1;
599
+ }
600
+ case BIN(opt_mod):{
601
+ return depth + -1;
602
+ }
603
+ case BIN(opt_eq):{
604
+ return depth + -1;
605
+ }
606
+ case BIN(opt_neq):{
607
+ return depth + -1;
608
+ }
609
+ case BIN(opt_lt):{
610
+ return depth + -1;
611
+ }
612
+ case BIN(opt_le):{
613
+ return depth + -1;
614
+ }
615
+ case BIN(opt_gt):{
616
+ return depth + -1;
617
+ }
618
+ case BIN(opt_ge):{
619
+ return depth + -1;
620
+ }
621
+ case BIN(opt_ltlt):{
622
+ return depth + -1;
623
+ }
624
+ case BIN(opt_aref):{
625
+ return depth + -1;
626
+ }
627
+ case BIN(opt_aset):{
628
+ return depth + -2;
629
+ }
630
+ case BIN(opt_length):{
631
+ return depth + 0;
632
+ }
633
+ case BIN(opt_size):{
634
+ return depth + 0;
635
+ }
636
+ case BIN(opt_empty_p):{
637
+ return depth + 0;
638
+ }
639
+ case BIN(opt_succ):{
640
+ return depth + 0;
641
+ }
642
+ case BIN(opt_not):{
643
+ return depth + 0;
644
+ }
645
+ case BIN(opt_regexpmatch1):{
646
+ return depth + 0;
647
+ }
648
+ case BIN(opt_regexpmatch2):{
649
+ return depth + -1;
650
+ }
651
+ case BIN(opt_call_c_function):{
652
+ return depth + 0;
653
+ }
654
+ case BIN(bitblt):{
655
+ return depth + 1;
656
+ }
657
+ case BIN(answer):{
658
+ return depth + 1;
659
+ }
660
+ case BIN(getlocal_OP__WC__0):{
661
+ return depth + 1;
662
+ }
663
+ case BIN(getlocal_OP__WC__1):{
664
+ return depth + 1;
665
+ }
666
+ case BIN(setlocal_OP__WC__0):{
667
+ return depth + -1;
668
+ }
669
+ case BIN(setlocal_OP__WC__1):{
670
+ return depth + -1;
671
+ }
672
+ case BIN(putobject_OP_INT2FIX_O_0_C_):{
673
+ return depth + 1;
674
+ }
675
+ case BIN(putobject_OP_INT2FIX_O_1_C_):{
676
+ return depth + 1;
677
+ }
678
+
679
+ default:
680
+ rb_bug("insn_sp_increase: unreachable");
681
+ }
682
+ return 0;
683
+ }
684
+ #endif
685
+
686
+ /* some utilities */
687
+
688
+ static int
689
+ insn_len(VALUE insn)
690
+ {
691
+ return insn_len_info[(int)insn];
692
+ }
693
+
694
+ static const char *
695
+ insn_name(VALUE insn)
696
+ {
697
+ return insn_name_info[(int)insn];
698
+ }
699
+
700
+ static const char *
701
+ insn_op_types(VALUE insn)
702
+ {
703
+ return insn_operand_info[(int)insn];
704
+ }
705
+
706
+ static int
707
+ insn_op_type(VALUE insn, long pos)
708
+ {
709
+ int len = insn_len(insn) - 1;
710
+ if(pos < len){
711
+ return insn_operand_info[(int)insn][pos];
712
+ }
713
+ else{
714
+ return 0;
715
+ }
716
+ }
717
+
718
+ #ifdef USE_INSN_RET_NUM
719
+ static int
720
+ insn_ret_num(VALUE insn)
721
+ {
722
+ return insn_stack_push_num_info[(int)insn];
723
+ }
724
+ #endif