ytljit 0.0.6 → 0.0.7
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 +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_sendnode.rb
CHANGED
@@ -48,6 +48,7 @@ module YTLJit
|
|
48
48
|
@@current_node = nil
|
49
49
|
@@special_node_tab = {}
|
50
50
|
@@macro_tab = {}
|
51
|
+
@@user_defined_method_tab = {}
|
51
52
|
|
52
53
|
def self.node
|
53
54
|
@@current_node
|
@@ -57,6 +58,10 @@ module YTLJit
|
|
57
58
|
@@macro_tab
|
58
59
|
end
|
59
60
|
|
61
|
+
def self.get_user_defined_method_tab
|
62
|
+
@@user_defined_method_tab
|
63
|
+
end
|
64
|
+
|
60
65
|
def self.add_special_send_node(name)
|
61
66
|
oldcls = @@special_node_tab[name]
|
62
67
|
if oldcls == nil or self < oldcls then
|
@@ -67,16 +72,42 @@ module YTLJit
|
|
67
72
|
end
|
68
73
|
end
|
69
74
|
|
70
|
-
def self.
|
71
|
-
if
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
+
def self.macro_expand(context, func, arguments, op_flag, seqno)
|
76
|
+
if @@macro_tab[func.name] and
|
77
|
+
(op_flag & (0b11 << 3)) != 0 then
|
78
|
+
cclsnode = context.current_class_node
|
79
|
+
if context.current_method_node == nil then
|
80
|
+
cclsnode = cclsnode.make_klassclass_node
|
81
|
+
end
|
82
|
+
|
83
|
+
cclsnode.klass_object.ancestors.each do |ccls|
|
84
|
+
cnode = ClassTopNode.get_class_top_node(ccls)
|
85
|
+
cobj = nil
|
86
|
+
if cnode then
|
87
|
+
cobj = cnode.klass_object
|
88
|
+
end
|
89
|
+
|
90
|
+
if @@user_defined_method_tab[func.name] and
|
91
|
+
@@user_defined_method_tab[func.name].include?(cobj) then
|
92
|
+
return nil
|
93
|
+
end
|
94
|
+
|
95
|
+
mproc = @@macro_tab[func.name][cobj]
|
96
|
+
if mproc then
|
97
|
+
args = []
|
98
|
+
arguments[3..-1].each do |ele|
|
99
|
+
argruby = ele.to_ruby(ToRubyContext.new).ret_code.last
|
100
|
+
args.push eval(argruby)
|
101
|
+
end
|
102
|
+
return mproc.call(*args)
|
103
|
+
end
|
75
104
|
end
|
76
|
-
res = mproc.call(*args)
|
77
|
-
return res
|
78
105
|
end
|
79
106
|
|
107
|
+
nil
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.make_send_node(parent, func, arguments, op_flag, seqno)
|
80
111
|
spcl = @@special_node_tab[func.name]
|
81
112
|
newobj = nil
|
82
113
|
if spcl then
|
@@ -109,6 +140,8 @@ module YTLJit
|
|
109
140
|
|
110
141
|
@result_cache = nil
|
111
142
|
@method_signature = []
|
143
|
+
|
144
|
+
@current_exception_table = nil
|
112
145
|
end
|
113
146
|
|
114
147
|
attr_accessor :func
|
@@ -122,6 +155,8 @@ module YTLJit
|
|
122
155
|
attr_accessor :result_cache
|
123
156
|
attr :seq_no
|
124
157
|
|
158
|
+
attr_accessor :current_exception_table
|
159
|
+
|
125
160
|
def traverse_childlen
|
126
161
|
@arguments.each do |arg|
|
127
162
|
yield arg
|
@@ -132,8 +167,7 @@ module YTLJit
|
|
132
167
|
|
133
168
|
def get_send_method_node(cursig)
|
134
169
|
mt = nil
|
135
|
-
@arguments[2].decide_type_once(cursig)
|
136
|
-
slf = @arguments[2].type
|
170
|
+
slf = @arguments[2].decide_type_once(cursig)
|
137
171
|
if slf.instance_of?(RubyType::DefaultType0) then
|
138
172
|
# Chaos
|
139
173
|
end
|
@@ -299,6 +333,8 @@ module YTLJit
|
|
299
333
|
when :ytl
|
300
334
|
context = compile_ytl(context)
|
301
335
|
|
336
|
+
when nil
|
337
|
+
|
302
338
|
else
|
303
339
|
raise "Unsupported calling conversion #{callconv}"
|
304
340
|
end
|
@@ -333,8 +369,16 @@ module YTLJit
|
|
333
369
|
super
|
334
370
|
@new_method = arguments[5]
|
335
371
|
if arguments[4].is_a?(LiteralNode) then
|
336
|
-
|
337
|
-
@
|
372
|
+
fname = arguments[4].value
|
373
|
+
@new_method.name = fname
|
374
|
+
@class_top.get_method_tab[fname] = @new_method
|
375
|
+
if @@macro_tab[fname] and
|
376
|
+
@@macro_tab[fname][:last] then
|
377
|
+
# This function is macro
|
378
|
+
proc = @@macro_tab[fname][:last]
|
379
|
+
@@macro_tab[fname][:last] = nil
|
380
|
+
@@macro_tab[fname][@class_top.klass_object] = proc
|
381
|
+
end
|
338
382
|
else
|
339
383
|
raise "Not supported not literal method name"
|
340
384
|
end
|
@@ -377,8 +421,15 @@ module YTLJit
|
|
377
421
|
super
|
378
422
|
@new_method = arguments[5]
|
379
423
|
if arguments[4].is_a?(LiteralNode) then
|
380
|
-
|
381
|
-
@
|
424
|
+
fname = arguments[4].value
|
425
|
+
@new_method.name = fname
|
426
|
+
klassclass_node = @class_top.make_klassclass_node
|
427
|
+
if @@macro_tab[fname] and
|
428
|
+
@@macro_tab[fname][:last] then
|
429
|
+
proc = @@macro_tab[fname][:last]
|
430
|
+
@@macro_tab[fname][:last] = nil
|
431
|
+
@@macro_tab[fname][klassclass_node.klass_object] = proc
|
432
|
+
end
|
382
433
|
else
|
383
434
|
raise "Not supported not literal method name"
|
384
435
|
end
|
@@ -425,6 +476,36 @@ module YTLJit
|
|
425
476
|
add_special_send_node :eval
|
426
477
|
end
|
427
478
|
|
479
|
+
class SendIncludeCommonNode<SendNode
|
480
|
+
def collect_candidate_type_regident(context, slf)
|
481
|
+
slfnode = @arguments[2]
|
482
|
+
rtype = slfnode.decide_type_once(context.to_signature)
|
483
|
+
add_type(context.to_signature, rtype)
|
484
|
+
modnode = @arguments[3].value_node
|
485
|
+
|
486
|
+
add_search_module(slfnode, modnode)
|
487
|
+
context
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
class SendIncludeNode<SendIncludeCommonNode
|
492
|
+
add_special_send_node :include
|
493
|
+
|
494
|
+
def add_search_module(slfnode, modnode)
|
495
|
+
clstop = slfnode.search_class_top
|
496
|
+
clstop.add_after_search_module(:parm, modnode)
|
497
|
+
end
|
498
|
+
end
|
499
|
+
|
500
|
+
class SendExtendNode<SendIncludeCommonNode
|
501
|
+
add_special_send_node :extend
|
502
|
+
|
503
|
+
def add_search_module(slfnode, modnode)
|
504
|
+
clsclstop = slfnode.search_class_top.make_klassclass_node
|
505
|
+
clsclstop.add_after_search_module(:parm, modnode)
|
506
|
+
end
|
507
|
+
end
|
508
|
+
|
428
509
|
class SendAllocateNode<SendNode
|
429
510
|
add_special_send_node :allocate
|
430
511
|
|
@@ -437,9 +518,11 @@ module YTLJit
|
|
437
518
|
case clstop
|
438
519
|
when ClassTopNode
|
439
520
|
tt = RubyType::BaseType.from_ruby_class(clstop.klass_object)
|
521
|
+
tt = tt.to_box
|
440
522
|
add_type(context.to_signature, tt)
|
441
523
|
when LiteralNode
|
442
524
|
tt = RubyType::BaseType.from_ruby_class(clstop.value)
|
525
|
+
tt = tt.to_box
|
443
526
|
add_type(context.to_signature, tt)
|
444
527
|
else
|
445
528
|
raise "Unkown node type in constant #{slfnode.value_node.class}"
|
@@ -538,11 +621,9 @@ module YTLJit
|
|
538
621
|
case clstop
|
539
622
|
when ClassTopNode
|
540
623
|
tt = RubyType::BaseType.from_ruby_class(clstop.klass_object)
|
541
|
-
add_type(sig, tt)
|
542
624
|
|
543
625
|
when LiteralNode
|
544
626
|
tt = RubyType::BaseType.from_ruby_class(clstop.value)
|
545
|
-
add_type(sig, tt)
|
546
627
|
|
547
628
|
else
|
548
629
|
raise "Unkown node type in constant #{slfnode.value_node.class}"
|
@@ -551,49 +632,94 @@ module YTLJit
|
|
551
632
|
# set element type
|
552
633
|
if tt.ruby_type == Range then
|
553
634
|
tt.args = @arguments[3..-1]
|
554
|
-
add_element_node(sig, @arguments[3], [0], context)
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
635
|
+
add_element_node(tt, sig, @arguments[3], [0], context)
|
636
|
+
add_element_node(tt, sig, @arguments[4], [1], context)
|
637
|
+
|
638
|
+
elsif tt.ruby_type == Array then
|
639
|
+
if context.options[:compile_array_as_uboxed] and
|
640
|
+
@element_node_list.size > 1 and
|
641
|
+
@element_node_list[1..-1].all? {|e|
|
642
|
+
e[3]
|
643
|
+
} then
|
644
|
+
tt = tt.to_unbox
|
645
|
+
end
|
646
|
+
if @arguments[4] then
|
647
|
+
siz = @arguments[3].get_constant_value
|
648
|
+
if siz and false then
|
649
|
+
# Here is buggy yet Fix me
|
650
|
+
siz[0].times do |i|
|
651
|
+
add_element_node(tt, sig, @arguments[4], [i], context)
|
652
|
+
end
|
653
|
+
else
|
654
|
+
add_element_node(tt, sig, @arguments[4], nil, context)
|
655
|
+
end
|
560
656
|
end
|
561
657
|
end
|
658
|
+
|
659
|
+
add_type(sig, tt)
|
562
660
|
else
|
563
661
|
raise "Unkonwn node type #{@arguments[2].class} "
|
564
662
|
end
|
565
663
|
end
|
566
664
|
context
|
567
665
|
end
|
568
|
-
|
666
|
+
|
667
|
+
def compile_range(context)
|
668
|
+
context = gen_alloca(context, 3)
|
669
|
+
asm = context.assembler
|
670
|
+
breg = context.ret_reg
|
671
|
+
|
672
|
+
off = 0
|
673
|
+
sig = context.to_signature
|
674
|
+
[3, 4, 5].each do |no|
|
675
|
+
context = @arguments[no].compile(context)
|
676
|
+
rtype = @arguments[no].decide_type_once(sig)
|
677
|
+
context = rtype.gen_unboxing(context)
|
678
|
+
dst = OpIndirect.new(breg, off)
|
679
|
+
asm.with_retry do
|
680
|
+
if context.ret_reg.is_a?(OpRegistor) then
|
681
|
+
asm.mov(dst, context.ret_reg)
|
682
|
+
else
|
683
|
+
asm.mov(TMPR, context.ret_reg)
|
684
|
+
asm.mov(dst, TMPR)
|
685
|
+
end
|
686
|
+
end
|
687
|
+
off = off + AsmType::MACHINE_WORD.size
|
688
|
+
end
|
689
|
+
|
690
|
+
context.ret_reg = breg
|
691
|
+
context.ret_node = self
|
692
|
+
context
|
693
|
+
end
|
694
|
+
|
695
|
+
def compile_array_unboxed(context)
|
696
|
+
siz = ((@element_node_list[1..-1].max_by {|a| a[3][0]})[3][0]) + 1
|
697
|
+
context = gen_alloca(context, siz)
|
698
|
+
asm = context.assembler
|
699
|
+
asm.with_retry do
|
700
|
+
(siz - 1).times do |i|
|
701
|
+
off = OpIndirect.new(THEPR, i * 8)
|
702
|
+
asm.mov(TMPR, OpImmidiateMachineWord.new(4))
|
703
|
+
asm.mov(off, TMPR)
|
704
|
+
end
|
705
|
+
end
|
706
|
+
context.ret_node = self
|
707
|
+
context
|
708
|
+
end
|
709
|
+
|
569
710
|
def compile(context)
|
570
711
|
@arguments[2].decide_type_once(context.to_signature)
|
571
712
|
rtype = @arguments[2].type
|
572
713
|
rrtype = rtype.ruby_type
|
573
714
|
if rrtype.is_a?(Class) then
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
off = 0
|
580
|
-
[3, 4, 5].each do |no|
|
581
|
-
context = @arguments[no].compile(context)
|
582
|
-
dst = OpIndirect.new(breg, off)
|
583
|
-
asm.with_retry do
|
584
|
-
if context.ret_reg.is_a?(OpRegistor) then
|
585
|
-
asm.mov(dst, context.ret_reg)
|
586
|
-
else
|
587
|
-
asm.mov(TMPR, context.ret_reg)
|
588
|
-
asm.mov(dst, TMPR)
|
589
|
-
end
|
590
|
-
end
|
591
|
-
off = off + AsmType::MACHINE_WORD.size
|
592
|
-
end
|
715
|
+
ctype = decide_type_once(context.to_signature)
|
716
|
+
crtype = ctype.ruby_type
|
717
|
+
if @is_escape != true and crtype == Range then
|
718
|
+
return compile_range(context)
|
593
719
|
|
594
|
-
|
595
|
-
|
596
|
-
context
|
720
|
+
elsif crtype == Array and
|
721
|
+
!ctype.boxed and @is_escape != true then
|
722
|
+
return compile_array_unboxed(context)
|
597
723
|
|
598
724
|
elsif @initmethod.func.calling_convention(context) then
|
599
725
|
context = @initmethod.compile(context)
|
@@ -602,6 +728,7 @@ module YTLJit
|
|
602
728
|
# initialize method not defined
|
603
729
|
context = @allocmethod.compile(context)
|
604
730
|
end
|
731
|
+
context.ret_node = self
|
605
732
|
@body.compile(context)
|
606
733
|
else
|
607
734
|
super
|
@@ -619,7 +746,7 @@ module YTLJit
|
|
619
746
|
when [Fixnum], [Float], [String], [Array]
|
620
747
|
cursig = context.to_signature
|
621
748
|
same_type(self, @arguments[2], cursig, cursig, context)
|
622
|
-
same_type(@arguments[
|
749
|
+
same_type(self, @arguments[3], cursig, cursig, context)
|
623
750
|
end
|
624
751
|
|
625
752
|
context
|
@@ -627,8 +754,8 @@ module YTLJit
|
|
627
754
|
|
628
755
|
#=begin
|
629
756
|
def compile(context)
|
630
|
-
@
|
631
|
-
rtype =
|
757
|
+
@type = nil
|
758
|
+
rtype = decide_type_once(context.to_signature)
|
632
759
|
rrtype = rtype.ruby_type
|
633
760
|
if rtype.is_a?(RubyType::DefaultType0) or
|
634
761
|
@class_top.search_method_with_super(@func.name, rrtype)[0] then
|
@@ -658,15 +785,15 @@ module YTLJit
|
|
658
785
|
when [Fixnum], [Float], [Array]
|
659
786
|
cursig = context.to_signature
|
660
787
|
same_type(self, @arguments[2], cursig, cursig, context)
|
661
|
-
same_type(@arguments[
|
788
|
+
same_type(self, @arguments[3], cursig, cursig, context)
|
662
789
|
end
|
663
790
|
|
664
791
|
context
|
665
792
|
end
|
666
793
|
|
667
794
|
def compile(context)
|
668
|
-
@
|
669
|
-
rtype =
|
795
|
+
@type = nil
|
796
|
+
rtype = decide_type_once(context.to_signature)
|
670
797
|
rrtype = rtype.ruby_type
|
671
798
|
if rtype.is_a?(RubyType::DefaultType0) or
|
672
799
|
@class_top.search_method_with_super(@func.name, rrtype)[0] then
|
@@ -696,11 +823,11 @@ module YTLJit
|
|
696
823
|
case [slf.ruby_type]
|
697
824
|
when [Fixnum], [Float]
|
698
825
|
same_type(self, @arguments[2], cursig, cursig, context)
|
699
|
-
same_type(@arguments[
|
826
|
+
same_type(self, @arguments[3], cursig, cursig, context)
|
700
827
|
|
701
828
|
when [String]
|
702
829
|
same_type(self, @arguments[2], cursig, cursig, context)
|
703
|
-
|
830
|
+
fixtype = RubyType::BaseType.from_ruby_class(Fixnum)
|
704
831
|
@arguments[3].add_type(context.to_signature, fixtype)
|
705
832
|
end
|
706
833
|
|
@@ -708,9 +835,8 @@ module YTLJit
|
|
708
835
|
end
|
709
836
|
|
710
837
|
def compile(context)
|
711
|
-
@
|
712
|
-
|
713
|
-
rtype = @arguments[2].type
|
838
|
+
@type = nil
|
839
|
+
rtype = decide_type_once(context.to_signature)
|
714
840
|
rrtype = rtype.ruby_type
|
715
841
|
if rtype.is_a?(RubyType::DefaultType0) or
|
716
842
|
@class_top.search_method_with_super(@func.name, rrtype)[0] then
|
@@ -765,16 +891,15 @@ module YTLJit
|
|
765
891
|
when [Fixnum], [Float]
|
766
892
|
cursig = context.to_signature
|
767
893
|
same_type(self, @arguments[2], cursig, cursig, context)
|
768
|
-
same_type(@arguments[
|
894
|
+
same_type(self, @arguments[3], cursig, cursig, context)
|
769
895
|
end
|
770
896
|
|
771
897
|
context
|
772
898
|
end
|
773
899
|
|
774
900
|
def compile(context)
|
775
|
-
@
|
776
|
-
|
777
|
-
rtype = @arguments[2].type
|
901
|
+
@type = nil
|
902
|
+
rtype = decide_type_once(context.to_signature)
|
778
903
|
rrtype = rtype.ruby_type
|
779
904
|
if rtype.is_a?(RubyType::DefaultType0) or
|
780
905
|
@class_top.search_method_with_super(@func.name, rrtype)[0] then
|
@@ -789,19 +914,22 @@ module YTLJit
|
|
789
914
|
if context.ret_reg == TMPR then
|
790
915
|
asm.push(TMPR)
|
791
916
|
asm.mov(DBLLOR, TMPR2)
|
792
|
-
asm.
|
917
|
+
asm.mov(DBLHIR, DBLLOR)
|
918
|
+
asm.sar(DBLHIR, AsmType::MACHINE_WORD.size * 8 - 1)
|
793
919
|
asm.idiv(INDIRECT_SPR)
|
794
920
|
asm.add(SPR, AsmType::MACHINE_WORD.size)
|
795
921
|
elsif context.ret_reg.is_a?(OpImmidiateMachineWord) then
|
796
922
|
asm.mov(TMPR, context.ret_reg)
|
797
923
|
asm.push(TMPR)
|
798
924
|
asm.mov(DBLLOR, TMPR2)
|
799
|
-
asm.
|
925
|
+
asm.mov(DBLHIR, DBLLOR)
|
926
|
+
asm.sar(DBLHIR, AsmType::MACHINE_WORD.size * 8 - 1)
|
800
927
|
asm.idiv(INDIRECT_SPR)
|
801
928
|
asm.add(SPR, AsmType::MACHINE_WORD.size)
|
802
929
|
else
|
803
930
|
asm.mov(DBLLOR, TMPR2)
|
804
|
-
asm.
|
931
|
+
asm.mov(DBLHIR, DBLLOR)
|
932
|
+
asm.sar(DBLHIR, AsmType::MACHINE_WORD.size * 8 - 1)
|
805
933
|
asm.idiv(context.ret_reg)
|
806
934
|
end
|
807
935
|
asm.and(DBLHIR, DBLHIR)
|
@@ -824,13 +952,125 @@ module YTLJit
|
|
824
952
|
end
|
825
953
|
end
|
826
954
|
|
955
|
+
class SendModNode<SendNode
|
956
|
+
include ArithmeticOperationUtil
|
957
|
+
include SendUtil
|
958
|
+
add_special_send_node :%
|
959
|
+
|
960
|
+
def collect_candidate_type_regident(context, slf)
|
961
|
+
case [slf.ruby_type]
|
962
|
+
when [Fixnum]
|
963
|
+
cursig = context.to_signature
|
964
|
+
same_type(self, @arguments[2], cursig, cursig, context)
|
965
|
+
same_type(self, @arguments[3], cursig, cursig, context)
|
966
|
+
end
|
967
|
+
|
968
|
+
context
|
969
|
+
end
|
970
|
+
|
971
|
+
def compile(context)
|
972
|
+
@type = nil
|
973
|
+
rtype = decide_type_once(context.to_signature)
|
974
|
+
rrtype = rtype.ruby_type
|
975
|
+
if rtype.is_a?(RubyType::DefaultType0) or
|
976
|
+
@class_top.search_method_with_super(@func.name, rrtype)[0] then
|
977
|
+
return super(context)
|
978
|
+
end
|
979
|
+
|
980
|
+
if rrtype == Fixnum then
|
981
|
+
context = gen_arithmetic_operation(context, nil, TMPR2,
|
982
|
+
TMPR) do |context|
|
983
|
+
asm = context.assembler
|
984
|
+
asm.with_retry do
|
985
|
+
if context.ret_reg == TMPR then
|
986
|
+
asm.push(TMPR)
|
987
|
+
asm.mov(DBLLOR, TMPR2)
|
988
|
+
asm.mov(DBLHIR, DBLLOR)
|
989
|
+
asm.sar(DBLHIR, AsmType::MACHINE_WORD.size * 8 - 1)
|
990
|
+
asm.idiv(INDIRECT_SPR)
|
991
|
+
asm.add(SPR, AsmType::MACHINE_WORD.size)
|
992
|
+
elsif context.ret_reg.is_a?(OpImmidiateMachineWord) then
|
993
|
+
asm.mov(TMPR, context.ret_reg)
|
994
|
+
asm.push(TMPR)
|
995
|
+
asm.mov(DBLLOR, TMPR2)
|
996
|
+
asm.mov(DBLHIR, DBLLOR)
|
997
|
+
asm.sar(DBLHIR, AsmType::MACHINE_WORD.size * 8 - 1)
|
998
|
+
asm.idiv(INDIRECT_SPR)
|
999
|
+
asm.add(SPR, AsmType::MACHINE_WORD.size)
|
1000
|
+
else
|
1001
|
+
asm.mov(DBLLOR, TMPR2)
|
1002
|
+
asm.mov(DBLHIR, DBLLOR)
|
1003
|
+
asm.sar(DBLHIR, AsmType::MACHINE_WORD.size * 8 - 1)
|
1004
|
+
asm.idiv(context.ret_reg)
|
1005
|
+
end
|
1006
|
+
asm.mov(DBLLOR, DBLHIR)
|
1007
|
+
context.end_using_reg(context.ret_reg)
|
1008
|
+
end
|
1009
|
+
end
|
1010
|
+
else
|
1011
|
+
raise "Unkown method #{rtype.ruby_type}##{@func.name}"
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
@body.compile(context)
|
1015
|
+
end
|
1016
|
+
end
|
1017
|
+
|
1018
|
+
class SendLtLtNode<SendNode
|
1019
|
+
include ArithmeticOperationUtil
|
1020
|
+
include SendUtil
|
1021
|
+
add_special_send_node :<<
|
1022
|
+
|
1023
|
+
def collect_candidate_type_regident(context, slf)
|
1024
|
+
case [slf.ruby_type]
|
1025
|
+
when [Fixnum]
|
1026
|
+
cursig = context.to_signature
|
1027
|
+
same_type(self, @arguments[2], cursig, cursig, context)
|
1028
|
+
same_type(self, @arguments[3], cursig, cursig, context)
|
1029
|
+
end
|
1030
|
+
|
1031
|
+
context
|
1032
|
+
end
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
class SendGtGtNode<SendNode
|
1036
|
+
include ArithmeticOperationUtil
|
1037
|
+
include SendUtil
|
1038
|
+
add_special_send_node :>>
|
1039
|
+
|
1040
|
+
def collect_candidate_type_regident(context, slf)
|
1041
|
+
case [slf.ruby_type]
|
1042
|
+
when [Fixnum]
|
1043
|
+
cursig = context.to_signature
|
1044
|
+
same_type(self, @arguments[2], cursig, cursig, context)
|
1045
|
+
same_type(self, @arguments[3], cursig, cursig, context)
|
1046
|
+
end
|
1047
|
+
|
1048
|
+
context
|
1049
|
+
end
|
1050
|
+
end
|
1051
|
+
|
1052
|
+
class SendAndNode<SendNode
|
1053
|
+
include ArithmeticOperationUtil
|
1054
|
+
include SendUtil
|
1055
|
+
add_special_send_node :&
|
1056
|
+
|
1057
|
+
def collect_candidate_type_regident(context, slf)
|
1058
|
+
case [slf.ruby_type]
|
1059
|
+
when [Fixnum]
|
1060
|
+
cursig = context.to_signature
|
1061
|
+
same_type(self, @arguments[2], cursig, cursig, context)
|
1062
|
+
same_type(self, @arguments[3], cursig, cursig, context)
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
context
|
1066
|
+
end
|
1067
|
+
end
|
1068
|
+
|
827
1069
|
class SendCompareNode<SendNode
|
828
1070
|
include SendUtil
|
829
1071
|
include CompareOperationUtil
|
830
1072
|
def collect_candidate_type_regident(context, slf)
|
831
1073
|
cursig = context.to_signature
|
832
|
-
same_type(@arguments[3], @arguments[2], cursig, cursig, context)
|
833
|
-
same_type(@arguments[2], @arguments[3], cursig, cursig, context)
|
834
1074
|
tt = RubyType::BaseType.from_object(true)
|
835
1075
|
add_type(cursig, tt)
|
836
1076
|
tt = RubyType::BaseType.from_object(false)
|
@@ -839,7 +1079,7 @@ module YTLJit
|
|
839
1079
|
context
|
840
1080
|
end
|
841
1081
|
|
842
|
-
def
|
1082
|
+
def common_compile_compare(context, rtype, fixcmp, flocmp)
|
843
1083
|
rrtype = rtype.ruby_type
|
844
1084
|
if rrtype == Fixnum then
|
845
1085
|
context = gen_compare_operation(context, :cmp, fixcmp,
|
@@ -855,136 +1095,300 @@ module YTLJit
|
|
855
1095
|
end
|
856
1096
|
|
857
1097
|
def compile(context)
|
858
|
-
@arguments[2].decide_type_once(context.to_signature)
|
859
|
-
rtype = @arguments[2].type
|
1098
|
+
rtype = @arguments[2].decide_type_once(context.to_signature)
|
860
1099
|
rrtype = rtype.ruby_type
|
861
|
-
if rtype.
|
1100
|
+
if rtype.is_a?(RubyType::DefaultType0) or
|
862
1101
|
@class_top.search_method_with_super(@func.name, rrtype)[0] then
|
863
1102
|
return super(context)
|
864
1103
|
end
|
865
1104
|
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
context = compile_compare(context, rtype)
|
872
|
-
|
873
|
-
elsif rrtype == Float then
|
1105
|
+
if rrtype == Fixnum or rrtype == Float then
|
1106
|
+
context = gen_eval_self(context)
|
1107
|
+
context.ret_node.type = nil
|
1108
|
+
srtype = context.ret_node.decide_type_once(context.to_signature)
|
1109
|
+
context = srtype.gen_unboxing(context)
|
874
1110
|
context = compile_compare(context, rtype)
|
875
|
-
|
1111
|
+
|
876
1112
|
else
|
877
|
-
|
1113
|
+
tcon = compile_compare_nonnum(context, rtype)
|
1114
|
+
if tcon then
|
1115
|
+
context = tcon
|
1116
|
+
else
|
1117
|
+
context = super(context)
|
1118
|
+
end
|
878
1119
|
end
|
879
1120
|
|
880
1121
|
@body.compile(context)
|
881
1122
|
end
|
882
1123
|
end
|
883
1124
|
|
1125
|
+
def compile_compare_nonnum(context, rtype)
|
1126
|
+
nil
|
1127
|
+
end
|
1128
|
+
|
884
1129
|
class SendGtNode<SendCompareNode
|
885
1130
|
add_special_send_node :<
|
886
1131
|
def compile_compare(context, rtype)
|
887
|
-
|
1132
|
+
common_compile_compare(context, rtype, :setg, :seta)
|
888
1133
|
end
|
889
1134
|
end
|
890
1135
|
|
891
1136
|
class SendGeNode<SendCompareNode
|
892
1137
|
add_special_send_node :<=
|
893
1138
|
def compile_compare(context, rtype)
|
894
|
-
|
1139
|
+
common_compile_compare(context, rtype, :setge, :setae)
|
895
1140
|
end
|
896
1141
|
end
|
897
1142
|
|
898
1143
|
class SendLtNode<SendCompareNode
|
899
1144
|
add_special_send_node :>
|
900
1145
|
def compile_compare(context, rtype)
|
901
|
-
|
1146
|
+
common_compile_compare(context, rtype, :setl, :setb)
|
902
1147
|
end
|
903
1148
|
end
|
904
1149
|
|
905
1150
|
class SendLeNode<SendCompareNode
|
906
1151
|
add_special_send_node :>=
|
907
1152
|
def compile_compare(context, rtype)
|
908
|
-
|
1153
|
+
common_compile_compare(context, rtype, :setle, :setbe)
|
1154
|
+
end
|
1155
|
+
end
|
1156
|
+
|
1157
|
+
class SendEqNode<SendCompareNode
|
1158
|
+
add_special_send_node :==
|
1159
|
+
def compile_compare(context, rtype)
|
1160
|
+
common_compile_compare(context, rtype, :setz, :setz)
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
def compile_compare_nonnum(context, rtype)
|
1164
|
+
if rtype.include_nil? then
|
1165
|
+
context = gen_eval_self(context)
|
1166
|
+
gen_compare_operation(context, :cmp, :setz,
|
1167
|
+
TMPR2, TMPR, RETR, false)
|
1168
|
+
else
|
1169
|
+
nil
|
1170
|
+
end
|
1171
|
+
end
|
1172
|
+
end
|
1173
|
+
|
1174
|
+
class SendNeqNode<SendCompareNode
|
1175
|
+
add_special_send_node :!=
|
1176
|
+
def compile_compare(context, rtype)
|
1177
|
+
common_compile_compare(context, rtype, :setnz, :setnz)
|
1178
|
+
end
|
1179
|
+
|
1180
|
+
def compile_compare_nonnum(context, rtype)
|
1181
|
+
if rtype.include_nil? then
|
1182
|
+
context = gen_eval_self(context)
|
1183
|
+
gen_compare_operation(context, :cmp, :setnz,
|
1184
|
+
TMPR2, TMPR, RETR, false)
|
1185
|
+
else
|
1186
|
+
nil
|
1187
|
+
end
|
909
1188
|
end
|
910
1189
|
end
|
911
1190
|
|
912
1191
|
class SendElementRefNode<SendNode
|
913
1192
|
include SendUtil
|
1193
|
+
include UnboxedArrayUtil
|
914
1194
|
add_special_send_node :[]
|
915
1195
|
def collect_candidate_type_regident(context, slf)
|
916
|
-
|
1196
|
+
cursig = context.to_signature
|
917
1197
|
case [slf.ruby_type]
|
918
1198
|
when [Array]
|
919
1199
|
fixtype = RubyType::BaseType.from_ruby_class(Fixnum)
|
920
|
-
@arguments[3].add_type(
|
1200
|
+
@arguments[3].add_type(cursig, fixtype)
|
921
1201
|
cidx = @arguments[3].get_constant_value
|
922
|
-
|
923
|
-
|
1202
|
+
|
1203
|
+
# decide type again
|
924
1204
|
@arguments[2].type = nil
|
925
|
-
@arguments[2].decide_type_once(
|
926
|
-
|
1205
|
+
slf = @arguments[2].decide_type_once(cursig)
|
1206
|
+
|
1207
|
+
epare = nil
|
1208
|
+
=begin
|
927
1209
|
@arguments[2].element_node_list.each do |ele|
|
928
|
-
if ele[
|
929
|
-
|
930
|
-
|
1210
|
+
if ele[3] == cidx and ele[2] != self and ele[0] == slf then
|
1211
|
+
epare2 = ele
|
1212
|
+
esig = epare2[1]
|
1213
|
+
enode = epare2[2]
|
1214
|
+
unless enode.type_list(esig) == [[], []]
|
1215
|
+
epare = epare2
|
1216
|
+
same_type(self, enode, cursig, esig, context)
|
1217
|
+
end
|
931
1218
|
end
|
932
1219
|
end
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
1220
|
+
=end
|
1221
|
+
if epare == nil then
|
1222
|
+
@arguments[2].element_node_list.each do |ele|
|
1223
|
+
if ele[3] == nil and ele[2] != self and ele[0] == slf then
|
1224
|
+
epare2 = ele
|
1225
|
+
esig = epare2[1]
|
1226
|
+
enode = epare2[2]
|
1227
|
+
unless enode.type_list(esig) == [[], []]
|
1228
|
+
epare = epare2
|
1229
|
+
same_type(self, enode, cursig, esig, context)
|
1230
|
+
end
|
1231
|
+
end
|
1232
|
+
end
|
1233
|
+
end
|
1234
|
+
if epare == nil then
|
1235
|
+
@arguments[2].element_node_list.each do |ele|
|
1236
|
+
if ele[3] == cidx and ele[2] != self and
|
1237
|
+
ele[0].ruby_type == slf.ruby_type then
|
1238
|
+
epare2 = ele
|
1239
|
+
esig = epare2[1]
|
1240
|
+
enode = epare2[2]
|
1241
|
+
unless enode.type_list(esig) == [[], []]
|
1242
|
+
epare = epare2
|
1243
|
+
same_type(self, enode, cursig, esig, context)
|
1244
|
+
end
|
1245
|
+
end
|
1246
|
+
end
|
1247
|
+
end
|
1248
|
+
if epare == nil then
|
1249
|
+
epare = @arguments[2].element_node_list[0]
|
1250
|
+
esig = epare[1]
|
1251
|
+
enode = epare[2]
|
1252
|
+
same_type(self, enode, cursig, esig, context)
|
937
1253
|
end
|
938
1254
|
|
1255
|
+
@type = nil
|
1256
|
+
|
939
1257
|
when [Hash]
|
940
1258
|
cidx = @arguments[3].get_constant_value
|
941
|
-
@arguments[2].
|
1259
|
+
rtype = @arguments[2].decide_type_once(sig)
|
1260
|
+
@arguments[2].add_element_node(rtype, cursig, self, cidx, context)
|
942
1261
|
end
|
943
1262
|
|
944
1263
|
context
|
945
1264
|
end
|
1265
|
+
|
1266
|
+
def compile(context)
|
1267
|
+
sig = context.to_signature
|
1268
|
+
rtype = @arguments[2].decide_type_once(sig)
|
1269
|
+
rrtype = rtype.ruby_type
|
1270
|
+
|
1271
|
+
if rrtype == Array and !rtype.boxed and
|
1272
|
+
@arguments[2].is_escape != true then
|
1273
|
+
context = gen_ref_element(context, @arguments[2], @arguments[3])
|
1274
|
+
@body.compile(context)
|
1275
|
+
else
|
1276
|
+
super
|
1277
|
+
end
|
1278
|
+
end
|
946
1279
|
end
|
947
1280
|
|
948
1281
|
class SendElementAssignNode<SendNode
|
949
1282
|
include SendUtil
|
1283
|
+
include UnboxedArrayUtil
|
950
1284
|
add_special_send_node :[]=
|
951
1285
|
def collect_candidate_type_regident(context, slf)
|
952
|
-
|
1286
|
+
cursig = context.to_signature
|
1287
|
+
rtype = nil
|
953
1288
|
case [slf.ruby_type]
|
954
1289
|
when [Array]
|
955
1290
|
fixtype = RubyType::BaseType.from_ruby_class(Fixnum)
|
956
1291
|
val = @arguments[4]
|
957
|
-
|
1292
|
+
val.is_escape = :export_object
|
1293
|
+
@arguments[3].add_type(cursig, fixtype)
|
958
1294
|
cidx = @arguments[3].get_constant_value
|
959
|
-
@arguments[2].add_element_node(sig, val, cidx, context)
|
960
|
-
decide_type_once(sig)
|
961
1295
|
@arguments[2].type = nil
|
962
|
-
@arguments[2].decide_type_once(
|
963
|
-
|
964
|
-
|
965
|
-
|
1296
|
+
slf = @arguments[2].decide_type_once(cursig)
|
1297
|
+
|
1298
|
+
arg = [slf, cursig, val, cidx, context]
|
1299
|
+
@arguments[2].add_element_node_backward(arg)
|
1300
|
+
|
1301
|
+
epare = nil
|
1302
|
+
@arguments[2].element_node_list.each do |ele|
|
1303
|
+
if ele[3] == cidx and ele[2] != self then
|
1304
|
+
epare = ele
|
1305
|
+
break
|
1306
|
+
end
|
1307
|
+
end
|
1308
|
+
if epare == nil then
|
1309
|
+
epare = @arguments[2].element_node_list[0]
|
1310
|
+
@arguments[2].element_node_list.each do |ele|
|
1311
|
+
if ele[3] == nil and ele[2] != self and ele[0] == slf then
|
1312
|
+
epare = ele
|
1313
|
+
break
|
1314
|
+
end
|
1315
|
+
end
|
1316
|
+
end
|
1317
|
+
|
1318
|
+
esig = epare[1]
|
1319
|
+
enode = epare[2]
|
966
1320
|
if enode != self then
|
967
|
-
same_type(self, enode,
|
968
|
-
same_type(enode, self, esig, sig, context)
|
1321
|
+
same_type(self, enode, cursig, esig, context)
|
1322
|
+
# same_type(enode, self, esig, sig, context)
|
1323
|
+
end
|
1324
|
+
if slf.boxed then
|
1325
|
+
@arguments[3].set_escape_node_backward(true)
|
969
1326
|
end
|
970
1327
|
|
971
1328
|
when [Hash]
|
972
1329
|
cidx = @arguments[3].get_constant_value
|
973
|
-
@arguments[2].add_element_node(sig, self, cidx, context)
|
1330
|
+
@arguments[2].add_element_node(slf, sig, self, cidx, context)
|
1331
|
+
@arguments[3].set_escape_node_backward(true)
|
974
1332
|
end
|
975
1333
|
|
976
1334
|
context
|
977
1335
|
end
|
1336
|
+
|
1337
|
+
def compile(context)
|
1338
|
+
sig = context.to_signature
|
1339
|
+
rtype = @arguments[2].decide_type_once(sig)
|
1340
|
+
rrtype = rtype.ruby_type
|
1341
|
+
if rrtype == Array and !rtype.boxed and
|
1342
|
+
@arguments[2].is_escape != true then
|
1343
|
+
context = gen_set_element(context,
|
1344
|
+
@arguments[2],
|
1345
|
+
@arguments[3],
|
1346
|
+
@arguments[4])
|
1347
|
+
@body.compile(context)
|
1348
|
+
else
|
1349
|
+
super
|
1350
|
+
end
|
1351
|
+
end
|
978
1352
|
end
|
979
1353
|
|
980
1354
|
class SendToFNode<SendNode
|
1355
|
+
include AbsArch
|
1356
|
+
|
981
1357
|
add_special_send_node :to_f
|
1358
|
+
|
982
1359
|
def collect_candidate_type_regident(context, slf)
|
983
1360
|
sig = context.to_signature
|
984
1361
|
floattype = RubyType::BaseType.from_ruby_class(Float)
|
985
1362
|
add_type(sig, floattype)
|
986
1363
|
context
|
987
1364
|
end
|
1365
|
+
|
1366
|
+
def compile(context)
|
1367
|
+
@arguments[2].decide_type_once(context.to_signature)
|
1368
|
+
rtype = @arguments[2].type
|
1369
|
+
rrtype = rtype.ruby_type
|
1370
|
+
if rrtype == Fixnum then
|
1371
|
+
context = gen_eval_self(context)
|
1372
|
+
context = rtype.gen_unboxing(context)
|
1373
|
+
asm = context.assembler
|
1374
|
+
if context.ret_reg.is_a?(OpRegistor) or
|
1375
|
+
context.ret_reg.is_a?(OpIndirect) then
|
1376
|
+
asm.with_retry do
|
1377
|
+
asm.cvtsi2sd(XMM0, context.ret_reg)
|
1378
|
+
end
|
1379
|
+
else
|
1380
|
+
asm.with_retry do
|
1381
|
+
asm.mov(TMPR, context.ret_reg)
|
1382
|
+
asm.cvtsi2sd(XMM0, TMPR)
|
1383
|
+
end
|
1384
|
+
end
|
1385
|
+
context.ret_node = self
|
1386
|
+
context.ret_reg = XMM0
|
1387
|
+
context
|
1388
|
+
else
|
1389
|
+
super(context)
|
1390
|
+
end
|
1391
|
+
end
|
988
1392
|
end
|
989
1393
|
|
990
1394
|
class SendToINode<SendNode
|
@@ -997,6 +1401,16 @@ module YTLJit
|
|
997
1401
|
end
|
998
1402
|
end
|
999
1403
|
|
1404
|
+
class SendChrNode<SendNode
|
1405
|
+
add_special_send_node :chr
|
1406
|
+
def collect_candidate_type_regident(context, slf)
|
1407
|
+
sig = context.to_signature
|
1408
|
+
strtype = RubyType::BaseType.from_ruby_class(String)
|
1409
|
+
add_type(sig, strtype)
|
1410
|
+
context
|
1411
|
+
end
|
1412
|
+
end
|
1413
|
+
|
1000
1414
|
class SendAMNode<SendNode
|
1001
1415
|
add_special_send_node :-@
|
1002
1416
|
def collect_candidate_type_regident(context, slf)
|
@@ -1035,6 +1449,9 @@ module YTLJit
|
|
1035
1449
|
end
|
1036
1450
|
context.ret_node = self
|
1037
1451
|
|
1452
|
+
if rtype.boxed then
|
1453
|
+
context = rtype.to_unbox.gen_boxing(context)
|
1454
|
+
end
|
1038
1455
|
@body.compile(context)
|
1039
1456
|
end
|
1040
1457
|
end
|
@@ -1056,8 +1473,8 @@ module YTLJit
|
|
1056
1473
|
cursig = context.to_signature
|
1057
1474
|
if slf.ruby_type == Range then
|
1058
1475
|
epare = @arguments[2].element_node_list[0]
|
1059
|
-
esig = epare[
|
1060
|
-
enode = epare[
|
1476
|
+
esig = epare[1]
|
1477
|
+
enode = epare[2]
|
1061
1478
|
tt = enode.decide_type_once(esig)
|
1062
1479
|
add_type(cursig, tt)
|
1063
1480
|
else
|
@@ -1068,9 +1485,12 @@ module YTLJit
|
|
1068
1485
|
end
|
1069
1486
|
|
1070
1487
|
def compile(context)
|
1071
|
-
|
1488
|
+
sig = context.to_signature
|
1489
|
+
rtype = @arguments[2].decide_type_once(sig)
|
1072
1490
|
rrtype = rtype.ruby_type
|
1073
|
-
|
1491
|
+
decide_type_once(sig)
|
1492
|
+
if rrtype == Range and !rtype.boxed and
|
1493
|
+
@arguments[2].is_escape != true then
|
1074
1494
|
context = @arguments[2].compile(context)
|
1075
1495
|
slotoff = OpIndirect.new(TMPR, arg_offset)
|
1076
1496
|
asm = context.assembler
|
@@ -1145,6 +1565,27 @@ module YTLJit
|
|
1145
1565
|
class SendPNode<SendSameArgTypeNode
|
1146
1566
|
add_special_send_node :p
|
1147
1567
|
end
|
1568
|
+
|
1569
|
+
class SendSameSelfTypeNode<SendNode
|
1570
|
+
def collect_candidate_type_regident(context, slf)
|
1571
|
+
sig = context.to_signature
|
1572
|
+
same_type(self, @arguments[2], sig, sig, context)
|
1573
|
+
context
|
1574
|
+
end
|
1575
|
+
end
|
1576
|
+
|
1577
|
+
class SendDupNode<SendSameSelfTypeNode
|
1578
|
+
add_special_send_node :dup
|
1579
|
+
|
1580
|
+
def compile(context)
|
1581
|
+
sig = context.to_signature
|
1582
|
+
rtype = @arguments[2].decide_type_once(sig)
|
1583
|
+
rrtype = rtype.ruby_type
|
1584
|
+
context = @arguments[2].compile(context)
|
1585
|
+
context = rtype.gen_copy(context)
|
1586
|
+
@body.compile(context)
|
1587
|
+
end
|
1588
|
+
end
|
1148
1589
|
|
1149
1590
|
class SendMathFuncNode<SendNode
|
1150
1591
|
include SendUtil
|
@@ -1257,17 +1698,61 @@ module YTLJit
|
|
1257
1698
|
end
|
1258
1699
|
|
1259
1700
|
class RetArraySendNode<RawSendNode
|
1701
|
+
include AbsArch
|
1702
|
+
include UnboxedArrayUtil
|
1703
|
+
|
1260
1704
|
def collect_candidate_type_body(context)
|
1261
1705
|
sig = context.to_signature
|
1262
1706
|
tt = RubyType::BaseType.from_ruby_class(Array)
|
1707
|
+
if context.options[:compile_array_as_uboxed] and
|
1708
|
+
@element_node_list.size > 1 and
|
1709
|
+
@element_node_list[1..-1].all? {|e|
|
1710
|
+
e[3]
|
1711
|
+
} then
|
1712
|
+
tt = tt.to_unbox
|
1713
|
+
end
|
1714
|
+
|
1263
1715
|
add_type(sig, tt)
|
1716
|
+
@type = nil
|
1717
|
+
tt = decide_type_once(sig)
|
1264
1718
|
|
1265
1719
|
@arguments[1..-1].each_with_index do |anode, idx|
|
1266
|
-
add_element_node(sig, anode, [idx], context)
|
1720
|
+
add_element_node(tt, sig, anode, [idx], context)
|
1267
1721
|
end
|
1268
1722
|
|
1269
1723
|
context
|
1270
1724
|
end
|
1725
|
+
|
1726
|
+
def compile(context)
|
1727
|
+
sig = context.to_signature
|
1728
|
+
rtype = decide_type_once(sig)
|
1729
|
+
rrtype = rtype.ruby_type
|
1730
|
+
if rrtype == Array and !rtype.boxed and @is_escape != true then
|
1731
|
+
siz = ((@element_node_list[1..-1].max_by {|a| a[3][0]})[3][0]) + 1
|
1732
|
+
context = gen_alloca(context, siz)
|
1733
|
+
|
1734
|
+
context.start_arg_reg(TMPR2)
|
1735
|
+
asm = context.assembler
|
1736
|
+
asm.with_retry do
|
1737
|
+
asm.mov(TMPR2, THEPR)
|
1738
|
+
end
|
1739
|
+
|
1740
|
+
@arguments[1..-1].each_with_index do |anode, idx|
|
1741
|
+
context = gen_set_element(context, nil, idx, anode)
|
1742
|
+
end
|
1743
|
+
|
1744
|
+
asm.with_retry do
|
1745
|
+
asm.mov(RETR, TMPR2)
|
1746
|
+
end
|
1747
|
+
context.end_arg_reg(TMPR2)
|
1748
|
+
|
1749
|
+
context.ret_reg = RETR
|
1750
|
+
context.ret_node = self
|
1751
|
+
@body.compile(context)
|
1752
|
+
else
|
1753
|
+
super
|
1754
|
+
end
|
1755
|
+
end
|
1271
1756
|
end
|
1272
1757
|
end
|
1273
1758
|
end
|