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/lib/ytljit/vm.rb CHANGED
@@ -110,7 +110,9 @@ LocalVarNode
110
110
  if @my_element_node == nil then
111
111
  @my_element_node = BaseNode.new(self)
112
112
  end
113
- @element_node_list = [[sig, @my_element_node, nil]]
113
+ if @element_node_list == [] then
114
+ @element_node_list = [[sig[2], sig, @my_element_node, nil]]
115
+ end
114
116
  end
115
117
  end
116
118
  end
@@ -137,7 +139,9 @@ LocalVarNode
137
139
  if @my_element_node == nil then
138
140
  @my_element_node = BaseNode.new(self)
139
141
  end
140
- @element_node_list = [[sig, @my_element_node, nil]]
142
+ if @element_node_list == [] then
143
+ @element_node_list = [[sig[2], sig, @my_element_node, nil]]
144
+ end
141
145
  end
142
146
  end
143
147
  end
@@ -158,12 +162,12 @@ LocalVarNode
158
162
  # iv for structure of VM
159
163
  @parent = parent
160
164
  @code_space = nil
161
- @id = nil
165
+ @id = [1]
162
166
  if @parent then
163
167
  @id = @parent.id.dup
164
168
  @id[-1] = @id[-1] + 1
165
169
  else
166
- @id = [0]
170
+ @id = [1]
167
171
  end
168
172
 
169
173
  # iv for type inference
@@ -172,7 +176,7 @@ LocalVarNode
172
176
  @element_node_list = []
173
177
  @my_element_node = nil
174
178
  @type_inference_proc = cs
175
- @type_cache = nil
179
+ @decided_signature = nil
176
180
  @is_escape = false
177
181
 
178
182
  @ti_observer = {}
@@ -261,11 +265,25 @@ LocalVarNode
261
265
  end
262
266
  end
263
267
 
264
- def merge_type(dst, src)
268
+ def marge_type(dst, src)
265
269
  res = dst
266
270
  src.each do |sele|
267
- if !res.include? sele then
268
- res.push sele
271
+ if sele.is_a?(Array) then
272
+ if !res.include?(sele) then
273
+ res.push sele
274
+ end
275
+ else
276
+ if res.all? {|e| e.ruby_type != sele.ruby_type or
277
+ e.boxed != sele.boxed } then
278
+ res.push sele
279
+ elsif sele.have_element? and sele.element_type then
280
+ # Replace type object which have more collect element type
281
+ res.each_with_index do |rele, i|
282
+ if rele == sele and rele.element_type == nil then
283
+ res[i] = sele
284
+ end
285
+ end
286
+ end
269
287
  end
270
288
  end
271
289
 
@@ -284,7 +302,7 @@ LocalVarNode
284
302
  =end
285
303
  orgsize = dtlist.size
286
304
  # pp "#{dst.class} #{src.class} #{dtlist} #{stlist}"
287
- newdt = merge_type(dtlistorg[1], stlist)
305
+ newdt = marge_type(dtlistorg[1], stlist)
288
306
  dst.set_type_list(dsig, newdt)
289
307
  dtsize = dtlistorg[0].size + newdt.size
290
308
 
@@ -297,13 +315,17 @@ LocalVarNode
297
315
  dtlist = dst.element_node_list
298
316
  stlist = src.element_node_list
299
317
  orgsize = dtlist.size
300
- dst.element_node_list = merge_type(dtlist, stlist)
318
+ dst.element_node_list = marge_type(dtlist, stlist)
301
319
  if orgsize != dtlist.size then
302
320
  dst.ti_changed
303
321
  context.convergent = false
304
322
  end
305
323
 
306
- dst.is_escape ||= src.is_escape
324
+ if src.is_escape then
325
+ if dst.is_escape != true then
326
+ dst.is_escape = src.is_escape
327
+ end
328
+ end
307
329
  end
308
330
 
309
331
  def same_type(dst, src, dsig, ssig, context)
@@ -327,29 +349,56 @@ LocalVarNode
327
349
  ti_update(dst, src, dsig, ssig, context)
328
350
  end
329
351
 
330
- def add_element_node(sig, enode, index, context)
352
+ def add_element_node_backward(args, visitnode = {})
353
+ if visitnode[self] then
354
+ return
355
+ end
356
+
357
+ add_element_node(*args)
358
+ visitnode[self] = true
359
+ @ti_observee.each do |rec|
360
+ rec.add_element_node_backward(args, visitnode)
361
+ end
362
+ end
363
+
364
+ def set_escape_node_backward(value = true, visitnode = {})
365
+ if visitnode[self] then
366
+ return
367
+ end
368
+
369
+ if @is_escape != true then
370
+ @is_escape = value
371
+ end
372
+ visitnode[self] = true
373
+ @ti_observee.each do |rec|
374
+ rec.set_escape_node_backward(value, visitnode)
375
+ end
376
+ end
377
+
378
+ def add_element_node(curslf, encsig, enode, index, context)
331
379
  slfetnode = @element_node_list
332
- unless slfetnode.include?(enode)
333
- if @element_node_list == nil and index != nil then
334
- @element_node_list.push [sig, enode, nil]
335
- end
336
- @element_node_list.push [sig, enode, index]
337
- orgsig = @element_node_list[0][0]
338
- orgnode = @element_node_list[0][1]
380
+ newele = [curslf, encsig, enode, index]
381
+ if @element_node_list == [] then
382
+ @element_node_list.push [curslf, encsig, enode, nil]
383
+ end
384
+ if !@element_node_list.include?(newele) then
385
+ @element_node_list.push newele
386
+ orgsig = @element_node_list[0][1]
387
+ orgnode = @element_node_list[0][2]
339
388
  if orgnode != enode then
340
- same_type(orgnode, enode, orgsig, sig, context)
389
+ same_type(orgnode, enode, orgsig, encsig, context)
341
390
  end
342
391
  if index != nil then
343
- @element_node_list.each do |orgsig, orgnode, orgindex|
392
+ @element_node_list.each do |sig, orgsig, orgnode, orgindex|
344
393
  if orgindex == index and
345
394
  orgnode != enode then
346
- same_type(orgnode, enode, orgsig, sig, context)
395
+ # same_type(orgnode, enode, orgsig, sig, context)
347
396
  end
348
397
  end
349
398
  end
350
-
399
+
351
400
  ti_changed
352
- # context.convergent = false
401
+ # context.convergent = false
353
402
  end
354
403
  end
355
404
 
@@ -358,28 +407,70 @@ LocalVarNode
358
407
  context
359
408
  end
360
409
 
361
- def decide_type_core(tlist, local_cache = {})
410
+ def decide_type_core(tlist, cursig, local_cache = {})
362
411
  tlist = tlist.select {|e| e.class != RubyType::DefaultType0 }
412
+
413
+ # This is for sitration of same class and differenc element type.
414
+ # Last element must be local type not propageted type
415
+ if tlist.size > 1 and tlist.all? {|e|
416
+ e.ruby_type == tlist[0].ruby_type and
417
+ e.boxed == tlist[0].boxed
418
+ } then
419
+ return tlist.last
420
+ end
421
+
363
422
  case tlist.size
364
423
  when 0
365
424
  RubyType::DefaultType0.new
366
425
 
367
426
  when 1
368
- local_cache[self] = tlist[0]
369
- if tlist[0].have_element? then
370
- sig = @element_node_list[0][0]
371
- node = @element_node_list[0][1]
372
- node.decide_type_once(sig, local_cache)
373
- tlist[0].element_type = node.type
374
- end
375
427
  tlist[0]
376
428
 
377
429
  when 2
378
- if tlist[0].ruby_type == tlist[1].ruby_type and
379
- tlist[0].boxed then
430
+ if tlist[0].ruby_type == tlist[1].ruby_type then
431
+ if tlist[0].abnormal? then
432
+ tlist[0]
433
+ else
434
+ tlist[1]
435
+ end
436
+
437
+ elsif tlist[0].ruby_type == NilClass then
438
+ # nil-able type
439
+ tlist[1].to_box
440
+
441
+ elsif tlist[1].ruby_type == NilClass then
442
+ # nil-able type
443
+ tlist[0].to_box
444
+
445
+ elsif tlist[0].ruby_type == Float and
446
+ tlist[1].ruby_type == Fixnum then
380
447
  tlist[0]
381
- else
448
+
449
+ elsif tlist[0].ruby_type == Fixnum and
450
+ tlist[1].ruby_type == Float then
382
451
  tlist[1]
