tombagby-llvmruby 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,323 @@
1
+ require 'test/unit'
2
+ require 'llvm'
3
+
4
+ include LLVM
5
+
6
+ class BasicTests < Test::Unit::TestCase
7
+ def function_tester(expected)
8
+ m = LLVM::Module.new("test_module")
9
+ type = Type::function(MACHINE_WORD, [])
10
+ f = m.get_or_insert_function("test", type)
11
+ yield(f)
12
+ ExecutionEngine.get(m);
13
+ assert_equal(expected, ExecutionEngine.run_autoconvert(f))
14
+ end
15
+
16
+ def test_module
17
+ function_tester(5) do |f|
18
+ b = f.create_block.builder
19
+ v = b.add(2.llvm, 3.llvm)
20
+ b.return(v)
21
+ end
22
+ end
23
+
24
+ def bin_op(op, v1, v2, expected)
25
+ function_tester(expected) do |f|
26
+ b = f.create_block.builder
27
+ ret = b.bin_op(op, v1.llvm, v2.llvm)
28
+ b.return(ret)
29
+ end
30
+ end
31
+
32
+ def test_bin_ops
33
+ bin_op(Instruction::Add, 2, 3, 5)
34
+ bin_op(Instruction::Sub, 5, 3, 2)
35
+ bin_op(Instruction::Mul, 2, 3, 6)
36
+ bin_op(Instruction::UDiv, 42, 6, 7)
37
+ bin_op(Instruction::SDiv, 42, 6, 7)
38
+ #bin_op(Instruction::FDiv, 23.0, 5, 0.23)
39
+ bin_op(Instruction::URem, 23, 5, 3)
40
+ bin_op(Instruction::SRem, 23, 5, 3)
41
+ #bin_op(Instruction::FRem, 23.0, 5, 0.23)
42
+
43
+ bin_op(Instruction::Shl, 2, 1, 4)
44
+ bin_op(Instruction::LShr, 8, 1, 4)
45
+ #bin_op(Instruction::AShr, 8, 1, 4)
46
+ bin_op(Instruction::And, 8, 15, 8)
47
+ bin_op(Instruction::Or, 8, 15, 15)
48
+ bin_op(Instruction::Xor, 8, 15, 7)
49
+ end
50
+
51
+ def builder_bin_op(op, v1, v2, expected)
52
+ function_tester(expected) do |f|
53
+ b = f.create_block.builder
54
+ ret = b.send(op, v1.llvm, v2.llvm)
55
+ b.return(ret)
56
+ end
57
+ end
58
+
59
+ def test_builder_bin_ops
60
+ builder_bin_op(:add, 23, 42, 65)
61
+ builder_bin_op(:sub, 69, 13, 56)
62
+ builder_bin_op(:mul, 23, 5, 115)
63
+ builder_bin_op(:udiv, 23, 5, 4)
64
+ builder_bin_op(:sdiv, 99, 33, 3)
65
+ #builder_bin_op(:fdiv, 23, 42, 65)
66
+ builder_bin_op(:urem, 23, 42, 23)
67
+ builder_bin_op(:srem, 77, 5, 2)
68
+ #builder_bin_op(:frem, 23, 42, 65)
69
+ builder_bin_op(:shl, 15, 1, 30)
70
+ builder_bin_op(:lshr, 32, 2, 8)
71
+ #builder_bin_op(:ashr, 23, 42, 65)
72
+ builder_bin_op(:and, 32, 37, 32)
73
+ builder_bin_op(:or, 15, 8, 15)
74
+ builder_bin_op(:xor, 33, 15, 46)
75
+ end
76
+
77
+ def test_insert_point
78
+ function_tester(2) do |f|
79
+ b1 = f.create_block
80
+ b2 = f.create_block
81
+ builder = b1.builder
82
+ builder.br(b2)
83
+ builder.set_insert_point(b2)
84
+ builder.return(2.llvm)
85
+ end
86
+ end
87
+
88
+ def test_builder_utils
89
+ function_tester(5) do |f|
90
+ b = f.create_block.builder
91
+ b.write do
92
+ ret = add(2.llvm, 3.llvm)
93
+ self.return(ret)
94
+ end
95
+ end
96
+ end
97
+
98
+ def test_cmps
99
+ m = LLVM::Module.new("test_cmps")
100
+ type = Type.function(MACHINE_WORD, [])
101
+ f = m.get_or_insert_function("sgt", type)
102
+
103
+ entry_block = f.create_block
104
+ exit_block_true = f.create_block
105
+ exit_block_false = f.create_block
106
+
107
+ b = entry_block.builder
108
+ cmp = b.icmp_sgt(-1.llvm, 1.llvm)
109
+ b.cond_br(cmp, exit_block_true, exit_block_false)
110
+
111
+ b = exit_block_true.builder
112
+ b.return(1.llvm)
113
+
114
+ b = exit_block_false.builder
115
+ b.return(0.llvm)
116
+
117
+ ExecutionEngine.get(m)
118
+ result = ExecutionEngine.run_autoconvert(f)
119
+ assert_equal(0, result)
120
+ end
121
+
122
+ def test_fcmps
123
+ m = LLVM::Module.new('test_fcmps')
124
+ type = Type.function(MACHINE_WORD, [])
125
+ f = m.get_or_insert_function('ult', type)
126
+
127
+ entry_block = f.create_block
128
+ exit_block_true = f.create_block
129
+ exit_block_false = f.create_block
130
+
131
+ b = entry_block.builder
132
+ cmp = b.fcmp_ult(1.0.llvm, 2.0.llvm)
133
+ b.cond_br(cmp, exit_block_true, exit_block_false)
134
+
135
+ b = exit_block_true.builder
136
+ b.return(0.llvm)
137
+
138
+ b = exit_block_false.builder
139
+ b.return(1.llvm)
140
+
141
+ ExecutionEngine.get(m)
142
+ result = ExecutionEngine.run_autoconvert(f)
143
+ assert_equal(0, result)
144
+ end
145
+
146
+ def test_function_calls
147
+ m = LLVM::Module.new('test_module')
148
+ type = Type::function(MACHINE_WORD, [])
149
+ f_caller = m.get_or_insert_function("caller", type)
150
+ type = Type::function(MACHINE_WORD, [MACHINE_WORD, MACHINE_WORD])
151
+ f_callee = m.get_or_insert_function("callee", type)
152
+
153
+ b = f_callee.create_block.builder
154
+ x, y = f_callee.arguments
155
+ sum = b.add(x, y)
156
+ b.return(sum)
157
+
158
+ b = f_caller.create_block.builder
159
+ ret = b.call(f_callee, 2.llvm, 3.llvm)
160
+ b.return(ret)
161
+
162
+ ExecutionEngine.get(m)
163
+ result = ExecutionEngine.run_autoconvert(f_caller)
164
+ assert_equal(5, result)
165
+ end
166
+
167
+ def test_phi_node
168
+ m = LLVM::Module.new('test_module')
169
+ type = Type::function(MACHINE_WORD, [])
170
+ f = m.get_or_insert_function('phi_node', type)
171
+
172
+ entry_block = f.create_block
173
+ loop_block = f.create_block
174
+ exit_block = f.create_block
175
+
176
+ b = entry_block.builder
177
+ b.br(loop_block)
178
+
179
+ b = loop_block.builder
180
+ phi = b.phi(MACHINE_WORD)
181
+ phi.add_incoming(0.llvm, entry_block)
182
+ count = b.add(phi, 1.llvm)
183
+ phi.add_incoming(count, loop_block)
184
+ cmp = b.icmp_ult(count, 10.llvm)
185
+ b.cond_br(cmp, loop_block, exit_block)
186
+
187
+ b = exit_block.builder
188
+ b.return(phi)
189
+
190
+ ExecutionEngine.get(m)
191
+ result = ExecutionEngine.run_autoconvert(f)
192
+ assert_equal(9, result)
193
+ end
194
+
195
+ def test_bitcode_writer
196
+ m = LLVM::Module.new('static_module')
197
+ # create main function
198
+ type = Type.function(Type::Int32Ty, [
199
+ Type::Int32Ty,
200
+ Type.pointer(Type.pointer(Type::Int8Ty))
201
+ ])
202
+ f = m.get_or_insert_function('main', type)
203
+ b = f.create_block.builder
204
+ b.return(666.llvm(Type::Int32Ty))
205
+
206
+ m.write_bitcode("test/static.o")
207
+ end
208
+
209
+ def test_type_errors
210
+ m = LLVM::Module.new('type_errors')
211
+ ftype = Type.function(Type::Int32Ty, [])
212
+ assert_raise(TypeError) { f = LLVM::Module.new(5) }
213
+ assert_raise(TypeError) { m.get_or_insert_function(5, ftype) }
214
+ assert_raise(TypeError) { m.get_or_insert_function('bad_arg', 5) }
215
+ assert_raise(TypeError) { ExecutionEngine.get(5) }
216
+ assert_raise(TypeError) { m.external_function(5, ftype) }
217
+ assert_raise(TypeError) { m.external_function('fname', 5) }
218
+ assert_raise(TypeError) { m.write_bitcode(5) }
219
+ assert_raise(ArgumentError) { ExecutionEngine.run_function }
220
+ assert_raise(TypeError) { ExecutionEngine.run_function(5) }
221
+ assert_raise(TypeError) { ExecutionEngine.run_function(5, 5) }
222
+
223
+ f = m.get_or_insert_function('test', ftype)
224
+ block1 = f.create_block
225
+ block2 = f.create_block
226
+ b = block1.builder
227
+ assert_raise(TypeError) { b.set_insert_point(5) }
228
+ assert_raise(TypeError) { b.phi(5) }
229
+ phi = b.phi(Type::Int32Ty)
230
+ assert_raise(TypeError) { phi.add_incoming(5, 5) }
231
+ assert_raise(TypeError) { phi.add_incoming(5.llvm(Type::Int32Ty), 5) }
232
+ assert_raise(TypeError) { b.bin_op([], 2.llvm, 3.llvm) }
233
+ assert_raise(TypeError) { b.bin_op(Instruction::Add, 5, 3.llvm) }
234
+ assert_raise(TypeError) { b.bin_op(Instruction::Add, 3.llvm, 5) }
235
+ end
236
+
237
+ def test_inspectors
238
+ m = LLVM::Module.new('example')
239
+ ftype = Type.function(Type::Int32Ty, [])
240
+ f = m.get_or_insert_function('inspect', ftype)
241
+ b = f.create_block.builder
242
+ b.return(5.llvm(Type::Int32Ty))
243
+
244
+ assert_match(/define i32 @inspect\(\)/, m.inspect)
245
+ assert_match(/define i32 @inspect\(\)/, f.inspect)
246
+ end
247
+
248
+ def test_global_strings
249
+ m = LLVM::Module.new('globalstrings')
250
+ ftype = Type.function(Type::Int32Ty, [])
251
+ f = m.get_or_insert_function('use_global_strings', ftype)
252
+ b = f.create_block.builder
253
+ v = b.create_global_string_ptr("SHAKA KHAN")
254
+ end
255
+
256
+ def test_var_arg_ftypes
257
+ ftype = Type.function(Type::Int32Ty, [], true)
258
+ end
259
+
260
+ def test_struct_constants
261
+ int_t = Type::Int32Ty
262
+ struct_type = Type.struct([int_t, int_t, int_t])
263
+ struct_const = Value.get_struct_constant(struct_type, 2.llvm(int_t), 3.llvm(int_t), 5.llvm(int_t))
264
+ assert_kind_of(Value, struct_const)
265
+
266
+ m = LLVM::Module.new('globals')
267
+ gv = m.global_variable(struct_type, struct_const)
268
+ assert_kind_of(Value, gv)
269
+ end
270
+
271
+ def test_malloc_free
272
+ function_tester(23) do |f|
273
+ b = f.create_block.builder
274
+ new_space = b.malloc(MACHINE_WORD, 1)
275
+ b.store(23.llvm(MACHINE_WORD), new_space)
276
+ v = b.load(new_space)
277
+ b.free(new_space)
278
+ b.return(v)
279
+ end
280
+ end
281
+
282
+ def test_cast
283
+ function_tester(5) do |f|
284
+ b = f.create_block.builder
285
+ b.return(b.cast(Instruction::FPToSI, 5.0.llvm, MACHINE_WORD))
286
+ end
287
+ end
288
+
289
+ def test_switch
290
+ function_tester(23) do |f|
291
+ b = f.create_block.builder
292
+ default = f.create_block
293
+ on5 = f.create_block
294
+ switch = b.switch(5.llvm, default)
295
+ switch.add_case(5.llvm, on5)
296
+ assert_instance_of(SwitchInst, switch)
297
+ assert_equal(2, switch.get_num_cases);
298
+
299
+ b = default.builder
300
+ b.return(7.llvm(MACHINE_WORD))
301
+
302
+ b = on5.builder
303
+ b.return(23.llvm)
304
+ end
305
+ end
306
+
307
+ def test_vector
308
+ function_tester(666) do |f|
309
+ b = f.create_block.builder
310
+ vt = Type.vector(MACHINE_WORD, 3)
311
+ vp = b.alloca(vt, 0)
312
+ v = b.load(vp)
313
+ v2 = b.insert_element(v, 666.llvm(MACHINE_WORD), 0.llvm(Type::Int32Ty))
314
+ r = b.extract_element(v2, 0.llvm(Type::Int32Ty))
315
+ b.return(r)
316
+ end
317
+ end
318
+
319
+ def test_pass_manager_run
320
+ m = LLVM::Module.new('test')
321
+ assert PassManager.new.run(m)
322
+ end
323
+ end
@@ -0,0 +1,65 @@
1
+ require 'test/unit'
2
+ require 'llvm'
3
+
4
+ include LLVM
5
+
6
+ class BasicBlockTests < Test::Unit::TestCase
7
+
8
+ def setup
9
+
10
+ @assembly_gcd=<<-EOF
11
+ ; ModuleID = 'gcd.o'
12
+ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
13
+ target triple = "i386-apple-darwin9"
14
+
15
+ define i32 @gcd(i32 %a, i32 %b) nounwind {
16
+ entry:
17
+ %tmp2 = icmp eq i32 %a, 0 ; <i1> [#uses=1]
18
+ br i1 %tmp2, label %bb26, label %bb19
19
+
20
+ bb5: ; preds = %bb19, %bb11
21
+ %indvar48 = phi i32 [ %indvar.next49, %bb11 ], [ 0, %bb19 ] ; <i32> [#uses=2]
22
+ %tmp50 = sub i32 0, %b_addr.0 ; <i32> [#uses=1]
23
+ %tmp51 = mul i32 %indvar48, %tmp50 ; <i32> [#uses=1]
24
+ %a_addr.0.reg2mem.0 = add i32 %tmp51, %a_addr.0 ; <i32> [#uses=3]
25
+ %tmp8 = icmp sgt i32 %a_addr.0.reg2mem.0, %b_addr.0 ; <i1> [#uses=1]
26
+ br i1 %tmp8, label %bb11, label %bb15.split
27
+
28
+ bb11: ; preds = %bb5
29
+ %indvar.next49 = add i32 %indvar48, 1 ; <i32> [#uses=1]
30
+ br label %bb5
31
+
32
+ bb15.split: ; preds = %bb5
33
+ %tmp18 = sub i32 %b_addr.0, %a_addr.0.reg2mem.0 ; <i32> [#uses=1]
34
+ br label %bb19
35
+
36
+ bb19: ; preds = %bb15.split, %entry
37
+ %b_addr.0 = phi i32 [ %tmp18, %bb15.split ], [ %b, %entry ] ; <i32> [#uses=4]
38
+ %a_addr.0 = phi i32 [ %a_addr.0.reg2mem.0, %bb15.split ], [ %a, %entry ] ; <i32> [#uses=2]
39
+ %tmp21 = icmp eq i32 %b_addr.0, 0 ; <i1> [#uses=1]
40
+ br i1 %tmp21, label %bb26, label %bb5
41
+
42
+ bb26: ; preds = %bb19, %entry
43
+ %tmp.0 = phi i32 [ %b, %entry ], [ %a_addr.0, %bb19 ] ; <i32> [#uses=1]
44
+ ret i32 %tmp.0
45
+ }
46
+ EOF
47
+
48
+ end
49
+
50
+
51
+ def test_count_intructions_in_basic_block
52
+ m = LLVM::Module.read_assembly(@assembly_gcd)
53
+ gcd = m.get_function("gcd")
54
+ assert(gcd)
55
+
56
+ bbs = gcd.get_basic_block_list
57
+ expected = { 'entry' => 2, 'bb5' => 6, 'bb11' => 2, 'bb15.split' => 2, 'bb19' => 4, 'bb26' => 2 }
58
+ res = Hash.new
59
+ bbs.each { |b|
60
+ res[b.get_name] = b.size
61
+ }
62
+ assert_equal(expected,res)
63
+ end
64
+
65
+ end
@@ -0,0 +1,46 @@
1
+ require 'test/unit'
2
+ require 'llvm'
3
+
4
+ include LLVM
5
+
6
+ class InstructionTests < Test::Unit::TestCase
7
+
8
+ def setup
9
+
10
+ @assembly_byteswap=<<-EOF
11
+ ; ModuleID = 'byteswap.bc'
12
+ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
13
+ target triple = "i386-apple-darwin9"
14
+
15
+ define i32 @bswap(i32 %x) nounwind {
16
+ entry:
17
+ %tmp3 = shl i32 %x, 24 ; <i32> [#uses=1]
18
+ %tmp5 = shl i32 %x, 8 ; <i32> [#uses=1]
19
+ %tmp6 = and i32 %tmp5, 16711680 ; <i32> [#uses=1]
20
+ %tmp9 = lshr i32 %x, 8 ; <i32> [#uses=1]
21
+ %tmp1018 = and i32 %tmp9, 65280 ; <i32> [#uses=1]
22
+ %tmp7 = or i32 %tmp1018, %tmp3 ; <i32> [#uses=1]
23
+ %tmp11 = or i32 %tmp7, %tmp6 ; <i32> [#uses=1]
24
+ ret i32 %tmp11
25
+ }
26
+ EOF
27
+
28
+ end
29
+
30
+ def test_count_intructions_in_basic_block
31
+ m = LLVM::Module.read_assembly(@assembly_byteswap)
32
+ bswap = m.get_function("bswap")
33
+ assert(bswap)
34
+
35
+ bbs = bswap.get_basic_block_list
36
+ assert_equal(1,bbs.size)
37
+ b = bbs[0]
38
+ assert_equal(8,b.size)
39
+
40
+ expected_opcodes_in_bswap = ["shl", "shl", "and", "lshr", "and", "lshr", "and", "or", "or", "ret"]
41
+ ins = b.get_instruction_list
42
+ actual_opcodes_in_bswap = ins.map { |i| i.get_opcode_name}
43
+ assert(expected_opcodes_in_bswap, actual_opcodes_in_bswap)
44
+ end
45
+
46
+ end
@@ -0,0 +1,38 @@
1
+ require 'test/unit'
2
+ require 'llvm'
3
+
4
+ include LLVM
5
+
6
+ class BitcodeReadTests < Test::Unit::TestCase
7
+
8
+ def test_read_bitcode
9
+ bc = File.open("test/byteswap.bc").read
10
+ m = LLVM::Module.read_bitcode(bc)
11
+ assert_match(/define i32 @bswap\(i32 \%x\) nounwind/, m.inspect)
12
+ end
13
+
14
+ def test_read_assembly
15
+ assembly =<<-END_ASSEMBLY
16
+ ; ModuleID = 'test/byteswap.bc'
17
+ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3
18
+ 2:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
19
+ target triple = "i386-apple-darwin9"
20
+
21
+ define i32 @bswap(i32 %x) nounwind {
22
+ entry:
23
+ %tmp3 = shl i32 %x, 24 ; <i32> [#uses=1]
24
+ %tmp5 = shl i32 %x, 8 ; <i32> [#uses=1]
25
+ %tmp6 = and i32 %tmp5, 16711680 ; <i32> [#uses=1]
26
+ %tmp9 = lshr i32 %x, 8 ; <i32> [#uses=1]
27
+ %tmp1018 = and i32 %tmp9, 65280 ; <i32> [#uses=1]
28
+ %tmp7 = or i32 %tmp1018, %tmp3 ; <i32> [#uses=1]
29
+ %tmp11 = or i32 %tmp7, %tmp6 ; <i32> [#uses=1]
30
+ ret i32 %tmp11
31
+ }
32
+ END_ASSEMBLY
33
+ m = LLVM::Module.read_assembly(assembly)
34
+ assert_match(/define i32 @bswap\(i32 \%x\) nounwind/, m.inspect)
35
+ assert(m.get_function("bswap"))
36
+ end
37
+
38
+ end
@@ -0,0 +1,172 @@
1
+ require 'test/unit'
2
+ require 'llvm'
3
+ require 'ruby_vm'
4
+
5
+ include LLVM
6
+ RubyVM.start
7
+
8
+ class RubyVMTests < Test::Unit::TestCase
9
+ def test_getinstancevariable
10
+ bytecode = [
11
+ [:putobject, nil.immediate],
12
+ [:getinstancevariable, :@shaka]
13
+ ]
14
+
15
+ obj = Object.new
16
+ obj.instance_variable_set(:@shaka, 'khan')
17
+ compiled_method = RubyVM.compile_bytecode(bytecode)
18
+ assert_equal('khan', RubyVM.method_send(obj, compiled_method))
19
+ end
20
+
21
+ def test_setinstancevariable
22
+ bytecode = [
23
+ [:putobject, 'puter'],
24
+ [:setinstancevariable, :@fem]
25
+ ]
26
+
27
+ obj = Object.new
28
+ compiled_method = RubyVM.compile_bytecode(bytecode)
29
+ RubyVM.method_send(obj, compiled_method)
30
+ assert_equal('puter', obj.instance_variable_get(:@fem))
31
+ end
32
+
33
+ def test_opt_aset
34
+ bytecode = [
35
+ [:newarray],
36
+ [:dup],
37
+ [:putobject, 0.immediate],
38
+ [:putobject, 'shaka'.immediate],
39
+ [:opt_aset],
40
+ [:pop]
41
+ ]
42
+
43
+ ret = RubyVM.call_bytecode(bytecode, nil)
44
+ assert_equal(ret, ['shaka'])
45
+ end
46
+
47
+ def opt_cmp_tester(op, truth_table)
48
+ truth_table.each do |x, y, z|
49
+ bytecode = [
50
+ [:putobject, x.immediate],
51
+ [:putobject, y.immediate],
52
+ [op]
53
+ ]
54
+ ret = RubyVM.call_bytecode(bytecode, nil)
55
+ assert_equal(z, ret)
56
+ end
57
+ end
58
+
59
+ def test_opt_lt
60
+ opt_cmp_tester(:opt_lt, [
61
+ [0, 1, true],
62
+ [1, 0, false],
63
+ [1, 1, false]
64
+ ])
65
+ end
66
+
67
+ def test_opt_gt
68
+ opt_cmp_tester(:opt_gt, [
69
+ [0, 1, false],
70
+ [1, 0, true],
71
+ [1, 1, false]
72
+ ])
73
+ end
74
+
75
+ def test_opt_ge
76
+ opt_cmp_tester(:opt_ge, [
77
+ [0, 1, false],
78
+ [1, 0, true],
79
+ [1, 1, true]
80
+ ])
81
+ end
82
+
83
+ def test_opt_length
84
+ bytecode = [
85
+ [:opt_length]
86
+ ]
87
+
88
+ ret1 = RubyVM.call_bytecode(bytecode, [])
89
+ assert_equal(0, ret1)
90
+
91
+ ret2 = RubyVM.call_bytecode(bytecode, [1,2,3,4,5])
92
+ assert_equal(5, ret2)
93
+ end
94
+
95
+ def test_simple_loop
96
+ bytecode = [
97
+ [:putobject, 1.immediate],
98
+ [:opt_plus],
99
+ [:dup],
100
+ [:putobject, 10.immediate],
101
+ [:opt_lt],
102
+ [:branchif, 0]
103
+ ]
104
+
105
+ ret = RubyVM.call_bytecode(bytecode, 6)
106
+ assert_equal(10, ret)
107
+ end
108
+
109
+ def test_array_loop
110
+ bytecode = [
111
+ [:dup],
112
+ [:setlocal, 0],
113
+ [:opt_length],
114
+ [:putobject, 1.immediate],
115
+ [:opt_minus],
116
+ [:dup],
117
+ [:getlocal, 0],
118
+ [:swap],
119
+ [:opt_aref],
120
+ [:putobject, 2.immediate],
121
+ [:opt_mult],
122
+ [:setlocal, 1],
123
+ [:dup],
124
+ [:getlocal, 0],
125
+ [:swap],
126
+ [:getlocal, 1],
127
+ [:opt_aset],
128
+ [:pop],
129
+ [:dup],
130
+ [:putobject, 0.immediate],
131
+ [:opt_gt],
132
+ [:branchif, 3],
133
+ [:getlocal, 0]
134
+ ]
135
+
136
+ ret = RubyVM.call_bytecode(bytecode, [1,2,3,4,5,6])
137
+ assert_equal([2,4,6,8,10,12], ret)
138
+ end
139
+
140
+ def test_send
141
+ bytecode = [
142
+ [:send]
143
+ ]
144
+
145
+ ret = RubyVM.call_bytecode(bytecode, nil)
146
+ assert_equal('nil', ret)
147
+ end
148
+
149
+ def test_putself
150
+ bytecode = [
151
+ [:putobject, 5.immediate],
152
+ [:putself]
153
+ ]
154
+ compiled_method = RubyVM.compile_bytecode(bytecode)
155
+ ret = RubyVM.method_send('me', compiled_method)
156
+ assert_equal('me', ret)
157
+ end
158
+
159
+ def test_newhash
160
+ bytecode = [
161
+ [:putobject, 'one'.immediate],
162
+ [:putobject, 1.immediate],
163
+ [:putobject, 'two'.immediate],
164
+ [:putobject, 2.immediate],
165
+ [:putobject, 'three'.immediate],
166
+ [:putobject, 3.immediate],
167
+ [:newhash, 6]
168
+ ]
169
+ ret = RubyVM.call_bytecode(bytecode, nil)
170
+ assert_equal({'one' => 1, 'two' => 2, 'three' => 3}, ret)
171
+ end
172
+ end