ytljit 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README +12 -6
- data/lib/ytljit/instruction.rb +11 -0
- data/lib/ytljit/vm.rb +37 -17
- data/lib/ytljit/vm_codegen.rb +14 -3
- data/lib/ytljit/vm_inline_method.rb +18 -2
- data/lib/ytljit/vm_sendnode.rb +6 -3
- data/test/vmtest.rb +3 -1
- metadata +17 -5
data/README
CHANGED
@@ -9,13 +9,19 @@ and refer to CPU flags (carry,zero,negative and so on).
|
|
9
9
|
|
10
10
|
2. Install
|
11
11
|
|
12
|
-
You
|
13
|
-
gem install
|
12
|
+
You can install by gem. Type
|
13
|
+
gem install ytljit
|
14
|
+
|
15
|
+
If you want install manually, please do the following steps.
|
16
|
+
|
17
|
+
Install iseq gem before installing ytljit
|
18
|
+
gem install iseq
|
19
|
+
|
20
|
+
Compile extend library writting in C (ext/*).
|
21
|
+
|
22
|
+
Copy extend library and main program writting in Ruby (lib/*) to
|
23
|
+
your ruby library directory.
|
14
24
|
|
15
|
-
GEM or install script doesn't exist yet.
|
16
|
-
compile extend library writting in C (ext/*).
|
17
|
-
copy extend library and main program writting in Ruby (lib/*) to
|
18
|
-
your ruby library directory.
|
19
25
|
|
20
26
|
3. License
|
21
27
|
|
data/lib/ytljit/instruction.rb
CHANGED
@@ -6,6 +6,9 @@ require 'singleton'
|
|
6
6
|
module YTLJit
|
7
7
|
|
8
8
|
class Operand
|
9
|
+
def using(reg)
|
10
|
+
false
|
11
|
+
end
|
9
12
|
end
|
10
13
|
|
11
14
|
class OpImmidiate<Operand
|
@@ -104,6 +107,10 @@ module YTLJit
|
|
104
107
|
def value
|
105
108
|
reg_no
|
106
109
|
end
|
110
|
+
|
111
|
+
def using(reg)
|
112
|
+
reg == self
|
113
|
+
end
|
107
114
|
end
|
108
115
|
|
109
116
|
class OpIndirect<Operand
|
@@ -119,6 +126,10 @@ module YTLJit
|
|
119
126
|
def to_as
|
120
127
|
"#{@disp}(#{@reg.to_as})"
|
121
128
|
end
|
129
|
+
|
130
|
+
def using(reg)
|
131
|
+
@reg == reg
|
132
|
+
end
|
122
133
|
end
|
123
134
|
|
124
135
|
case $ruby_platform
|
data/lib/ytljit/vm.rb
CHANGED
@@ -383,6 +383,10 @@ LocalVarNode
|
|
383
383
|
end
|
384
384
|
|
385
385
|
class DummyNode
|
386
|
+
def collect_info(context)
|
387
|
+
context
|
388
|
+
end
|
389
|
+
|
386
390
|
def collect_candidate_type(context)
|
387
391
|
context
|
388
392
|
end
|
@@ -495,9 +499,13 @@ LocalVarNode
|
|
495
499
|
end
|
496
500
|
|
497
501
|
def collect_candidate_type(context, signode, sig)
|
498
|
-
if add_cs_for_signature(sig) == nil
|
499
|
-
|
502
|
+
if add_cs_for_signature(sig) == nil and
|
503
|
+
context.visited_top_node[self] then
|
504
|
+
return context
|
500
505
|
end
|
506
|
+
|
507
|
+
context.visited_top_node[self] = true
|
508
|
+
|
501
509
|
context.current_method_signature_node.push signode
|
502
510
|
context = @body.collect_candidate_type(context)
|
503
511
|
@end_nodes.each do |enode|
|
@@ -533,7 +541,10 @@ LocalVarNode
|
|
533
541
|
if oldcs then
|
534
542
|
context.set_code_space(oldcs)
|
535
543
|
end
|
536
|
-
|
544
|
+
|
545
|
+
if context.options[:disp_signature] then
|
546
|
+
disp_signature
|
547
|
+
end
|
537
548
|
context
|
538
549
|
end
|
539
550
|
end
|
@@ -613,6 +624,7 @@ LocalVarNode
|
|
613
624
|
|
614
625
|
def collect_candidate_type(context, signode, sig)
|
615
626
|
context.convergent = true
|
627
|
+
context.visited_top_node = {}
|
616
628
|
super
|
617
629
|
end
|
618
630
|
|
@@ -692,10 +704,16 @@ LocalVarNode
|
|
692
704
|
end
|
693
705
|
|
694
706
|
def offset_arg(n, basereg)
|
695
|
-
rc =
|
696
|
-
|
707
|
+
rc = nil
|
708
|
+
if basereg == BPR then
|
709
|
+
rc = @offset_cache[n]
|
710
|
+
unless rc
|
711
|
+
off = offset_by_byte(n)
|
712
|
+
rc = @offset_cache[n] = OpIndirect.new(basereg, off)
|
713
|
+
end
|
714
|
+
else
|
697
715
|
off = offset_by_byte(n)
|
698
|
-
rc =
|
716
|
+
rc = OpIndirect.new(basereg, off)
|
699
717
|
end
|
700
718
|
|
701
719
|
rc
|
@@ -716,7 +734,7 @@ LocalVarNode
|
|
716
734
|
asm.with_retry do
|
717
735
|
asm.sub(SPR, siz)
|
718
736
|
end
|
719
|
-
cpustack_pushn(siz)
|
737
|
+
context.cpustack_pushn(siz)
|
720
738
|
end
|
721
739
|
context = @body.compile(context)
|
722
740
|
context
|
@@ -890,10 +908,12 @@ LocalVarNode
|
|
890
908
|
|
891
909
|
def collect_candidate_type(context)
|
892
910
|
@local_label.come_from.values.each do |vnode|
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
911
|
+
if vnode then
|
912
|
+
same_type(self, vnode,
|
913
|
+
context.to_key, context.to_key, context)
|
914
|
+
same_type(vnode, self,
|
915
|
+
context.to_key, context.to_key, context)
|
916
|
+
end
|
897
917
|
end
|
898
918
|
context
|
899
919
|
end
|
@@ -1463,7 +1483,6 @@ LocalVarNode
|
|
1463
1483
|
def compile(context)
|
1464
1484
|
context = super(context)
|
1465
1485
|
context = gen_pursue_parent_function(context, @depth)
|
1466
|
-
asm = context.assembler
|
1467
1486
|
base = context.ret_reg
|
1468
1487
|
offarg = @current_frame_info.offset_arg(@offset, base)
|
1469
1488
|
context.ret_node = self
|
@@ -1479,9 +1498,7 @@ LocalVarNode
|
|
1479
1498
|
end
|
1480
1499
|
|
1481
1500
|
def compile_main(context)
|
1482
|
-
|
1483
|
-
base = context.ret_reg
|
1484
|
-
offarg = @current_frame_info.offset_arg(@offset, base)
|
1501
|
+
offarg = @current_frame_info.offset_arg(@offset, BPR)
|
1485
1502
|
context.ret_node = self
|
1486
1503
|
context.ret_reg = offarg
|
1487
1504
|
end
|
@@ -1527,14 +1544,14 @@ LocalVarNode
|
|
1527
1544
|
def compile(context)
|
1528
1545
|
context = super(context)
|
1529
1546
|
context = @val.compile(context)
|
1530
|
-
|
1547
|
+
|
1531
1548
|
decide_type_once(context.to_key)
|
1532
1549
|
if @type.boxed then
|
1533
1550
|
@val.decide_type_once(context.to_key)
|
1534
1551
|
rtype = @val.type
|
1535
1552
|
context = rtype.gen_boxing(context)
|
1536
1553
|
end
|
1537
|
-
|
1554
|
+
|
1538
1555
|
valr = context.ret_reg
|
1539
1556
|
context = gen_pursue_parent_function(context, @depth)
|
1540
1557
|
base = context.ret_reg
|
@@ -1554,6 +1571,9 @@ LocalVarNode
|
|
1554
1571
|
end
|
1555
1572
|
|
1556
1573
|
context.ret_reg = nil
|
1574
|
+
if base == TMPR2 then
|
1575
|
+
context.end_using_reg(base)
|
1576
|
+
end
|
1557
1577
|
context = @body.compile(context)
|
1558
1578
|
context
|
1559
1579
|
end
|
data/lib/ytljit/vm_codegen.rb
CHANGED
@@ -125,6 +125,7 @@ LO | | | |
|
|
125
125
|
@top_node = tnode
|
126
126
|
@current_method_signature_node = []
|
127
127
|
@convergent = false
|
128
|
+
@visited_top_node = {}
|
128
129
|
end
|
129
130
|
|
130
131
|
def to_key(offset = -1)
|
@@ -143,6 +144,7 @@ LO | | | |
|
|
143
144
|
attr :top_node
|
144
145
|
attr :current_method_signature_node
|
145
146
|
attr_accessor :convergent
|
147
|
+
attr_accessor :visited_top_node
|
146
148
|
end
|
147
149
|
|
148
150
|
class CompileContext
|
@@ -158,12 +160,16 @@ LO | | | |
|
|
158
160
|
# RETR(EAX, RAX) or RETFR(STO, XM0) or Immdiage object
|
159
161
|
@ret_reg = RETR
|
160
162
|
@ret_node = nil
|
161
|
-
@depth_reg = {}
|
163
|
+
# @depth_reg = {}
|
164
|
+
@depth_reg = Hash.new(0)
|
162
165
|
@stack_content = []
|
163
166
|
@reg_content = {}
|
164
167
|
|
165
168
|
# Use only type inference compile mode
|
166
169
|
@slf = nil
|
170
|
+
|
171
|
+
# Options from user
|
172
|
+
@options = {}
|
167
173
|
end
|
168
174
|
|
169
175
|
attr :top_node
|
@@ -180,6 +186,8 @@ LO | | | |
|
|
180
186
|
|
181
187
|
attr_accessor :slf
|
182
188
|
|
189
|
+
attr :options
|
190
|
+
|
183
191
|
def set_reg_content(dst, val)
|
184
192
|
if dst.is_a?(FunctionArgument) then
|
185
193
|
dst = dst.dst_opecode
|
@@ -246,7 +254,8 @@ LO | | | |
|
|
246
254
|
end
|
247
255
|
|
248
256
|
def reset_using_reg
|
249
|
-
@depth_reg = {}
|
257
|
+
# @depth_reg = {}
|
258
|
+
@depth_reg = Hash.new(0)
|
250
259
|
end
|
251
260
|
|
252
261
|
def start_using_reg_aux(reg)
|
@@ -483,7 +492,9 @@ LO | | | |
|
|
483
492
|
dmy, callpos = casm.call_with_arg(fnc, numarg)
|
484
493
|
end
|
485
494
|
@var_return_address = casm.output_stream.var_base_address(callpos)
|
486
|
-
dump_context
|
495
|
+
if context.options[:dump_context] then
|
496
|
+
dump_context(context)
|
497
|
+
end
|
487
498
|
context
|
488
499
|
end
|
489
500
|
end
|
@@ -1,11 +1,20 @@
|
|
1
1
|
module YTLJit
|
2
2
|
module VM
|
3
3
|
module ArithmeticOperationUtil
|
4
|
+
include AbsArch
|
4
5
|
def gen_arithmetic_operation(context, inst, tempreg, resreg)
|
5
6
|
context.start_using_reg(tempreg)
|
7
|
+
context = gen_eval_self(context)
|
6
8
|
asm = context.assembler
|
7
9
|
asm.with_retry do
|
8
|
-
|
10
|
+
if context.ret_reg.using(tempreg) then
|
11
|
+
asm.mov(TMPR, context.ret_reg)
|
12
|
+
context.end_using_reg(context.ret_reg)
|
13
|
+
asm.mov(tempreg, TMPR)
|
14
|
+
else
|
15
|
+
asm.mov(tempreg, context.ret_reg)
|
16
|
+
context.end_using_reg(context.ret_reg)
|
17
|
+
end
|
9
18
|
end
|
10
19
|
context.set_reg_content(tempreg, context.ret_node)
|
11
20
|
|
@@ -20,7 +29,14 @@ module YTLJit
|
|
20
29
|
|
21
30
|
asm = context.assembler
|
22
31
|
asm.with_retry do
|
23
|
-
|
32
|
+
if context.ret_reg.using(tempreg) then
|
33
|
+
asm.mov(TMPR, context.ret_reg)
|
34
|
+
context.end_using_reg(context.ret_reg)
|
35
|
+
asm.send(inst, tempreg, TMPR)
|
36
|
+
else
|
37
|
+
asm.send(inst, tempreg, context.ret_reg)
|
38
|
+
context.end_using_reg(context.ret_reg)
|
39
|
+
end
|
24
40
|
end
|
25
41
|
end
|
26
42
|
|
data/lib/ytljit/vm_sendnode.rb
CHANGED
@@ -105,7 +105,6 @@ module YTLJit
|
|
105
105
|
end
|
106
106
|
|
107
107
|
def collect_candidate_type_regident(context, slf)
|
108
|
-
p @func.name
|
109
108
|
context
|
110
109
|
end
|
111
110
|
|
@@ -129,7 +128,7 @@ module YTLJit
|
|
129
128
|
@modified_local_var = context.modified_local_var.dup
|
130
129
|
@modified_instance_var = context.modified_instance_var.dup
|
131
130
|
|
132
|
-
context
|
131
|
+
@body.collect_info(context)
|
133
132
|
end
|
134
133
|
|
135
134
|
def collect_candidate_type(context)
|
@@ -395,6 +394,11 @@ module YTLJit
|
|
395
394
|
yield @new_method
|
396
395
|
end
|
397
396
|
|
397
|
+
def collect_info(context)
|
398
|
+
context = @new_method.collect_info(context)
|
399
|
+
@body.collect_info(context)
|
400
|
+
end
|
401
|
+
|
398
402
|
def collect_candidate_type(context)
|
399
403
|
# type inference of @new method execute when "send" instruction.
|
400
404
|
@body.collect_candidate_type(context)
|
@@ -447,7 +451,6 @@ module YTLJit
|
|
447
451
|
end
|
448
452
|
|
449
453
|
context.current_method_signature.push signature(context)
|
450
|
-
context = gen_eval_self(context)
|
451
454
|
if rtype.ruby_type == Fixnum then
|
452
455
|
context = gen_arithmetic_operation(context, :add, TMPR2, TMPR)
|
453
456
|
elsif rtype.ruby_type == Float then
|
data/test/vmtest.rb
CHANGED
@@ -10,12 +10,14 @@ is = RubyVM::InstructionSequence.compile(
|
|
10
10
|
# "def test(x);if x then a = 1 else a = 3 end;p a end;test(3)","", "", 0,
|
11
11
|
# "def test(x);if x == 3 then a = 1 else a = 3 end;p a end;test(3)","", "", 0,
|
12
12
|
# "def fib(x);if x < 2 then 1 else fib(x + -1) + fib(x + -2) end;end;p fib(35)","", "", 0,
|
13
|
+
# "def fib(x);if x < 2 then 1 else fib(x - 1) + fib(x - 2) end;end;p fib(35)","", "", 0,
|
13
14
|
# "def ffib(x);if x < 2 then 1.0 else ffib(x + -1) + ffib(x + -2) end;end;p ffib(5)","", "", 0,
|
14
15
|
# "def foo; [1, 2, 3][0] + [1, 2, 3][1] end; p foo", "", "", 0,
|
15
16
|
# "def foo(x); if x then x = 1 else x = 2 end; x; end; p foo(1)", "", "", 0,
|
16
17
|
# "def foo(x); if x then x = 2.0 else x = 1 end; x; end; p foo(1)", "", "", 0,
|
17
|
-
"def foo(x); yield(x) + 2; end; p foo(1) {|a| a + 1}", "", "", 0,
|
18
|
+
# "def foo(x); yield(x) + 2; end; p foo(1) {|a| a + 1}", "", "", 0,
|
18
19
|
# "def id(x); x; end; p id(1); p id(1.0)", "", "", 0,
|
20
|
+
"def id(x); x; end; p id(1); p id(1.0); def id2(x) x end; id2(1)", "", "", 0,
|
19
21
|
# "1.1","", "", 0,
|
20
22
|
{ :peephole_optimization => true,
|
21
23
|
:inline_const_cache => false,
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Hideki Miura
|
@@ -14,10 +14,22 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-10-
|
17
|
+
date: 2010-10-20 00:00:00 +09:00
|
18
18
|
default_executable:
|
19
|
-
dependencies:
|
20
|
-
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: iseq
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 0
|
30
|
+
version: "0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
21
33
|
description:
|
22
34
|
email:
|
23
35
|
executables: []
|