452
+
453
+ else
454
+ RubyType::DefaultType0.new
455
+ end
456
+
457
+ when 3
458
+ tmptlist = tlist.dup
459
+ tmptlist.delete_if {|ele| ele.ruby_type == NilClass}
460
+ if tmptlist.size == 2 and
461
+ tmptlist[0].ruby_type == tmptlist[1].ruby_type then
462
+ if tmptlist[0].abnormal? then
463
+ tmptlist[0]
464
+ else
465
+ tmptlist[1]
466
+ end
467
+
468
+ elsif tmptlist[0].ruby_type == tmptlist[1].ruby_type and
469
+ tmptlist[0].ruby_type == tmptlist[2].ruby_type then
470
+ tmptlist[1]
471
+
472
+ else
473
+ RubyType::DefaultType0.new
383
474
  end
384
475
 
385
476
  else
@@ -387,16 +478,49 @@ LocalVarNode
387
478
  end
388
479
  end
389
480
 
390
- def decide_type_once(sig, local_cache = {})
481
+ def decide_type_once(cursig, local_cache = {})
391
482
  if local_cache[self] then
392
483
  return local_cache[self]
393
484
  end
394
485
 
395
- if @type.equal?(nil) or @type.is_a?(RubyType::DefaultType0) then
396
- tlist = type_list(sig).flatten.uniq
397
- @type = decide_type_core(tlist, local_cache)
398
- else
399
- @type
486
+ =begin
487
+ if @decided_signature and @decided_signature != sig then
488
+ p cursig
489
+ p @decided_signature
490
+ p debug_info
491
+ p self.class
492
+ p caller[0]
493
+ @decided_signature = cursig
494
+ end
495
+ =end
496
+
497
+ if # @decided_signature != cursig or
498
+ @type.equal?(nil) or
499
+ @type.is_a?(RubyType::DefaultType0) then
500
+ tlist = type_list(cursig).flatten.uniq
501
+ @decided_signature = cursig
502
+ @type = decide_type_core(tlist, cursig, local_cache)
503
+ end
504
+
505
+ if @type.have_element? and
506
+ (@type.element_type == nil or
507
+ @type.element_type == {}) then
508
+ local_cache[self] = @type
509
+ etype = {}
510
+ @element_node_list.each do |ele|
511
+ sig = ele[1]
512
+ slf = ele[0]
513
+ if sig == cursig then
514
+ node = ele[2]
515
+ tt = node.decide_type_once(sig, local_cache)
516
+ etype[ele[3]] ||= []
517
+ curidx = etype[ele[3]]
518
+ if !curidx.include?(tt) then
519
+ curidx.push tt
520
+ end
521
+ end
522
+ end
523
+ @type.element_type = etype
400
524
  end
401
525
 
402
526
  @type
@@ -508,27 +632,23 @@ LocalVarNode
508
632
  def signature(context, args = @arguments)
509
633
  res = []
510
634
  cursig = context.to_signature
511
- args[0].decide_type_once(cursig)
512
- res.push args[0].type
635
+ res.push args[0].decide_type_once(cursig)
513
636
 
514
637
  mt, slf = get_send_method_node(cursig)
515
638
  if mt and (ynode = mt.yield_node[0]) then
516
639
  context.push_signature(args, mt)
517
640
  args[1].type = nil
518
- args[1].decide_type_once(ynode.signature(context))
519
- res.push args[1].type
641
+ res.push args[1].decide_type_once(ynode.signature(context))
520
642
  context.pop_signature
521
643
  else
522
- args[1].decide_type_once(cursig)
523
- res.push args[1].type
524
- args[2].decide_type_once(cursig)
525
- slf = args[2].type
644
+ res.push args[1].decide_type_once(cursig)
645
+ slf = args[2].decide_type_once(cursig)
526
646
  end
527
647
  res.push slf
528
648
 
529
649
  args[3..-1].each do |ele|
530
- ele.decide_type_once(cursig)
531
- res.push ele.type
650
+ # ele.type = nil
651
+ res.push ele.decide_type_once(cursig)
532
652
  end
533
653
 
534
654
  res
@@ -560,6 +680,7 @@ LocalVarNode
560
680
  end
561
681
  context.set_reg_content(FUNC_ARG[2].dst_opecode, context.ret_node)
562
682
 
683
+ context = gen_save_thepr(context)
563
684
  context = gen_call(context, fnc, 3)
564
685
  context.cpustack_popn(3 * AsmType::MACHINE_WORD.size)
565
686
  context.end_arg_reg
@@ -567,9 +688,10 @@ LocalVarNode
567
688
  context.ret_reg = RETR
568
689
  context.set_reg_content(context.ret_reg, self)
569
690
  context.ret_node = self
570
-
691
+
692
+ @type = nil
571
693
  decide_type_once(context.to_signature)
572
- if !@type.boxed then
694
+ if !@type.boxed then
573
695
  context = @type.to_box.gen_unboxing(context)
574
696
  end
575
697
 
@@ -580,6 +702,7 @@ LocalVarNode
580
702
  def compile_c_fixarg(context)
581
703
  fnc = nil
582
704
  numarg = @arguments.size - 2
705
+ sig = context.to_signature
583
706
 
584
707
  context.start_arg_reg
585
708
  context.cpustack_pushn(numarg * AsmType::MACHINE_WORD.size)
@@ -609,9 +732,12 @@ LocalVarNode
609
732
  else
610
733
  # other arg.
611
734
  context = arg.compile(context)
612
- context.ret_node.decide_type_once(context.to_signature)
613
- rtype = context.ret_node.type
614
- context = rtype.gen_boxing(context)
735
+ context.ret_node.decide_type_once(sig)
736
+ rnode = context.ret_node
737
+ rtype = rnode.type
738
+ if rnode.is_escape != true then
739
+ context = rtype.gen_boxing(context)
740
+ end
615
741
  casm = context.assembler
616
742
  casm.with_retry do
617
743
  casm.mov(FUNC_ARG[argpos], context.ret_reg)
@@ -623,6 +749,7 @@ LocalVarNode
623
749
  cursrc = cursrc + 1
624
750
  end
625
751
 
752
+ context = gen_save_thepr(context)
626
753
  context = gen_call(context, fnc, numarg)
627
754
 
628
755
  context.cpustack_popn(numarg * AsmType::MACHINE_WORD.size)
@@ -631,7 +758,7 @@ LocalVarNode
631
758
  context.ret_reg = RETR
632
759
  context.set_reg_content(context.ret_reg, self)
633
760
 
634
- decide_type_once(context.to_signature)
761
+ decide_type_once(sig)
635
762
  if !@type.boxed then
636
763
  context = @type.to_box.gen_unboxing(context)
637
764
  end
@@ -642,13 +769,38 @@ LocalVarNode
642
769
  def compile_ytl(context)
643
770
  fnc = nil
644
771
  numarg = @arguments.size
772
+ sig = context.to_signature
645
773
 
646
774
  context.start_arg_reg
647
775
  context.start_arg_reg(FUNC_ARG_YTL)
648
776
  context.cpustack_pushn(numarg * 8)
649
-
650
- # push prev env
777
+
651
778
  casm = context.assembler
779
+ # construct and set exception handler in current frame
780
+ fstentry = nil
781
+ if @current_exception_table then
782
+ [:ensure].each do |kind|
783
+ ent = nil
784
+ if entbase = @current_exception_table[kind] then
785
+ ent = entbase[3]
786
+ end
787
+ if ent then
788
+ csadd = ent.get_code_space(sig).var_base_immidiate_address
789
+ else
790
+ csadd = TopTopNode.get_nothing_proc.var_base_immidiate_address
791
+ end
792
+ entry = casm.add_value_entry(csadd)
793
+ fstentry ||= entry.to_immidiate
794
+ end
795
+ handoff = OpIndirect.new(BPR, AsmType::MACHINE_WORD.size * 2)
796
+ casm.with_retry do
797
+ casm.mov(TMPR, fstentry)
798
+ casm.mov(handoff, TMPR)
799
+ end
800
+ context.set_reg_content(handoff, nil)
801
+ end
802
+
803
+ # push prev env
652
804
  if @func.is_a?(YieldNode) then
653
805
  prevenv = @frame_info.offset_arg(0, BPR)
654
806
  casm.with_retry do
@@ -709,6 +861,7 @@ LocalVarNode
709
861
  context.end_arg_reg
710
862
  context.end_arg_reg(FUNC_ARG_YTL)
711
863
  context.end_using_reg(fnc)
