ytljit 0.0.8 → 0.0.9
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.
- data/ext/code_alloc.c +2 -2
- data/ext/memory.c +2 -5
- data/ext/thread.c +144 -0
- data/ext/thread.h +24 -0
- data/ext/ytljit.c +33 -6
- data/ext/ytljit.h +33 -0
- data/lib/ytljit.rb +1 -1
- data/lib/ytljit/asm.rb +11 -4
- data/lib/ytljit/asmext_x64.rb +1 -1
- data/lib/ytljit/asmext_x86.rb +1 -1
- data/lib/ytljit/dyna_method.rb +136 -0
- data/lib/ytljit/marshal.rb +11 -0
- data/lib/ytljit/type.rb +2 -2
- data/lib/ytljit/vm.rb +781 -211
- data/lib/ytljit/vm_codegen.rb +73 -24
- data/lib/ytljit/vm_cruby_obj.rb +42 -30
- data/lib/ytljit/vm_inline_method.rb +40 -14
- data/lib/ytljit/vm_sendnode.rb +609 -190
- data/lib/ytljit/vm_trans.rb +60 -16
- data/lib/ytljit/vm_type.rb +29 -9
- data/lib/ytljit/vm_type_gen.rb +131 -56
- data/test/foo.rb +12 -0
- metadata +9 -16
data/lib/ytljit/marshal.rb
CHANGED
data/lib/ytljit/type.rb
CHANGED
@@ -104,8 +104,8 @@ module YTLJit
|
|
104
104
|
deftype :uint32, [4, 4]
|
105
105
|
deftype :int64, [8, 8]
|
106
106
|
deftype :uint64, [8, 8]
|
107
|
-
deftype :double, [8, 8]
|
108
|
-
deftype :float, [4, 4]
|
107
|
+
deftype :double, [8, 8, :float]
|
108
|
+
deftype :float, [4, 4, :float]
|
109
109
|
|
110
110
|
case $ruby_platform
|
111
111
|
when /i.86/
|
data/lib/ytljit/vm.rb
CHANGED
@@ -111,7 +111,7 @@ LocalVarNode
|
|
111
111
|
@my_element_node = BaseNode.new(self)
|
112
112
|
end
|
113
113
|
if @element_node_list == [] then
|
114
|
-
@element_node_list = [[
|
114
|
+
@element_node_list = [[type, sig, @my_element_node, nil]]
|
115
115
|
end
|
116
116
|
end
|
117
117
|
end
|
@@ -140,7 +140,7 @@ LocalVarNode
|
|
140
140
|
@my_element_node = BaseNode.new(self)
|
141
141
|
end
|
142
142
|
if @element_node_list == [] then
|
143
|
-
@element_node_list = [[
|
143
|
+
@element_node_list = [[type, sig, @my_element_node, nil]]
|
144
144
|
end
|
145
145
|
end
|
146
146
|
end
|
@@ -223,7 +223,8 @@ LocalVarNode
|
|
223
223
|
end
|
224
224
|
|
225
225
|
def ti_changed
|
226
|
-
@ti_observer.each do |rec
|
226
|
+
@ti_observer.keys.each do |rec|
|
227
|
+
lst = @ti_observer[rec]
|
227
228
|
lst.each do |dsig, ssig, prc|
|
228
229
|
prc.call
|
229
230
|
end
|
@@ -265,31 +266,54 @@ LocalVarNode
|
|
265
266
|
end
|
266
267
|
end
|
267
268
|
|
268
|
-
def marge_element_node(dst, src)
|
269
|
+
def marge_element_node(dst, src, context)
|
269
270
|
res = dst
|
270
|
-
regnode = dst[0]
|
271
271
|
src.each do |sele|
|
272
|
-
|
272
|
+
exist_same_type = false
|
273
|
+
#=begin
|
274
|
+
res.each do |rele|
|
275
|
+
if rele[3] == sele[3] and
|
276
|
+
rele[1] == sele[1] and
|
277
|
+
rele[2] != sele[2] then
|
278
|
+
# Add entry for old element type version of self
|
279
|
+
rtype = rele[2].decide_type_once(rele[1])
|
280
|
+
if rtype == nil or
|
281
|
+
rtype.ruby_type == NilClass then
|
282
|
+
nele = [rele[0], sele[1], sele[2], sele[3]]
|
283
|
+
if !res.include?(nele) then
|
284
|
+
res.push nele
|
285
|
+
exist_same_type = true
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
#=end
|
291
|
+
|
292
|
+
if !exist_same_type and !res.include?(sele) then
|
273
293
|
res.push sele
|
274
294
|
end
|
275
295
|
end
|
276
|
-
|
296
|
+
|
277
297
|
res
|
278
298
|
end
|
279
299
|
|
280
300
|
def marge_type(dst, src)
|
281
301
|
res = dst
|
282
302
|
src.each do |sele|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
res[i] = sele
|
291
|
-
end
|
303
|
+
org = nil
|
304
|
+
res.delete_if {|e|
|
305
|
+
if e.ruby_type == sele.ruby_type and
|
306
|
+
e.boxed == sele.boxed then
|
307
|
+
org = e
|
308
|
+
else
|
309
|
+
nil
|
292
310
|
end
|
311
|
+
}
|
312
|
+
|
313
|
+
if org and org.have_element? and org.element_type then
|
314
|
+
res.push org
|
315
|
+
else
|
316
|
+
res.push sele
|
293
317
|
end
|
294
318
|
end
|
295
319
|
|
@@ -315,17 +339,17 @@ LocalVarNode
|
|
315
339
|
if orgsize != dtsize then
|
316
340
|
dst.type = nil
|
317
341
|
dst.ti_changed
|
318
|
-
context.convergent = false
|
342
|
+
# context.convergent = false
|
319
343
|
end
|
320
344
|
|
321
345
|
dtlist = dst.element_node_list
|
322
346
|
stlist = src.element_node_list
|
323
347
|
|
324
348
|
orgsize = dtlist.size
|
325
|
-
dst.element_node_list = marge_element_node(dtlist, stlist)
|
349
|
+
dst.element_node_list = marge_element_node(dtlist, stlist, context)
|
326
350
|
if orgsize != dtlist.size then
|
327
351
|
dst.ti_changed
|
328
|
-
context.convergent = false
|
352
|
+
# context.convergent = false
|
329
353
|
end
|
330
354
|
|
331
355
|
dst.set_escape_node(src.is_escape)
|
@@ -352,15 +376,25 @@ LocalVarNode
|
|
352
376
|
ti_update(dst, src, dsig, ssig, context)
|
353
377
|
end
|
354
378
|
|
355
|
-
def add_element_node_backward(args
|
379
|
+
def add_element_node_backward(args)
|
380
|
+
add_element_node(*args)
|
381
|
+
visitnode = {}
|
382
|
+
visitnode[self] = true
|
383
|
+
@ti_observee.each do |rec|
|
384
|
+
rec.add_element_node(*args, true)
|
385
|
+
# rec.add_element_node_backward_aux(args, visitnode)
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
def add_element_node_backward_aux(args, visitnode)
|
356
390
|
if visitnode[self] then
|
357
391
|
return
|
358
392
|
end
|
359
393
|
|
360
|
-
add_element_node(*args)
|
394
|
+
add_element_node(*args, true)
|
361
395
|
visitnode[self] = true
|
362
396
|
@ti_observee.each do |rec|
|
363
|
-
rec.
|
397
|
+
rec.add_element_node_backward_aux(args, visitnode)
|
364
398
|
end
|
365
399
|
end
|
366
400
|
|
@@ -390,30 +424,48 @@ LocalVarNode
|
|
390
424
|
end
|
391
425
|
end
|
392
426
|
|
393
|
-
def add_element_node(curslf, encsig, enode, index, context
|
394
|
-
|
427
|
+
def add_element_node(curslf, encsig, enode, index, context,
|
428
|
+
backp = false)
|
395
429
|
newele = [curslf, encsig, enode, index]
|
396
|
-
|
397
|
-
|
430
|
+
|
431
|
+
# search entry whose index( [3]) is nil
|
432
|
+
nlentry = nil
|
433
|
+
@element_node_list.each do |e|
|
434
|
+
if e[1] == encsig and
|
435
|
+
e[0] == curslf and
|
436
|
+
e[3] == nil then
|
437
|
+
nlentry = e
|
438
|
+
break
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
# entry nil index of new self to non-empty table
|
443
|
+
if nlentry == nil then
|
444
|
+
nlnode = BaseNode.new(nil)
|
445
|
+
nlentry = [curslf, encsig, nlnode, nil]
|
446
|
+
@element_node_list.push nlentry
|
398
447
|
end
|
448
|
+
|
399
449
|
if !@element_node_list.include?(newele) then
|
400
450
|
@element_node_list.push newele
|
401
|
-
|
402
|
-
|
403
|
-
if
|
404
|
-
same_type(
|
451
|
+
nelesig = nlentry[1]
|
452
|
+
nelenode = nlentry[2]
|
453
|
+
if nelenode != enode then
|
454
|
+
same_type(nelenode, enode, nelesig, encsig, context)
|
405
455
|
end
|
406
456
|
if index != nil then
|
407
|
-
@element_node_list.each do |
|
408
|
-
if
|
409
|
-
|
410
|
-
|
411
|
-
same_type(
|
457
|
+
@element_node_list.each do |tmpslf, tmpsig, tmpnode, tmpindex|
|
458
|
+
if tmpslf == curslf and
|
459
|
+
tmpindex == index and
|
460
|
+
tmpnode != enode then
|
461
|
+
same_type(tmpnode, enode, tmpsig, encsig, context)
|
412
462
|
end
|
413
463
|
end
|
414
464
|
end
|
415
465
|
|
416
|
-
|
466
|
+
if !backp then
|
467
|
+
ti_changed
|
468
|
+
end
|
417
469
|
# context.convergent = false
|
418
470
|
end
|
419
471
|
end
|
@@ -444,11 +496,7 @@ LocalVarNode
|
|
444
496
|
|
445
497
|
when 2
|
446
498
|
if tlist[0].ruby_type == tlist[1].ruby_type then
|
447
|
-
|
448
|
-
tlist[0]
|
449
|
-
else
|
450
|
-
tlist[1]
|
451
|
-
end
|
499
|
+
tlist[0]
|
452
500
|
|
453
501
|
elsif tlist[0].ruby_type == NilClass then
|
454
502
|
# nil-able type
|
@@ -466,6 +514,14 @@ LocalVarNode
|
|
466
514
|
tlist[1].ruby_type == Float then
|
467
515
|
tlist[1]
|
468
516
|
|
517
|
+
elsif tlist[0].ruby_type == TrueClass and
|
518
|
+
tlist[1].ruby_type == FalseClass then
|
519
|
+
tlist[0]
|
520
|
+
|
521
|
+
elsif tlist[0].ruby_type == FalseClass and
|
522
|
+
tlist[1].ruby_type == TrueClass then
|
523
|
+
tlist[1]
|
524
|
+
|
469
525
|
else
|
470
526
|
RubyType::DefaultType0.new
|
471
527
|
end
|
@@ -475,11 +531,7 @@ LocalVarNode
|
|
475
531
|
tmptlist.delete_if {|ele| ele.ruby_type == NilClass}
|
476
532
|
if tmptlist.size == 2 and
|
477
533
|
tmptlist[0].ruby_type == tmptlist[1].ruby_type then
|
478
|
-
|
479
|
-
tmptlist[0]
|
480
|
-
else
|
481
|
-
tmptlist[1]
|
482
|
-
end
|
534
|
+
tmptlist[0]
|
483
535
|
|
484
536
|
elsif tmptlist[0].ruby_type == tmptlist[1].ruby_type and
|
485
537
|
tmptlist[0].ruby_type == tmptlist[2].ruby_type then
|
@@ -513,7 +565,7 @@ LocalVarNode
|
|
513
565
|
if # @decided_signature != cursig or
|
514
566
|
@type.equal?(nil) or
|
515
567
|
@type.is_a?(RubyType::DefaultType0) then
|
516
|
-
tlist = type_list(cursig).flatten.uniq
|
568
|
+
tlist = type_list(cursig).flatten.reverse.uniq
|
517
569
|
@decided_signature = cursig
|
518
570
|
@type = decide_type_core(tlist, cursig, local_cache)
|
519
571
|
end
|
@@ -525,11 +577,12 @@ LocalVarNode
|
|
525
577
|
etype2 = {}
|
526
578
|
etype = nil
|
527
579
|
@element_node_list.each do |ele|
|
580
|
+
node = ele[2]
|
528
581
|
sig = ele[1]
|
529
582
|
slf = ele[0]
|
530
|
-
|
531
|
-
|
532
|
-
node.type = nil
|
583
|
+
|
584
|
+
if @type == slf then
|
585
|
+
# node.type = nil
|
533
586
|
tt = node.decide_type_once(sig, local_cache)
|
534
587
|
etype2[ele[3]] ||= []
|
535
588
|
curidx = etype2[ele[3]]
|
@@ -555,6 +608,15 @@ LocalVarNode
|
|
555
608
|
end
|
556
609
|
end
|
557
610
|
|
611
|
+
def search_valid_signature
|
612
|
+
node = @type_list.search_valid_node
|
613
|
+
if node then
|
614
|
+
node.key
|
615
|
+
else
|
616
|
+
nil
|
617
|
+
end
|
618
|
+
end
|
619
|
+
|
558
620
|
def inference_type
|
559
621
|
cs = @type_inference_proc
|
560
622
|
cs.call(cs.var_base_address)
|
@@ -652,25 +714,35 @@ LocalVarNode
|
|
652
714
|
def signature(context, args = @arguments)
|
653
715
|
res = []
|
654
716
|
cursig = context.to_signature
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
res.push
|
662
|
-
context.pop_signature
|
717
|
+
if args[1].is_a?(BlockTopNode) then
|
718
|
+
res.push cursig[1]
|
719
|
+
else
|
720
|
+
res.push args[0].decide_type_once(cursig)
|
721
|
+
end
|
722
|
+
if @func.is_a?(YieldNode) then
|
723
|
+
res.push cursig[0]
|
663
724
|
else
|
664
|
-
# args[1].type = nil
|
665
725
|
res.push args[1].decide_type_once(cursig)
|
666
|
-
# args[2].type = nil
|
667
|
-
slf = args[2].decide_type_once(cursig)
|
668
726
|
end
|
727
|
+
|
728
|
+
mt, slf = get_send_method_node(cursig)
|
669
729
|
res.push slf
|
670
730
|
|
671
731
|
args[3..-1].each do |ele|
|
672
|
-
|
673
|
-
|
732
|
+
if ele.type_list(cursig) == [[], []] then
|
733
|
+
res.push ele.type
|
734
|
+
else
|
735
|
+
ele.type = nil
|
736
|
+
res.push ele.decide_type_once(cursig)
|
737
|
+
end
|
738
|
+
end
|
739
|
+
|
740
|
+
if mt and args[1].is_a?(BlockTopNode) then
|
741
|
+
sig = @yield_signature_cache[cursig]
|
742
|
+
if sig then
|
743
|
+
args[1].type = nil
|
744
|
+
res[1] = args[1].decide_type_once(sig)
|
745
|
+
end
|
674
746
|
end
|
675
747
|
|
676
748
|
res
|
@@ -689,7 +761,7 @@ LocalVarNode
|
|
689
761
|
casm.mov(FUNC_ARG[0], rarg.size) # argc
|
690
762
|
casm.mov(FUNC_ARG[1], TMPR2) # argv
|
691
763
|
end
|
692
|
-
context.set_reg_content(FUNC_ARG[0].dst_opecode,
|
764
|
+
context.set_reg_content(FUNC_ARG[0].dst_opecode, :argc)
|
693
765
|
context.set_reg_content(FUNC_ARG[1].dst_opecode, TMPR2)
|
694
766
|
|
695
767
|
# Method Select
|
@@ -756,9 +828,7 @@ LocalVarNode
|
|
756
828
|
context = arg.compile(context)
|
757
829
|
rnode = context.ret_node
|
758
830
|
rtype = rnode.decide_type_once(sig)
|
759
|
-
|
760
|
-
context = rtype.gen_boxing(context)
|
761
|
-
# end
|
831
|
+
context = rtype.gen_boxing(context)
|
762
832
|
casm = context.assembler
|
763
833
|
casm.with_retry do
|
764
834
|
casm.mov(FUNC_ARG[argpos], context.ret_reg)
|
@@ -775,7 +845,6 @@ LocalVarNode
|
|
775
845
|
|
776
846
|
context.cpustack_popn(numarg * AsmType::MACHINE_WORD.size)
|
777
847
|
context.end_arg_reg
|
778
|
-
context.end_using_reg(fnc)
|
779
848
|
context.ret_reg = RETR
|
780
849
|
context.set_reg_content(context.ret_reg, self)
|
781
850
|
|
@@ -790,7 +859,7 @@ LocalVarNode
|
|
790
859
|
def compile_ytl(context)
|
791
860
|
fnc = nil
|
792
861
|
numarg = @arguments.size
|
793
|
-
|
862
|
+
cursig = context.to_signature
|
794
863
|
|
795
864
|
context.start_arg_reg
|
796
865
|
context.start_arg_reg(FUNC_ARG_YTL)
|
@@ -806,7 +875,7 @@ LocalVarNode
|
|
806
875
|
ent = entbase[3]
|
807
876
|
end
|
808
877
|
if ent then
|
809
|
-
csadd = ent.get_code_space(
|
878
|
+
csadd = ent.get_code_space(cursig).var_base_immidiate_address
|
810
879
|
else
|
811
880
|
csadd = TopTopNode.get_nothing_proc.var_base_immidiate_address
|
812
881
|
end
|
@@ -818,7 +887,7 @@ LocalVarNode
|
|
818
887
|
casm.mov(TMPR, fstentry)
|
819
888
|
casm.mov(handoff, TMPR)
|
820
889
|
end
|
821
|
-
context.set_reg_content(handoff,
|
890
|
+
context.set_reg_content(handoff, :first_exception_entry)
|
822
891
|
end
|
823
892
|
|
824
893
|
# push prev env
|
@@ -829,6 +898,12 @@ LocalVarNode
|
|
829
898
|
casm.mov(FUNC_ARG_YTL[0], TMPR)
|
830
899
|
end
|
831
900
|
context.set_reg_content(FUNC_ARG_YTL[0].dst_opecode, prevenv)
|
901
|
+
elsif @func.is_a?(DirectBlockNode) then
|
902
|
+
context = @arguments[0].compile(context)
|
903
|
+
casm.with_retry do
|
904
|
+
casm.mov(FUNC_ARG_YTL[0], context.ret_reg)
|
905
|
+
end
|
906
|
+
context.set_reg_content(FUNC_ARG_YTL[0].dst_opecode, context.ret_node)
|
832
907
|
else
|
833
908
|
casm.with_retry do
|
834
909
|
casm.mov(FUNC_ARG_YTL[0], BPR)
|
@@ -843,6 +918,7 @@ LocalVarNode
|
|
843
918
|
# compile block with other code space and context
|
844
919
|
tcontext = context.dup
|
845
920
|
tcontext.prev_context = context
|
921
|
+
tcontext.stack_content = []
|
846
922
|
@arguments[1].compile(tcontext)
|
847
923
|
|
848
924
|
casm = context.assembler
|
@@ -857,12 +933,15 @@ LocalVarNode
|
|
857
933
|
context.set_reg_content(FUNC_ARG_YTL[i + 3].dst_opecode,
|
858
934
|
context.ret_node)
|
859
935
|
end
|
860
|
-
|
936
|
+
|
937
|
+
sig = @yield_signature_cache[cursig]
|
938
|
+
ecs = @arguments[1].code_space_from_signature[sig]
|
939
|
+
ecs ||= @arguments[1].code_space
|
940
|
+
entry = ecs.var_base_immidiate_address
|
861
941
|
casm.with_retry do
|
862
|
-
entry = @arguments[1].code_space.var_base_immidiate_address
|
863
942
|
casm.mov(FUNC_ARG_YTL[1], entry)
|
864
943
|
end
|
865
|
-
context.set_reg_content(FUNC_ARG_YTL[1].dst_opecode,
|
944
|
+
context.set_reg_content(FUNC_ARG_YTL[1].dst_opecode, entry)
|
866
945
|
|
867
946
|
# self
|
868
947
|
# Method Select
|
@@ -876,12 +955,12 @@ LocalVarNode
|
|
876
955
|
end
|
877
956
|
context.set_reg_content(FUNC_ARG_YTL[2].dst_opecode, @arguments[2])
|
878
957
|
|
958
|
+
context = gen_save_thepr(context)
|
879
959
|
context = gen_call(context, fnc, numarg)
|
880
960
|
|
881
961
|
context.cpustack_popn(numarg * 8)
|
882
962
|
context.end_arg_reg
|
883
963
|
context.end_arg_reg(FUNC_ARG_YTL)
|
884
|
-
context.end_using_reg(fnc)
|
885
964
|
|
886
965
|
context
|
887
966
|
end
|
@@ -922,7 +1001,6 @@ LocalVarNode
|
|
922
1001
|
|
923
1002
|
context.cpustack_popn(numarg * AsmType::MACHINE_WORD.size)
|
924
1003
|
context.end_arg_reg
|
925
|
-
context.end_using_reg(fnc)
|
926
1004
|
context.ret_reg = RETR
|
927
1005
|
context.set_reg_content(context.ret_reg, self)
|
928
1006
|
|
@@ -931,6 +1009,29 @@ LocalVarNode
|
|
931
1009
|
end
|
932
1010
|
end
|
933
1011
|
|
1012
|
+
module SendSingletonClassUtil
|
1013
|
+
def get_singleton_class_object(slfnode)
|
1014
|
+
tt = nil
|
1015
|
+
case slfnode
|
1016
|
+
when ConstantRefNode
|
1017
|
+
clstop = slfnode.value_node
|
1018
|
+
case clstop
|
1019
|
+
when ClassTopNode
|
1020
|
+
tt = RubyType::BaseType.from_ruby_class(clstop.klass_object)
|
1021
|
+
when LiteralNode
|
1022
|
+
tt = RubyType::BaseType.from_ruby_class(clstop.value)
|
1023
|
+
else
|
1024
|
+
raise "Unkown node type in constant #{slfnode.value_node.class}"
|
1025
|
+
end
|
1026
|
+
|
1027
|
+
else
|
1028
|
+
raise "Unkonwn node type #{@arguments[2].class} "
|
1029
|
+
end
|
1030
|
+
|
1031
|
+
tt
|
1032
|
+
end
|
1033
|
+
end
|
1034
|
+
|
934
1035
|
module MultipleCodeSpaceUtil
|
935
1036
|
def find_cs_by_signature(sig)
|
936
1037
|
@code_spaces.each do |csig, val|
|
@@ -979,6 +1080,21 @@ LocalVarNode
|
|
979
1080
|
end
|
980
1081
|
end
|
981
1082
|
|
1083
|
+
class TypedDummyNode<BaseNode
|
1084
|
+
include TypeListWithoutSignature
|
1085
|
+
@@node_table = {}
|
1086
|
+
|
1087
|
+
def self.instance(cursig, type)
|
1088
|
+
ins = @@node_table[type]
|
1089
|
+
if ins == nil then
|
1090
|
+
ins = @@node_table[type] = TypedDummyNode.new(nil)
|
1091
|
+
ins.add_type(cursig, type)
|
1092
|
+
end
|
1093
|
+
|
1094
|
+
ins
|
1095
|
+
end
|
1096
|
+
end
|
1097
|
+
|
982
1098
|
# The top of top node
|
983
1099
|
class TopNode<BaseNode
|
984
1100
|
include HaveChildlenMixin
|
@@ -989,6 +1105,7 @@ LocalVarNode
|
|
989
1105
|
super(parent)
|
990
1106
|
@name = name
|
991
1107
|
@code_spaces = [] # [[nil, CodeSpace.new]]
|
1108
|
+
@code_space_from_signature = {} # return type -> codespace
|
992
1109
|
@yield_node = []
|
993
1110
|
if @parent then
|
994
1111
|
@classtop = search_class_top
|
@@ -997,15 +1114,25 @@ LocalVarNode
|
|
997
1114
|
end
|
998
1115
|
@end_nodes = []
|
999
1116
|
@signature_cache = []
|
1117
|
+
@current_signature = []
|
1000
1118
|
@exception_table = nil
|
1119
|
+
@send_nodes_with_block = nil
|
1120
|
+
|
1121
|
+
@escape_info_tab = {}
|
1122
|
+
@escape_info = nil
|
1001
1123
|
end
|
1002
1124
|
|
1003
1125
|
attr_accessor :name
|
1126
|
+
attr :code_space_from_signature
|
1004
1127
|
attr :end_nodes
|
1005
1128
|
attr :yield_node
|
1006
1129
|
|
1007
1130
|
attr :signature_cache
|
1131
|
+
attr :current_signature
|
1132
|
+
attr :classtop
|
1008
1133
|
attr_accessor :exception_table
|
1134
|
+
attr_accessor :send_nodes_with_block
|
1135
|
+
attr :escape_info
|
1009
1136
|
|
1010
1137
|
def modified_instance_var
|
1011
1138
|
search_end.modified_instance_var
|
@@ -1033,7 +1160,8 @@ LocalVarNode
|
|
1033
1160
|
|
1034
1161
|
def construct_frame_info(locals, argnum, args)
|
1035
1162
|
finfo = LocalFrameInfoNode.new(self)
|
1036
|
-
|
1163
|
+
# 5means BP on Stack, HP, Exception Tag, BP and SP
|
1164
|
+
finfo.system_num = 5
|
1037
1165
|
|
1038
1166
|
argc = args
|
1039
1167
|
opt_label = []
|
@@ -1043,16 +1171,17 @@ LocalVarNode
|
|
1043
1171
|
block_index = -1
|
1044
1172
|
simple = -1
|
1045
1173
|
if args.is_a?(Array) then
|
1046
|
-
argc
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1174
|
+
argc, opt_label, post_len, post_start,
|
1175
|
+
rest_index, block_index, simple = args
|
1176
|
+
finfo.opt_label = opt_label
|
1177
|
+
finfo.post_len = post_len
|
1178
|
+
finfo.post_start = post_start
|
1179
|
+
finfo.rest_index = rest_index
|
1180
|
+
finfo.block_index = block_index
|
1181
|
+
finfo.simple = simple
|
1182
|
+
end
|
1183
|
+
finfo.argc = argc
|
1054
1184
|
|
1055
|
-
# 5means BP, HP, Exception Tag, BP and SP
|
1056
1185
|
lsize = locals.size + finfo.system_num
|
1057
1186
|
|
1058
1187
|
# construct frame
|
@@ -1102,7 +1231,7 @@ LocalVarNode
|
|
1102
1231
|
finfo
|
1103
1232
|
end
|
1104
1233
|
|
1105
|
-
def
|
1234
|
+
def collect_info_top(context)
|
1106
1235
|
context.yield_node.push []
|
1107
1236
|
context = @body.collect_info(context)
|
1108
1237
|
@yield_node = context.yield_node.pop
|
@@ -1118,21 +1247,13 @@ LocalVarNode
|
|
1118
1247
|
context
|
1119
1248
|
end
|
1120
1249
|
|
1121
|
-
def
|
1122
|
-
|
1123
|
-
|
1124
|
-
return context
|
1125
|
-
end
|
1126
|
-
|
1127
|
-
context.visited_top_node[self] = true
|
1250
|
+
def collect_info(context)
|
1251
|
+
collect_info_top(context)
|
1252
|
+
end
|
1128
1253
|
|
1129
|
-
|
1130
|
-
@signature_cache.push sig
|
1131
|
-
end
|
1132
|
-
|
1254
|
+
def collect_candidate_type_common(context, signode, sig)
|
1133
1255
|
context.push_signature(signode, self)
|
1134
1256
|
context = @body.collect_candidate_type(context)
|
1135
|
-
|
1136
1257
|
if @exception_table then
|
1137
1258
|
@exception_table.each do |kind, lst|
|
1138
1259
|
lst.each do |st, ed, cnt, body|
|
@@ -1142,13 +1263,13 @@ LocalVarNode
|
|
1142
1263
|
end
|
1143
1264
|
end
|
1144
1265
|
end
|
1145
|
-
|
1146
1266
|
context.pop_signature
|
1147
1267
|
|
1148
1268
|
@end_nodes.each do |enode|
|
1149
1269
|
same_type(self, enode, sig, sig, context)
|
1150
1270
|
same_type(enode, self, sig, sig, context)
|
1151
1271
|
end
|
1272
|
+
@current_signature = nil
|
1152
1273
|
context
|
1153
1274
|
end
|
1154
1275
|
|
@@ -1166,6 +1287,24 @@ LocalVarNode
|
|
1166
1287
|
end
|
1167
1288
|
end
|
1168
1289
|
|
1290
|
+
def gen_comment(context)
|
1291
|
+
if debug_info then
|
1292
|
+
lineno = debug_info[3]
|
1293
|
+
fname = debug_info[0]
|
1294
|
+
entry = [1, @name]
|
1295
|
+
@code_spaces.each do |sig, cs|
|
1296
|
+
ent2 = []
|
1297
|
+
ent2.push sig
|
1298
|
+
ent2.push decide_type_once(sig)
|
1299
|
+
entry.push ent2
|
1300
|
+
end
|
1301
|
+
|
1302
|
+
context.comment[fname] ||= {}
|
1303
|
+
context.comment[fname][lineno] ||= []
|
1304
|
+
context.comment[fname][lineno].push entry
|
1305
|
+
end
|
1306
|
+
end
|
1307
|
+
|
1169
1308
|
def compile_init(context)
|
1170
1309
|
context
|
1171
1310
|
end
|
@@ -1191,6 +1330,7 @@ LocalVarNode
|
|
1191
1330
|
end
|
1192
1331
|
end
|
1193
1332
|
context.current_method_signature.pop
|
1333
|
+
@code_space_from_signature[sig] = cs
|
1194
1334
|
end
|
1195
1335
|
|
1196
1336
|
if oldcs then
|
@@ -1201,6 +1341,10 @@ LocalVarNode
|
|
1201
1341
|
disp_signature
|
1202
1342
|
end
|
1203
1343
|
|
1344
|
+
if context.options[:insert_signature_comment] then
|
1345
|
+
gen_comment(context)
|
1346
|
+
end
|
1347
|
+
|
1204
1348
|
context.ret_node = self
|
1205
1349
|
context
|
1206
1350
|
end
|
@@ -1217,6 +1361,37 @@ LocalVarNode
|
|
1217
1361
|
context
|
1218
1362
|
end
|
1219
1363
|
|
1364
|
+
def apply_escape_info_to_args(signode)
|
1365
|
+
@escape_info.each_with_index do |val, idx|
|
1366
|
+
if val then
|
1367
|
+
signode[idx].set_escape_node_backward(val)
|
1368
|
+
end
|
1369
|
+
end
|
1370
|
+
end
|
1371
|
+
|
1372
|
+
def collect_candidate_type(context, signode, sig)
|
1373
|
+
@current_signature = nil
|
1374
|
+
@escape_info_tab[sig] ||= []
|
1375
|
+
@escape_info = @escape_info_tab[sig]
|
1376
|
+
context.visited_top_node[self] ||= []
|
1377
|
+
if add_cs_for_signature(sig) == nil and
|
1378
|
+
context.visited_top_node[self].include?(sig) then
|
1379
|
+
apply_escape_info_to_args(signode)
|
1380
|
+
return context
|
1381
|
+
end
|
1382
|
+
|
1383
|
+
@current_signature = sig
|
1384
|
+
context.visited_top_node[self].push sig
|
1385
|
+
|
1386
|
+
if !@signature_cache.include?(sig) then
|
1387
|
+
@signature_cache.push sig
|
1388
|
+
end
|
1389
|
+
|
1390
|
+
context = collect_candidate_type_common(context, signode, sig)
|
1391
|
+
@escape_info = nil
|
1392
|
+
context
|
1393
|
+
end
|
1394
|
+
|
1220
1395
|
def construct_frame_info(locals, argnum, args)
|
1221
1396
|
locals.unshift :_self
|
1222
1397
|
locals.unshift :_block
|
@@ -1230,7 +1405,7 @@ LocalVarNode
|
|
1230
1405
|
class BlockTopNode<MethodTopNode
|
1231
1406
|
def collect_info(context)
|
1232
1407
|
context.modified_local_var.last.push Hash.new
|
1233
|
-
context =
|
1408
|
+
context = collect_info_top(context)
|
1234
1409
|
context.modified_local_var.last.pop
|
1235
1410
|
context
|
1236
1411
|
end
|
@@ -1369,6 +1544,13 @@ LocalVarNode
|
|
1369
1544
|
def search_constant_with_super(name, klassobj = @klass_object)
|
1370
1545
|
clsnode = @@class_top_tab[klassobj]
|
1371
1546
|
if clsnode then
|
1547
|
+
clsnode.before_search_module.each do |scope, mod|
|
1548
|
+
ctab = mod.get_constant_tab
|
1549
|
+
if val = ctab[name] then
|
1550
|
+
return [val, mod]
|
1551
|
+
end
|
1552
|
+
end
|
1553
|
+
|
1372
1554
|
ctab = clsnode.get_constant_tab
|
1373
1555
|
if val = ctab[name] then
|
1374
1556
|
return [val, clsnode]
|
@@ -1390,16 +1572,21 @@ LocalVarNode
|
|
1390
1572
|
end
|
1391
1573
|
|
1392
1574
|
def collect_candidate_type(context, signode, sig)
|
1575
|
+
@current_signature = nil
|
1393
1576
|
@type = RubyType::BaseType.from_ruby_class(@klassclass)
|
1394
1577
|
add_type(sig, @type)
|
1578
|
+
context.visited_top_node[self] ||= []
|
1395
1579
|
|
1396
1580
|
if add_cs_for_signature(sig) == nil and
|
1397
|
-
context.visited_top_node[self] then
|
1581
|
+
context.visited_top_node[self].include?(sig) then
|
1398
1582
|
return context
|
1399
1583
|
end
|
1400
1584
|
|
1401
|
-
|
1402
|
-
|
1585
|
+
@current_signature = sig
|
1586
|
+
context.visited_top_node[self].push sig
|
1587
|
+
if !@signature_cache.include?(sig) then
|
1588
|
+
@signature_cache.push sig
|
1589
|
+
end
|
1403
1590
|
|
1404
1591
|
context.push_signature(signode, self)
|
1405
1592
|
context = @body.collect_candidate_type(context)
|
@@ -1411,6 +1598,7 @@ LocalVarNode
|
|
1411
1598
|
end
|
1412
1599
|
|
1413
1600
|
set_escape_node(:not_export)
|
1601
|
+
@current_signature = nil
|
1414
1602
|
|
1415
1603
|
context
|
1416
1604
|
end
|
@@ -1441,6 +1629,7 @@ LocalVarNode
|
|
1441
1629
|
context.set_reg_content(FUNC_ARG_YTL[1].dst_opecode, true)
|
1442
1630
|
context.set_reg_content(FUNC_ARG_YTL[2].dst_opecode, self)
|
1443
1631
|
add = cs.var_base_address
|
1632
|
+
context = gen_save_thepr(context)
|
1444
1633
|
context = gen_call(context, add, 3)
|
1445
1634
|
context.end_arg_reg
|
1446
1635
|
end
|
@@ -1569,32 +1758,40 @@ LocalVarNode
|
|
1569
1758
|
|
1570
1759
|
def get_global_arena_address
|
1571
1760
|
ar = @@global_object_area
|
1572
|
-
|
1761
|
+
addr = lambda {
|
1762
|
+
ar.raw_address
|
1763
|
+
}
|
1764
|
+
OpVarImmidiateAddress.new(addr)
|
1573
1765
|
end
|
1574
1766
|
|
1575
1767
|
def get_global_arena_end_address
|
1576
1768
|
ar = @@global_object_area
|
1577
|
-
|
1769
|
+
addr = lambda {
|
1770
|
+
ar.body_address + ar.size
|
1771
|
+
}
|
1772
|
+
OpVarImmidiateAddress.new(addr)
|
1578
1773
|
end
|
1579
1774
|
|
1580
1775
|
def get_local_arena_address
|
1581
1776
|
ar = @@local_object_area
|
1582
|
-
|
1777
|
+
addr = lambda {
|
1778
|
+
ar.raw_address
|
1779
|
+
}
|
1780
|
+
OpVarImmidiateAddress.new(addr)
|
1583
1781
|
end
|
1584
1782
|
|
1585
1783
|
def get_local_arena_end_address
|
1586
1784
|
ar = @@local_object_area
|
1587
|
-
|
1785
|
+
addr = lambda {
|
1786
|
+
(ar.body_address + ar.size) & (~0xf)
|
1787
|
+
}
|
1788
|
+
OpVarImmidiateAddress.new(addr)
|
1588
1789
|
end
|
1589
1790
|
|
1590
1791
|
def compile_init(context)
|
1591
|
-
addr = lambda {
|
1592
|
-
get_local_arena_end_address
|
1593
|
-
}
|
1594
|
-
aa = OpVarImmidiateAddress.new(addr)
|
1595
1792
|
asm = context.assembler
|
1596
1793
|
asm.with_retry do
|
1597
|
-
asm.mov(THEPR,
|
1794
|
+
asm.mov(THEPR, get_local_arena_end_address)
|
1598
1795
|
end
|
1599
1796
|
context
|
1600
1797
|
end
|
@@ -1671,6 +1868,15 @@ LocalVarNode
|
|
1671
1868
|
@offset_cache = {}
|
1672
1869
|
@local_area_size = nil
|
1673
1870
|
@alloca_area_size = 0
|
1871
|
+
|
1872
|
+
@argc = nil
|
1873
|
+
@opt_label = []
|
1874
|
+
@opt_label_node = []
|
1875
|
+
@post_len = nil
|
1876
|
+
@post_start = nil
|
1877
|
+
@rest_index = nil
|
1878
|
+
@block_index = nil
|
1879
|
+
@simple = true
|
1674
1880
|
end
|
1675
1881
|
|
1676
1882
|
def init_after_construct
|
@@ -1699,6 +1905,15 @@ LocalVarNode
|
|
1699
1905
|
attr_accessor :system_num
|
1700
1906
|
attr :previous_frame
|
1701
1907
|
|
1908
|
+
attr_accessor :argc
|
1909
|
+
attr_accessor :opt_label
|
1910
|
+
attr_accessor :opt_label_node
|
1911
|
+
attr_accessor :post_len
|
1912
|
+
attr_accessor :post_start
|
1913
|
+
attr_accessor :rest_index
|
1914
|
+
attr_accessor :block_index
|
1915
|
+
attr_accessor :simple
|
1916
|
+
|
1702
1917
|
def traverse_childlen
|
1703
1918
|
@frame_layout.each do |vinf|
|
1704
1919
|
yield vinf
|
@@ -1825,16 +2040,29 @@ LocalVarNode
|
|
1825
2040
|
if fragstart <= @offset then
|
1826
2041
|
argoff = @offset - fragstart
|
1827
2042
|
tobj = context.current_method_signature_node.last[argoff]
|
1828
|
-
cursig = context.to_signature
|
1829
|
-
cursig2 = context.to_signature(-2)
|
1830
2043
|
if tobj then
|
2044
|
+
cursig = context.to_signature
|
2045
|
+
cursig2 = context.to_signature(-2)
|
1831
2046
|
same_type(self, tobj, cursig, cursig2, context)
|
1832
|
-
#
|
2047
|
+
# same_type(tobj, self, cursig2, cursig, context)
|
1833
2048
|
end
|
1834
2049
|
end
|
1835
2050
|
context
|
1836
2051
|
end
|
1837
2052
|
|
2053
|
+
def set_escape_node(value)
|
2054
|
+
topnode = @parent.parent
|
2055
|
+
if topnode.escape_info then
|
2056
|
+
flay = @parent.frame_layout
|
2057
|
+
fragstart = flay.size - @parent.argument_num
|
2058
|
+
if fragstart <= @offset then
|
2059
|
+
argoff = @offset - fragstart
|
2060
|
+
topnode.escape_info[argoff] = value
|
2061
|
+
end
|
2062
|
+
end
|
2063
|
+
super(value)
|
2064
|
+
end
|
2065
|
+
|
1838
2066
|
def compile(context)
|
1839
2067
|
context = super(context)
|
1840
2068
|
context
|
@@ -1849,6 +2077,7 @@ LocalVarNode
|
|
1849
2077
|
end
|
1850
2078
|
|
1851
2079
|
attr :offset
|
2080
|
+
attr :name
|
1852
2081
|
|
1853
2082
|
def collect_candidate_type(context)
|
1854
2083
|
context
|
@@ -1894,6 +2123,16 @@ LocalVarNode
|
|
1894
2123
|
|
1895
2124
|
def compile(context)
|
1896
2125
|
context = super(context)
|
2126
|
+
if context.options[:insert_signature_comment] then
|
2127
|
+
lineno = debug_info[3] + 1
|
2128
|
+
fname = debug_info[0]
|
2129
|
+
context.comment[fname] ||= {}
|
2130
|
+
context.comment[fname][lineno] ||= []
|
2131
|
+
ent = []
|
2132
|
+
ent.push 3
|
2133
|
+
ent.push @is_escape
|
2134
|
+
context.comment[fname][lineno].push ent
|
2135
|
+
end
|
1897
2136
|
context = gen_method_epilogue(context)
|
1898
2137
|
curas = context.assembler
|
1899
2138
|
curas.with_retry do
|
@@ -2288,8 +2527,10 @@ LocalVarNode
|
|
2288
2527
|
handoff = OpIndirect.new(BPR, AsmType::MACHINE_WORD.size * 2)
|
2289
2528
|
ensureoff = OpIndirect.new(TMPR, 0)
|
2290
2529
|
asm.with_retry do
|
2530
|
+
asm.push(TMPR)
|
2291
2531
|
asm.mov(TMPR, handoff)
|
2292
2532
|
asm.call(ensureoff)
|
2533
|
+
asm.pop(TMPR)
|
2293
2534
|
end
|
2294
2535
|
gen_method_epilogue(context)
|
2295
2536
|
end
|
@@ -2301,9 +2542,9 @@ LocalVarNode
|
|
2301
2542
|
|
2302
2543
|
elsif @state == 2 then # break
|
2303
2544
|
context = @exception_object.compile(context)
|
2304
|
-
|
2305
|
-
|
2306
|
-
asm.mov(
|
2545
|
+
if context.ret_reg != TMPR then
|
2546
|
+
asm.with_retry do
|
2547
|
+
asm.mov(TMPR, context.ret_reg)
|
2307
2548
|
end
|
2308
2549
|
end
|
2309
2550
|
context.set_reg_content(RETR, context.ret_node)
|
@@ -2316,13 +2557,15 @@ LocalVarNode
|
|
2316
2557
|
end
|
2317
2558
|
|
2318
2559
|
elsif @state == 1 then # return
|
2319
|
-
|
2320
|
-
|
2560
|
+
context = @exception_object.compile(context)
|
2561
|
+
if context.ret_reg != TMPR then
|
2562
|
+
asm.with_retry do
|
2563
|
+
asm.mov(TMPR, context.ret_reg)
|
2564
|
+
end
|
2321
2565
|
end
|
2322
2566
|
context.set_reg_content(RETR, context.ret_node)
|
2323
2567
|
tnode = search_frame_info
|
2324
2568
|
finfo = tnode
|
2325
|
-
depth = 0
|
2326
2569
|
while finfo.parent.is_a?(BlockTopNode)
|
2327
2570
|
finfo = finfo.previous_frame
|
2328
2571
|
# two epilogue means block and method which is called with block
|
@@ -2343,18 +2586,49 @@ LocalVarNode
|
|
2343
2586
|
include HaveChildlenMixin
|
2344
2587
|
end
|
2345
2588
|
|
2589
|
+
# Holder of MultiplexNode
|
2590
|
+
class MultiplexHolderNode<BaseNode
|
2591
|
+
include HaveChildlenMixin
|
2592
|
+
|
2593
|
+
def initialize(parent, node)
|
2594
|
+
super(parent)
|
2595
|
+
@mult = node
|
2596
|
+
end
|
2597
|
+
|
2598
|
+
def traverse_childlen
|
2599
|
+
yield @mult
|
2600
|
+
end
|
2601
|
+
|
2602
|
+
def collect_info(context)
|
2603
|
+
context = @mult.collect_info(context)
|
2604
|
+
@body.collect_info(context)
|
2605
|
+
end
|
2606
|
+
|
2607
|
+
def collect_candidate_type(context)
|
2608
|
+
context = @mult.collect_candidate_type(context)
|
2609
|
+
@body.collect_candidate_type(context)
|
2610
|
+
end
|
2611
|
+
|
2612
|
+
def compile(context)
|
2613
|
+
context = @mult.compile(context)
|
2614
|
+
@body.compile(context)
|
2615
|
+
end
|
2616
|
+
end
|
2617
|
+
|
2346
2618
|
# Multiplexer of node (Using YARV stack operation)
|
2347
2619
|
class MultiplexNode<BaseNode
|
2348
2620
|
include HaveChildlenMixin
|
2349
2621
|
include NodeUtil
|
2350
2622
|
|
2351
|
-
def initialize(node)
|
2352
|
-
super(
|
2623
|
+
def initialize(parent, node)
|
2624
|
+
super(parent)
|
2353
2625
|
@node = node
|
2354
2626
|
@compiled_by_signature = []
|
2355
2627
|
@res_area = nil
|
2356
2628
|
end
|
2357
2629
|
|
2630
|
+
attr :node
|
2631
|
+
|
2358
2632
|
def traverse_childlen
|
2359
2633
|
yield @node
|
2360
2634
|
end
|
@@ -2392,19 +2666,26 @@ LocalVarNode
|
|
2392
2666
|
end
|
2393
2667
|
context.set_reg_content(@res_area, self)
|
2394
2668
|
@compiled_by_signature.push sig
|
2395
|
-
|
2396
|
-
context
|
2397
2669
|
else
|
2398
2670
|
asm = context.assembler
|
2399
|
-
|
2400
|
-
|
2671
|
+
rtype = decide_type_once(sig)
|
2672
|
+
if rtype.ruby_type == Float and !rtype.boxed then
|
2673
|
+
asm.with_retry do
|
2674
|
+
asm.movsd(XMM0, @res_area)
|
2675
|
+
end
|
2676
|
+
context.set_reg_content(XMM0, self)
|
2677
|
+
context.ret_reg = XMM0
|
2678
|
+
else
|
2679
|
+
asm.with_retry do
|
2680
|
+
asm.mov(RETR, @res_area)
|
2681
|
+
end
|
2682
|
+
context.set_reg_content(RETR, self)
|
2683
|
+
context.ret_reg = RETR
|
2401
2684
|
end
|
2402
|
-
context.set_reg_content(RETR, self)
|
2403
|
-
context.ret_reg = RETR
|
2404
2685
|
context.ret_node = self
|
2405
|
-
|
2406
|
-
context
|
2407
2686
|
end
|
2687
|
+
|
2688
|
+
context
|
2408
2689
|
end
|
2409
2690
|
end
|
2410
2691
|
|
@@ -2421,14 +2702,15 @@ LocalVarNode
|
|
2421
2702
|
|
2422
2703
|
attr :value
|
2423
2704
|
|
2705
|
+
# Dummy for pass as block (nil)
|
2706
|
+
def code_space_from_signature
|
2707
|
+
{}
|
2708
|
+
end
|
2709
|
+
|
2424
2710
|
def collect_candidate_type(context)
|
2425
2711
|
sig = context.to_signature
|
2426
2712
|
if @type == nil then
|
2427
|
-
|
2428
|
-
@type = decide_type_once(sig)
|
2429
|
-
else
|
2430
|
-
@type = RubyType::BaseType.from_object(@value)
|
2431
|
-
end
|
2713
|
+
@type = RubyType::BaseType.from_object(@value)
|
2432
2714
|
end
|
2433
2715
|
|
2434
2716
|
case @value
|
@@ -2464,6 +2746,7 @@ LocalVarNode
|
|
2464
2746
|
@type.args.push exclnode
|
2465
2747
|
context = exclnode.collect_candidate_type(context)
|
2466
2748
|
add_element_node(@type, sig, fstnode, [0], context)
|
2749
|
+
add_element_node(@type, sig, sndnode, [1], context)
|
2467
2750
|
end
|
2468
2751
|
else
|
2469
2752
|
add_type(sig, @type)
|
@@ -2525,9 +2808,9 @@ LocalVarNode
|
|
2525
2808
|
[@value]
|
2526
2809
|
end
|
2527
2810
|
|
2528
|
-
|
2529
|
-
|
2530
|
-
|
2811
|
+
def type=(val)
|
2812
|
+
val
|
2813
|
+
end
|
2531
2814
|
end
|
2532
2815
|
|
2533
2816
|
class ClassValueNode<BaseNode
|
@@ -2598,10 +2881,12 @@ LocalVarNode
|
|
2598
2881
|
super(parent)
|
2599
2882
|
@name = "block yield"
|
2600
2883
|
@frame_info = search_frame_info
|
2884
|
+
@depth = 0
|
2601
2885
|
end
|
2602
2886
|
|
2603
2887
|
attr :name
|
2604
2888
|
attr :frame_info
|
2889
|
+
attr_accessor :depth
|
2605
2890
|
|
2606
2891
|
def collect_info(context)
|
2607
2892
|
context.yield_node.last.push @parent
|
@@ -2623,27 +2908,96 @@ LocalVarNode
|
|
2623
2908
|
def compile(context)
|
2624
2909
|
context = super(context)
|
2625
2910
|
asm = context.assembler
|
2626
|
-
# You can crash when you use yield in block.
|
2627
|
-
# You can fix this bug for traversing PTMPR for method top.
|
2628
|
-
# But is is little troublesome. So it is not supported.
|
2629
2911
|
prevenv = @frame_info.offset_arg(0, BPR)
|
2912
|
+
prevenv2 = @frame_info.offset_arg(0, TMPR2)
|
2630
2913
|
# offset of self is common, so it no nessery traverse prev frame
|
2631
2914
|
# for @frame_info.
|
2632
2915
|
slfarg = @frame_info.offset_arg(2, PTMPR)
|
2633
2916
|
asm.with_retry do
|
2634
2917
|
asm.mov(PTMPR, prevenv)
|
2918
|
+
end
|
2919
|
+
|
2920
|
+
@depth.times do
|
2921
|
+
asm.with_retry do
|
2922
|
+
asm.mov(PTMPR, prevenv)
|
2923
|
+
end
|
2924
|
+
end
|
2925
|
+
|
2926
|
+
asm.with_retry do
|
2635
2927
|
asm.mov(PTMPR, slfarg)
|
2636
2928
|
end
|
2637
|
-
context.set_reg_content(PTMPR,
|
2929
|
+
context.set_reg_content(PTMPR, :self_of_block)
|
2638
2930
|
context.ret_reg2 = PTMPR
|
2639
|
-
|
2640
|
-
|
2931
|
+
|
2932
|
+
if @depth == 0 then
|
2933
|
+
context.ret_reg = @frame_info.offset_arg(1, BPR)
|
2934
|
+
else
|
2935
|
+
context.start_using_reg(TMPR2)
|
2936
|
+
asm.with_retry do
|
2937
|
+
asm.mov(TMPR2, prevenv)
|
2938
|
+
end
|
2939
|
+
(@depth - 1).times do
|
2940
|
+
asm.with_retry do
|
2941
|
+
asm.mov(TMPR2, prevenv2)
|
2942
|
+
end
|
2943
|
+
end
|
2944
|
+
asm.with_retry do
|
2945
|
+
asm.mov(TMPR2, @frame_info.offset_arg(1, TMPR2))
|
2946
|
+
end
|
2947
|
+
context.ret_reg = TMPR2
|
2948
|
+
end
|
2949
|
+
|
2641
2950
|
context.ret_node = self
|
2642
2951
|
context.set_reg_content(context.ret_reg, self)
|
2643
2952
|
context
|
2644
2953
|
end
|
2645
2954
|
end
|
2646
2955
|
|
2956
|
+
# Use when you wish call block without calling method with block
|
2957
|
+
class DirectBlockNode<BaseNode
|
2958
|
+
include NodeUtil
|
2959
|
+
|
2960
|
+
include SendUtil
|
2961
|
+
|
2962
|
+
def initialize(parent, blk)
|
2963
|
+
super(parent)
|
2964
|
+
@name = "direct call block"
|
2965
|
+
@block = blk
|
2966
|
+
@frame_info = search_frame_info
|
2967
|
+
end
|
2968
|
+
|
2969
|
+
attr :name
|
2970
|
+
attr :frame_info
|
2971
|
+
|
2972
|
+
def collect_info(context)
|
2973
|
+
context
|
2974
|
+
end
|
2975
|
+
|
2976
|
+
def collect_candidate_type(context)
|
2977
|
+
context
|
2978
|
+
end
|
2979
|
+
|
2980
|
+
def calling_convention(context)
|
2981
|
+
:ytl
|
2982
|
+
end
|
2983
|
+
|
2984
|
+
def method_top_node(ctop, slf)
|
2985
|
+
@block
|
2986
|
+
end
|
2987
|
+
|
2988
|
+
def compile(context)
|
2989
|
+
context = super(context)
|
2990
|
+
asm = context.assembler
|
2991
|
+
slfarg = OpIndirect.new(TMPR2, AsmType::MACHINE_WORD.size * 3)
|
2992
|
+
asm.with_retry do
|
2993
|
+
asm.mov(PTMPR, slfarg)
|
2994
|
+
end
|
2995
|
+
context.ret_reg = @block.code_space.var_base_address
|
2996
|
+
context.ret_reg2 = PTMPR
|
2997
|
+
context
|
2998
|
+
end
|
2999
|
+
end
|
3000
|
+
|
2647
3001
|
class CApiCommonNode<BaseNode
|
2648
3002
|
include NodeUtil
|
2649
3003
|
include SendUtil
|
@@ -2699,13 +3053,16 @@ LocalVarNode
|
|
2699
3053
|
|
2700
3054
|
# Method name
|
2701
3055
|
class MethodSelectNode<BaseNode
|
2702
|
-
|
3056
|
+
include SendNodeCodeGen
|
3057
|
+
|
3058
|
+
def initialize(parent, name)
|
2703
3059
|
super(parent)
|
2704
|
-
@name =
|
3060
|
+
@name = name
|
2705
3061
|
@calling_convention = :unkown
|
2706
3062
|
@reciever = nil
|
2707
3063
|
@send_node = nil
|
2708
3064
|
@ruby_reciever = nil
|
3065
|
+
@inline_node = nil
|
2709
3066
|
end
|
2710
3067
|
|
2711
3068
|
def set_reciever(sendnode)
|
@@ -2724,6 +3081,7 @@ LocalVarNode
|
|
2724
3081
|
attr :name
|
2725
3082
|
attr :calling_convention
|
2726
3083
|
attr_accessor :reciever
|
3084
|
+
attr :inline_node
|
2727
3085
|
|
2728
3086
|
def collect_candidate_type(context)
|
2729
3087
|
context
|
@@ -2756,12 +3114,14 @@ LocalVarNode
|
|
2756
3114
|
addr = recobj.method_address_of(@name)
|
2757
3115
|
$symbol_table[addr] = @name
|
2758
3116
|
if addr then
|
2759
|
-
|
3117
|
+
mth = recobj.instance_method(@name)
|
3118
|
+
if variable_argument?(mth.parameters) then
|
2760
3119
|
@calling_convention = :c_vararg
|
2761
3120
|
else
|
2762
3121
|
@calling_convention = :c_fixarg
|
2763
3122
|
end
|
2764
3123
|
else
|
3124
|
+
p parent.debug_info
|
2765
3125
|
raise "Unkown method - #{recobj}##{@name}"
|
2766
3126
|
@calling_convention = :c
|
2767
3127
|
end
|
@@ -2786,17 +3146,45 @@ LocalVarNode
|
|
2786
3146
|
rklass = rtype.ruby_type_raw
|
2787
3147
|
|
2788
3148
|
knode = ClassTopNode.get_class_top_node(rklass)
|
2789
|
-
if knode and
|
3149
|
+
if knode and
|
3150
|
+
(mtop = knode.search_method_with_super(@name)[0]) then
|
2790
3151
|
@calling_convention = :ytl
|
3152
|
+
|
3153
|
+
# Check getter/setter
|
3154
|
+
body = mtop.body.body
|
3155
|
+
if body.is_a?(SetResultNode) then
|
3156
|
+
if body.value_node.is_a?(CRubyInstanceVarRefNode) and
|
3157
|
+
body.body.is_a?(MethodEndNode) then
|
3158
|
+
@calling_convention = :getter
|
3159
|
+
@inline_node = body.value_node
|
3160
|
+
end
|
3161
|
+
else
|
3162
|
+
if body.is_a?(CRubyInstanceVarAssignNode) and
|
3163
|
+
body.val.is_a?(MultiplexNode) and
|
3164
|
+
body.val.node.is_a?(LocalVarRefNode) and
|
3165
|
+
! body.val.node.is_a?(SelfRefNode) and
|
3166
|
+
body.body.is_a?(SetResultNode) and
|
3167
|
+
body.body.body.is_a?(MethodEndNode) then
|
3168
|
+
@calling_convention = :setter
|
3169
|
+
@inline_node = body
|
3170
|
+
end
|
3171
|
+
end
|
2791
3172
|
@ruby_reciever = rklass
|
2792
3173
|
else
|
2793
3174
|
slfval = @reciever.get_constant_value
|
2794
3175
|
mth = nil
|
2795
3176
|
if slfval then
|
2796
3177
|
begin
|
2797
|
-
|
2798
|
-
|
3178
|
+
# search normal method
|
3179
|
+
mth = slfval[0].class.instance_method(@name)
|
3180
|
+
@ruby_reciever = slfval[0].class
|
2799
3181
|
rescue NameError
|
3182
|
+
begin
|
3183
|
+
# search sigleton method
|
3184
|
+
mth = slfval[0].method(@name)
|
3185
|
+
@ruby_reciever = ClassClassWrapper.instance(slfval[0])
|
3186
|
+
rescue NameError
|
3187
|
+
end
|
2800
3188
|
end
|
2801
3189
|
end
|
2802
3190
|
if slfval == nil or mth == nil then
|
@@ -2807,21 +3195,56 @@ LocalVarNode
|
|
2807
3195
|
mth = rklass.instance_method(@name)
|
2808
3196
|
@ruby_reciever = rtype.ruby_type_raw
|
2809
3197
|
rescue NameError
|
2810
|
-
|
3198
|
+
=begin
|
2811
3199
|
p @parent.debug_info
|
2812
3200
|
p sig
|
2813
3201
|
p @name
|
2814
3202
|
p @reciever.class
|
2815
|
-
|
2816
|
-
p type_list(sig)
|
2817
|
-
=begin
|
3203
|
+
p @reciever.instance_eval {@type_list }
|
3204
|
+
p @reciever.type_list(sig)
|
2818
3205
|
mc = @reciever.get_send_method_node(context.to_signature)[0]
|
2819
3206
|
iv = mc.end_nodes[0].parent.value_node
|
2820
3207
|
p iv.instance_eval {@name}
|
2821
3208
|
p iv.instance_eval {@type_list}
|
2822
3209
|
=end
|
2823
|
-
|
2824
|
-
|
3210
|
+
tlist = @reciever.type_list(sig).flatten
|
3211
|
+
if tlist.all? {|e|
|
3212
|
+
eklass = e.ruby_type_raw
|
3213
|
+
knode = ClassTopNode.get_class_top_node(eklass)
|
3214
|
+
knode and knode.search_method_with_super(@name)[0]
|
3215
|
+
} then
|
3216
|
+
@calling_convention = :ytl
|
3217
|
+
|
3218
|
+
elsif tlist.all? {|e|
|
3219
|
+
begin
|
3220
|
+
mth = rklass.instance_method(@name)
|
3221
|
+
variable_argument?(mth.parameters)
|
3222
|
+
rescue NameError
|
3223
|
+
false
|
3224
|
+
end
|
3225
|
+
} then
|
3226
|
+
@calling_convention = :c_vararg
|
3227
|
+
|
3228
|
+
elsif tlist.all? {|e|
|
3229
|
+
begin
|
3230
|
+
mth = rklass.instance_method(@name)
|
3231
|
+
!variable_argument?(mth.parameters)
|
3232
|
+
rescue NameError
|
3233
|
+
false
|
3234
|
+
end
|
3235
|
+
} then
|
3236
|
+
@calling_convention = :c_fixarg
|
3237
|
+
|
3238
|
+
else
|
3239
|
+
@calling_convention = :mixed
|
3240
|
+
end
|
3241
|
+
|
3242
|
+
p sig
|
3243
|
+
p @reciever.instance_eval {@type_list}
|
3244
|
+
p @name
|
3245
|
+
p @parent.debug_info
|
3246
|
+
p @calling_convention
|
3247
|
+
return @calling_convention
|
2825
3248
|
end
|
2826
3249
|
end
|
2827
3250
|
|
@@ -2844,7 +3267,7 @@ LocalVarNode
|
|
2844
3267
|
asm.with_retry do
|
2845
3268
|
asm.mov(PTMPR, slfop)
|
2846
3269
|
end
|
2847
|
-
context.set_reg_content(PTMPR,
|
3270
|
+
context.set_reg_content(PTMPR, :callee_reciever)
|
2848
3271
|
context.ret_reg2 = PTMPR
|
2849
3272
|
mtop = @reciever.search_method_with_super(@name)[0]
|
2850
3273
|
if mtop then
|
@@ -2888,10 +3311,9 @@ LocalVarNode
|
|
2888
3311
|
context = @reciever.compile(context)
|
2889
3312
|
rnode = context.ret_node
|
2890
3313
|
rtype = rnode.decide_type_once(context.to_signature)
|
3314
|
+
do_dyna = rtype.is_a?(RubyType::DefaultType0)
|
2891
3315
|
if @calling_convention != :ytl then
|
2892
|
-
|
2893
|
-
context = rtype.gen_boxing(context)
|
2894
|
-
# end
|
3316
|
+
context = rtype.gen_boxing(context)
|
2895
3317
|
rtype = rtype.to_box
|
2896
3318
|
elsif !rtype.boxed then
|
2897
3319
|
context = rtype.gen_unboxing(context)
|
@@ -2901,7 +3323,7 @@ LocalVarNode
|
|
2901
3323
|
knode = ClassTopNode.get_class_top_node(rrtype)
|
2902
3324
|
mtop = nil
|
2903
3325
|
|
2904
|
-
if
|
3326
|
+
if do_dyna then
|
2905
3327
|
# Can't type inference. Dynamic method search
|
2906
3328
|
mnval = @name.address
|
2907
3329
|
addr = lambda {
|
@@ -2944,8 +3366,8 @@ LocalVarNode
|
|
2944
3366
|
context.end_arg_reg
|
2945
3367
|
|
2946
3368
|
context.ret_node = self
|
2947
|
-
context.set_reg_content(RETR,
|
2948
|
-
context.set_reg_content(TMPR2,
|
3369
|
+
context.set_reg_content(RETR, :method_address)
|
3370
|
+
context.set_reg_content(TMPR2, RETR)
|
2949
3371
|
context.set_reg_content(PTMPR, @reciever)
|
2950
3372
|
context.ret_reg = TMPR2
|
2951
3373
|
|
@@ -2970,8 +3392,11 @@ LocalVarNode
|
|
2970
3392
|
|
2971
3393
|
sig = @parent.signature(context)
|
2972
3394
|
cs = mtop.find_cs_by_signature(sig)
|
3395
|
+
if cs == nil then
|
3396
|
+
sig[0] = context.to_signature[1]
|
3397
|
+
cs = mtop.find_cs_by_signature(sig)
|
3398
|
+
end
|
2973
3399
|
context.ret_reg = cs.var_base_address
|
2974
|
-
|
2975
3400
|
else
|
2976
3401
|
# regident type
|
2977
3402
|
|
@@ -2987,6 +3412,7 @@ LocalVarNode
|
|
2987
3412
|
asm.with_retry do
|
2988
3413
|
asm.mov(PTMPR, recval)
|
2989
3414
|
end
|
3415
|
+
context.set_reg_content(PTMPR, context.ret_node)
|
2990
3416
|
context.set_reg_content(TMPR2, @reciever)
|
2991
3417
|
context.ret_reg2 = PTMPR
|
2992
3418
|
end
|
@@ -3044,7 +3470,9 @@ LocalVarNode
|
|
3044
3470
|
end
|
3045
3471
|
@current_frame_info = tnode
|
3046
3472
|
end
|
3047
|
-
|
3473
|
+
|
3474
|
+
attr :offset
|
3475
|
+
attr :depth
|
3048
3476
|
attr :frame_info
|
3049
3477
|
attr :current_frame_info
|
3050
3478
|
end
|
@@ -3062,7 +3490,11 @@ LocalVarNode
|
|
3062
3490
|
end
|
3063
3491
|
|
3064
3492
|
if vti then
|
3065
|
-
|
3493
|
+
if depth == 0 then
|
3494
|
+
@var_type_info = vti.map {|e| e.dup }
|
3495
|
+
else
|
3496
|
+
@var_type_info = vti
|
3497
|
+
end
|
3066
3498
|
else
|
3067
3499
|
raise "maybe bug"
|
3068
3500
|
roff = @current_frame_info.real_offset(@offset)
|
@@ -3073,11 +3505,12 @@ LocalVarNode
|
|
3073
3505
|
end
|
3074
3506
|
|
3075
3507
|
def collect_candidate_type(context)
|
3076
|
-
|
3077
|
-
|
3508
|
+
cursig = context.to_signature
|
3509
|
+
@type = nil
|
3510
|
+
@var_type_info.reverse.each do |topnode, node|
|
3078
3511
|
varsig = context.to_signature(topnode)
|
3079
3512
|
same_type(self, node, cursig, varsig, context)
|
3080
|
-
same_type(node, self, varsig, cursig, context)
|
3513
|
+
# same_type(node, self, varsig, cursig, context)
|
3081
3514
|
end
|
3082
3515
|
context
|
3083
3516
|
end
|
@@ -3129,8 +3562,22 @@ LocalVarNode
|
|
3129
3562
|
#=begin
|
3130
3563
|
def collect_candidate_type(context)
|
3131
3564
|
if @topnode.is_a?(ClassTopNode) then
|
3132
|
-
|
3133
|
-
|
3565
|
+
tt = RubyType::BaseType.from_ruby_class(@classtop.klass_object)
|
3566
|
+
cursig = context.to_signature
|
3567
|
+
# size of @var_type_info is always 1.because you can't assign self
|
3568
|
+
topnode, node = @var_type_info[0]
|
3569
|
+
|
3570
|
+
vsig = context.to_signature(topnode)
|
3571
|
+
vtype = node.decide_type_once(vsig)
|
3572
|
+
same_type(self, node, cursig, vsig, context)
|
3573
|
+
if vtype.boxed != tt.boxed then
|
3574
|
+
if vtype.boxed then
|
3575
|
+
tt= tt.to_box
|
3576
|
+
else
|
3577
|
+
tt = tt.to_unbox
|
3578
|
+
end
|
3579
|
+
end
|
3580
|
+
add_type(cursig, tt)
|
3134
3581
|
context
|
3135
3582
|
else
|
3136
3583
|
super(context)
|
@@ -3151,6 +3598,7 @@ LocalVarNode
|
|
3151
3598
|
val.parent = self
|
3152
3599
|
@val = val
|
3153
3600
|
@var_from = nil
|
3601
|
+
@var_type_info = nil
|
3154
3602
|
end
|
3155
3603
|
|
3156
3604
|
def traverse_childlen
|
@@ -3180,6 +3628,7 @@ LocalVarNode
|
|
3180
3628
|
end
|
3181
3629
|
|
3182
3630
|
context.modified_local_var.last[-@depth - 1][@offset] = nodepare
|
3631
|
+
@var_type_info = nodepare
|
3183
3632
|
|
3184
3633
|
@body.collect_info(context)
|
3185
3634
|
end
|
@@ -3187,9 +3636,16 @@ LocalVarNode
|
|
3187
3636
|
def collect_candidate_type(context)
|
3188
3637
|
context = @val.collect_candidate_type(context)
|
3189
3638
|
cursig = context.to_signature
|
3190
|
-
|
3191
|
-
|
3192
|
-
|
3639
|
+
varsig = context.to_signature(@var_from)
|
3640
|
+
@var_type_info.reverse.each do |topnode, node|
|
3641
|
+
if node != self then
|
3642
|
+
varsig2 = context.to_signature(topnode)
|
3643
|
+
same_type(self, node, cursig, varsig2, context)
|
3644
|
+
end
|
3645
|
+
end
|
3646
|
+
same_type(self, @val, varsig, cursig, context)
|
3647
|
+
# same_type(@val, self, cursig, varsig, context)
|
3648
|
+
|
3193
3649
|
@body.collect_candidate_type(context)
|
3194
3650
|
end
|
3195
3651
|
|
@@ -3197,15 +3653,29 @@ LocalVarNode
|
|
3197
3653
|
context = super(context)
|
3198
3654
|
context = @val.compile(context)
|
3199
3655
|
|
3200
|
-
|
3201
|
-
|
3202
|
-
|
3203
|
-
|
3204
|
-
|
3205
|
-
|
3206
|
-
|
3656
|
+
cursig = context.to_signature
|
3657
|
+
varsig = context.to_signature(-@depth - 1)
|
3658
|
+
|
3659
|
+
vartype = decide_type_once(varsig)
|
3660
|
+
valtype = @val.decide_type_once(cursig)
|
3661
|
+
|
3662
|
+
asm = context.assembler
|
3663
|
+
# type conversion
|
3664
|
+
if vartype.ruby_type == Float and
|
3665
|
+
valtype.ruby_type == Fixnum then
|
3666
|
+
context = valtype.gen_unboxing(context)
|
3667
|
+
asm.with_retry do
|
3668
|
+
asm.mov(TMPR, context.ret_reg)
|
3669
|
+
asm.cvtsi2sd(XMM0, TMPR)
|
3670
|
+
end
|
3671
|
+
context.ret_reg = XMM0
|
3672
|
+
valtype = valtype.to_unbox
|
3673
|
+
end
|
3674
|
+
|
3675
|
+
if vartype.boxed then
|
3676
|
+
context = valtype.gen_boxing(context)
|
3207
3677
|
else
|
3208
|
-
context =
|
3678
|
+
context = valtype.gen_unboxing(context)
|
3209
3679
|
end
|
3210
3680
|
|
3211
3681
|
valr = context.ret_reg
|
@@ -3214,7 +3684,6 @@ LocalVarNode
|
|
3214
3684
|
base = context.ret_reg
|
3215
3685
|
offarg = @current_frame_info.offset_arg(@offset, base)
|
3216
3686
|
|
3217
|
-
asm = context.assembler
|
3218
3687
|
if valr.is_a?(OpRegistor) or
|
3219
3688
|
(valr.is_a?(OpImmidiate) and !valr.is_a?(OpImmidiate64)) then
|
3220
3689
|
asm.with_retry do
|
@@ -3230,9 +3699,9 @@ LocalVarNode
|
|
3230
3699
|
|
3231
3700
|
tmpctx = context
|
3232
3701
|
@depth.times { tmpctx = tmpctx.prev_context}
|
3233
|
-
tmpctx.set_reg_content(offarg,
|
3702
|
+
tmpctx.set_reg_content(offarg, @val)
|
3234
3703
|
|
3235
|
-
context.ret_reg =
|
3704
|
+
context.ret_reg = TMPR
|
3236
3705
|
if base == TMPR2 then
|
3237
3706
|
context.end_using_reg(base)
|
3238
3707
|
end
|
@@ -3277,9 +3746,11 @@ LocalVarNode
|
|
3277
3746
|
end
|
3278
3747
|
|
3279
3748
|
def collect_candidate_type(context)
|
3280
|
-
|
3281
|
-
|
3282
|
-
|
3749
|
+
cursig = context.to_signature
|
3750
|
+
@var_type_info.each do |node, sigs|
|
3751
|
+
sigs.each do |sig|
|
3752
|
+
same_type(self, node, cursig, sig, context)
|
3753
|
+
end
|
3283
3754
|
end
|
3284
3755
|
|
3285
3756
|
context
|
@@ -3301,8 +3772,11 @@ LocalVarNode
|
|
3301
3772
|
super(parent, name, mnode)
|
3302
3773
|
val.parent = self
|
3303
3774
|
@val = val
|
3775
|
+
@curpare = [self, []]
|
3304
3776
|
end
|
3305
3777
|
|
3778
|
+
attr :val
|
3779
|
+
|
3306
3780
|
def traverse_childlen
|
3307
3781
|
yield @val
|
3308
3782
|
yield @body
|
@@ -3313,22 +3787,26 @@ LocalVarNode
|
|
3313
3787
|
if context.modified_instance_var[@name] == nil then
|
3314
3788
|
context.modified_instance_var[@name] = []
|
3315
3789
|
end
|
3316
|
-
context.modified_instance_var[@name].push
|
3790
|
+
context.modified_instance_var[@name].push @curpare
|
3317
3791
|
@body.collect_info(context)
|
3318
3792
|
end
|
3319
3793
|
|
3320
3794
|
def collect_candidate_type(context)
|
3321
3795
|
context = @val.collect_candidate_type(context)
|
3322
3796
|
cursig = context.to_signature
|
3797
|
+
if !@curpare[1].include? cursig then
|
3798
|
+
@curpare[1].push cursig
|
3799
|
+
end
|
3323
3800
|
same_type(self, @val, cursig, cursig, context)
|
3324
3801
|
# same_type(@val, self, cursig, cursig, context)
|
3325
3802
|
@val.type = nil
|
3326
3803
|
rtype = @val.decide_type_once(cursig)
|
3327
3804
|
rrtype = rtype.ruby_type
|
3328
3805
|
if rrtype != Fixnum and rrtype != Float then
|
3329
|
-
if cursig[2].boxed then
|
3806
|
+
if cursig[2].boxed and @val.is_escape != :global_export and true then
|
3330
3807
|
@val.set_escape_node_backward(:global_export)
|
3331
|
-
|
3808
|
+
context = @val.collect_candidate_type(context)
|
3809
|
+
# context.convergent = false
|
3332
3810
|
else
|
3333
3811
|
@val.set_escape_node_backward(:local_export)
|
3334
3812
|
end
|
@@ -3348,6 +3826,23 @@ LocalVarNode
|
|
3348
3826
|
|
3349
3827
|
# Global Variable
|
3350
3828
|
class GlobalVarRefNode<VariableRefCommonNode
|
3829
|
+
def self.instance(parent, name)
|
3830
|
+
if /^\$[a-zA-Z_]/ =~ name.to_s then
|
3831
|
+
GlobalVarNormalRefNode.new(parent, name)
|
3832
|
+
else
|
3833
|
+
GlobalVarSpecialRefNode.new(parent, name)
|
3834
|
+
end
|
3835
|
+
end
|
3836
|
+
|
3837
|
+
def collect_info(context)
|
3838
|
+
context.modified_global_var[@name] ||= []
|
3839
|
+
@assign_nodes = context.modified_global_var[@name]
|
3840
|
+
context
|
3841
|
+
end
|
3842
|
+
end
|
3843
|
+
|
3844
|
+
|
3845
|
+
class GlobalVarNormalRefNode<GlobalVarRefNode
|
3351
3846
|
include NodeUtil
|
3352
3847
|
include TypeListWithoutSignature
|
3353
3848
|
include UnboxedArrayUtil
|
@@ -3358,15 +3853,14 @@ LocalVarNode
|
|
3358
3853
|
@offset = nil
|
3359
3854
|
end
|
3360
3855
|
|
3361
|
-
def collect_info(context)
|
3362
|
-
@assign_nodes = context.modified_global_var[@name]
|
3363
|
-
context
|
3364
|
-
end
|
3365
|
-
|
3366
3856
|
def collect_candidate_type(context)
|
3367
|
-
|
3368
|
-
|
3369
|
-
|
3857
|
+
if @assign_nodes then
|
3858
|
+
@offset = @assign_nodes[0][0].offset
|
3859
|
+
sig = context.to_signature
|
3860
|
+
@assign_nodes.reverse.each do |an, asig|
|
3861
|
+
same_type(self, an, sig, asig, context)
|
3862
|
+
end
|
3863
|
+
end
|
3370
3864
|
context
|
3371
3865
|
end
|
3372
3866
|
|
@@ -3377,7 +3871,7 @@ LocalVarNode
|
|
3377
3871
|
asm.with_retry do
|
3378
3872
|
asm.mov(TMPR2, context.top_node.get_global_arena_end_address)
|
3379
3873
|
end
|
3380
|
-
context.set_reg_content(TMPR2,
|
3874
|
+
context.set_reg_content(TMPR2, :global_arena)
|
3381
3875
|
context = gen_ref_element(context, nil, -@offset)
|
3382
3876
|
context.end_using_reg(TMPR2)
|
3383
3877
|
rtype = decide_type_once(sig)
|
@@ -3396,6 +3890,61 @@ LocalVarNode
|
|
3396
3890
|
end
|
3397
3891
|
end
|
3398
3892
|
|
3893
|
+
class GlobalVarSpecialRefNode<GlobalVarRefNode
|
3894
|
+
include NodeUtil
|
3895
|
+
include TypeListWithoutSignature
|
3896
|
+
include UnboxedArrayUtil
|
3897
|
+
include SendNodeCodeGen
|
3898
|
+
|
3899
|
+
def initialize(parent, name)
|
3900
|
+
super(parent)
|
3901
|
+
@name = name
|
3902
|
+
@assign_nodes = nil
|
3903
|
+
@offset = nil
|
3904
|
+
end
|
3905
|
+
|
3906
|
+
def collect_candidate_type(context)
|
3907
|
+
tt = RubyType::BaseType.from_object(eval(@name.to_s))
|
3908
|
+
sig = context.to_signature
|
3909
|
+
add_type(sig, tt)
|
3910
|
+
|
3911
|
+
context
|
3912
|
+
end
|
3913
|
+
|
3914
|
+
def compile(context)
|
3915
|
+
asm = context.assembler
|
3916
|
+
add = lambda {
|
3917
|
+
a = address_of("rb_global_entry")
|
3918
|
+
$symbol_table[a] = "rb_global_entry"
|
3919
|
+
a
|
3920
|
+
}
|
3921
|
+
gentry = OpVarMemAddress.new(add)
|
3922
|
+
|
3923
|
+
add = lambda {
|
3924
|
+
a = address_of("rb_gvar_get")
|
3925
|
+
$symbol_table[a] = "rb_gvar_get"
|
3926
|
+
a
|
3927
|
+
}
|
3928
|
+
gget = OpVarMemAddress.new(add)
|
3929
|
+
wsize = AsmType::MACHINE_WORD.size
|
3930
|
+
symid = ((@name.__id__ << 1) / (5 * wsize))
|
3931
|
+
asm.with_retry do
|
3932
|
+
asm.mov(FUNC_ARG[0], symid)
|
3933
|
+
end
|
3934
|
+
context = gen_save_thepr(context)
|
3935
|
+
context = gen_call(context, gentry, 1)
|
3936
|
+
|
3937
|
+
asm.with_retry do
|
3938
|
+
asm.mov(FUNC_ARG[0], RETR)
|
3939
|
+
end
|
3940
|
+
context = gen_save_thepr(context)
|
3941
|
+
context = gen_call(context, gget, 1)
|
3942
|
+
|
3943
|
+
context.ret_reg = RETR
|
3944
|
+
context
|
3945
|
+
end
|
3946
|
+
end
|
3947
|
+
|
3399
3948
|
class GlobalVarAssignNode<VariableRefCommonNode
|
3400
3949
|
include NodeUtil
|
3401
3950
|
include HaveChildlenMixin
|
@@ -3407,28 +3956,31 @@ LocalVarNode
|
|
3407
3956
|
@value = value
|
3408
3957
|
@assign_nodes = nil
|
3409
3958
|
@offset = nil
|
3959
|
+
@assign_no = nil
|
3410
3960
|
end
|
3411
3961
|
|
3412
3962
|
attr :offset
|
3413
3963
|
|
3414
3964
|
def collect_info(context)
|
3415
3965
|
context = @value.collect_info(context)
|
3416
|
-
|
3417
|
-
|
3966
|
+
context.modified_global_var[@name] ||= []
|
3967
|
+
@assign_nodes = context.modified_global_var[@name]
|
3968
|
+
asize = @assign_nodes.size
|
3969
|
+
if asize == 0 then
|
3418
3970
|
@offset = context.modified_global_var.keys.size - 1
|
3419
3971
|
end
|
3420
|
-
@
|
3421
|
-
@assign_nodes.push self
|
3972
|
+
@assign_no = asize
|
3973
|
+
@assign_nodes.push [self, nil]
|
3422
3974
|
@body.collect_info(context)
|
3423
3975
|
end
|
3424
3976
|
|
3425
3977
|
def collect_candidate_type(context)
|
3426
3978
|
sig = context.to_signature
|
3979
|
+
@assign_nodes[@assign_no][1] = sig
|
3427
3980
|
context = @value.collect_candidate_type(context)
|
3428
|
-
same_type(
|
3429
|
-
same_type(self, @assign_nodes[0], sig, sig, context)
|
3981
|
+
same_type(self, @value, sig, sig, context)
|
3430
3982
|
if @offset == nil then
|
3431
|
-
@offset = @assign_nodes[0].offset
|
3983
|
+
@offset = @assign_nodes[0][0].offset
|
3432
3984
|
end
|
3433
3985
|
@body.collect_candidate_type(context)
|
3434
3986
|
end
|
@@ -3440,7 +3992,7 @@ LocalVarNode
|
|
3440
3992
|
asm.with_retry do
|
3441
3993
|
asm.mov(TMPR2, context.top_node.get_global_arena_end_address)
|
3442
3994
|
end
|
3443
|
-
context.set_reg_content(TMPR2, :
|
3995
|
+
context.set_reg_content(TMPR2, :global_arena)
|
3444
3996
|
contet = gen_set_element(context, nil, -@offset, @value)
|
3445
3997
|
context.end_using_reg(TMPR2)
|
3446
3998
|
@body.compile(context)
|
@@ -3469,13 +4021,23 @@ LocalVarNode
|
|
3469
4021
|
end
|
3470
4022
|
|
3471
4023
|
@class_top = klass # .search_class_top
|
4024
|
+
@rklass = rklass
|
3472
4025
|
@value_node = nil
|
4026
|
+
set_value_node
|
4027
|
+
end
|
4028
|
+
|
4029
|
+
def set_value_node
|
4030
|
+
klass = @class_top
|
4031
|
+
rklass = @rklass
|
3473
4032
|
clsnode = nil
|
3474
4033
|
if klass then
|
3475
4034
|
@value_node, clsnode = klass.search_constant_with_super(@name)
|
3476
4035
|
end
|
3477
4036
|
if clsnode == nil and rklass then
|
3478
|
-
|
4037
|
+
begin
|
4038
|
+
@value_node = LiteralNode.new(self, rklass.const_get(@name))
|
4039
|
+
rescue
|
4040
|
+
end
|
3479
4041
|
end
|
3480
4042
|
end
|
3481
4043
|
|
@@ -3493,6 +4055,13 @@ LocalVarNode
|
|
3493
4055
|
context
|
3494
4056
|
end
|
3495
4057
|
|
4058
|
+
def collect_info(context)
|
4059
|
+
if @value_node == nil then
|
4060
|
+
set_value_node
|
4061
|
+
end
|
4062
|
+
super
|
4063
|
+
end
|
4064
|
+
|
3496
4065
|
def compile(context)
|
3497
4066
|
case @value_node
|
3498
4067
|
when ClassTopNode
|
@@ -3540,6 +4109,7 @@ LocalVarNode
|
|
3540
4109
|
end
|
3541
4110
|
|
3542
4111
|
def traverse_childlen
|
4112
|
+
yield @value
|
3543
4113
|
yield @body
|
3544
4114
|
end
|
3545
4115
|
|