ytljit 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/README +29 -0
  2. data/Rakefile +22 -0
  3. data/ext/code_alloc.c +266 -0
  4. data/ext/extconf.rb +3 -0
  5. data/ext/ytljit.c +527 -0
  6. data/ext/ytljit.h +285 -0
  7. data/lib/ytljit/asm.rb +205 -0
  8. data/lib/ytljit/asmext.rb +199 -0
  9. data/lib/ytljit/asmext_x64.rb +212 -0
  10. data/lib/ytljit/asmext_x86.rb +128 -0
  11. data/lib/ytljit/asmutil.rb +182 -0
  12. data/lib/ytljit/codespace.rb +92 -0
  13. data/lib/ytljit/error.rb +7 -0
  14. data/lib/ytljit/instruction.rb +138 -0
  15. data/lib/ytljit/instruction_ia.rb +1298 -0
  16. data/lib/ytljit/instruction_x64.rb +41 -0
  17. data/lib/ytljit/instruction_x86.rb +11 -0
  18. data/lib/ytljit/marshal.rb +133 -0
  19. data/lib/ytljit/matcher.rb +235 -0
  20. data/lib/ytljit/rubyvm.rb +63 -0
  21. data/lib/ytljit/struct.rb +125 -0
  22. data/lib/ytljit/type.rb +112 -0
  23. data/lib/ytljit/util.rb +63 -0
  24. data/lib/ytljit/vm.rb +1649 -0
  25. data/lib/ytljit/vm_codegen.rb +491 -0
  26. data/lib/ytljit/vm_inline_method.rb +85 -0
  27. data/lib/ytljit/vm_inspect.rb +74 -0
  28. data/lib/ytljit/vm_sendnode.rb +561 -0
  29. data/lib/ytljit/vm_trans.rb +508 -0
  30. data/lib/ytljit/vm_type.rb +299 -0
  31. data/lib/ytljit/vm_type_gen.rb +158 -0
  32. data/lib/ytljit/vm_typeinf.rb +98 -0
  33. data/lib/ytljit.rb +46 -0
  34. data/test/asmsample.rb +117 -0
  35. data/test/cstest.rb +61 -0
  36. data/test/marshaltest.rb +27 -0
  37. data/test/test_assemble.rb +148 -0
  38. data/test/test_assemble2.rb +286 -0
  39. data/test/test_codespace.rb +102 -0
  40. data/test/test_typeinf.rb +21 -0
  41. data/test/tivmtest.rb +54 -0
  42. data/test/vmtest.rb +59 -0
  43. data/test/vmtest2.rb +41 -0
  44. data/test/vmtest3.rb +22 -0
  45. data/test/vmtest_compile_only.rb +41 -0
  46. data/test/vmtest_execute_only.rb +22 -0
  47. metadata +121 -0