864
+
712
865
  context
713
866
  end
714
867
 
@@ -743,6 +896,7 @@ LocalVarNode
743
896
  context.ret_node)
744
897
  end
745
898
 
899
+ context = gen_save_thepr(context)
746
900
  context = gen_call(context, fnc, numarg)
747
901
 
748
902
  context.cpustack_popn(numarg * AsmType::MACHINE_WORD.size)
@@ -756,6 +910,39 @@ LocalVarNode
756
910
  end
757
911
  end
758
912
 
913
+ module MultipleCodeSpaceUtil
914
+ def find_cs_by_signature(sig)
915
+ @code_spaces.each do |csig, val|
916
+ if csig == sig then
917
+ return val
918
+ end
919
+ end
920
+
921
+ nil
922
+ end
923
+
924
+ def add_cs_for_signature(sig)
925
+ cs = find_cs_by_signature(sig)
926
+ if cs then
927
+ return nil
928
+
929
+ else
930
+ cs = CodeSpace.new
931
+ @code_spaces.push [sig, cs]
932
+ return cs
933
+ end
934
+ end
935
+
936
+ def get_code_space(sig)
937
+ cs = find_cs_by_signature(sig)
938
+ if cs == nil then
939
+ cs = CodeSpace.new
940
+ @code_spaces.push [sig, cs]
941
+ end
942
+ cs
943
+ end
944
+ end
945
+
759
946
  class DummyNode
760
947
  def collect_info(context)
761
948
  context
@@ -775,11 +962,12 @@ LocalVarNode
775
962
  class TopNode<BaseNode
776
963
  include HaveChildlenMixin
777
964
  include NodeUtil
965
+ include MultipleCodeSpaceUtil
966
+
778
967
  def initialize(parent, name = nil)
779
968
  super(parent)
780
969
  @name = name
781
970
  @code_spaces = [] # [[nil, CodeSpace.new]]
782
- @orig_modified_local_var = []
783
971
  @yield_node = []
784
972
  if @parent then
785
973
  @classtop = search_class_top
@@ -788,14 +976,15 @@ LocalVarNode
788
976
  end
789
977
  @end_nodes = []
790
978
  @signature_cache = []
979
+ @exception_table = nil
791
980
  end
792
981
 
793
982
  attr_accessor :name
794
983
  attr :end_nodes
795
- attr :orig_modified_local_var
796
984
  attr :yield_node
797
985
 
798
986
  attr :signature_cache
987
+ attr_accessor :exception_table
799
988
 
800
989
  def modified_instance_var
801
990
  search_end.modified_instance_var
@@ -805,28 +994,6 @@ LocalVarNode
805
994
  yield @body
806
995
  end
807
996
 
808
- def find_cs_by_signature(sig)
809
- @code_spaces.each do |csig, val|
810
- if csig == sig then
811
- return val
812
- end
813
- end
814
-
815
- nil
816
- end
817
-
818
- def add_cs_for_signature(sig)
819
- cs = find_cs_by_signature(sig)
820
- if cs then
821
- return nil
822
-
823
- else
824
- cs = CodeSpace.new
825
- @code_spaces.push [sig, cs]
826
- return cs
827
- end
828
- end
829
-
830
997
  def add_arg_to_args(args, addnum)
831
998
  if args.is_a?(Integer) then
832
999
  args = args + addnum
@@ -918,6 +1085,15 @@ LocalVarNode
918
1085
  context.yield_node.push []
919
1086
  context = @body.collect_info(context)
920
1087
  @yield_node = context.yield_node.pop
1088
+ if @exception_table then
1089
+ @exception_table.each do |kind, lst|
1090
+ lst.each do |st, ed, cnt, body|
1091
+ if body then
1092
+ context = body.collect_info(context)
1093
+ end
1094
+ end
1095
+ end
1096
+ end
921
1097
  context
922
1098
  end
923
1099
 
@@ -935,6 +1111,17 @@ LocalVarNode
935
1111
 
936
1112
  context.push_signature(signode, self)
937
1113
  context = @body.collect_candidate_type(context)
1114
+
1115
+ if @exception_table then
1116
+ @exception_table.each do |kind, lst|
1117
+ lst.each do |st, ed, cnt, body|
1118
+ if body then
1119
+ context = body.collect_candidate_type(context)
1120
+ end
1121
+ end
1122
+ end
1123
+ end
1124
+
938
1125
  context.pop_signature
939
1126
 
940
1127
  @end_nodes.each do |enode|
@@ -946,11 +1133,12 @@ LocalVarNode
946
1133
 
947
1134
  def disp_signature
948
1135
  tcontext = CompileContext.new(self)
1136
+ print "#{debug_info.inspect}\n"
949
1137
  print "#{@classtop.klass_object}##{@name} "
950
1138
  @code_spaces.each do |sig, cs|
951
1139
  print sig, " -> "
952
1140
  tl = type_list(sig).flatten.uniq
953
- print decide_type_core(tl).inspect, "\n"
1141
+ print decide_type_core(tl, sig).inspect, "\n"
954
1142
  pp tl
955
1143
  # print "CodeSpace 0x#{cs.base_address.to_s(16)}\n"
956
1144
  print "CodeSpace #{cs.inspect}\n"
@@ -971,6 +1159,16 @@ LocalVarNode
971
1159
  context = gen_method_prologue(context)
972
1160
  context = compile_init(context)
973
1161
  context = @body.compile(context)
1162
+
1163
+ if @exception_table then
1164
+ @exception_table.each do |kind, lst|
1165
+ lst.each do |st, ed, cnt, body|
1166
+ if body then
1167
+ context = body.compile(context)
1168
+ end
1169
+ end
1170
+ end
1171
+ end
974
1172
  context.current_method_signature.pop
975
1173
  end
976
1174
 
@@ -1010,9 +1208,6 @@ LocalVarNode
1010
1208
 
1011
1209
  class BlockTopNode<MethodTopNode
1012
1210
  def collect_info(context)
1013
- @orig_modified_local_var = context.modified_local_var.last.map {|e|
1014
- e.dup
1015
- }
1016
1211
  context.modified_local_var.last.push Hash.new
1017
1212
  context = @body.collect_info(context)
1018
1213
  context.modified_local_var.last.pop
@@ -1033,6 +1228,8 @@ LocalVarNode
1033
1228
 
1034
1229
  def initialize(parent, klassobj, name = nil)
1035
1230
  super(parent, name)
1231
+ @before_search_module = []
1232
+ @after_search_module = []
1036
1233
  @constant_tab = {}
1037
1234
  @method_tab = {}
1038
1235
  @klass_object = klassobj
@@ -1050,6 +1247,8 @@ LocalVarNode
1050
1247
  attr :method_tab
1051
1248
  attr :klassclass
1052
1249
  attr :klassclass_node
1250
+ attr :before_search_module
1251
+ attr :after_search_module
1053
1252
 
1054
1253
  def collect_info(context)
1055
1254
  context.modified_local_var.push [{}]
@@ -1071,6 +1270,7 @@ LocalVarNode
1071
1270
  clsclsnode.body = DummyNode.new
1072
1271
  @klassclass_node = clsclsnode
1073
1272
  end
1273
+ @klassclass_node
1074
1274
  end
1075
1275
 
1076
1276
  def get_method_tab(klassobj = @klass_object)
@@ -1092,15 +1292,54 @@ LocalVarNode
1092
1292
  end
1093
1293
  end
1094
1294
 
1295
+ def add_before_search_module(scope, mod)
1296
+ clsnode = @@class_top_tab[@klass_object]
1297
+ clsnode.before_search_module.each do |scope, modnode|
1298
+ if modnode == mod then
1299
+ return
1300
+ end
1301
+ end
1302
+ clsnode.before_search_module.push [scope, mod]
1303
+ end
1304
+
1305
+ def add_after_search_module(scope, mod)
1306
+ clsnode = @@class_top_tab[@klass_object]
1307
+ clsnode.after_search_module.each do |scope, modnode|
1308
+ if modnode == mod then
1309
+ return
1310
+ end
1311
+ end
1312
+ clsnode.before_search_module.unshift [scope, mod]
1313
+ end
1314
+
1095
1315
  def search_method_with_super(name, klassobj = @klass_object)
1096
1316
  clsnode = @@class_top_tab[klassobj]
1097
1317
  if clsnode then
1318
+ clsnode.before_search_module.each do |scope, mod|
1319
+ mtab = mod.get_method_tab
1320
+ if val = mtab[name] then
1321
+ return [val, mod]
1322
+ end
1323
+ end
1324
+
1098
1325
  mtab = clsnode.get_method_tab
