ruby-decompiler 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,27 @@
1
+ require 'internal/vm'
2
+
3
+ if defined?(RubyVM::InstructionSequence) then
4
+ require 'internal/vm/bytedecoder'
5
+
6
+ class RubyVM
7
+ class InstructionSequence
8
+ def as_code(indent=0)
9
+ env = Internal::ByteDecoder::Environment.new(local_table())
10
+ opt_pc = self.opt_pc
11
+ self.bytedecode(env, opt_pc)
12
+ expressions = env.expressions + env.stack
13
+ if expressions.length == 0 then
14
+ return nil
15
+ elsif expressions.length == 1 and
16
+ expressions[0].is_a?(Internal::ByteDecoder::Expression::Literal) and
17
+ expressions[0].value == nil then
18
+ return nil
19
+ else
20
+ expressions.map! { |e| "#{' '*indent}#{e}" }
21
+ return expressions.join("\n")
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,26 @@
1
+ require 'internal/vm'
2
+
3
+ if defined?(RubyVM::InstructionSequence) then
4
+ require 'internal/vm/bytedecoder'
5
+
6
+ class RubyVM
7
+ class InstructionSequence
8
+ def as_expression
9
+ env = Internal::ByteDecoder::Environment.new(local_table())
10
+ opt_pc = self.opt_pc
11
+ self.bytedecode(env, opt_pc)
12
+ expressions = env.expressions + env.stack
13
+ if expressions.length == 0 then
14
+ return nil
15
+ elsif expressions.length == 1 and
16
+ expressions[0].is_a?(Internal::ByteDecoder::Expression::Literal) and
17
+ expressions[0].value == nil then
18
+ return nil
19
+ else
20
+ return expressions.join('; ')
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
@@ -0,0 +1,261 @@
1
+ require 'test/unit'
2
+ require 'timeout'
3
+
4
+ dir = File.dirname(__FILE__)
5
+ $:.unshift(dir) if not $:.include?(dir)
6
+ $:.unshift("#{dir}/../lib") if not $:.include?("#{dir}/../lib")
7
+ $:.unshift("#{dir}/../ext") if not $:.include?("#{dir}/../ext")
8
+
9
+ require 'internal/node/as_code'
10
+ require 'internal/method/as_code'
11
+ require 'internal/module/as_code'
12
+ require 'internal/proc/as_code'
13
+
14
+ require 'expression_samples'
15
+
16
+ $stdout.sync = true
17
+ $stderr.sync = true
18
+
19
+ class TC_As_Code < Test::Unit::TestCase
20
+ MAJOR = Config::CONFIG['MAJOR'].to_i
21
+ MINOR = Config::CONFIG['MINOR'].to_i
22
+ TEENY = Config::CONFIG['TEENY'].to_i
23
+ RUBY_VERSION_CODE = MAJOR * 100 + MINOR * 10 + TEENY
24
+
25
+ extend Test::Unit::Assertions
26
+
27
+ # Some of the samples use this
28
+ def foo(*a, &b)
29
+ return b.call(1, 2) if b
30
+ return a
31
+ end
32
+
33
+ EXPRESSION_SAMPLES.each do |name, code|
34
+ p = proc {
35
+ p_orig = eval("proc { #{code} }")
36
+ code_new = p_orig.body.as_code
37
+ # p code, code_new
38
+ p_new = eval("proc { #{code_new} }")
39
+ result_orig = result_new = nil
40
+ exc_orig = exc_new = nil
41
+ timeout(1) { begin; result_orig = p_orig.call; rescue; exc_orig = $!; end }
42
+ timeout(1) { begin; result_new = p_new.call; rescue; exc_new = $!; end }
43
+ assert_equal(
44
+ exc_orig.class,
45
+ exc_new.class,
46
+ "Expected #{exc_orig.inspect} but got #{exc_new.inspect} " + \
47
+ "(code_orig=#{code}, code_new=#{code_new})")
48
+ if exc_orig and exc_new then
49
+ assert_equal(exc_orig.message, exc_new.message)
50
+ end
51
+ assert_equal(result_orig, result_new)
52
+ }
53
+ define_method "test_#{name}", p
54
+ end
55
+
56
+ def initialize(test_method_name)
57
+ # TODO: This seems to be the only way to get tests defined with #
58
+ # define_method to run on 1.8.1 and earlier.
59
+ catch(:invalid_test) { super(test_method_name) }
60
+ end
61
+
62
+ def method_no_args
63
+ 42
64
+ end
65
+
66
+ def test_method_no_args_as_code
67
+ m = method(:method_no_args)
68
+ assert_equal "def method_no_args()\n 42\nend", m.as_code
69
+ end
70
+
71
+ def method_one_arg(a)
72
+ 42
73
+ end
74
+
75
+ def test_method_one_arg_as_code
76
+ m = method(:method_one_arg)
77
+ assert_equal "def method_one_arg(a)\n 42\nend", m.as_code
78
+ end
79
+
80
+ def method_two_args(a, b)
81
+ 42
82
+ end
83
+
84
+ def test_method_two_args_as_code
85
+ m = method(:method_two_args)
86
+ assert_equal "def method_two_args(a, b)\n 42\nend", m.as_code
87
+ end
88
+
89
+ def method_rest_arg(*rest)
90
+ 42
91
+ end
92
+
93
+ def test_method_rest_arg_as_code
94
+ m = method(:method_rest_arg)
95
+ assert_equal "def method_rest_arg(*rest)\n 42\nend", m.as_code
96
+ end
97
+
98
+ def method_block_arg(&block)
99
+ 42
100
+ end
101
+
102
+ def test_method_block_arg_as_code
103
+ m = method(:method_block_arg)
104
+ assert_equal "def method_block_arg(&block)\n 42\nend", m.as_code
105
+ end
106
+
107
+ def method_rest_and_block_arg(*rest, &block)
108
+ 42
109
+ end
110
+
111
+ def test_method_rest_and_block_arg_as_code
112
+ m = method(:method_rest_and_block_arg)
113
+ assert_equal "def method_rest_and_block_arg(*rest, &block)\n 42\nend", m.as_code
114
+ end
115
+
116
+ def method_two_args_and_rest_and_block_arg(a, b, *rest, &block)
117
+ 42
118
+ end
119
+
120
+ def test_method_two_args_and_rest_and_block_arg_as_code
121
+ m = method(:method_two_args_and_rest_and_block_arg)
122
+ assert_equal "def method_two_args_and_rest_and_block_arg(a, b, *rest, &block)\n 42\nend", m.as_code
123
+ end
124
+
125
+ def method_with_body(a, b)
126
+ a + b
127
+ end
128
+
129
+ def test_method_with_body_as_code
130
+ m = method(:method_with_body)
131
+ assert_equal "def method_with_body(a, b)\n a + b\nend", m.as_code
132
+ end
133
+
134
+ def method_begin_ensure_as_code(a, b, *rest, &block)
135
+ begin
136
+ if not a and not b then
137
+ raise "Need more input!"
138
+ end
139
+ return a + b
140
+ ensure
141
+ puts "In ensure block"
142
+ end
143
+ end
144
+
145
+ def test_method_begin_ensure_as_code
146
+ m = method(:method_begin_ensure_as_code)
147
+ if RUBY_VERSION_CODE >= 190 then
148
+ ret = ''
149
+ else
150
+ ret = 'return '
151
+ end
152
+
153
+ assert_equal <<-END.chomp, m.as_code(3)
154
+ def method_begin_ensure_as_code(a, b, *rest, &block)
155
+ begin
156
+ (raise("Need more input!")) if (not a and not b)
157
+ #{ret}a + b
158
+ ensure
159
+ puts("In ensure block")
160
+ end
161
+ end
162
+ END
163
+ end
164
+
165
+ def test_proc_no_args_as_code
166
+ p = proc { }
167
+ assert_equal "proc do\nend", p.as_code
168
+ end
169
+
170
+ def test_proc_empty_args_as_code
171
+ if not defined?(RubyVM) then
172
+ # indistinguishable from proc { } on YARV
173
+ p = proc { || }
174
+ assert_equal "proc do ||\nend", p.as_code
175
+ end
176
+ end
177
+
178
+ def test_proc_one_arg_as_code
179
+ p = proc { |a| }
180
+ assert_equal "proc do |a|\nend", p.as_code
181
+ end
182
+
183
+ def test_proc_one_array_arg_as_expression
184
+ p = proc { |a,| }
185
+ assert_equal "proc do |a,|\nend", p.as_code
186
+ end
187
+
188
+ def test_proc_two_args_as_code
189
+ p = proc { |a, b| }
190
+ assert_equal "proc do |a, b|\nend", p.as_code
191
+ end
192
+
193
+ def test_proc_rest_arg_as_code
194
+ p = proc { |*rest| }
195
+ assert_equal "proc do |*rest|\nend", p.as_code
196
+ end
197
+
198
+ def test_proc_two_args_and_rest_arg_as_code
199
+ p = proc { |a, b, *rest| }
200
+ assert_equal "proc do |a, b, *rest|\nend", p.as_code
201
+ end
202
+
203
+ def test_proc_with_body_as_code
204
+ p = proc { |a, b| a + b }
205
+ assert_equal "proc do |a, b|\n a + b\nend", p.as_code
206
+ end
207
+
208
+ def setup
209
+ @foo = 42
210
+ end
211
+
212
+ # 1.7 and later
213
+ def foo(*args)
214
+ return args
215
+ end
216
+
217
+ def remove_foo
218
+ self.class.remove_foo
219
+ end
220
+
221
+ # 1.6
222
+ def self.foo(*args)
223
+ return args
224
+ end
225
+
226
+ def self.remove_foo
227
+ self.class_eval { remove_const(:FOO) if const_defined?(:FOO) }
228
+ end
229
+
230
+ @@foo = 10
231
+
232
+ FOO = 57
233
+
234
+ class ObjectWithFooAccessor
235
+ attr_accessor :foo
236
+ end
237
+
238
+ OWFA = ObjectWithFooAccessor.new
239
+ end
240
+
241
+ if __FILE__ == $0 then
242
+ require 'test/unit/ui/console/testrunner'
243
+
244
+ if Test::Unit.const_defined?(:AutoRunner) then
245
+ exit Test::Unit::AutoRunner.run
246
+ else
247
+ if ARGV.empty? then
248
+ suite = TC_As_Code.suite
249
+ else
250
+ suite = Test::Unit::TestSuite.new('TC_As_Code')
251
+ TC_As_Code.suite.tests.each do |test|
252
+ ARGV.each do |arg|
253
+ suite << test if /#{arg}/ =~ test.name
254
+ end
255
+ end
256
+ end
257
+ result = Test::Unit::UI::Console::TestRunner.run(suite)
258
+ exit(result.error_count + result.failure_count)
259
+ end
260
+ end
261
+
@@ -0,0 +1,229 @@
1
+ require 'test/unit'
2
+ require 'timeout'
3
+
4
+ dir = File.dirname(__FILE__)
5
+ $:.unshift(dir) if not $:.include?(dir)
6
+ $:.unshift("#{dir}/../lib") if not $:.include?("#{dir}/../lib")
7
+ $:.unshift("#{dir}/../ext") if not $:.include?("#{dir}/../ext")
8
+
9
+ require 'internal/node/as_expression'
10
+ require 'internal/method/as_expression'
11
+ require 'internal/proc/as_expression'
12
+
13
+ require 'expression_samples'
14
+
15
+ $stdout.sync = true
16
+ $stderr.sync = true
17
+
18
+ class TC_As_Expression < Test::Unit::TestCase
19
+ extend Test::Unit::Assertions
20
+
21
+ # Some of the samples use this
22
+ def foo(*a, &b)
23
+ return b.call(1, 2) if b
24
+ return a
25
+ end
26
+
27
+ EXPRESSION_SAMPLES.each do |name, code|
28
+ p = proc {
29
+ p_orig = eval("proc { #{code} }")
30
+ code_new = p_orig.body.as_expression
31
+ # p code, code_new
32
+ p_new = eval("proc { #{code_new} }")
33
+ result_orig = result_new = nil
34
+ exc_orig = exc_new = nil
35
+ timeout(1) { begin; result_orig = p_orig.call; rescue; exc_orig = $!; end }
36
+ timeout(1) { begin; result_new = p_new.call; rescue; exc_new = $!; end }
37
+ assert_equal(result_orig, result_new)
38
+ assert_equal(exc_orig.class, exc_new.class)
39
+ if exc_orig and exc_new then
40
+ assert_equal(exc_orig.message, exc_new.message)
41
+ end
42
+ }
43
+ define_method "test_#{name}", p
44
+ end
45
+
46
+ def initialize(test_method_name)
47
+ # TODO: This seems to be the only way to get tests defined with #
48
+ # define_method to run on 1.8.1 and earlier.
49
+ catch(:invalid_test) { super(test_method_name) }
50
+ end
51
+
52
+ def method_no_args
53
+ 42
54
+ end
55
+
56
+ def test_method_no_args_as_expression
57
+ m = method(:method_no_args)
58
+ assert_equal 'def method_no_args(); 42; end', m.as_expression
59
+ end
60
+
61
+ def method_one_arg(a)
62
+ 42
63
+ end
64
+
65
+ def test_method_one_arg_as_expression
66
+ m = method(:method_one_arg)
67
+ assert_equal 'def method_one_arg(a); 42; end', m.as_expression
68
+ end
69
+
70
+ def method_two_args(a, b)
71
+ 42
72
+ end
73
+
74
+ def test_method_two_args_as_expression
75
+ m = method(:method_two_args)
76
+ assert_equal 'def method_two_args(a, b); 42; end', m.as_expression
77
+ end
78
+
79
+ def method_rest_arg(*rest)
80
+ 42
81
+ end
82
+
83
+ def test_method_rest_arg_as_expression
84
+ m = method(:method_rest_arg)
85
+ assert_equal 'def method_rest_arg(*rest); 42; end', m.as_expression
86
+ end
87
+
88
+ def method_block_arg(&block)
89
+ 42
90
+ end
91
+
92
+ def test_method_block_arg_as_expression
93
+ m = method(:method_block_arg)
94
+ assert_equal 'def method_block_arg(&block); 42; end', m.as_expression
95
+ end
96
+
97
+ def method_rest_and_block_arg(*rest, &block)
98
+ 42
99
+ end
100
+
101
+ def test_method_rest_and_block_arg_as_expression
102
+ m = method(:method_rest_and_block_arg)
103
+ assert_equal 'def method_rest_and_block_arg(*rest, &block); 42; end', m.as_expression
104
+ end
105
+
106
+ def method_two_args_and_rest_and_block_arg(a, b, *rest, &block)
107
+ 42
108
+ end
109
+
110
+ def test_method_two_args_and_rest_and_block_arg_as_expression
111
+ m = method(:method_two_args_and_rest_and_block_arg)
112
+ assert_equal 'def method_two_args_and_rest_and_block_arg(a, b, *rest, &block); 42; end', m.as_expression
113
+ end
114
+
115
+ def method_two_default_args(a = 1, b = 2)
116
+ 42
117
+ end
118
+
119
+ def test_method_two_default_args_as_expression
120
+ m = method(:method_two_default_args)
121
+ assert_equal('def method_two_default_args(a=1, b=2); 42; end', m.as_expression)
122
+ end
123
+
124
+ def method_with_body(a, b)
125
+ a + b
126
+ end
127
+
128
+ def test_method_with_body_as_expression
129
+ m = method(:method_with_body)
130
+ assert_equal 'def method_with_body(a, b); a + b; end', m.as_expression
131
+ end
132
+
133
+ def test_proc_no_args_as_expression
134
+ p = proc { }
135
+ assert_equal 'proc { }', p.as_expression
136
+ end
137
+
138
+ def test_proc_empty_args_as_expression
139
+ if not defined?(RubyVM) then
140
+ # indistinguishable from proc { } on YARV
141
+ p = proc { || }
142
+ assert_equal 'proc { || }', p.as_expression
143
+ end
144
+ end
145
+
146
+ def test_proc_one_arg_as_expression
147
+ p = proc { |a| }
148
+ assert_equal 'proc { |a| }', p.as_expression
149
+ end
150
+
151
+ def test_proc_one_array_arg_as_expression
152
+ p = proc { |a,| }
153
+ assert_equal 'proc { |a,| }', p.as_expression
154
+ end
155
+
156
+ def test_proc_two_args_as_expression
157
+ p = proc { |a, b| }
158
+ assert_equal 'proc { |a, b| }', p.as_expression
159
+ end
160
+
161
+ def test_proc_rest_arg_as_expression
162
+ p = proc { |*rest| }
163
+ assert_equal 'proc { |*rest| }', p.as_expression
164
+ end
165
+
166
+ def test_proc_two_args_and_rest_arg_as_expression
167
+ p = proc { |a, b, *rest| }
168
+ assert_equal 'proc { |a, b, *rest| }', p.as_expression
169
+ end
170
+
171
+ def test_proc_with_body_as_expression
172
+ p = proc { |a, b| a + b }
173
+ assert_equal 'proc { |a, b| a + b }', p.as_expression
174
+ end
175
+
176
+ def setup
177
+ @foo = 42
178
+ end
179
+
180
+ # 1.7 and later
181
+ def foo(*args)
182
+ return args
183
+ end
184
+
185
+ def remove_foo
186
+ self.class.remove_foo
187
+ end
188
+
189
+ # 1.6
190
+ def self.foo(*args)
191
+ return args
192
+ end
193
+
194
+ def self.remove_foo
195
+ self.class_eval { remove_const(:FOO) if const_defined?(:FOO) }
196
+ end
197
+
198
+ @@foo = 10
199
+
200
+ FOO = 57
201
+
202
+ class ObjectWithFooAccessor
203
+ attr_accessor :foo
204
+ end
205
+
206
+ OWFA = ObjectWithFooAccessor.new
207
+ end
208
+
209
+ if __FILE__ == $0 then
210
+ require 'test/unit/ui/console/testrunner'
211
+
212
+ if Test::Unit.const_defined?(:AutoRunner) then
213
+ exit Test::Unit::AutoRunner.run
214
+ else
215
+ if ARGV.empty? then
216
+ suite = TC_As_Expression.suite
217
+ else
218
+ suite = Test::Unit::TestSuite.new('TC_As_Expression')
219
+ TC_As_Expression.suite.tests.each do |test|
220
+ ARGV.each do |arg|
221
+ suite << test if /#{arg}/ =~ test.name
222
+ end
223
+ end
224
+ end
225
+ result = Test::Unit::UI::Console::TestRunner.run(suite)
226
+ exit(result.error_count + result.failure_count)
227
+ end
228
+ end
229
+