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