1099
1326
  if val = mtab[name] then
1100
1327
  return [val, clsnode]
1101
1328
  end
1102
-
1103
- return search_method_with_super(name, klassobj.superclass)
1329
+
1330
+ clsnode.after_search_module.each do |scope, mod|
1331
+ mtab = mod.get_method_tab
1332
+ if val = mtab[name] then
1333
+ return [val, mod]
1334
+ end
1335
+ end
1336
+
1337
+ if klassobj.is_a?(Class) then
1338
+ return search_method_with_super(name, klassobj.superclass)
1339
+ else
1340
+ # klassobj is Module
1341
+ return search_method_with_super(name, Object)
1342
+ end
1104
1343
  end
1105
1344
 
1106
1345
  [nil, nil]
@@ -1113,7 +1352,7 @@ LocalVarNode
1113
1352
  if val = ctab[name] then
1114
1353
  return [val, clsnode]
1115
1354
  end
1116
-
1355
+
1117
1356
  return search_constant_with_super(name, klassobj.superclass)
1118
1357
  end
1119
1358
 
@@ -1139,6 +1378,7 @@ LocalVarNode
1139
1378
  end
1140
1379
 
1141
1380
  context.visited_top_node[self] = true
1381
+ @signature_cache.push sig
1142
1382
 
1143
1383
  context.push_signature(signode, self)
1144
1384
  context = @body.collect_candidate_type(context)
@@ -1193,11 +1433,22 @@ LocalVarNode
1193
1433
  include MethodTopCodeGen
1194
1434
  @@frame_struct_tab = {}
1195
1435
  @@local_object_area = Runtime::Arena.new
1436
+ @@unwind_proc = CodeSpace.new
1437
+ @@nothing_proc = CodeSpace.new
1196
1438
 
1197
1439
  def self.get_frame_struct_tab
1198
1440
  @@frame_struct_tab
1199
1441
  end
1200
1442
 
1443
+ def self.get_unwind_proc
1444
+ @@unwind_proc
1445
+ end
1446
+
1447
+
1448
+ def self.get_nothing_proc
1449
+ @@nothing_proc
1450
+ end
1451
+
1201
1452
  def initialize(parent, klassobj, name = :top)
1202
1453
  super
1203
1454
 
@@ -1206,10 +1457,10 @@ LocalVarNode
1206
1457
  @id.push 0
1207
1458
 
1208
1459
  @frame_struct_array = []
1209
- @unwind_proc = CodeSpace.new
1210
1460
  @init_node = nil
1211
- init_unwind_proc
1212
- add_code_space(nil, @unwind_proc)
1461
+
1462
+ # Dummy for marshal
1463
+ @op_var_value_instaces = nil
1213
1464
  end
1214
1465
 
1215
1466
  attr_accessor :init_node
@@ -1231,16 +1482,28 @@ LocalVarNode
1231
1482
  end
1232
1483
 
1233
1484
  def init_unwind_proc
1234
- asm = Assembler.new(@unwind_proc)
1485
+ asm = Assembler.new(@@unwind_proc)
1486
+ # Make linkage of frame pointer
1487
+ asm.with_retry do
1488
+ asm.mov(SPR, BPR)
1489
+ asm.pop(BPR)
1490
+ # must be asm.pop(THEPR)? Maybe not because release caller
1491
+ asm.pop(TMPR) # Dummy pop THEPR
1492
+ asm.pop(TMPR2) # exception handler
1493
+ asm.mov(SPR, BPR)
1494
+ asm.pop(BPR) # Return address store by call inst.
1495
+ asm.pop(TMPR) # return address
1496
+ asm.add(TMPR2, TMPR3) # TMPR3 store offset of exception handler
1497
+ asm.mov(TMPR2, INDIRECT_TMPR2)
1498
+ asm.and(TMPR2, TMPR2)
1499
+ asm.jz(@@unwind_proc.var_base_address)
1500
+ asm.jmp(TMPR2)
1501
+ end
1502
+
1503
+ asm = Assembler.new(@@nothing_proc)
1235
1504
  # Make linkage of frame pointer
1236
- finfo = OpIndirect.new(TMPR3, AsmType::MACHINE_WORD.size)
1237
- retadd = OpIndirect.new(TMPR3, AsmType::MACHINE_WORD.size)
1238
1505
  asm.with_retry do
1239
- asm.mov(TMPR3, BPR)
1240
- asm.mov(TMPR3, INDIRECT_TMPR3)
1241
- asm.mov(TMPR, finfo)
1242
- asm.mov(TMPR3, INDIRECT_TMPR3)
1243
- asm.mov(TMPR2, retadd) # Return address store by call inst.
1506
+ asm.ret
1244
1507
  end
1245
1508
  end
1246
1509
 
@@ -1253,6 +1516,9 @@ LocalVarNode
1253
1516
  def collect_info(context)
1254
1517
  if @init_node then
1255
1518
  context = @init_node.collect_info(context)
1519
+ else
1520
+ init_unwind_proc
1521
+ add_code_space(nil, @@unwind_proc)
1256
1522
  end
1257
1523
  super(context)
1258
1524
  end
@@ -1263,12 +1529,31 @@ LocalVarNode
1263
1529
  if @init_node then
1264
1530
  context = @init_node.collect_candidate_type(context, signode, sig)
1265
1531
  end
1532
+
1533
+ # This is for return boxed object to CRuby system
1534
+ if @end_nodes[0] then
1535
+ @end_nodes[0].add_type(sig, RubyType::BaseType.from_object(nil))
1536
+ end
1537
+
1266
1538
  super(context, signode, sig)
1267
1539
  end
1268
1540
 
1269
- def compile_init(context)
1541
+ def get_arena_address
1270
1542
  ar = @@local_object_area
1271
- aa = (ar.address + ar.size) & (~0xf)
1543
+ # 2 means used and size
1544
+ ar.raw_address
1545
+ end
1546
+
1547
+ def get_arena_end_address
1548
+ ar = @@local_object_area
1549
+ (ar.body_address + ar.size) & (~0xf)
1550
+ end
1551
+
1552
+ def compile_init(context)
1553
+ addr = lambda {
1554
+ get_arena_end_address
1555
+ }
1556
+ aa = OpVarImmidiateAddress.new(addr)
1272
1557
  asm = context.assembler
1273
1558
  asm.with_retry do
1274
1559
  asm.mov(THEPR, aa)
@@ -1282,6 +1567,51 @@ LocalVarNode
1282
1567
  end
1283
1568
  super(context)
1284
1569
  end
1570
+
1571
+ def code_store_hook
1572
+ @op_var_value_instaces = OpVarValueMixin.instances
1573
+ end
1574
+
1575
+ def update_after_restore
1576
+ @op_var_value_instaces.each do |ins|
1577
+ ins.refer.each do |stfn|
1578
+ stfn.call
1579
+ end
1580
+ end
1581
+ end
1582
+ end
1583
+
1584
+ class ExceptionTopNode<TopNode
1585
+ include HaveChildlenMixin
1586
+ include NodeUtil
1587
+ include MultipleCodeSpaceUtil
1588
+ include MethodEndCodeGen
1589
+
1590
+ def initialize(parent, name = nil)
1591
+ super
1592
+ @code_spaces = []
1593
+ end
1594
+
1595
+ def collect_info(context)
1596
+ @body.collect_info(context)
1597
+ end
1598
+
1599
+ def collect_candidate_type(context)
1600
+ @body.collect_candidate_type(context)
1601
+ end
1602
+
1603
+ def compile(context)
1604
+ sig = context.to_signature
1605
+ cs = get_code_space(sig)
1606
+ oldcs = context.set_code_space(cs)
1607
+ context = @body.compile(context)
1608
+ asm = context.assembler
1609
+ asm.with_retry do
1610
+ asm.ret
1611
+ end
1612
+ context.set_code_space(oldcs)
1613
+ context
1614
+ end
1285
1615
  end
1286
1616
 
1287
1617
  class LocalFrameInfoNode<BaseNode
@@ -1379,7 +1709,7 @@ LocalVarNode
1379
1709
  rc
1380
1710
  end
1381
1711
 
1382
- def alloca(size)
1712
+ def static_alloca(size)
1383
1713
  # base = -offset_by_byte(0)
1384
1714
  @alloca_area_size += size
1385
1715
  -(@local_area_size + @alloca_area_size)
