ytljit 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/code_alloc.c +39 -17
- data/ext/memory.c +170 -22
- data/ext/ytljit.c +57 -2
- data/ext/ytljit.h +15 -2
- data/lib/ytljit/asm.rb +21 -0
- data/lib/ytljit/asmext_x64.rb +1 -1
- data/lib/ytljit/asmutil.rb +1 -0
- data/lib/ytljit/instruction.rb +6 -0
- data/lib/ytljit/instruction_ia.rb +31 -2
- data/lib/ytljit/util.rb +5 -4
- data/lib/ytljit/vm.rb +771 -182
- data/lib/ytljit/vm_codegen.rb +76 -25
- data/lib/ytljit/vm_cruby_obj.rb +34 -13
- data/lib/ytljit/vm_inline_method.rb +154 -32
- data/lib/ytljit/vm_sendnode.rb +597 -112
- data/lib/ytljit/vm_trans.rb +148 -35
- data/lib/ytljit/vm_type.rb +5 -1
- data/lib/ytljit/vm_type_gen.rb +224 -51
- data/lib/ytljit.rb +5 -0
- data/test/test_assemble2.rb +35 -5
- metadata +3 -3
data/lib/ytljit/vm_trans.rb
CHANGED
@@ -3,11 +3,15 @@ module YTLJit
|
|
3
3
|
class YARVContext
|
4
4
|
include Node
|
5
5
|
|
6
|
-
def initialize
|
7
|
-
|
6
|
+
def initialize(oldcontext = nil)
|
7
|
+
if oldcontext and false then
|
8
|
+
@the_top = oldcontext.the_top
|
9
|
+
else
|
10
|
+
@the_top = TopTopNode.new(nil, Object)
|
11
|
+
end
|
8
12
|
@top_nodes = [@the_top]
|
9
13
|
@current_file_name = nil
|
10
|
-
@current_class_node = the_top
|
14
|
+
@current_class_node = @the_top
|
11
15
|
@current_method_node = nil
|
12
16
|
|
13
17
|
@enc_label = ""
|
@@ -16,10 +20,15 @@ module YTLJit
|
|
16
20
|
@current_local_label = nil
|
17
21
|
|
18
22
|
@current_node = @the_top
|
23
|
+
|
19
24
|
@vmtab = []
|
20
25
|
|
21
26
|
@expstack = []
|
27
|
+
|
22
28
|
@local_label_tab = {}
|
29
|
+
@local_label_list = []
|
30
|
+
|
31
|
+
@exception_table = {}
|
23
32
|
|
24
33
|
@not_reached_pos = false
|
25
34
|
|
@@ -39,10 +48,14 @@ module YTLJit
|
|
39
48
|
attr_accessor :current_local_label
|
40
49
|
|
41
50
|
attr_accessor :current_node
|
51
|
+
|
42
52
|
attr :vmtab
|
43
53
|
|
44
54
|
attr :expstack
|
45
55
|
attr :local_label_tab
|
56
|
+
attr :local_label_list
|
57
|
+
|
58
|
+
attr_accessor :exception_table
|
46
59
|
|
47
60
|
attr_accessor :not_reached_pos
|
48
61
|
|
@@ -53,7 +66,19 @@ module YTLJit
|
|
53
66
|
if ctn == nil then
|
54
67
|
ctn = ClassTopNode.new(@the_top, klass, klass.name)
|
55
68
|
end
|
56
|
-
|
69
|
+
|
70
|
+
valnode = nil
|
71
|
+
if value.is_a?(Class) then
|
72
|
+
valnode = ClassTopNode.get_class_top_node(value)
|
73
|
+
if valnode == nil then
|
74
|
+
valnode = ClassTopNode.new(@the_top, value, value.name)
|
75
|
+
klassclass = valnode.klassclass
|
76
|
+
valnode.type = RubyType::BaseType.from_ruby_class(klassclass)
|
77
|
+
end
|
78
|
+
else
|
79
|
+
valnode = LiteralNode.new(ctn, value)
|
80
|
+
end
|
81
|
+
|
57
82
|
ctn.get_constant_tab[name] = valnode
|
58
83
|
end
|
59
84
|
|
@@ -71,6 +96,22 @@ module YTLJit
|
|
71
96
|
mname,
|
72
97
|
@current_line_no]
|
73
98
|
end
|
99
|
+
|
100
|
+
def current_exception_table
|
101
|
+
result = {}
|
102
|
+
@exception_table.each do |kind, lst|
|
103
|
+
lst.each do |st, ed, cnt, body|
|
104
|
+
if @local_label_list.include?(st) and
|
105
|
+
!@local_label_list.include?(ed) and
|
106
|
+
body then
|
107
|
+
result[kind] = [st, ed, cnt, body]
|
108
|
+
break
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
result
|
114
|
+
end
|
74
115
|
end
|
75
116
|
|
76
117
|
class YARVTranslatorBase
|
@@ -131,6 +172,7 @@ module YTLJit
|
|
131
172
|
nllab = context.local_label_tab[label]
|
132
173
|
if nllab == nil then
|
133
174
|
nllab = LocalLabel.new(curnode, label)
|
175
|
+
nllab.value_node = PhiNode.new(nllab)
|
134
176
|
nllab.debug_info = context.debug_info
|
135
177
|
context.local_label_tab[label] = nllab
|
136
178
|
end
|
@@ -148,23 +190,26 @@ module YTLJit
|
|
148
190
|
|
149
191
|
def visit_symbol(code, ins, context)
|
150
192
|
context.current_local_label = ins
|
193
|
+
context.local_label_list.push ins
|
151
194
|
|
152
195
|
curnode = context.current_node
|
153
196
|
nllab = get_vmnode_from_label(context, ins)
|
154
197
|
|
155
|
-
|
198
|
+
if !(curnode.is_a?(JumpNode) or
|
199
|
+
curnode.is_a?(MethodEndNode) or
|
200
|
+
curnode.is_a?(ThrowNode)) then
|
156
201
|
jmpnode = JumpNode.new(curnode, nllab)
|
157
202
|
jmpnode.debug_info = context.debug_info
|
158
203
|
nllab.parent = jmpnode
|
159
204
|
|
160
205
|
val = context.expstack.pop
|
161
206
|
nllab.come_from[jmpnode] = val
|
162
|
-
|
207
|
+
|
163
208
|
curnode.body = jmpnode
|
164
209
|
jmpnode.body = nllab
|
165
210
|
context.expstack.push nllab.value_node
|
166
211
|
end
|
167
|
-
|
212
|
+
|
168
213
|
context.current_node = nllab
|
169
214
|
end
|
170
215
|
|
@@ -187,20 +232,53 @@ module YTLJit
|
|
187
232
|
(arg_size - locals.size).times do
|
188
233
|
locals.push nil
|
189
234
|
end
|
190
|
-
|
191
235
|
cnode = mtopnode.construct_frame_info(locals, arg_size, args)
|
236
|
+
exptab = code.header['exception_table']
|
237
|
+
context.exception_table = {}
|
238
|
+
if exptab.size != 0 then
|
239
|
+
exptab.each do |tag, body, st, ed, cont, sp|
|
240
|
+
context.exception_table[tag] ||= []
|
241
|
+
nbody = nil
|
242
|
+
if body then
|
243
|
+
ncontext = YARVContext.new(context)
|
244
|
+
nbody = ExceptionTopNode.new(mtopnode)
|
245
|
+
nbody.debug_info = context.debug_info
|
246
|
+
ncontext.current_node = nbody
|
247
|
+
ncontext.top_nodes.push nbody
|
248
|
+
ncontext.current_file_name = context.current_file_name
|
249
|
+
ncontext.current_class_node = context.current_class_node
|
250
|
+
ncontext.current_method_node = context.current_method_node
|
251
|
+
tr = self.class.new([VMLib::InstSeqTree.new(code, body)])
|
252
|
+
tr.translate(ncontext)
|
253
|
+
end
|
254
|
+
context.exception_table[tag].push [st, ed, cont, nbody]
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
context.not_reached_pos = false
|
192
259
|
context.current_node = cnode
|
193
260
|
end
|
194
261
|
|
195
262
|
def visit_block_end(code, ins, context)
|
196
263
|
curnode = context.current_node
|
197
264
|
top = context.top_nodes.last
|
265
|
+
klassnode = context.current_class_node
|
266
|
+
top.exception_table = context.exception_table
|
198
267
|
if top.class == MethodTopNode then
|
199
268
|
if context.macro_method then
|
200
269
|
code = top.to_ruby(ToRubyContext.new).ret_code.last
|
201
|
-
# print code
|
270
|
+
# print code
|
202
271
|
proc = eval("lambda" + code)
|
203
|
-
SendNode.get_macro_tab[top.name]
|
272
|
+
if SendNode.get_macro_tab[top.name] == nil then
|
273
|
+
SendNode.get_macro_tab[top.name] = {}
|
274
|
+
end
|
275
|
+
SendNode.get_macro_tab[top.name][:last] = proc
|
276
|
+
else
|
277
|
+
if !SendNode.get_user_defined_method_tab[top.name] then
|
278
|
+
SendNode.get_user_defined_method_tab[top.name] = []
|
279
|
+
end
|
280
|
+
klassobj = klassnode.klass_object
|
281
|
+
SendNode.get_user_defined_method_tab[top.name].push klassobj
|
204
282
|
end
|
205
283
|
end
|
206
284
|
end
|
@@ -216,6 +294,9 @@ module YTLJit
|
|
216
294
|
dep
|
217
295
|
end
|
218
296
|
|
297
|
+
def visit_nop(code, ins, context)
|
298
|
+
end
|
299
|
+
|
219
300
|
def visit_getlocal(code, ins, context)
|
220
301
|
dep = depth_of_block(code)
|
221
302
|
visit_getdynamic(code, [:getlocal, ins[1], dep], context)
|
@@ -237,8 +318,14 @@ module YTLJit
|
|
237
318
|
curcode = curcode.parent
|
238
319
|
end
|
239
320
|
offset = curcode.header['misc'][:local_size] + 3 - ins[1]
|
240
|
-
node =
|
241
|
-
|
321
|
+
node = nil
|
322
|
+
if curcode.header['type'] == :ensure and offset == 3 then
|
323
|
+
node = LiteralNode.new(context.current_node, nil)
|
324
|
+
node.debug_info = context.debug_info
|
325
|
+
else
|
326
|
+
node = LocalVarRefNode.new(context.current_node, offset, dep)
|
327
|
+
node.debug_info = context.debug_info
|
328
|
+
end
|
242
329
|
context.expstack.push node
|
243
330
|
end
|
244
331
|
|
@@ -348,7 +435,7 @@ module YTLJit
|
|
348
435
|
def visit_putiseq(code, ins, context)
|
349
436
|
body = VMLib::InstSeqTree.new(code, ins[1])
|
350
437
|
curnode = context.current_node
|
351
|
-
ncontext = YARVContext.new
|
438
|
+
ncontext = YARVContext.new(context)
|
352
439
|
|
353
440
|
case body.header['type']
|
354
441
|
when :block
|
@@ -356,7 +443,7 @@ module YTLJit
|
|
356
443
|
when :method
|
357
444
|
mtopnode = MethodTopNode.new(curnode, body.header['name'].to_sym)
|
358
445
|
when :class
|
359
|
-
mtopnode = ClassTopNode.new(curnode, body.header['name'].to_sym)
|
446
|
+
mtopnode = ClassTopNode.new(curnode, Object, body.header['name'].to_sym)
|
360
447
|
when :top
|
361
448
|
raise "Maybe bug not appear top block."
|
362
449
|
end
|
@@ -426,7 +513,8 @@ module YTLJit
|
|
426
513
|
|
427
514
|
def visit_newarray(code, ins, context)
|
428
515
|
curnode = context.current_node
|
429
|
-
func = FixArgCApiNode.new(curnode, "rb_ary_new3",
|
516
|
+
func = FixArgCApiNode.new(curnode, "rb_ary_new3",
|
517
|
+
[:int, :VALUE, :"..."])
|
430
518
|
argnum = ins[1]
|
431
519
|
argnumnode = LiteralNode.new(nil, argnum)
|
432
520
|
args = []
|
@@ -453,7 +541,7 @@ module YTLJit
|
|
453
541
|
# newhash
|
454
542
|
|
455
543
|
def visit_newrange(code, ins, context)
|
456
|
-
exclflag = LiteralNode.new(nil, ins[1]
|
544
|
+
exclflag = LiteralNode.new(nil, ins[1] != 0)
|
457
545
|
context.expstack.push exclflag
|
458
546
|
newinst_to_sendnode(3, Range, code, ins, context)
|
459
547
|
end
|
@@ -483,7 +571,20 @@ module YTLJit
|
|
483
571
|
end
|
484
572
|
|
485
573
|
def visit_dupn(code, ins, context)
|
486
|
-
|
574
|
+
res = []
|
575
|
+
n = ins[1]
|
576
|
+
n.times do
|
577
|
+
orgnode = context.expstack.pop
|
578
|
+
nnode = MultiplexNode.new(orgnode)
|
579
|
+
res.push nnode
|
580
|
+
end
|
581
|
+
res = res.reverse
|
582
|
+
res.each do |ele|
|
583
|
+
context.expstack.push ele
|
584
|
+
end
|
585
|
+
res.each do |ele|
|
586
|
+
context.expstack.push ele
|
587
|
+
end
|
487
588
|
end
|
488
589
|
|
489
590
|
def visit_swap(code, ins, context)
|
@@ -568,7 +669,7 @@ module YTLJit
|
|
568
669
|
context.current_class_node.constant_tab[name] = cnode
|
569
670
|
|
570
671
|
body = VMLib::InstSeqTree.new(code, ins[2])
|
571
|
-
ncontext = YARVContext.new
|
672
|
+
ncontext = YARVContext.new(context)
|
572
673
|
ncontext.current_file_name = context.current_file_name
|
573
674
|
ncontext.current_node = cnode
|
574
675
|
ncontext.current_class_node = cnode
|
@@ -612,7 +713,7 @@ module YTLJit
|
|
612
713
|
# block
|
613
714
|
if blk_iseq then
|
614
715
|
body = VMLib::InstSeqTree.new(code, blk_iseq)
|
615
|
-
ncontext = YARVContext.new
|
716
|
+
ncontext = YARVContext.new(context)
|
616
717
|
ncontext.current_file_name = context.current_file_name
|
617
718
|
ncontext.current_class_node = context.current_class_node
|
618
719
|
ncontext.current_method_node = context.current_method_node
|
@@ -639,32 +740,30 @@ module YTLJit
|
|
639
740
|
arg = arg.reverse
|
640
741
|
|
641
742
|
func = MethodSelectNode.new(curnode, ins[1])
|
642
|
-
sn = SendNode.
|
643
|
-
if sn
|
644
|
-
|
645
|
-
|
743
|
+
sn = SendNode.macro_expand(context, func, arg, op_flag, seqno)
|
744
|
+
if sn == nil then
|
745
|
+
sn = SendNode.make_send_node(curnode, func, arg, op_flag, seqno)
|
746
|
+
sn.current_exception_table = context.current_exception_table
|
747
|
+
if sn.is_a?(SendEvalNode) then
|
748
|
+
if context.macro_method == nil then
|
749
|
+
context.macro_method = true
|
750
|
+
end
|
646
751
|
end
|
647
|
-
|
648
|
-
|
649
|
-
if sn.is_a?(SendNode) then
|
752
|
+
|
650
753
|
sn.debug_info = context.debug_info
|
651
754
|
func.set_reciever(sn)
|
652
755
|
context.expstack.push sn
|
653
|
-
|
654
|
-
elsif sn.is_a?(Array)
|
756
|
+
else
|
655
757
|
# macro(including eval method). execute in compile time and
|
656
758
|
# compile eval strings.
|
657
759
|
val, evalstr = sn
|
658
760
|
evalstr = evalstr.join("\n")
|
659
761
|
is = RubyVM::InstructionSequence.compile(
|
660
|
-
|
661
|
-
).to_a
|
762
|
+
evalstr, "macro #{ins[1]}", "", 0, YTL::ISEQ_OPTS).to_a
|
662
763
|
ncode = VMLib::InstSeqTree.new(code, is)
|
663
764
|
ncode.body.pop # Chop leave instruction
|
664
765
|
translate_main(ncode, context)
|
665
|
-
# context.expstack.push val
|
666
|
-
else
|
667
|
-
raise "Unexcepted data type #{sn.class}"
|
766
|
+
# context.expstack.push val
|
668
767
|
end
|
669
768
|
|
670
769
|
context
|
@@ -710,6 +809,7 @@ module YTLJit
|
|
710
809
|
args = args.reverse
|
711
810
|
|
712
811
|
nnode = SendNode.new(curnode, func, args, op_flag, seqno)
|
812
|
+
nnode.current_exception_table = context.current_exception_table
|
713
813
|
nnode.debug_info = context.debug_info
|
714
814
|
func.parent = nnode
|
715
815
|
context.expstack.push nnode
|
@@ -726,13 +826,16 @@ module YTLJit
|
|
726
826
|
visit_pop(code, ins, context)
|
727
827
|
curnode = context.current_node
|
728
828
|
vnode = SelfRefNode.new(curnode)
|
729
|
-
vnode.debug_info = context.debug_info
|
730
829
|
else
|
731
830
|
curnode = context.current_node
|
732
831
|
vnode = context.expstack.pop
|
733
|
-
vnode.debug_info = context.debug_info
|
734
832
|
end
|
735
833
|
|
834
|
+
if vnode then
|
835
|
+
vnode.debug_info = context.debug_info
|
836
|
+
else
|
837
|
+
vnode = LiteralNode.new(curnode, nil)
|
838
|
+
end
|
736
839
|
srnode = SetResultNode.new(curnode, vnode)
|
737
840
|
srnode.debug_info = context.debug_info
|
738
841
|
curnode.body = srnode
|
@@ -748,14 +851,24 @@ module YTLJit
|
|
748
851
|
nnode = ClassEndNode.new(srnode)
|
749
852
|
when :top
|
750
853
|
nnode = ClassEndNode.new(srnode)
|
854
|
+
else
|
855
|
+
raise "unkown type #{code.header['type']}"
|
751
856
|
end
|
752
857
|
nnode.debug_info = context.debug_info
|
753
858
|
|
754
859
|
context.top_nodes.last.end_nodes.push nnode
|
755
860
|
srnode.body = nnode
|
861
|
+
context.current_node = nnode
|
862
|
+
context.not_reached_pos = true
|
756
863
|
end
|
757
864
|
|
758
865
|
def visit_throw(code, ins, context)
|
866
|
+
curnode = context.current_node
|
867
|
+
exceptobj = context.expstack.pop
|
868
|
+
|
869
|
+
thnode = ThrowNode.new(curnode, ins[1], exceptobj)
|
870
|
+
curnode.body = thnode
|
871
|
+
context.current_node = thnode
|
759
872
|
end
|
760
873
|
|
761
874
|
def visit_jump(code, ins, context)
|
data/lib/ytljit/vm_type.rb
CHANGED
@@ -14,7 +14,7 @@ module YTLJit
|
|
14
14
|
return cnode
|
15
15
|
end
|
16
16
|
|
17
|
-
if key.zip(cnode.key).all? {|k, n| k.is_a?(n.class)}
|
17
|
+
if key.zip(cnode.key).all? {|k, n| k.is_a?(n.class)} then
|
18
18
|
cnode = cnode.same_klass
|
19
19
|
if cnode == nil then
|
20
20
|
ocnode.same_klass = KlassTreeNode.new(key, value)
|
@@ -245,6 +245,10 @@ module YTLJit
|
|
245
245
|
@ruby_type
|
246
246
|
end
|
247
247
|
|
248
|
+
def abnormal?
|
249
|
+
@@base_type_tab[ruby_type].boxed != boxed
|
250
|
+
end
|
251
|
+
|
248
252
|
attr_writer :ruby_type
|
249
253
|
end
|
250
254
|
|