data/test/cstest.rb ADDED
@@ -0,0 +1,61 @@
1
+ require 'ytljit.rb'
2
+
3
+ include YTLJit
4
+ include AbsArch
5
+
6
+ # Fib number
7
+ def fib(n)
8
+ cs0 = CodeSpace.new
9
+ cs1 = CodeSpace.new
10
+ cs2 = CodeSpace.new
11
+
12
+ asm = Assembler.new(cs0)
13
+ # asm.step_mode = true
14
+ ent = nil
15
+ asm.with_retry do
16
+ ent = cs1.var_base_address
17
+ asm.mov(TMPR, OpImmidiate32.new(n))
18
+ asm.call(ent)
19
+ asm.add(TMPR, TMPR)
20
+ asm.add(TMPR, OpImmidiate8.new(1))
21
+ asm.ret
22
+ end
23
+
24
+ asm = Assembler.new(cs1)
25
+ # asm.step_mode = true
26
+ asm.with_retry do
27
+ asm.cmp(TMPR, OpImmidiate32.new(2))
28
+ asm.jl(cs2.var_base_address)
29
+ asm.sub(TMPR, OpImmidiate32.new(1))
30
+ asm.push(TMPR)
31
+ asm.call(ent)
32
+ asm.pop(TMPR2)
33
+ asm.sub(TMPR2, OpImmidiate32.new(1))
34
+ asm.push(TMPR)
35
+ asm.mov(TMPR, TMPR2)
36
+ asm.call(ent)
37
+ asm.pop(TMPR2)
38
+ asm.add(TMPR, TMPR2)
39
+ asm.ret
40
+ end
41
+
42
+ asm = Assembler.new(cs2)
43
+ # asm.step_mode = true
44
+ asm.with_retry do
45
+ asm.mov(TMPR, OpImmidiate32.new(1))
46
+ asm.ret
47
+ end
48
+
49
+ # cs0.disassemble
50
+ # cs1.disassemble
51
+ # cs2.disassemble
52
+
53
+ p cs1.refer_operands
54
+ ref = cs1.refer_operands
55
+ p ref[0].refer[0].binding.to_a
56
+ p ref[0].refer[0].binding.variables
57
+
58
+ cs0.call(cs0.base_address)
59
+ end
60
+
61
+ p fib(2)
@@ -0,0 +1,27 @@
1
+ require 'ytljit'
2
+ require 'pp'
3
+
4
+ class Foo
5
+ def foo
6
+ x = 10
7
+ lambda {|y, z|
8
+ lambda {|c|
9
+ [1, 2][0] = 2
10
+ p y
11
+ p self
12
+ lambda {
13
+ a = 1
14
+ p c + y + z + x + a
15
+ }.call
16
+ }
17
+ }.call(1, 3)
18
+ end
19
+ end
20
+
21
+ a = Foo.new
22
+ b = a.foo
23
+ b.call(2)
24
+
25
+ b = Marshal.load(Marshal.dump(b))
26
+ b.call(2)
27
+ pp b.to_iseq.to_a
@@ -0,0 +1,148 @@
1
+ require 'test/unit'
2
+ require 'ytljit.rb'
3
+
4
+ include YTLJit
5
+ class InstructionTests < Test::Unit::TestCase
6
+ def setup
7
+ @cs = CodeSpace.new
8
+ @asm = Assembler.new(@cs, GeneratorExtend)
9
+ @eax = OpEAX.instance
10
+ @ecx = OpECX.instance
11
+ @esp = OpESP.instance
12
+ @lit32 = OpImmidiate32.new(0x12345678)
13
+ @in_eax = OpIndirect.new(@eax)
14
+ @in_eax_125 = OpIndirect.new(@eax, OpImmidiate8.new(125))
15
+ @in_eax_4096 = OpIndirect.new(@eax, OpImmidiate32.new(4096))
16
+ @in_esp_0 = OpIndirect.new(@esp)
17
+ @in_esp_10 = OpIndirect.new(@esp, OpImmidiate8.new(-10))
18
+ end
19
+
20
+ def test_add
21
+
22
+ assert_equal(@asm.add(@eax, @lit32), [5, 0x12345678].pack("CL"))
23
+ assert_equal(@asm.add(@ecx, @lit32), [0x81, 0xC1, 0x12345678].pack("CCL"))
24
+ assert_equal(@asm.add(@ecx, @eax), [3, 0xC8].pack("CC"))
25
+ assert_equal(@asm.add(@eax, @in_eax), [3, 0].pack("CC"))
26
+ assert_equal(@asm.add(@eax, @in_eax_125), [3, 0x40, 125].pack("C3"))
27
+ assert_equal(@asm.add(@in_eax_4096, @eax), [1, 0x80, 0, 0x10, 0, 0].pack("C*"))
28
+ assert_equal(@asm.imul(@eax, @lit32), "i\xC0xV4\x12")
29
+ assert_equal(@asm.imul(@eax, @ecx, @lit32), "i\xC1xV4\x12")
30
+ assert_equal(@asm.imul(@eax, @in_eax_4096, @lit32), "i\x80\x00\x10\x00\x00xV4\x12")
31
+ # @cs.disassemble
32
+ end
33
+
34
+ def test_mov
35
+ assert_equal(@asm.mov(@eax, @lit32), [0xB8, 0x12345678].pack("CL"))
36
+ assert_equal(@asm.mov(@eax, @in_eax_125), [0x8B, 0x40, 0x7d].pack("C3"))
37
+ assert_equal(@asm.mov(@in_eax_125, @eax), [0x89, 0x40, 0x7d].pack("C3"))
38
+ File.open("foo.bin", "w") {|fp|
39
+ =begin
40
+ lab = @asm.current_address
41
+ fp.write @asm.add(@eax, @in_eax_125)
42
+ fp.write @asm.add(@in_eax_125, @eax)
43
+ fp.write @asm.add(@in_eax_4096, @eax)
44
+ fp.write @asm.sub(@eax, @in_eax_125)
45
+ fp.write @asm.and(@in_eax_125, @eax)
46
+ fp.write @asm.or(@in_eax_4096, @eax)
47
+ lab2 = @asm.current_address
48
+ fp.write @asm.xor(@in_eax_4096, @eax)
49
+ fp.write @asm.cmp(@in_eax_4096, @eax)
50
+ fp.write @asm.mov(@eax, @lit32)
51
+ fp.write @asm.mov(@eax, @in_eax_125)
52
+ fp.write @asm.mov(@in_eax_125, @eax)
53
+ fp.write @asm.mov(@in_esp_0, @eax)
54
+ fp.write @asm.mov(@in_esp_10, @eax)
55
+ fp.write @asm.push(@eax)
56
+ fp.write @asm.pop(@in_eax_125)
57
+ fp.write @asm.call(lab)
58
+ fp.write @asm.jo(lab)
59
+ fp.write @asm.jl(lab2)
60
+ fp.write @asm.lea(@eax, @in_esp_0)
61
+ fp.write @asm.lea(@eax, @in_esp_10)
62
+ fp.write @asm.sal(@eax)
63
+ fp.write @asm.sar(@eax)
64
+ fp.write @asm.shl(@eax)
65
+ fp.write @asm.shr(@eax)
66
+ fp.write @asm.sal(@eax, 2)
67
+ fp.write @asm.sar(@eax, 2)
68
+ fp.write @asm.shl(@eax, 2)
69
+ fp.write @asm.shr(@eax, 2)
70
+
71
+ fp.write @asm.rcl(@eax)
72
+ fp.write @asm.rcr(@eax)
73
+ fp.write @asm.rol(@eax)
74
+ fp.write @asm.ror(@eax)
75
+ fp.write @asm.rcl(@eax, 2)
76
+ fp.write @asm.rcr(@eax, 2)
77
+ fp.write @asm.rol(@eax, 2)
78
+ fp.write @asm.ror(@eax, 2)
79
+ st = AsmType::Struct.new(
80
+ AsmType::INT32, :foo,
81
+ AsmType::INT32, :bar,
82
+ AsmType::Struct.new(
83
+ AsmType::INT32, :kkk,
84
+ AsmType::INT32, :ass,
85
+ AsmType::INT32, :baz,
86
+ ), :aaa,
87
+ AsmType::INT32, :baz
88
+ )
89
+ foo = TypedData.new(st, X86::EAX)
90
+ cd, foo = @asm.mov(X86::EAX, foo[:baz])
91
+ fp.write cd
92
+ =end
93
+ hello = OpImmidiate32.new("Hello World".address)
94
+ rshello = TypedData.new(InternalRubyType::RString, hello)
95
+ cd, foo = @asm.mov(X86::EAX, rshello[:as][:heap][:ptr])
96
+ fp.write cd
97
+ fp.write @asm.push(X86::EAX)
98
+ rbp = address_of("puts")
99
+ fp.write @asm.call(rbp)
100
+ fp.write @asm.add(X86::ESP, OpImmidiate8.new(4))
101
+ fp.write @asm.ret
102
+ }
103
+ end
104
+
105
+ def test_struct
106
+ st = AsmType::Struct.new(
107
+ AsmType::INT32, :foo,
108
+ AsmType::INT32, :bar,
109
+ AsmType::INT32, :baz
110
+ )
111
+ foo = TypedData.new(st, X86::EAX)
112
+ cd, type = @asm.mov(X86::EAX, foo[:baz])
113
+ assert_equal(cd,
114
+ [0x8b, 0x80, 0x8, 0x0, 0x0, 0x0].pack("C*"))
115
+
116
+ st = AsmType::Struct.new(
117
+ AsmType::INT32, :foo,
118
+ AsmType::INT32, :bar,
119
+ AsmType::Struct.new(
120
+ AsmType::INT32, :kkk,
121
+ AsmType::INT32, :ass,
122
+ AsmType::INT32, :baz,
123
+ ), :aaa,
124
+ AsmType::INT32, :baz
125
+ )
126
+ foo = TypedData.new(st, X86::EBX)
127
+ cd, type = @asm.mov(X86::EDX, foo[:aaa][:baz])
128
+ assert_equal(cd,
129
+ [0x89, 0xd8, 0x8b, 0x80, 0x10, 0x0, 0x0, 0x0, 0x89, 0xc2].pack("C*"))
130
+ end
131
+
132
+ def test_callseq_macro
133
+ @asm.mov(AbsArch::FUNC_ARG[0], OpImmidiate32.new(1))
134
+ @asm.call_with_arg(OpImmidiate32.new(0), 1)
135
+ @cs.disassemble
136
+ end
137
+
138
+ include X86
139
+ def test_movss
140
+ @asm.movss(XMM0, @in_esp_0)
141
+ @asm.movss(XMM7, @in_esp_10)
142
+ @asm.movss(@in_esp_10, XMM0)
143
+ @asm.movsd(XMM0, @in_esp_0)
144
+ @asm.movsd(XMM7, @in_esp_10)
145
+ @asm.movsd(@in_esp_10, XMM0)
146
+ @cs.disassemble
147
+ end
148
+ end
@@ -0,0 +1,286 @@
1
+ require 'test/unit'
2
+ require 'ytljit.rb'
3
+
4
+ include YTLJit
5
+
6
+ class Integer
7
+ def to_as
8
+ "$0X#{self.to_s(16)}"
9
+ end
10
+ end
11
+
12
+ class InstructionTests < Test::Unit::TestCase
13
+ include X86
14
+ include X64
15
+
16
+ def setup
17
+ @cs = CodeSpace.new
18
+ @asm = Assembler.new(@cs, GeneratorExtend)
19
+ @asout = ""
20
+ @regs = [EAX, ECX, EDX, EBX, EBP, EDI, ESI, ESP]
21
+ @regs8 = [AL, CL, DL, BL]
22
+ # @regs = [RAX, RCX, RDX, RBX, RBP, RDI, RSI, RSP, R8, R9, R10,
23
+ # R11, R12, R13, R14, R15]
24
+
25
+ @xmmregs = [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]
26
+ @lits = [OpImmidiate32.new(0x0), OpImmidiate32.new(0x92),
27
+ OpImmidiate32.new(0x8212), OpImmidiate32.new(0x12345678),
28
+ 0, 0x92, 0x8212, 0x12345678]# , 0xffffffff]
29
+ @indirects = []
30
+ [EBP, EDI, ESI, ESP].each do |reg|
31
+ # [RBP, RDI, RSI, RSP].each do |reg|
32
+ [0, 12, 255, 8192, 65535].each do |offset|
33
+ @indirects.push OpIndirect.new(reg, offset)
34
+ end
35
+ end
36
+ end
37
+
38
+ def asm_ytljit(nm, dst, src)
39
+ @asm.with_retry do
40
+ if src then
41
+ @asm.send(nm, dst, src)
42
+ else
43
+ @asm.send(nm, dst)
44
+ end
45
+ end
46
+ end
47
+
48
+ def disasm_ytljit(cs)
49
+ tmpfp = Tempfile.open("ytljitcode")
50
+ tmpfp.write cs.code
51
+ tmpfp.close(false)
52
+ # quick dirty hack to work on Cygwin & Mac OS X/Core2Duo
53
+ # TODO: bdf and instruction set architecture should be automatically selected
54
+ case $ruby_platform
55
+ when /x86_64-darwin/
56
+ objcopy_cmd = "gobjcopy -I binary -O mach-o-i386 -B i386 --adjust-vma=#{cs.base_address} #{tmpfp.path}"
57
+ objdump_cmd = "gobjdump -M x86-64 -D #{tmpfp.path}"
58
+
59
+ when /x86_64/
60
+ objcopy_cmd = "objcopy -I binary -O elf64-x86-64 -B i386 --adjust-vma=#{cs.base_address} #{tmpfp.path}"
61
+ objdump_cmd = "objdump -M x86-64 -D #{tmpfp.path}"
62
+
63
+ when /i.86/
64
+ objcopy_cmd = "objcopy -I binary -O elf32-i386 -B i386 --adjust-vma=#{cs.base_address} #{tmpfp.path}"
65
+ objdump_cmd = "objdump -M i386 -D #{tmpfp.path}"
66
+ end
67
+ system(objcopy_cmd)
68
+ res = []
69
+ File.popen(objdump_cmd, "r") {|fp|
70
+ fp.readlines.each do |lin|
71
+ if /([0-9a-f]*):(\t[0-9a-f ]+? *\t.*)/ =~ lin then
72
+ res.push lin
73
+ end
74
+ end
75
+ }
76
+
77
+ res
78
+ end
79
+
80
+ def asm_gas(nm, dst, src)
81
+ if dst then
82
+ if src then
83
+ @asout += "\t#{nm}\t#{src.to_as}, #{dst.to_as}\n"
84
+ else
85
+ @asout += "\t#{nm}\t#{dst.to_as}\n"
86
+ end
87
+ else
88
+ if src then
89
+ @asout += "\t#{nm}\t#{src.to_as}\n"
90
+ else
91
+ @asout += "\t#{nm}\n"
92
+ end
93
+ end
94
+ end
95
+
96
+ def disasm_gas(cs)
97
+ tmpfp = Tempfile.open("gascode")
98
+ tmpfp.write @asout
99
+ tmpfp.close(false)
100
+ system("as #{tmpfp.path}")
101
+
102
+ case $ruby_platform
103
+ when /x86_64-darwin/
104
+ objdump_cmd = "gobjdump -M x86-64 -D --adjust-vma=#{cs.base_address} a.out"
105
+
106
+ when /x86_64/
107
+ objdump_cmd = "objdump -M x86-64 -D --adjust-vma=#{cs.base_address} a.out"
108
+
109
+ when /i.86/
110
+ objdump_cmd = "objdump -M i386 -D --adjust-vma=#{cs.base_address} a.out"
111
+ end
112
+
113
+ res = []
114
+ File.popen(objdump_cmd, "r") {|fp|
115
+ fp.readlines.each do |lin|
116
+ if /([0-9a-f]*):(\t[0-9a-f ]+? *\t.*)/ =~ lin then
117
+ res.push lin
118
+ end
119
+ end
120
+ }
121
+
122
+ res
123
+ end
124
+
125
+ def test_asm
126
+ [:mov, :add, :or, :adc, :sbb, :and, :sub, :xor, :cmp].each do |mnm|
127
+ # Pattern reg, immidiate
128
+ @regs.each do |reg|
129
+ @lits.each do |src|
130
+ asm_ytljit(mnm, reg, src)
131
+ asm_gas(mnm, reg, src)
132
+ end
133
+ end
134
+
135
+ # Pattern reg, reg
136
+ @regs.each do |reg|
137
+ @regs.each do |src|
138
+ asm_ytljit(mnm, reg, src)
139
+ asm_gas(mnm, reg, src)
140
+ end
141
+ end
142
+
143
+ # Pattern indirect, reg
144
+ @indirects.each do |dst|
145
+ # asm_ytljit(mnm, dst, @lits[0])
146
+ # asm_gas(mnm, dst, @lits[0])
147
+ @regs.each do |src|
148
+ asm_ytljit(mnm, dst, src)
149
+ asm_gas(mnm, dst, src)
150
+ end
151
+ end
152
+
153
+ # Pattern reg, indirect
154
+ @indirects.each do |src|
155
+ @regs.each do |dst|
156
+ asm_ytljit(mnm, dst, src)
157
+ asm_gas(mnm, dst, src)
158
+ end
159
+ end
160
+
161
+ ytlres = disasm_ytljit(@cs)
162
+ gasres = disasm_gas(@cs)
163
+ # print @asout
164
+ ytlres.each_with_index do |lin, i|
165
+ assert_equal(gasres[i], lin)
166
+ end
167
+ @cs.reset
168
+ @asout = ""
169
+ end
170
+ end
171
+
172
+ def test_lea
173
+ [:lea].each do |mnm|
174
+ @indirects.each do |src|
175
+ # asm_ytljit(mnm, dst, @lits[0])
176
+ # asm_gas(mnm, dst, @lits[0])
177
+ @regs.each do |dst|
178
+ asm_ytljit(mnm, dst, src)
179
+ asm_gas(mnm, dst, src)
180
+ end
181
+ end
182
+
183
+ ytlres = disasm_ytljit(@cs)
184
+ gasres = disasm_gas(@cs)
185
+ ytlres.each_with_index do |lin, i|
186
+ assert_equal(gasres[i], lin)
187
+ end
188
+ @cs.reset
189
+ @asout = ""
190
+ end
191
+ end
192
+
193
+ def test_setcc
194
+ [:seta, :setae, :setb, :setbe, :setg, :setge, :setl, :setle,
195
+ :setna, :setnae, :setnb, :setnle, :setno, :seto,
196
+ :setz, :setnz].each do |mnm|
197
+ @indirects.each do |dst|
198
+ asm_ytljit(mnm, dst, nil)
199
+ asm_gas(mnm, dst, nil)
200
+ end
201
+
202
+ @regs8.each do |dst|
203
+ asm_ytljit(mnm, dst, nil)
204
+ asm_gas(mnm, dst, nil)
205
+ end
206
+
207
+ ytlres = disasm_ytljit(@cs)
208
+ gasres = disasm_gas(@cs)
209
+ ytlres.each_with_index do |lin, i|
210
+ assert_equal(gasres[i], lin)
211
+ end
212
+ @cs.reset
213
+ @asout = ""
214
+ end
215
+ end
216
+
217
+ def test_xmm_mov
218
+ [:movss, :movsd].each do |mnm|
219
+
220
+ # Pattern reg, reg
221
+ @xmmregs.each do |reg|
222
+ @xmmregs.each do |src|
223
+ asm_ytljit(mnm, reg, src)
224
+ asm_gas(mnm, reg, src)
225
+ end
226
+ end
227
+
228
+ # Pattern indirect, reg
229
+ @indirects.each do |dst|
230
+ # asm_ytljit(mnm, dst, @lits[0])
231
+ # asm_gas(mnm, dst, @lits[0])
232
+ @xmmregs.each do |src|
233
+ asm_ytljit(mnm, dst, src)
234
+ asm_gas(mnm, dst, src)
235
+ end
236
+ end
237
+
238
+ # Pattern reg, indirect
239
+ @indirects.each do |src|
240
+ @xmmregs.each do |dst|
241
+ asm_ytljit(mnm, dst, src)
242
+ asm_gas(mnm, dst, src)
243
+ end
244
+ end
245
+
246
+ ytlres = disasm_ytljit(@cs)
247
+ gasres = disasm_gas(@cs)
248
+ # print @asout
249
+ ytlres.each_with_index do |lin, i|
250
+ assert_equal(gasres[i], lin)
251
+ end
252
+ @cs.reset
253
+ @asout = ""
254
+ end
255
+ end
256
+
257
+ def test_xmm_arith
258
+ [:addss, :addsd, :subss, :subsd,
259
+ :mulss, :mulsd, :divss, :divsd].each do |mnm|
260
+
261
+ # Pattern reg, reg
262
+ @xmmregs.each do |reg|
263
+ @xmmregs.each do |src|
264
+ asm_ytljit(mnm, reg, src)
265
+ asm_gas(mnm, reg, src)
266
+ end
267
+ end
268
+
269
+ # Pattern reg, indirect
270
+ @indirects.each do |src|
271
+ @xmmregs.each do |dst|
272
+ asm_ytljit(mnm, dst, src)
273
+ asm_gas(mnm, dst, src)
274
+ end
275
+ end
276
+
277
+ ytlres = disasm_ytljit(@cs)
278
+ gasres = disasm_gas(@cs)
279
+ ytlres.each_with_index do |lin, i|
280
+ assert_equal(gasres[i], lin)
281
+ end
282
+ @cs.reset
283
+ @asout = ""
284
+ end
285
+ end
286
+ end
@@ -0,0 +1,102 @@
1
+ require 'test/unit'
2
+ require 'ytljit.rb'
3
+
4
+ class CodeSpaceTests < Test::Unit::TestCase
5
+ include YTLJit
6
+
7
+ def test_emit
8
+ cs = CodeSpace.new
9
+ cs[0] = "Hello"
10
+ assert_equal(cs.code, "Hello")
11
+ cs.emit("World")
12
+ assert_equal(cs.code, "HelloWorld")
13
+ end
14
+
15
+ def test_ref
16
+ cs = CodeSpace.new
17
+ cs[0] = "Hello"
18
+ assert_equal(cs[1], 'e'.ord)
19
+ # p cs.base_address.to_s(16)
20
+ end
21
+
22
+ def test_withasm
23
+ asm = Assembler.new(cs = CodeSpace.new)
24
+
25
+ # registor definition
26
+ eax = OpEAX.instance
27
+ esp = OpESP.instance
28
+ hello = OpImmidiate32.new("Hello World".address)
29
+ asm.mov(eax, hello)
30
+ asm.push(eax)
31
+ rbp = address_of("rb_p")
32
+ asm.call(rbp)
33
+ asm.add(esp, OpImmidiate8.new(4))
34
+ asm.ret
35
+ # cs.call(cs.base_address)
36
+ end
37
+
38
+ def test_resize
39
+ cs = CodeSpace.new
40
+
41
+ cs[0] = "Hello"
42
+ assert_equal(cs[0], 'H'.ord)
43
+
44
+ cs[32] = "Hello"
45
+ assert_equal(cs[1], 'e'.ord)
46
+
47
+ cs[64] = "Hello"
48
+ assert_equal(cs[2], 'l'.ord)
49
+
50
+ cs[128] = "Hello"
51
+ assert_equal(cs[3], 'l'.ord)
52
+
53
+ cs[256] = "Hello"
54
+ assert_equal(cs[4], 'o'.ord)
55
+
56
+ cs[768] = "Hello"
57
+ assert_equal(cs[4], 'o'.ord)
58
+
59
+ cs[2000] = "Hello"
60
+ assert_equal(cs[4], 'o'.ord)
61
+
62
+ cs[4096] = "Hello"
63
+ assert_equal(cs[4], 'o'.ord)
64
+
65
+ cs[8155] = "Hello"
66
+ assert_equal(cs[4], 'o'.ord)
67
+
68
+ =begin
69
+ #Large Memory area not support
70
+ cs[10920] = "Hello"
71
+ assert_equal(cs[4], 'o'.ord)
72
+
73
+ cs[32768] = "Hello"
74
+ assert_equal(cs[4], 'o'.ord)
75
+
76
+ cs[65520] = "Hello"
77
+ assert_equal(cs[4], 'o'.ord)
78
+ =end
79
+ end
80
+
81
+ def test_manyspace
82
+ cs = []
83
+ 100.times do
84
+ cs = []
85
+ 100.times do |i|
86
+ cs.push CodeSpace.new
87
+ cs.last[4090] = "Hello"
88
+ cs.push CodeSpace.new
89
+ cs.last[90] = "Hello"
90
+ end
91
+ GC.start
92
+
93
+ 321.times do |i|
94
+ cs.push CodeSpace.new
95
+ cs.last[18] = "Hello"
96
+ cs.push CodeSpace.new
97
+ cs.last[289] = "Hello"
98
+ end
99
+ end
100
+ assert_equal(cs.last[293], 'o'.ord)
101
+ end
102
+ end
@@ -0,0 +1,21 @@
1
+ require 'test/unit'
2
+ require 'lib/ytljit/ytljit.rb'
3
+
4
+ include YTLJit::TypeUtil
5
+
6
+ class TreeTests < Test::Unit::TestCase
7
+
8
+ def test_tree
9
+ tree = KlassTree.new
10
+
11
+ tree.add([0], :int)
12
+ tree.add([1.0], :float)
13
+ tree.add([2], :fixnum)
14
+ tree.add([[]], :a)
15
+
16
+ assert_equal(tree.search([[]]).value, :a)
17
+ assert_equal(tree.search([2]).value, :fixnum)
18
+ assert_equal(tree.search([1.0]).value, :float)
19
+ assert_equal(tree.search([]).value, [])
20
+ end
21
+ end
data/test/tivmtest.rb ADDED
@@ -0,0 +1,54 @@
1
+ # test program
2
+ require 'ytljit'
3
+ require 'pp'
4
+
5
+ include YTLJit
6
+ is = RubyVM::InstructionSequence.compile(
7
+ # "def typeinf; p @name; end ; typeinf","", "", 0,
8
+ "p @name","", "", 0,
9
+ # "def typeinf; p @name; end ; ","", "", 0,
10
+ { :peephole_optimization => true,
11
+ :inline_const_cache => false,
12
+ :specialized_instruction => false,}
13
+ ).to_a
14
+ iseq = VMLib::InstSeqTree.new(nil, is)
15
+ pp iseq
16
+
17
+ tr = VM::YARVTranslatorTypeInference.new([iseq])
18
+ #tr = VM::YARVTranslatorSimple.new([iseq])
19
+ context = VM::YARVContext.new
20
+ class Foo;def initialize;@name = :foo;end;end
21
+ class Bar;def initialize;@name = :bar;end;end
22
+ foo = Foo.new
23
+ bar = Bar.new
24
+ tnode = tr.translate(context)
25
+ tnode.inspect_by_graph
26
+ context = VM::CollectInfoContext.new(tnode)
27
+ context = tnode.collect_info(context)
28
+
29
+ context = VM::CompileContext.new(tnode)
30
+ context.slf = foo
31
+ context = tnode.compile(context)
32
+ tnode.code_space.call(tnode.code_space.base_address)
33
+
34
+ context = VM::CompileContext.new(tnode)
35
+ context.slf = bar
36
+ context = tnode.compile(context)
37
+ tnode.code_space.call(tnode.code_space.base_address)
38
+
39
+ # context.code_space.disassemble
40
+ p tnode.code_space
41
+ # tnode.code_space.disassemble
42
+ =begin
43
+ tnode = Marshal.load(Marshal.dump(tnode))
44
+ asm = Assembler.new(tnode.code_space)
45
+ asm.with_retry do
46
+ end
47
+ tnode.code_space.disassemble
48
+ =end
49
+ tnode.code_space_tab.each do |cs|
50
+ cs.fill_disasm_cache
51
+ end
52
+ tnode.code_space.disassemble
53
+
54
+