@@ -1394,15 +1724,18 @@ LocalVarNode
1394
1724
  def compile(context)
1395
1725
  context = super(context)
1396
1726
  siz = @local_area_size + @alloca_area_size
1397
- if siz != 0 then
1727
+ if siz != 0 and !(@parent.is_a?(ExceptionTopNode)) then
1398
1728
  asm = context.assembler
1399
1729
  asm.with_retry do
1400
1730
  asm.sub(SPR, siz)
1401
1731
  end
1732
+ context.cpustack_pushn(siz)
1733
+ context = @body.compile(context)
1734
+ context.cpustack_popn(siz)
1735
+ else
1736
+ context = @body.compile(context)
1402
1737
  end
1403
- context.cpustack_pushn(siz)
1404
- context = @body.compile(context)
1405
- context.cpustack_popn(siz)
1738
+
1406
1739
  context
1407
1740
  end
1408
1741
  end
@@ -1451,7 +1784,7 @@ LocalVarNode
1451
1784
  cursig2 = context.to_signature(-2)
1452
1785
  if tobj then
1453
1786
  same_type(self, tobj, cursig, cursig2, context)
1454
- same_type(tobj, self, cursig2, cursig, context)
1787
+ # same_type(tobj, self, cursig2, cursig, context)
1455
1788
  end
1456
1789
  end
1457
1790
  context
@@ -1531,6 +1864,18 @@ LocalVarNode
1531
1864
 
1532
1865
  class ClassEndNode<MethodEndNode
1533
1866
  include MethodEndCodeGen
1867
+
1868
+ def initialize(parent)
1869
+ super(parent)
1870
+ @modified_instance_var = nil
1871
+ end
1872
+
1873
+ attr :modified_instance_var
1874
+
1875
+ def collect_info(context)
1876
+ @modified_instance_var = context.modified_instance_var
1877
+ context
1878
+ end
1534
1879
  end
1535
1880
 
1536
1881
  # Set result of method/block
@@ -1550,11 +1895,18 @@ LocalVarNode
1550
1895
  end
1551
1896
 
1552
1897
  def collect_candidate_type(context)
1553
- @is_escape = true
1554
- context = @value_node.collect_candidate_type(context)
1555
1898
  cursig = context.to_signature
1899
+ context = @value_node.collect_candidate_type(context)
1556
1900
  same_type(self, @value_node, cursig, cursig, context)
1557
1901
  same_type(@value_node, self, cursig, cursig, context)
1902
+
1903
+ rtype = decide_type_once(cursig)
1904
+ rrtype = rtype.ruby_type
1905
+ if !rtype.boxed and rrtype != Fixnum and rrtype != Float then
1906
+ set_escape_node_backward(:export_object)
1907
+ else
1908
+ set_escape_node_backward(:not_export)
1909
+ end
1558
1910
  @body.collect_candidate_type(context)
1559
1911
  end
1560
1912
 
@@ -1598,7 +1950,7 @@ LocalVarNode
1598
1950
  super(parent)
1599
1951
  @local_label = parent
1600
1952
  end
1601
-
1953
+
1602
1954
  def collect_candidate_type(context)
1603
1955
  @local_label.come_from.values.each do |vnode|
1604
1956
  if vnode then
@@ -1612,27 +1964,32 @@ LocalVarNode
1612
1964
  def compile(context)
1613
1965
  context = super(context)
1614
1966
  context.ret_node = self
1615
- context.ret_reg = RETR
1616
- context.set_reg_content(RETR, self)
1967
+ context.ret_reg = @local_label.res_area
1617
1968
  context
1618
1969
  end
1619
1970
  end
1620
1971
 
1621
1972
  class LocalLabel<BaseNode
1622
1973
  include HaveChildlenMixin
1974
+ include NodeUtil
1975
+ include MultipleCodeSpaceUtil
1976
+
1623
1977
  def initialize(parent, name)
1624
1978
  super(parent)
1625
1979
  @name = name
1626
1980
  @come_from = {}
1627
1981
  @come_from_val = []
1628
- @code_space = CodeSpace.new
1629
- @value_node = PhiNode.new(self)
1982
+ @current_signature = nil
1983
+ @code_spaces = []
1984
+ @value_node = nil
1630
1985
  @modified_local_var_list = []
1986
+ @res_area = nil
1631
1987
  end
1632
1988
 
1633
1989
  attr :name
1634
1990
  attr :come_from
1635
- attr :value_node
1991
+ attr_accessor :value_node
1992
+ attr :res_area
1636
1993
 
1637
1994
  def traverse_childlen
1638
1995
  yield @value_node
@@ -1673,9 +2030,12 @@ LocalVarNode
1673
2030
  modlocvar = context.modified_local_var.last.map {|ele| ele.dup}
1674
2031
  @modified_local_var_list.push modlocvar
1675
2032
  if @modified_local_var_list.size == 1 then
2033
+ tnode = search_frame_info
2034
+ offset = tnode.static_alloca(8)
2035
+ @res_area = OpIndirect.new(BPR, offset)
1676
2036
  @body.collect_info(context)
1677
2037
  elsif @modified_local_var_list.size == @come_from.size then
1678
- context.merge_local_var(@modified_local_var_list)
2038
+ context.marge_local_var(@modified_local_var_list)
1679
2039
  @body.collect_info(context)
1680
2040
  else
1681
2041
  context
@@ -1688,13 +2048,11 @@ LocalVarNode
1688
2048
  context = valnode.compile(context)
1689
2049
  asm = context.assembler
1690
2050
  if !context.ret_reg.is_a?(OpRegXMM) then
1691
- if RETR != context.ret_reg then
1692
- asm.with_retry do
1693
- asm.mov(RETR, context.ret_reg)
1694
- end
1695
- context.set_reg_content(RETR, context.ret_node)
1696
- context.ret_reg = RETR
2051
+ asm.with_retry do
2052
+ asm.mov(TMPR, context.ret_reg)
2053
+ asm.mov(@res_area, TMPR)
1697
2054
  end
2055
+ context.ret_reg = TMPR
1698
2056
  end
1699
2057
  end
1700
2058
 
@@ -1712,15 +2070,21 @@ LocalVarNode
1712
2070
  end
1713
2071
 
1714
2072
  def collect_candidate_type(context, sender = nil)
1715
- if @come_from.keys[0] == sender then
1716
- @body.collect_candidate_type(context)
2073
+ if @come_from.keys[0] == sender then
2074
+ @body.collect_candidate_type(context)
1717
2075
  else
1718
2076
  context
1719
2077
  end
1720
- end
2078
+ end
1721
2079
 
1722
2080
  def compile(context)
1723
2081
  context = super(context)
2082
+ if @current_signature == nil or
2083
+ @current_signature != context.to_signature then
2084
+ @come_from_val = []
2085
+ @current_signature = context.to_signature
2086
+ end
2087
+
1724
2088
  @come_from_val.push context.ret_reg
1725
2089
 
1726
2090
  if @come_from_val.size == 1 then
@@ -1761,12 +2125,13 @@ LocalVarNode
1761
2125
  end
1762
2126
 
1763
2127
  def compile(context)
2128
+ sig = context.to_signature
1764
2129
  context = super(context)
1765
2130
  context = @jmp_to_node.compile_block_value(context, self)
2131
+ jmptocs = @jmp_to_node.get_code_space(sig)
1766
2132
 
1767
- jmptocs = @jmp_to_node.code_space
1768
- context = @cond.compile(context)
1769
2133
  curas = context.assembler
2134
+ context = @cond.compile(context)
1770
2135
  curas.with_retry do
1771
2136
  if context.ret_reg != TMPR then
1772
2137
  curas.mov(TMPR, context.ret_reg)
@@ -1826,13 +2191,15 @@ LocalVarNode
1826
2191
  end
1827
2192
 
1828
2193
  def compile(context)
2194
+ sig = context.to_signature
1829
2195
  context = super(context)
1830
2196
  context = @jmp_to_node.compile_block_value(context, self)
2197
+ jmptocs = @jmp_to_node.get_code_space(sig)
1831
2198
 
1832
- jmptocs = @jmp_to_node.code_space
1833
2199
  curas = context.assembler
1834
2200
  curas.with_retry do
1835
2201
  curas.jmp(jmptocs.var_base_address)
2202
+ curas.ud2 # Maybe no means but this line may be useful
1836
2203
  end
1837
2204
 
1838
2205
  oldcs = context.set_code_space(jmptocs)
