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.
@@ -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.make_send_node(parent, func, arguments, op_flag, seqno)
71
- if mproc = @@macro_tab[func.name] then
72
- args = []
73
- arguments[3..-1].each do |ele|
74
- args.push eval(ele.to_ruby(ToRubyContext.new).ret_code.last)
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
- @new_method.name = arguments[4].value
337
- @class_top.get_method_tab[arguments[4].value] = @new_method
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
- @new_method.name = arguments[4].value
381
- @class_top.make_klassclass_node
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
- end
556
-
557
- if tt.ruby_type == Array then
558
- @arguments[3..-1].each_with_index do |anode, idx|
559
- add_element_node(sig, anode, [idx - 3], context)
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
- if !@is_escape and rrtype.to_s == '#<Class:Range>' then
575
- context = gen_alloca(context, 3)
576
- asm = context.assembler
577
- breg = context.ret_reg
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
- context.ret_reg = breg
595
- context.ret_node = self
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[2], self, cursig, cursig, context)
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
- @arguments[2].decide_type_once(context.to_signature)
631
- rtype = @arguments[2].type
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[2], self, cursig, cursig, context)
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
- @arguments[2].decide_type_once(context.to_signature)
669
- rtype = @arguments[2].type
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[2], self, cursig, cursig, context)
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
- same_type(@arguments[2], self, cursig, cursig, context)
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
- @arguments[2].type = nil
712
- @arguments[2].decide_type_once(context.to_signature)
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[2], self, cursig, cursig, context)
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
- @arguments[2].type = nil
776
- @arguments[2].decide_type_once(context.to_signature)
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.cdq
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.cdq
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.cdq
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 commmon_compile_compare(context, rtype, fixcmp, flocmp)
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.ruby_type.is_a?(RubyType::DefaultType0) or
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
- context = gen_eval_self(context)
867
- context.ret_node.type = nil
868
- srtype = context.ret_node.decide_type_once(context.to_signature)
869
- context = srtype.gen_unboxing(context)
870
- if rrtype == Fixnum then
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
- raise "Unkown method #{rtype.ruby_type} #{@func.name}"
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
- commmon_compile_compare(context, rtype, :setg, :seta)
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
- commmon_compile_compare(context, rtype, :setge, :setae)
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
- commmon_compile_compare(context, rtype, :setl, :setb)
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
- commmon_compile_compare(context, rtype, :setle, :setbe)
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
- sig = context.to_signature
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(sig, fixtype)
1200
+ @arguments[3].add_type(cursig, fixtype)
921
1201
  cidx = @arguments[3].get_constant_value
922
- @arguments[2].add_element_node(sig, self, cidx, context)
923
- decide_type_once(sig)
1202
+
1203
+ # decide type again
924
1204
  @arguments[2].type = nil
925
- @arguments[2].decide_type_once(sig)
926
- epare = @arguments[2].element_node_list[0]
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[2] == cidx and ele[1] != self then
929
- epare = ele
930
- break
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
- esig = epare[0]
934
- enode = epare[1]
935
- if enode != self then
936
- same_type(self, enode, sig, esig, context)
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].add_element_node(sig, self, cidx, context)
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
- sig = context.to_signature
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
- @arguments[3].add_type(sig, fixtype)
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(sig)
963
- epare = @arguments[2].element_node_list[0]
964
- esig = epare[0]
965
- enode = epare[1]
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, sig, esig, context)
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[0]
1060
- enode = epare[1]
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
- rtype = @arguments[2].decide_type_once(context.to_signature)
1488
+ sig = context.to_signature
1489
+ rtype = @arguments[2].decide_type_once(sig)
1072
1490
  rrtype = rtype.ruby_type
1073
- if rrtype == Range and !rtype.boxed then
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