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.
@@ -130,4 +130,15 @@ module YTLJit
130
130
  @refer_operands = obj.pop
131
131
  end
132
132
  end
133
+
134
+ module Runtime
135
+ class Arena
136
+ def _dump_data
137
+ []
138
+ end
139
+
140
+ def _load_data(obj)
141
+ end
142
+ end
143
+ end
133
144
  end
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 = [[sig[2], sig, @my_element_node, nil]]
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 = [[sig[2], sig, @my_element_node, nil]]
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, lst|
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
- if !res.include?(sele) then
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
- if res.all? {|e| e.ruby_type != sele.ruby_type or
284
- e.boxed != sele.boxed } then
285
- res.push sele
286
- elsif sele.have_element? and sele.element_type then
287
- # Replace type object which have more collect element type
288
- res.each_with_index do |rele, i|
289
- if rele == sele and rele.element_type == nil then
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, visitnode = {})
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.add_element_node_backward(args, visitnode)
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
- slfetnode = @element_node_list
427
+ def add_element_node(curslf, encsig, enode, index, context,
428
+ backp = false)
395
429
  newele = [curslf, encsig, enode, index]
396
- if @element_node_list == [] then
397
- @element_node_list.push [curslf, encsig, enode, nil]
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
- orgsig = @element_node_list[0][1]
402
- orgnode = @element_node_list[0][2]
403
- if orgnode != enode then
404
- same_type(orgnode, enode, orgsig, encsig, context)
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 |orgslf, orgsig, orgnode, orgindex|
408
- if orgslf == curslf and
409
- orgindex == index and
410
- orgnode != enode then
411
- same_type(orgnode, enode, orgsig, encsig, context)
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
- ti_changed
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
- if tlist[0].abnormal? then
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
- if tmptlist[0].abnormal? then
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
- if sig == cursig then
531
- node = ele[2]
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
- res.push args[0].decide_type_once(cursig)
656
-
657
- mt, slf = get_send_method_node(cursig)
658
- if mt and (ynode = mt.yield_node[0]) then
659
- context.push_signature(args, mt)
660
- args[1].type = nil
661
- res.push args[1].decide_type_once(ynode.signature(context))
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
- # ele.type = nil
673
- res.push ele.decide_type_once(cursig)
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, true)
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
- # if rnode.is_escape != :global_export then
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
- sig = context.to_signature
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(sig).var_base_immidiate_address
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, true)
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, true)
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
- finfo.system_num = 5 # BP ON Stack, HP, ET, BP, RET
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 = args[0]
1047
- opt_label = args[1]
1048
- post_len = args[2]
1049
- post_start = args[3]
1050
- rest_index = args[4]
1051
- block_index = args[5]
1052
- simple = args[6]
1053
- end
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 collect_info(context)
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 collect_candidate_type(context, signode, sig)
1122
- if add_cs_for_signature(sig) == nil and
1123
- context.visited_top_node[self] then
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
- if !@signature_cache.include?(sig) then
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 = @body.collect_info(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
- context.visited_top_node[self] = true
1402
- @signature_cache.push sig
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
- ar.raw_address
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
- ar.body_address + ar.size
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
- ar.raw_address
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
- (ar.body_address + ar.size) & (~0xf)
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, aa)
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
- # same_type(tobj, self, cursig2, cursig, context)
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
- asm.with_retry do
2305
- if context.ret_reg != RETR then
2306
- asm.mov(RETR, context.ret_reg)
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
- if context.ret_reg != RETR then
2320
- asm.mov(RETR, context.ret_reg)
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(node.parent)
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
- asm.with_retry do
2400
- asm.mov(RETR, @res_area)
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
- if @type_list != [[], []] then
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
- # def type=(val)
2529
- # val
2530
- # end
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, true)
2929
+ context.set_reg_content(PTMPR, :self_of_block)
2638
2930
  context.ret_reg2 = PTMPR
2639
-
2640
- context.ret_reg = @frame_info.offset_arg(1, BPR)
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
- def initialize(parent, val)
3056
+ include SendNodeCodeGen
3057
+
3058
+ def initialize(parent, name)
2703
3059
  super(parent)
2704
- @name = val
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
- if variable_argument?(recobj.method(@name).parameters) then
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 knode.search_method_with_super(@name)[0] then
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
- mth = slfval[0].instance_method(@name)
2798
- @ruby_reciever = slfval[0]
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
- #=begin
3198
+ =begin
2811
3199
  p @parent.debug_info
2812
3200
  p sig
2813
3201
  p @name
2814
3202
  p @reciever.class
2815
- # p @reciever.instance_eval {@type_list }
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
- return :c_fixarg
2824
- raise
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, true)
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
- # if rnode.is_escape != :global_export then
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 rtype.is_a?(RubyType::DefaultType0) then
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, true)
2948
- context.set_reg_content(TMPR2, true)
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
- @var_type_info = vti.map {|e| e.dup }
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
- @var_type_info.each do |topnode, node|
3077
- cursig = context.to_signature
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
- @type = RubyType::BaseType.from_ruby_class(@classtop.klass_object)
3133
- add_type(context.to_signature, @type)
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
- varcursig = context.to_signature(@var_from)
3191
- same_type(self, @val, varcursig, cursig, context)
3192
- # same_type(@val, self, cursig, varcursig, context)
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
- sig = context.to_signature(-@depth - 1)
3201
- decide_type_once(sig)
3202
- rtype = @val.decide_type_once(context.to_signature)
3203
- if @type.boxed then
3204
- # if @val.is_escape != :global_export then
3205
- context = rtype.gen_boxing(context)
3206
- # end
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 = rtype.gen_unboxing(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, valn)
3702
+ tmpctx.set_reg_content(offarg, @val)
3234
3703
 
3235
- context.ret_reg = nil
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
- @var_type_info.each do |src|
3281
- cursig = context.to_signature
3282
- same_type(self, src, cursig, cursig, context)
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 self
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
- # @class_top.set_escape_node(:global_export)
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
- @offset = @assign_nodes[0].offset
3368
- sig = context.to_signature
3369
- same_type(self, @assign_nodes[0], sig, sig, context)
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, true)
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
- if context.modified_global_var[@name] == nil then
3417
- context.modified_global_var[@name] = []
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
- @assign_nodes = context.modified_global_var[@name]
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(@assign_nodes[0], @value, sig, sig, context)
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, :foo)
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
- @value_node = LiteralNode.new(self, rklass.const_get(@name))
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