@@ -1842,6 +2209,87 @@ LocalVarNode
1842
2209
  end
1843
2210
  end
1844
2211
 
2212
+ class ThrowNode<BaseNode
2213
+ include HaveChildlenMixin
2214
+ include MethodEndCodeGen
2215
+ include NodeUtil
2216
+
2217
+ def initialize(parent, state, exceptobj)
2218
+ super(parent)
2219
+ @state = state
2220
+ @exception_object = exceptobj
2221
+ end
2222
+
2223
+ def traverse_childlen
2224
+ yield @exception_object
2225
+ end
2226
+
2227
+ def collect_info(context)
2228
+ @exception_object.collect_info(context)
2229
+ end
2230
+
2231
+ def collect_candidate_type(context)
2232
+ @exception_object.collect_candidate_type(context)
2233
+ end
2234
+
2235
+ def gen_unwind(context)
2236
+ end
2237
+
2238
+ def compile_unwind(context)
2239
+ asm = context.assembler
2240
+ handoff = OpIndirect.new(BPR, AsmType::MACHINE_WORD.size * 2)
2241
+ ensureoff = OpIndirect.new(TMPR, 0)
2242
+ asm.with_retry do
2243
+ asm.mov(TMPR, handoff)
2244
+ asm.call(ensureoff)
2245
+ end
2246
+ gen_method_epilogue(context)
2247
+ end
2248
+
2249
+ def compile(context)
2250
+ asm = context.assembler
2251
+ if @state == 0 then
2252
+ context = @exception_object.compile(context)
2253
+
2254
+ elsif @state == 2 then # break
2255
+ context = @exception_object.compile(context)
2256
+ asm.with_retry do
2257
+ if context.ret_reg != RETR then
2258
+ asm.mov(RETR, context.ret_reg)
2259
+ end
2260
+ end
2261
+ context.set_reg_content(RETR, context.ret_node)
2262
+ # two epilogue means block and method which is called with block
2263
+ context = gen_method_epilogue(context)
2264
+ # instead of gen_method_epilogue because may need to ensure proc.
2265
+ context = compile_unwind(context)
2266
+ asm.with_retry do
2267
+ asm.ret
2268
+ end
2269
+
2270
+ elsif @state == 1 then # return
2271
+ if context.ret_reg != RETR then
2272
+ asm.mov(RETR, context.ret_reg)
2273
+ end
2274
+ context.set_reg_content(RETR, context.ret_node)
2275
+ tnode = search_frame_info
2276
+ finfo = tnode
2277
+ depth = 0
2278
+ while finfo.parent.is_a?(BlockTopNode)
2279
+ finfo = finfo.previous_frame
2280
+ # two epilogue means block and method which is called with block
2281
+ context = gen_method_epilogue(context)
2282
+ context = compile_unwind(context)
2283
+ end
2284
+ context = compile_unwind(context)
2285
+ asm.with_retry do
2286
+ asm.ret
2287
+ end
2288
+ end
2289
+ context
2290
+ end
2291
+ end
2292
+
1845
2293
  # Holder of Nodes Assign. These assignes execute parallel potencially.
1846
2294
  class LetNode<BaseNode
1847
2295
  include HaveChildlenMixin
@@ -1855,7 +2303,7 @@ LocalVarNode
1855
2303
  def initialize(node)
1856
2304
  super(node.parent)
1857
2305
  @node = node
1858
- @first_compile = true
2306
+ @compiled_by_signature = []
1859
2307
  @res_area = nil
1860
2308
  end
1861
2309
 
@@ -1865,7 +2313,7 @@ LocalVarNode
1865
2313
 
1866
2314
  def collect_info(context)
1867
2315
  tnode = search_frame_info
1868
- offset = tnode.alloca(8)
2316
+ offset = tnode.static_alloca(8)
1869
2317
  @res_area = OpIndirect.new(BPR, offset)
1870
2318
  @node.collect_info(context)
1871
2319
  end
@@ -1878,14 +2326,24 @@ LocalVarNode
1878
2326
  end
1879
2327
 
1880
2328
  def compile(context)
1881
- if @first_compile then
2329
+ sig = context.to_signature
2330
+ if !@compiled_by_signature.include?(sig) then
1882
2331
  context = @node.compile(context)
1883
2332
  asm = context.assembler
1884
- asm.with_retry do
1885
- asm.mov(@res_area, context.ret_reg)
2333
+ if context.ret_reg.is_a?(OpRegistor) then
2334
+ asm.with_retry do
2335
+ asm.mov(@res_area, context.ret_reg)
2336
+ end
2337
+ context.set_reg_content(@res_area, context.ret_node)
2338
+ else
2339
+ asm.with_retry do
2340
+ asm.mov(TMPR, context.ret_reg)
2341
+ asm.mov(@res_area, TMPR)
2342
+ end
2343
+ context.set_reg_content(@res_area, context.ret_node)
1886
2344
  end
1887
2345
  context.set_reg_content(@res_area, self)
1888
- @first_compile = false
2346
+ @compiled_by_signature.push sig
1889
2347
 
1890
2348
  context
1891
2349
  else
@@ -1893,7 +2351,7 @@ LocalVarNode
1893
2351
  asm.with_retry do
1894
2352
  asm.mov(RETR, @res_area)
1895
2353
  end
1896
- context.set_reg_content(@res_area, self)
2354
+ context.set_reg_content(RETR, self)
1897
2355
  context.ret_reg = RETR
1898
2356
  context.ret_node = self
1899
2357
 
@@ -1915,24 +2373,40 @@ LocalVarNode
1915
2373
  attr :value
1916
2374
 
1917
2375
  def collect_candidate_type(context)
1918
- # ???
1919
- if @type == nil then
2376
+ sig = context.to_signature
2377
+ if @type_list != [[], []] then
2378
+ @type = decide_type_once(sig)
2379
+ elsif @type == nil then
1920
2380
  @type = RubyType::BaseType.from_object(@value)
1921
2381
  end
1922
2382
 
1923
- sig = context.to_signature
1924
2383
  case @value
1925
2384
  when Array
1926
2385
  add_type(sig, @type)
1927
2386
  @value.each do |ele|
1928
2387
  etype = RubyType::BaseType.from_object(ele)
1929
- @element_node_list[0][1].add_type(sig, etype)
2388
+ @element_node_list[0][2].add_type(sig, etype)
1930
2389
  end
1931
2390
 
1932
2391
  when Range
1933
2392
  @type = @type.to_box
1934
2393
  add_type(sig, @type)
1935
-
2394
+ if @type.args == nil then
2395
+ @type.args = []
2396
+ ele = @value.first
2397
+ fstnode = LiteralNode.new(self, ele)
2398
+ context = fstnode.collect_candidate_type(context)
2399
+ @type.args.push fstnode
2400
+ ele = @value.last
2401
+ sndnode = LiteralNode.new(self, ele)
2402
+ @type.args.push sndnode
2403
+ context = sndnode.collect_candidate_type(context)
2404
+ ele = @value.exclude_end?
2405
+ exclnode = LiteralNode.new(self, ele)
2406
+ @type.args.push exclnode
2407
+ context = exclnode.collect_candidate_type(context)
2408
+ add_element_node(@type, sig, fstnode, [0], context)
2409
+ end
1936
2410
  else
1937
2411
  add_type(sig, @type)
1938
2412
  end
@@ -1940,6 +2414,10 @@ LocalVarNode
1940
2414
  context
1941
2415
  end
1942
2416
 
2417
+ def compile_get_constant(context)
2418
+ compile(context)
2419
+ end
2420
+
1943
2421
  def compile(context)
1944
2422
  context = super(context)
1945
2423
 
@@ -2094,6 +2572,7 @@ LocalVarNode
2094
2572
  asm.mov(PTMPR, prevenv)
2095
2573
  asm.mov(PTMPR, slfarg)
2096
2574
  end
2575
+ context.set_reg_content(PTMPR, nil)
2097
2576
  context.ret_reg2 = PTMPR
2098
2577
 
2099
2578
  context.ret_reg = @frame_info.offset_arg(1, BPR)
@@ -2130,7 +2609,10 @@ LocalVarNode
2130
2609
 
2131
2610
  def compile(context)
2132
2611
  context = super(context)
2133
- context.ret_reg = OpMemAddress.new(address_of(@name))
2612
+ addr = lambda {
2613
+ address_of(@name)
2614
+ }
2615
+ context.ret_reg = OpVarMemAddress.new(addr)
2134
2616
  context.ret_node = self
