ruby-decompiler 0.0.1

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.
@@ -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
+