2135
2617
  context.set_reg_content(context.ret_reg, self)
2136
2618
  context
@@ -2168,8 +2650,7 @@ LocalVarNode
2168
2650
  @reciever = @parent.class_top
2169
2651
  if @reciever == @parent.search_top and
2170
2652
  !@reciever.is_a?(TopTopNode) then
2171
- @reciever.make_klassclass_node
2172
- @reciever = @reciever.klassclass_node
2653
+ @reciever = @reciever.make_klassclass_node
2173
2654
  end
2174
2655
  else
2175
2656
  @reciever = sendnode.arguments[2]
@@ -2203,6 +2684,10 @@ LocalVarNode
2203
2684
  if recobj.is_a?(ClassClassWrapper) then
2204
2685
  recobj = recobj.value
2205
2686
  end
2687
+ if recobj and !recobj.is_a?(Class) then
2688
+ # recobj is Module
2689
+ recobj = Object
2690
+ end
2206
2691
  if recobj then
2207
2692
  addr = recobj.method_address_of(@name)
2208
2693
  if addr then
@@ -2220,8 +2705,21 @@ LocalVarNode
2220
2705
  end
2221
2706
  end
2222
2707
  else
2223
- rtype = @reciever.decide_type_once(context.to_signature)
2708
+ sig = context.to_signature
2709
+ =begin
2710
+ p @name
2711
+ p @parent.debug_info
2712
+ p context.to_signature
2713
+ p sig
2714
+ p @parent.arguments[2].class
2715
+ =end
2716
+
2717
+ if @reciever.type_list(sig).flatten.uniq.size != 0 then
2718
+ @reciever.type = nil
2719
+ end
2720
+ rtype = @reciever.decide_type_once(sig)
2224
2721
  rklass = rtype.ruby_type_raw
2722
+
2225
2723
  knode = ClassTopNode.get_class_top_node(rklass)
2226
2724
  if knode and knode.search_method_with_super(@name)[0] then
2227
2725
  @calling_convention = :ytl
@@ -2242,11 +2740,12 @@ LocalVarNode
2242
2740
  end
2243
2741
  begin
2244
2742
  mth = rklass.instance_method(@name)
2743
+ @ruby_reciever = rtype.ruby_type_raw
2245
2744
  rescue NameError
2246
2745
  p @parent.debug_info
2247
- p context.to_signature
2746
+ p sig
2248
2747
  p @name
2249
- # p @reciever.func.reciever.class
2748
+ p @reciever.class
2250
2749
  p @reciever.instance_eval {@type_list }
2251
2750
  =begin
2252
2751
  mc = @reciever.get_send_method_node(context.to_signature)[0]
@@ -2256,7 +2755,6 @@ LocalVarNode
2256
2755
  =end
2257
2756
  raise
2258
2757
  end
2259
- @ruby_reciever = rtype.ruby_type_raw
2260
2758
  end
2261
2759
 
2262
2760
  if variable_argument?(mth.parameters) then
@@ -2283,12 +2781,21 @@ LocalVarNode
2283
2781
  if mtop then
2284
2782
  sig = @parent.signature(context)
2285
2783
  cs = mtop.find_cs_by_signature(sig)
2286
- context.ret_reg = cs.var_base_address
2784
+ if cs then
2785
+ context.ret_reg = cs.var_base_address
2786
+ else
2787
+ # Maybe not reached program
2788
+ context.ret_reg = 0
2789
+ end
2287
2790
  else
2288
2791
  recobj = @reciever.klass_object
2289
2792
  if recobj.is_a?(ClassClassWrapper) then
2290
2793
  recobj = recobj.value
2291
2794
  end
2795
+ if recobj and !recobj.is_a?(Class) then
2796
+ # recobj is Module
2797
+ recobj = Object
2798
+ end
2292
2799
  if recobj then
2293
2800
  addr = lambda {
2294
2801
  recobj.method_address_of(@name)
@@ -2308,9 +2815,12 @@ LocalVarNode
2308
2815
  end
2309
2816
  else
2310
2817
  context = @reciever.compile(context)
2311
- rtype = context.ret_node.decide_type_once(context.to_signature)
2818
+ rnode = context.ret_node
2819
+ rtype = rnode.decide_type_once(context.to_signature)
2312
2820
  if @calling_convention != :ytl then
2313
- context = rtype.gen_boxing(context)
2821
+ if rnode.is_escape != true then
2822
+ context = rtype.gen_boxing(context)
2823
+ end
2314
2824
  rtype = rtype.to_box
2315
2825
  elsif !rtype.boxed then
2316
2826
  context = rtype.gen_unboxing(context)
@@ -2323,9 +2833,14 @@ LocalVarNode
2323
2833
  if rtype.is_a?(RubyType::DefaultType0) then
2324
2834
  # Can't type inference. Dynamic method search
2325
2835
  mnval = @name.address
2326
- objclass = OpMemAddress.new(address_of("rb_obj_class"))
2327
- addr = address_of("ytl_method_address_of_raw")
2328
- meaddrof = OpMemAddress.new(addr)
2836
+ addr = lambda {
2837
+ address_of("rb_obj_class")
2838
+ }
2839
+ objclass = OpVarMemAddress.new(addr)
2840
+ addr = lambda {
2841
+ address_of("ytl_method_address_of_raw")
2842
+ }
2843
+ addrof = OpVarMemAddress.new(addr)
2329
2844
 
2330
2845
  context.start_using_reg(TMPR2)
2331
2846
  context.start_arg_reg
@@ -2337,7 +2852,12 @@ LocalVarNode
2337
2852
  asm.call_with_arg(objclass, 1)
2338
2853
  asm.mov(FUNC_ARG[0], RETR)
2339
2854
  asm.mov(FUNC_ARG[1], mnval)
2340
- asm.call_with_arg(meaddrof, 2)
2855
+ end
2856
+ context.set_reg_content(FUNC_ARG[0], nil)
2857
+ context.set_reg_content(FUNC_ARG[1], nil)
2858
+ context = gen_save_thepr(context)
2859
+ asm.with_retry do
2860
+ asm.call_with_arg(addrof, 2)
2341
2861
  asm.mov(TMPR2, RETR)
2342
2862
  asm.pop(PTMPR)
2343
2863
  end
@@ -2348,8 +2868,8 @@ LocalVarNode
2348
2868
  context.end_arg_reg
2349
2869
 
2350
2870
  context.ret_node = self
2351
- context.set_reg_content(RETR, self)
2352
- context.set_reg_content(TMPR2, self)
2871
+ context.set_reg_content(RETR, nil)
2872
+ context.set_reg_content(TMPR2, nil)
2353
2873
  context.set_reg_content(PTMPR, @reciever)
2354
2874
  context.ret_reg = TMPR2
2355
2875
 
@@ -2409,7 +2929,7 @@ LocalVarNode
2409
2929
  context.code_space.refer_operands.push context.ret_reg
2410
2930
  context.ret_node = self
2411
2931
  else
2412
- raise "Unkown method - #{@name}"
2932
+ raise "Unkown method - #{@ruby_reciever}##{@name}"
2413
2933
  context.ret_reg = OpImmidiateAddress.new(0)
2414
2934
  context.ret_node = self
2415
2935
  end
@@ -2546,6 +3066,7 @@ LocalVarNode
2546
3066
  super(parent, offset, depth)
2547
3067
  val.parent = self
2548
3068
  @val = val
3069
+ @var_from = nil
2549
3070
  end
2550
3071
 
2551
3072
  def traverse_childlen
@@ -2555,19 +3076,23 @@ LocalVarNode
2555
3076
 
2556
3077
  def collect_info(context)
2557
3078
  context = @val.collect_info(context)
2558
- top = @frame_info.parent
3079
+ top = @frame_info
3080
+ @depth.times do |i|
3081
+ top = top.previous_frame
3082
+ end
3083
+ @var_from = top.parent
2559
3084
 
2560
3085
  nodepare = nil
2561
3086
  if @depth > 0 then
2562
- nodepare = top.orig_modified_local_var[-@depth]
3087
+ nodepare = context.modified_local_var.last[-@depth - 1]
2563
3088
  end
2564
3089
  if nodepare then
2565
3090
  nodepare = nodepare[@offset]
2566
3091
  end
2567
3092
  if nodepare then
2568
- nodepare.push [top, self]
3093
+ nodepare.push [@var_from, self]
2569
3094
  else
2570
- nodepare = [[top, self]]
3095
+ nodepare = [[@var_from, self]]
2571
3096
  end
2572
3097
 
2573
3098
  context.modified_local_var.last[-@depth - 1][@offset] = nodepare
@@ -2578,8 +3103,9 @@ LocalVarNode
2578
3103
  def collect_candidate_type(context)
2579
3104
  context = @val.collect_candidate_type(context)
2580
3105
  cursig = context.to_signature
2581
- same_type(self, @val, cursig, cursig, context)
2582
- # same_type(@val, self, cursig, cursig, context)
3106
+ varcursig = context.to_signature(@var_from)
3107
+ same_type(self, @val, varcursig, cursig, context)
3108
+ # same_type(@val, self, cursig, varcursig, context)
2583
3109
  @body.collect_candidate_type(context)
2584
3110
  end
2585
3111
 
@@ -2587,11 +3113,15 @@ LocalVarNode
2587
3113
  context = super(context)
2588
3114
  context = @val.compile(context)
2589
3115
 
2590
- decide_type_once(context.to_signature)
3116
+ sig = context.to_signature(-@depth - 1)
3117
+ decide_type_once(sig)
3118
+ rtype = @val.decide_type_once(context.to_signature)
2591
3119
  if @type.boxed then
2592
- @val.decide_type_once(context.to_signature)
2593
- rtype = @val.type
2594
- context = rtype.gen_boxing(context)
3120
+ if @val.is_escape != true then
3121
+ context = rtype.gen_boxing(context)
3122
+ end
3123
+ else
3124
+ context = rtype.gen_unboxing(context)
2595
3125
  end
2596
3126
 
2597
3127
  valr = context.ret_reg
@@ -2631,15 +3161,21 @@ LocalVarNode
2631
3161
  class InstanceVarRefCommonNode<VariableRefCommonNode
2632
3162
  include NodeUtil
2633
3163
 
2634
- def initialize(parent, name)
3164
+ def initialize(parent, name, mnode)
2635
3165
  super(parent)
2636
3166
  @name = name
3167
+ @method_node = mnode
3168
+ mname = nil
3169
+ if @method_node then
3170
+ mname = @method_node.get_constant_value
3171
+ end
3172
+ @method_name = mname
2637
3173
  @class_top = search_class_top
2638
3174
  end
2639
3175
  end
2640
3176
 
2641
3177
  class InstanceVarRefNode<InstanceVarRefCommonNode
2642
- def initialize(parent, name)
3178
+ def initialize(parent, name, mnode)
2643
3179
  super
2644
3180
  @var_type_info = nil
2645
3181
  end
@@ -2661,7 +3197,7 @@ LocalVarNode
2661
3197
  cursig = context.to_signature
2662
3198
  same_type(self, src, cursig, cursig, context)
2663
3199
  end
2664
-
3200
+
2665
3201
  context
2666
3202
  end
2667
3203
 
@@ -2677,8 +3213,8 @@ LocalVarNode
2677
3213
 
2678
3214
  class InstanceVarAssignNode<InstanceVarRefCommonNode
2679
3215
  include HaveChildlenMixin
2680
- def initialize(parent, name, val)
2681
- super(parent, name)
3216
+ def initialize(parent, name, mnode, val)
3217
+ super(parent, name, mnode)
2682
3218
  val.parent = self
2683
3219
  @val = val
2684
3220
  end
@@ -2698,12 +3234,15 @@ LocalVarNode
2698
3234
  end
2699
3235
 
2700
3236
  def collect_candidate_type(context)
2701
- @is_escape = true
2702
- @val.is_escape = true
2703
3237
  context = @val.collect_candidate_type(context)
2704
3238
  cursig = context.to_signature
2705
3239
  same_type(self, @val, cursig, cursig, context)
2706
3240
  # same_type(@val, self, cursig, cursig, context)
3241
+ rtype = @val.decide_type_once(cursig)
3242
+ rrtype = rtype.ruby_type
3243
+ if cursig[2].boxed and rrtype != Fixnum and rrtype != Float then
3244
+ @val.set_escape_node_backward(true)
3245
+ end
2707
3246
  @body.collect_candidate_type(context)
2708
3247
  end
2709
3248
 
@@ -2751,13 +3290,14 @@ LocalVarNode
2751
3290
  attr :value_node
2752
3291
 
2753
3292
  def collect_candidate_type(context)
2754
- if @value_node.is_a?(ClassTopNode) then
3293
+ if @value_node.is_a?(ClassTopNode) or
3294
+ @value_node.is_a?(LiteralNode) then
2755
3295
  add_type(context.to_signature, @value_node.type)
2756
3296
  else
2757
- context = @value_node.collect_candidate_type(context)
2758
3297
  cursig = context.to_signature
2759
3298
  same_type(self, @value_node, cursig, cursig, context)
2760
3299
  end
3300
+
2761
3301
  context
2762
3302
  end
2763
3303
 
@@ -2769,7 +3309,7 @@ LocalVarNode
2769
3309
  context.ret_reg = OpVarImmidiateAddress.new(objadd)
2770
3310
 
2771
3311
  else
2772
- context = @value_node.compile(context)
3312
+ context = @value_node.compile_get_constant(context)
2773
3313
  end
2774
3314
 
2775
3315
  context.ret_node = self
@@ -2784,19 +3324,27 @@ LocalVarNode
2784
3324
  class ConstantAssignNode<VariableRefCommonNode
2785
3325
  include NodeUtil
2786
3326
  include HaveChildlenMixin
3327
+ include TypeListWithoutSignature
2787
3328
 
2788
3329
  def initialize(parent, klass, name, value)
2789
3330
  super(parent)
2790
3331
  @name = name
2791
3332
  @class_top = klass # .search_class_top
3333
+
3334
+ pvalue = nil
2792
3335
  @value = value
3336
+ @value_node = value
3337
+ if !value.is_a?(LiteralNode) then
3338
+ @value_node = self
3339
+ end
2793
3340
 
2794
3341
  if klass.is_a?(ClassTopNode) then
2795
- klass.constant_tab[@name] = @value
3342
+ klass.constant_tab[@name] = @value_node
2796
3343
  else
2797
3344
  pp klass.class
2798
3345
  raise "Not Implemented yet for set constant for dynamic class"
2799
3346
  end
3347
+ @constant_area = nil
2800
3348
  end
2801
3349
 
2802
3350
  def traverse_childlen
@@ -2804,14 +3352,55 @@ LocalVarNode
2804
3352
  end
2805
3353
 
2806
3354
  def collect_candidate_type(context)
3355
+ sig = context.to_signature
3356
+ context = @value.collect_candidate_type(context)
3357
+ same_type(self, @value, sig, sig, context)
2807
3358
  @body.collect_candidate_type(context)
2808
3359
  end
2809
3360
 
2810
- def type
2811
- @value.type
3361
+ # def type
3362
+ # @value.type
3363
+ # end
3364
+
3365
+ def compile_get_constant(context)
3366
+ asm = context.assembler
3367
+ rtype = decide_type_once(context.to_signature)
3368
+ retr = RETR
3369
+ if rtype.ruby_type == Float and !rtype.boxed then
3370
+ retr = XMM0
3371
+ end
3372
+ asm.with_retry do
3373
+ asm.mov(TMPR, @constant_area)
3374
+ asm.mov(retr, INDIRECT_TMPR)
3375
+ end
3376
+ context.ret_reg = retr
3377
+ context.ret_node = self
3378
+ context
2812
3379
  end
2813
3380
 
2814
3381
  def compile(context)
3382
+ if !@value.is_a?(LiteralNode) then
3383
+ asm = context.assembler
3384
+ valproc = lambda { 4 }
3385
+ varnilval = OpVarMemAddress.new(valproc)
3386
+ @constant_area = asm.add_value_entry_no_cache(varnilval)
3387
+ @constant_area = @constant_area.to_immidiate
3388
+ context = @value.compile(context)
3389
+ rtype = decide_type_once(context.to_signature)
3390
+ tmpr = TMPR
3391
+ if rtype.ruby_type == Float and !rtype.boxed then
3392
+ tmpr = XMM0
3393
+ end
3394
+
3395
+ asm.with_retry do
3396
+ asm.push(TMPR2)
3397
+ asm.mov(tmpr, context.ret_reg)
3398
+ asm.mov(TMPR2, @constant_area)
3399
+ asm.mov(INDIRECT_TMPR2, tmpr)
3400
+ asm.pop(TMPR2)
3401
+ end
3402
+ end
3403
+
2815
3404
  @body.compile(context)
2816
3405
  end
2817
3406
  end