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.
@@ -99,6 +99,20 @@ module YTLJit
99
99
  argruby = ele.to_ruby(ToRubyContext.new).ret_code.last
100
100
  args.push eval(argruby)
101
101
  end
102
+
103
+ # define used methods in macro
104
+ @@macro_tab.each do |name, val|
105
+ val.each do |rec, proc|
106
+ if rec.is_a?(Module) then
107
+ name1 = ("ytl__eval_" + name.to_s).to_sym
108
+ if proc.is_a?(Proc)
109
+ rec.class_eval {define_method(name1, &proc)}
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ # call eval included method
102
116
  return mproc.call(*args)
103
117
  end
104
118
  end
@@ -140,6 +154,7 @@ module YTLJit
140
154
 
141
155
  @result_cache = nil
142
156
  @method_signature = []
157
+ @yield_signature_cache = {}
143
158
 
144
159
  @current_exception_table = nil
145
160
  end
@@ -154,9 +169,20 @@ module YTLJit
154
169
  attr :modified_instance_var
155
170
  attr_accessor :result_cache
156
171
  attr :seq_no
172
+ attr :yield_signature_cache
157
173
 
158
174
  attr_accessor :current_exception_table
159
175
 
176
+ def traverse_node(&blk)
177
+ @arguments.each_with_index do |arg, i|
178
+ if arg.is_a?(SendNode) then
179
+ arg.traverse_node(&blk)
180
+ else
181
+ yield(arg, @arguments, i)
182
+ end
183
+ end
184
+ end
185
+
160
186
  def traverse_childlen
161
187
  @arguments.each do |arg|
162
188
  yield arg
@@ -167,14 +193,20 @@ module YTLJit
167
193
 
168
194
  def get_send_method_node(cursig)
169
195
  mt = nil
170
- # @arguments[2].type = nil
171
- slf = @arguments[2].decide_type_once(cursig)
196
+ if @arguments[2].type_list(cursig) != [[], []] then
197
+ @arguments[2].type = nil
198
+ end
199
+ slf = nil
172
200
  if is_fcall or is_vcall then
201
+ slf = @arguments[2].decide_type_once(cursig)
173
202
  mt = @func.method_top_node(@class_top, nil)
174
-
175
203
  else
204
+ slf = @arguments[2].decide_type_once(cursig)
176
205
  if slf.instance_of?(RubyType::DefaultType0) then
177
206
  # Chaos
207
+ #p debug_info
208
+ #p cursig
209
+ #p @arguments[2].instance_eval { @type_list }
178
210
  # raise "chaos"
179
211
  end
180
212
 
@@ -213,8 +245,8 @@ module YTLJit
213
245
  end
214
246
  end
215
247
 
216
- @modified_local_var = context.modified_local_var.last.dup
217
- @modified_instance_var = context.modified_instance_var.dup
248
+ @modified_local_var = context.modified_local_var.last
249
+ @modified_instance_var = context.modified_instance_var
218
250
 
219
251
  context = fill_result_cache(context)
220
252
 
@@ -248,15 +280,105 @@ module YTLJit
248
280
  end
249
281
  end
250
282
 
283
+ # inherit self/block from caller node
284
+ def inherit_from_callee(context, cursig, prevsig, signat, args, nest)
285
+ if context.is_a?(TypeInferenceContext) then
286
+ (0..2).each do |n|
287
+ args[n] = context.current_method_signature_node[-2 - nest][n]
288
+ end
289
+ end
290
+ (0..2).each do |n|
291
+ signat[n] = prevsig[n]
292
+ end
293
+
294
+ if args[2].decide_type_once(cursig).ruby_type == Object then
295
+ context.current_method_signature_node.reverse.each {|e0|
296
+ if e0[2].class == SendNewArenaNode then
297
+ if args[2].type then
298
+ args[2] = e0[2]
299
+ signat[2] = args[2].type
300
+ end
301
+ break
302
+ end
303
+ }
304
+ end
305
+ end
306
+
307
+ def collect_candidate_type_block(context, blknode, signat, mt, cursig)
308
+ # traverse a nested block
309
+ # mt and signat are set corresponding to the nest level of yield
310
+ if @func.is_a?(YieldNode) and false then
311
+ level = @depth
312
+ else
313
+ level = 0
314
+ end
315
+ nest = 0
316
+ sn = nil
317
+ while mt.yield_node.size == 0 and
318
+ mt.send_nodes_with_block.size != 0
319
+ sn = mt.send_nodes_with_block[0]
320
+ mt, slf = sn.get_send_method_node(cursig)
321
+ if mt == nil then
322
+ return context
323
+ end
324
+ args = sn.arguments
325
+
326
+ context.push_signature(args, mt)
327
+
328
+ nest = nest + 1
329
+ if mt.yield_node.size == 0 then
330
+ break
331
+ end
332
+ ynode = mt.yield_node[0]
333
+ yargs = ynode.arguments.dup
334
+ (0..2).each do |n|
335
+ cl = nest + level
336
+ yargs[n] = context.current_method_signature_node[-1 - cl][n]
337
+ end
338
+ mt = args[1]
339
+ context.push_signature(yargs, mt)
340
+ nest = nest + 1
341
+ end
342
+ if sn then
343
+ signat = sn.signature(context)
344
+ end
345
+
346
+ mt.yield_node.map do |ynode|
347
+ yargs = ynode.arguments.dup
348
+ yargs[2.. -1].each do |arg|
349
+ context = arg.collect_candidate_type(context)
350
+ end
351
+ ysignat = ynode.signature(context)
352
+
353
+ # inherit self from caller node
354
+ # notice: this region pushed callee signature_node
355
+ cl = nest + level
356
+ prevsig = context.to_signature(-2 - cl)
357
+ inherit_from_callee(context, cursig, prevsig, ysignat, yargs, cl)
358
+ # ysignat[1] = signat[0]
359
+
360
+ # collect candidate type of block and yield
361
+ context = blknode.collect_candidate_type(context, yargs, ysignat)
362
+ same_type(ynode, blknode, signat, ysignat, context)
363
+ @yield_signature_cache[cursig] = ysignat
364
+
365
+ # fill type cache(@type) of block node
366
+ blknode.type = nil
367
+ blknode.decide_type_once(ysignat)
368
+ end
369
+
370
+ nest.times do
371
+ context.pop_signature
372
+ end
373
+
374
+ context
375
+ end
376
+
251
377
  def collect_candidate_type(context)
252
378
  cursig = context.to_signature
253
379
 
254
380
  # get saved original signature
255
381
  metsigent = search_signature(cursig)
256
- oldsignat = nil
257
- if metsigent then
258
- oldsignat = metsigent[1]
259
- end
260
382
 
261
383
  # prev env
262
384
  context = @arguments[0].collect_candidate_type(context)
@@ -273,7 +395,13 @@ module YTLJit
273
395
  context = @func.collect_candidate_type(context)
274
396
 
275
397
  signat = signature(context)
276
- changed = check_signature_changed(context, signat, metsigent, cursig)
398
+ ysig = @yield_signature_cache[cursig]
399
+ if ysig then
400
+ signat[1] = blknode.decide_type_once(ysig)
401
+ end
402
+ if @func.is_a?(YieldNode) then
403
+ signat[1] = cursig[0]
404
+ end
277
405
  =begin
278
406
  if changed then
279
407
  @arguments.each do |arg|
@@ -285,57 +413,52 @@ module YTLJit
285
413
 
286
414
  mt, slf = get_send_method_node(cursig)
287
415
  if mt then
416
+ =begin
417
+ changed = check_signature_changed(context, signat,
418
+ metsigent, cursig)
288
419
  if changed then
289
420
  mt.type_list(metsigent[1])[1] = []
290
421
  mt.ti_reset
291
422
  end
423
+ =end
292
424
 
293
425
  context = mt.collect_candidate_type(context, @arguments, signat)
294
426
 
295
- same_type(self, mt, cursig, signat, context)
296
-
297
- context.push_signature(@arguments, mt)
298
427
  if blknode.is_a?(TopNode) then
428
+ context.push_signature(@arguments, mt)
299
429
  # Have block
300
- mt.yield_node.map do |ynode|
301
- yargs = ynode.arguments.dup
302
- ysignat = ynode.signature(context)
303
-
304
- same_type(ynode, blknode, signat, ysignat, context)
305
-
306
- # inherit self from caller node
307
- yargs[2] = context.current_method_signature_node[-2][2]
308
- ysignat[2] = cursig[2]
309
- if yargs[2].decide_type_once(cursig).ruby_type == Object then
310
- context.current_method_signature_node.reverse.each {|e0|
311
- if e0[2].class == SendNewArenaNode then
312
- if yargs[2].type then
313
- yargs[2] = e0[2]
314
- ysignat[2] = yargs[2].type
315
- end
316
- break
317
- end
318
- }
319
- end
320
- context = blknode.collect_candidate_type(context,
321
- yargs, ysignat)
322
-
430
+ context = collect_candidate_type_block(context, blknode,
431
+ signat, mt, cursig)
432
+ context.pop_signature
433
+ if signat[1] != blknode.type then
434
+ signat[1] = blknode.type
435
+ context = mt.collect_candidate_type(context,
436
+ @arguments, signat)
323
437
  end
324
438
  else
439
+ context.push_signature(@arguments, mt)
325
440
  context = blknode.collect_candidate_type(context)
441
+ context.pop_signature
326
442
  end
327
- context.pop_signature
328
-
443
+ same_type(self, mt, cursig, signat, context)
444
+
329
445
  else
330
446
  context = collect_candidate_type_regident(context, slf)
331
447
  end
332
448
 
449
+ if @func.is_a?(YieldNode) then
450
+ add_type(cursig, cursig[1])
451
+ @type = nil
452
+ decide_type_once(cursig)
453
+ end
333
454
  @body.collect_candidate_type(context)
334
455
  end
335
456
 
336
457
  def compile(context)
337
458
  context = super(context)
338
459
 
460
+ @type = nil
461
+ cursig = context.to_signature
339
462
  context.start_using_reg(TMPR2)
340
463
  context.start_using_reg(PTMPR)
341
464
  callconv = @func.calling_convention(context)
@@ -353,14 +476,29 @@ module YTLJit
353
476
  when :ytl
354
477
  context = compile_ytl(context)
355
478
 
479
+ when :getter
480
+ inode = @func.inline_node
481
+ context = @arguments[2].compile(context)
482
+ rectype = @arguments[2].decide_type_once(cursig)
483
+ context = inode.compile_main_aux(context, context.ret_reg, rectype)
484
+
485
+ when :setter
486
+ inode = @func.inline_node
487
+ context = @arguments[2].compile(context)
488
+ rectype = @arguments[2].decide_type_once(cursig)
489
+ context = inode.compile_main_aux(context, context.ret_reg, rectype,
490
+ @arguments[3], nil)
491
+
356
492
  when nil
357
493
 
358
494
  else
359
- raise "Unsupported calling conversion #{callconv}"
495
+ # p @arguments[2].type_list(context.to_signature)
496
+ # p @func.name
497
+ # raise "Unsupported calling conversion #{callconv}"
360
498
  end
361
499
 
362
- decide_type_once(context.to_signature)
363
- if @type.is_a?(RubyType::RubyTypeUnboxed) and
500
+ decide_type_once(cursig)
501
+ if !@type.boxed and
364
502
  @type.ruby_type == Float then
365
503
  context.ret_reg = XMM0
366
504
  else
@@ -496,16 +634,66 @@ module YTLJit
496
634
  add_special_send_node :eval
497
635
  end
498
636
 
637
+ class SendEvalNode<SendNode
638
+ add_special_send_node :unpack
639
+
640
+ def collect_candidate_type_regident(context, slf)
641
+ if slf.ruby_type == String
642
+ cursig = context.to_signature
643
+ arytype = RubyType::BaseType.from_ruby_class(Array)
644
+ add_type(cursig, arytype)
645
+
646
+ fmt = @arguments[3].get_constant_value
647
+ if fmt.is_a?(Array) and fmt[0].is_a?(String) then
648
+ fmt = fmt[0]
649
+ else
650
+ fmt = nil
651
+ end
652
+ fmt.each_char do |ch|
653
+ type = nil
654
+ case ch
655
+ when 'c', 'C', 's', 'S', 'i', 'I', 'l', 'L', 'n', 'N', 'v', 'V'
656
+ type = RubyType::BaseType.from_ruby_class(Fixnum)
657
+
658
+ when 'a', 'A', 'Z', 'b', 'B', 'h', 'H', 'm', 'M', 'u', 'U', 'w'
659
+ type = RubyType::BaseType.from_ruby_class(String)
660
+
661
+ when 'f', 'd', 'e', 'E', 'g', 'G'
662
+ type = RubyType::BaseType.from_ruby_class(Float)
663
+
664
+ end
665
+
666
+ if type then
667
+ tnode = TypedDummyNode.instance(cursig, type)
668
+ add_element_node(arytype, cursig, tnode, nil, context)
669
+ end
670
+ end
671
+ end
672
+
673
+ context
674
+ end
675
+ end
676
+
499
677
  class SendIncludeCommonNode<SendNode
678
+ def collect_info(context)
679
+ slfnode = @arguments[2]
680
+ modvalue = @arguments[3].value_node
681
+ modnode = ClassTopNode.get_class_top_node(modvalue.get_constant_value[0])
682
+ add_search_module(slfnode, modnode)
683
+ super
684
+ end
685
+
500
686
  def collect_candidate_type_regident(context, slf)
501
687
  slfnode = @arguments[2]
502
688
  rtype = slfnode.decide_type_once(context.to_signature)
503
689
  add_type(context.to_signature, rtype)
504
- modnode = @arguments[3].value_node
505
690
 
506
- add_search_module(slfnode, modnode)
507
691
  context
508
692
  end
693
+
694
+ def compile(context)
695
+ @body.compile(context)
696
+ end
509
697
  end
510
698
 
511
699
  class SendIncludeNode<SendIncludeCommonNode
@@ -528,6 +716,7 @@ module YTLJit
528
716
 
529
717
  class SendAllocateNode<SendNode
530
718
  include UnboxedObjectUtil
719
+ include SendSingletonClassUtil
531
720
 
532
721
  add_special_send_node :allocate
533
722
 
@@ -535,25 +724,11 @@ module YTLJit
535
724
  slfnode = @arguments[2]
536
725
  cursig = context.to_signature
537
726
  if slf.ruby_type.is_a?(Class) then
538
- tt = nil
539
- case slfnode
540
- when ConstantRefNode
541
- clstop = slfnode.value_node
542
- case clstop
543
- when ClassTopNode
544
- tt = RubyType::BaseType.from_ruby_class(clstop.klass_object)
545
- when LiteralNode
546
- tt = RubyType::BaseType.from_ruby_class(clstop.value)
547
- else
548
- raise "Unkown node type in constant #{slfnode.value_node.class}"
549
- end
550
-
551
- else
552
- raise "Unkonwn node type #{@arguments[2].class} "
553
- end
554
-
727
+ tt = get_singleton_class_object(@arguments[2])
555
728
  clt = ClassTopNode.get_class_top_node(tt.ruby_type_raw)
729
+ @type = nil
556
730
  if context.options[:compile_array_as_uboxed] and
731
+ tt.ruby_type != Array and
557
732
  @is_escape and @is_escape != :global_export and
558
733
  (clt and !clt.body.is_a?(DummyNode)) then
559
734
  tt = tt.to_unbox
@@ -561,6 +736,48 @@ module YTLJit
561
736
  type_list(cursig)[0] = []
562
737
  end
563
738
 
739
+ # set element type
740
+ parg = @parent.arguments
741
+ if tt.ruby_type == Range then
742
+ if @is_escape != :global_export then
743
+ tt = tt.to_unbox
744
+ end
745
+ tt.args = parg[3..-1]
746
+ add_element_node(tt, cursig, parg[3], [0], context)
747
+ add_element_node(tt, cursig, parg[4], [1], context)
748
+
749
+ elsif tt.ruby_type == Array then
750
+ if context.options[:compile_array_as_uboxed] and
751
+ @is_escape and @is_escape != :global_export then
752
+ if @element_node_list.size > 1 and
753
+ @element_node_list[1..-1].all? {|e|
754
+ e[3] or e[2].class == BaseNode
755
+ } then
756
+ tt = tt.to_unbox
757
+ elsif parg[3] and
758
+ siz0 = parg[3].get_constant_value and
759
+ (siz = siz0[0]) < 10 then
760
+ @element_node_list = []
761
+ dnode = LiteralNode.new(self, nil)
762
+ tt = tt.to_unbox
763
+ siz.times do |i|
764
+ add_element_node(tt, cursig, dnode, [i], context)
765
+ end
766
+ end
767
+ end
768
+ if parg[4] then
769
+ siz = parg[3].get_constant_value
770
+ if siz and false then
771
+ # Here is buggy yet Fix me
772
+ siz[0].times do |i|
773
+ add_element_node(tt, cursig, parg[4], [i], context)
774
+ end
775
+ else
776
+ add_element_node(tt, cursig, parg[4], nil, context)
777
+ end
778
+ end
779
+ end
780
+
564
781
  add_type(cursig, tt)
565
782
  end
566
783
  context
@@ -659,67 +876,15 @@ module YTLJit
659
876
  cursig = context.to_signature
660
877
 
661
878
  if slf.ruby_type.is_a?(Class) then
662
- @is_escape = search_class_top.is_escape
663
- @allocmethod.is_escape = @is_escape
664
- case slfnode
665
- when ConstantRefNode
666
- context = @initmethod.collect_candidate_type(context)
667
- clstop = slfnode.value_node
668
- tt = nil
669
- case clstop
670
- when ClassTopNode
671
- tt = RubyType::BaseType.from_ruby_class(clstop.klass_object)
672
-
673
- when LiteralNode
674
- tt = RubyType::BaseType.from_ruby_class(clstop.value)
675
-
676
- else
677
- raise "Unkown node type in constant #{slfnode.value_node.class}"
678
- end
679
-
680
- clt = ClassTopNode.get_class_top_node(tt.ruby_type_raw)
681
- if context.options[:compile_array_as_uboxed] and
682
- @is_escape and @is_escape != :global_export and
683
- (clt and !clt.body.is_a?(DummyNode)) then
684
- tt = tt.to_unbox
685
- elsif type_list(cursig)[0].include?(tt.to_unbox) then
686
- type_list(cursig)[0] = []
687
- end
688
-
689
- # set element type
690
- if tt.ruby_type == Range then
691
- tt.args = @arguments[3..-1]
692
- add_element_node(tt, cursig, @arguments[3], [0], context)
693
- add_element_node(tt, cursig, @arguments[4], [1], context)
694
-
695
- elsif tt.ruby_type == Array then
696
- if context.options[:compile_array_as_uboxed] and
697
- @element_node_list.size > 1 and
698
- @element_node_list[1..-1].all? {|e|
699
- e[3]
700
- } and
701
- @is_escape and @is_escape != :global_export then
702
- tt = tt.to_unbox
703
- end
704
- if @arguments[4] then
705
- siz = @arguments[3].get_constant_value
706
- if siz and false then
707
- # Here is buggy yet Fix me
708
- siz[0].times do |i|
709
- add_element_node(tt, cursig, @arguments[4], [i], context)
710
- end
711
- else
712
- add_element_node(tt, cursig, @arguments[4], nil, context)
713
- end
714
- end
715
- end
716
-
717
- add_type(cursig, tt)
718
- else
719
- raise "Unkonwn node type #{@arguments[2].class} "
720
- end
879
+ set_escape_node(@parent.is_escape)
880
+ @allocmethod.set_escape_node(@is_escape)
881
+ @initmethod.type = nil
882
+ context = @initmethod.collect_candidate_type(context)
883
+ same_type(self, @allocmethod, cursig, cursig, context)
884
+ context
885
+ else
886
+ super
721
887
  end
722
- context
723
888
  end
724
889
 
725
890
  def compile_range(context)
@@ -744,7 +909,7 @@ module YTLJit
744
909
  end
745
910
  off = off + AsmType::MACHINE_WORD.size
746
911
  end
747
-
912
+
748
913
  context.ret_reg = breg
749
914
  context.ret_node = self
750
915
  context
@@ -752,11 +917,23 @@ module YTLJit
752
917
 
753
918
  def compile(context)
754
919
  rtype = @arguments[2].decide_type_once(context.to_signature)
920
+ if context.options[:insert_signature_comment] then
921
+ lineno = debug_info[3]
922
+ fname = debug_info[0]
923
+ context.comment[fname] ||= {}
924
+ context.comment[fname][lineno] ||= []
925
+ ent = []
926
+ ent.push 2
927
+ ent.push is_escape
928
+ ent.push rtype
929
+ context.comment[fname][lineno].push ent
930
+ end
931
+
755
932
  rrtype = rtype.ruby_type
756
933
  if rrtype.is_a?(Class) then
757
934
  ctype = decide_type_once(context.to_signature)
758
935
  crtype = ctype.ruby_type
759
- if @is_escape != :global_export and
936
+ if !ctype.boxed and
760
937
  crtype == Range then
761
938
  return compile_range(context)
762
939
 
@@ -786,11 +963,13 @@ module YTLJit
786
963
  add_special_send_node :+
787
964
 
788
965
  def collect_candidate_type_regident(context, slf)
966
+ cursig = context.to_signature
789
967
  case [slf.ruby_type]
790
968
  when [Fixnum], [Float], [String], [Array]
791
- cursig = context.to_signature
792
969
  same_type(self, @arguments[2], cursig, cursig, context)
793
970
  same_type(self, @arguments[3], cursig, cursig, context)
971
+ else
972
+ same_type(self, @arguments[2], cursig, cursig, context)
794
973
  end
795
974
 
796
975
  context
@@ -803,6 +982,7 @@ module YTLJit
803
982
  rrtype = rtype.ruby_type
804
983
  if rtype.is_a?(RubyType::DefaultType0) or
805
984
  rrtype == Array or
985
+ rrtype == String or
806
986
  @class_top.search_method_with_super(@func.name, rrtype)[0] then
807
987
  return super(context)
808
988
  end
@@ -877,6 +1057,11 @@ module YTLJit
877
1057
  same_type(self, @arguments[2], cursig, cursig, context)
878
1058
  fixtype = RubyType::BaseType.from_ruby_class(Fixnum)
879
1059
  @arguments[3].add_type(context.to_signature, fixtype)
1060
+
1061
+ when [Array]
1062
+ same_type(self, @arguments[2], cursig, cursig, context)
1063
+ fixtype = RubyType::BaseType.from_ruby_class(Fixnum)
1064
+ @arguments[3].add_type(context.to_signature, fixtype)
880
1065
  end
881
1066
 
882
1067
  context
@@ -887,6 +1072,8 @@ module YTLJit
887
1072
  rtype = decide_type_once(context.to_signature)
888
1073
  rrtype = rtype.ruby_type
889
1074
  if rtype.is_a?(RubyType::DefaultType0) or
1075
+ rrtype == String or
1076
+ rrtype == Array or
890
1077
  @class_top.search_method_with_super(@func.name, rrtype)[0] then
891
1078
  return super(context)
892
1079
  end
@@ -1069,7 +1256,6 @@ module YTLJit
1069
1256
  end
1070
1257
 
1071
1258
  class SendLtLtNode<SendNode
1072
- include ArithmeticOperationUtil
1073
1259
  include SendUtil
1074
1260
  add_special_send_node :<<
1075
1261
 
@@ -1082,9 +1268,19 @@ module YTLJit
1082
1268
 
1083
1269
  when [Array]
1084
1270
  val = @arguments[3]
1271
+ if slf.boxed and val.is_escape != :global_export then
1272
+ val.set_escape_node_backward(:global_export)
1273
+ context = val.collect_candidate_type(context)
1274
+ else
1275
+ val.set_escape_node_backward(:local_export)
1276
+ end
1085
1277
  arg = [slf, cursig, val, nil, context]
1086
1278
  @arguments[2].add_element_node_backward(arg)
1087
1279
  same_type(self, val, cursig, cursig, context)
1280
+
1281
+ when [String]
1282
+ tt = RubyType::BaseType.from_ruby_class(String)
1283
+ add_type(cursig, tt)
1088
1284
  end
1089
1285
 
1090
1286
  context
@@ -1092,7 +1288,6 @@ module YTLJit
1092
1288
  end
1093
1289
 
1094
1290
  class SendGtGtNode<SendNode
1095
- include ArithmeticOperationUtil
1096
1291
  include SendUtil
1097
1292
  add_special_send_node :>>
1098
1293
 
@@ -1109,7 +1304,6 @@ module YTLJit
1109
1304
  end
1110
1305
 
1111
1306
  class SendAndNode<SendNode
1112
- include ArithmeticOperationUtil
1113
1307
  include SendUtil
1114
1308
  add_special_send_node :&
1115
1309
 
@@ -1126,7 +1320,6 @@ module YTLJit
1126
1320
  end
1127
1321
 
1128
1322
  class SendOrNode<SendNode
1129
- include ArithmeticOperationUtil
1130
1323
  include SendUtil
1131
1324
  add_special_send_node :|
1132
1325
 
@@ -1143,7 +1336,6 @@ module YTLJit
1143
1336
  end
1144
1337
 
1145
1338
  class SendXorNode<SendNode
1146
- include ArithmeticOperationUtil
1147
1339
  include SendUtil
1148
1340
  add_special_send_node :^
1149
1341
 
@@ -1160,14 +1352,13 @@ module YTLJit
1160
1352
  end
1161
1353
 
1162
1354
  class SendLengthNode<SendNode
1163
- include ArithmeticOperationUtil
1164
1355
  include SendUtil
1165
1356
  add_special_send_node :length
1166
1357
 
1167
1358
  def collect_candidate_type_regident(context, slf)
1168
1359
  cursig = context.to_signature
1169
1360
  case [slf.ruby_type]
1170
- when [Array]
1361
+ when [Array], [String]
1171
1362
  tt = RubyType::BaseType.from_ruby_class(Fixnum)
1172
1363
  add_type(cursig, tt)
1173
1364
  end
@@ -1176,6 +1367,117 @@ module YTLJit
1176
1367
  end
1177
1368
  end
1178
1369
 
1370
+ class SendCountNode<SendNode
1371
+ include SendUtil
1372
+ add_special_send_node :count
1373
+
1374
+ def collect_candidate_type_regident(context, slf)
1375
+ cursig = context.to_signature
1376
+ case [slf.ruby_type]
1377
+ when [String]
1378
+ tt = RubyType::BaseType.from_ruby_class(Fixnum)
1379
+ add_type(cursig, tt)
1380
+ end
1381
+
1382
+ context
1383
+ end
1384
+ end
1385
+
1386
+ class SendStripExNode<SendNode
1387
+ include SendUtil
1388
+ add_special_send_node :strip!
1389
+
1390
+ def collect_candidate_type_regident(context, slf)
1391
+ cursig = context.to_signature
1392
+ case [slf.ruby_type]
1393
+ when [String]
1394
+ tt = RubyType::BaseType.from_ruby_class(String)
1395
+ add_type(cursig, tt)
1396
+ tt = RubyType::BaseType.from_ruby_class(NilClass)
1397
+ add_type(cursig, tt)
1398
+ end
1399
+
1400
+ context
1401
+ end
1402
+ end
1403
+
1404
+ class SendTrExNode<SendNode
1405
+ include SendUtil
1406
+ add_special_send_node :tr!
1407
+
1408
+ def collect_candidate_type_regident(context, slf)
1409
+ cursig = context.to_signature
1410
+ case [slf.ruby_type]
1411
+ when [String]
1412
+ tt = RubyType::BaseType.from_ruby_class(String)
1413
+ add_type(cursig, tt)
1414
+ end
1415
+
1416
+ context
1417
+ end
1418
+ end
1419
+
1420
+ class SendOpenNode<SendNode
1421
+ include SendUtil
1422
+ include SendSingletonClassUtil
1423
+ add_special_send_node :open
1424
+
1425
+ def collect_candidate_type_regident(context, slf)
1426
+ cursig = context.to_signature
1427
+ case [slf.ruby_type]
1428
+ when [NilClass], [Object]
1429
+ tt = RubyType::BaseType.from_ruby_class(IO)
1430
+ add_type(cursig, tt)
1431
+ when [Class]
1432
+ clsobj = get_singleton_class_object(@arguments[2])
1433
+ if clsobj.ruby_type <= IO then
1434
+ tt = RubyType::BaseType.from_ruby_class(IO)
1435
+ add_type(cursig, tt)
1436
+ end
1437
+ end
1438
+
1439
+ context
1440
+ end
1441
+ end
1442
+
1443
+ class SendReadNode<SendNode
1444
+ include SendUtil
1445
+ add_special_send_node :read
1446
+
1447
+ def collect_candidate_type_regident(context, slf)
1448
+ cursig = context.to_signature
1449
+ case [slf.ruby_type]
1450
+ when [IO], [NilClass], [Object]
1451
+ tt = RubyType::BaseType.from_ruby_class(String)
1452
+ add_type(cursig, tt)
1453
+ end
1454
+
1455
+ context
1456
+ end
1457
+ end
1458
+
1459
+ class SendGetsNode<SendReadNode
1460
+ add_special_send_node :gets
1461
+ end
1462
+
1463
+ class SendDirnameNode<SendNode
1464
+ include SendUtil
1465
+ include SendSingletonClassUtil
1466
+ add_special_send_node :dirname
1467
+
1468
+ def collect_candidate_type_regident(context, slf)
1469
+ cursig = context.to_signature
1470
+ if slf.ruby_type == Class and
1471
+ clsobj = get_singleton_class_object(@arguments[2]) and
1472
+ clsobj.ruby_type <= File then
1473
+ tt = RubyType::BaseType.from_ruby_class(String)
1474
+ add_type(cursig, tt)
1475
+ end
1476
+
1477
+ context
1478
+ end
1479
+ end
1480
+
1179
1481
  class SendCompareNode<SendNode
1180
1482
  include SendUtil
1181
1483
  include CompareOperationUtil
@@ -1205,7 +1507,9 @@ module YTLJit
1205
1507
  end
1206
1508
 
1207
1509
  def compile(context)
1208
- rtype = @arguments[2].decide_type_once(context.to_signature)
1510
+ cursig = context.to_signature
1511
+ @arguments[2].type = nil
1512
+ rtype = @arguments[2].decide_type_once(cursig)
1209
1513
  rrtype = rtype.ruby_type
1210
1514
  if rtype.is_a?(RubyType::DefaultType0) or
1211
1515
  @class_top.search_method_with_super(@func.name, rrtype)[0] then
@@ -1215,7 +1519,7 @@ module YTLJit
1215
1519
  if rrtype == Fixnum or rrtype == Float then
1216
1520
  context = gen_eval_self(context)
1217
1521
  context.ret_node.type = nil
1218
- srtype = context.ret_node.decide_type_once(context.to_signature)
1522
+ srtype = context.ret_node.decide_type_once(cursig)
1219
1523
  context = srtype.gen_unboxing(context)
1220
1524
  context = compile_compare(context, rtype)
1221
1525
 
@@ -1308,7 +1612,8 @@ module YTLJit
1308
1612
  when [Array]
1309
1613
  fixtype = RubyType::BaseType.from_ruby_class(Fixnum)
1310
1614
  idxtype = @arguments[3].decide_type_once(cursig)
1311
- if idxtype.ruby_type == Range then
1615
+ if idxtype.ruby_type == Range or
1616
+ @arguments[4] then
1312
1617
  same_type(self, @arguments[2], cursig, cursig, context)
1313
1618
  return context
1314
1619
  end
@@ -1318,6 +1623,8 @@ module YTLJit
1318
1623
  # decide type again
1319
1624
  @arguments[2].type = nil
1320
1625
  slf = @arguments[2].decide_type_once(cursig)
1626
+ # p debug_info
1627
+ # p @arguments[2].type_list(cursig)
1321
1628
 
1322
1629
  epare = nil
1323
1630
 
@@ -1327,7 +1634,7 @@ module YTLJit
1327
1634
  epare2 = ele
1328
1635
  esig = epare2[1]
1329
1636
  enode = epare2[2]
1330
- if enode.type_list(esig) != [[], []] then
1637
+ if enode.decide_type_once(esig).ruby_type != Object then
1331
1638
  epare = epare2
1332
1639
  same_type(self, enode, cursig, esig, context)
1333
1640
  end
@@ -1341,7 +1648,7 @@ module YTLJit
1341
1648
  epare2 = ele
1342
1649
  esig = epare2[1]
1343
1650
  enode = epare2[2]
1344
- if enode.type_list(esig) != [[], []] then
1651
+ if enode.decide_type_once(esig).ruby_type != Object then
1345
1652
  epare = epare2
1346
1653
  same_type(self, enode, cursig, esig, context)
1347
1654
  end
@@ -1351,16 +1658,15 @@ module YTLJit
1351
1658
 
1352
1659
  =begin
1353
1660
  if epare == nil then
1354
- @arguments[2].element_node_list.reverse.each do |ele|
1661
+ @arguments[2].element_node_list.each do |ele|
1355
1662
  if ele[3] == cidx and ele[2] != self and
1356
1663
  ele[0].ruby_type == slf.ruby_type then
1357
1664
  epare2 = ele
1358
1665
  esig = epare2[1]
1359
1666
  enode = epare2[2]
1360
- unless enode.type_list(esig) == [[], []]
1667
+ if enode.decide_type_once(esig).ruby_type != Object then
1361
1668
  epare = epare2
1362
1669
  same_type(self, enode, cursig, esig, context)
1363
- break
1364
1670
  end
1365
1671
  end
1366
1672
  end
@@ -1369,7 +1675,7 @@ module YTLJit
1369
1675
  if epare == nil then
1370
1676
  nele = @arguments[2].element_node_list.select {|e| e[3] == nil}
1371
1677
  if nele.size == 1 then
1372
- epare = @arguments[2].element_node_list[0]
1678
+ epare = nele[0]
1373
1679
  esig = epare[1]
1374
1680
  enode = epare[2]
1375
1681
  same_type(self, enode, cursig, esig, context)
@@ -1378,11 +1684,15 @@ module YTLJit
1378
1684
  =end
1379
1685
 
1380
1686
  if epare == nil then
1381
- if slf.have_element? and slf.element_type then
1687
+ if slf.have_element? and
1688
+ slf.element_type and
1689
+ slf.element_type[nil] and
1690
+ slf.element_type[nil][0] then
1382
1691
  add_type(cursig, slf.element_type[nil][0])
1692
+ else
1693
+ p "foo"
1383
1694
  end
1384
1695
  end
1385
-
1386
1696
  @type = nil
1387
1697
 
1388
1698
  when [Hash]
@@ -1392,6 +1702,10 @@ module YTLJit
1392
1702
  @arguments[3].type = nil
1393
1703
  @arguments[3].add_type(cursig, niltype)
1394
1704
  @arguments[2].add_element_node(rtype, cursig, self, cidx, context)
1705
+
1706
+ when [String]
1707
+ tt = RubyType::BaseType.from_ruby_class(String)
1708
+ add_type(cursig, tt)
1395
1709
  end
1396
1710
 
1397
1711
  context
@@ -1400,13 +1714,14 @@ module YTLJit
1400
1714
  def compile(context)
1401
1715
  sig = context.to_signature
1402
1716
  asm = context.assembler
1403
- @arguments[2].type = nil
1717
+ # @arguments[2].type = nil
1404
1718
  rtype = @arguments[2].decide_type_once(sig)
1405
1719
  rrtype = rtype.ruby_type
1406
1720
 
1407
1721
  if rrtype == Array and !rtype.boxed and
1408
1722
  @arguments[2].is_escape != :global_export then
1409
1723
  context = gen_ref_element(context, @arguments[2], @arguments[3])
1724
+ # @type = nil
1410
1725
  rtype = decide_type_once(sig)
1411
1726
  if rtype.ruby_type == Float and !rtype.boxed then
1412
1727
  asm.with_retry do
@@ -1441,47 +1756,26 @@ module YTLJit
1441
1756
  add_special_send_node :[]=
1442
1757
  def collect_candidate_type_regident(context, slf)
1443
1758
  cursig = context.to_signature
1444
- rtype = nil
1445
1759
  case [slf.ruby_type]
1446
1760
  when [Array]
1447
1761
  fixtype = RubyType::BaseType.from_ruby_class(Fixnum)
1448
1762
  val = @arguments[4]
1449
- val.is_escape = :local_export
1450
1763
  @arguments[3].add_type(cursig, fixtype)
1451
1764
  cidx = @arguments[3].get_constant_value
1452
1765
  @arguments[2].type = nil
1453
1766
  slf = @arguments[2].decide_type_once(cursig)
1454
1767
 
1768
+ val.type = nil
1769
+ if slf.boxed and val.is_escape != :global_export then
1770
+ val.set_escape_node_backward(:global_export)
1771
+ context = val.collect_candidate_type(context)
1772
+ else
1773
+ val.set_escape_node_backward(:local_export)
1774
+ end
1455
1775
  arg = [slf, cursig, val, cidx, context]
1456
1776
  @arguments[2].add_element_node_backward(arg)
1457
1777
 
1458
- epare = nil
1459
- @arguments[2].element_node_list.each do |ele|
1460
- if ele[3] == cidx and ele[2] != self then
1461
- epare = ele
1462
- break
1463
- end
1464
- end
1465
- if epare == nil then
1466
- epare = @arguments[2].element_node_list[0]
1467
- @arguments[2].element_node_list.each do |ele|
1468
- if ele[3] == nil and ele[2] != self and ele[0] == slf then
1469
- epare = ele
1470
- break
1471
- end
1472
- end
1473
- end
1474
-
1475
- esig = epare[1]
1476
- enode = epare[2]
1477
- if enode != self then
1478
- same_type(self, enode, cursig, esig, context)
1479
- end
1480
- if slf.boxed then
1481
- @arguments[4].set_escape_node_backward(:global_export)
1482
- else
1483
- @arguments[4].set_escape_node_backward(:local_export)
1484
- end
1778
+ same_type(self, val, cursig, cursig, context)
1485
1779
 
1486
1780
  when [Hash]
1487
1781
  cidx = @arguments[3].get_constant_value
@@ -1515,6 +1809,17 @@ module YTLJit
1515
1809
  end
1516
1810
  end
1517
1811
 
1812
+ class Send__ID__Node<SendNode
1813
+ add_special_send_node :__id__
1814
+
1815
+ def collect_candidate_type_regident(context, slf)
1816
+ sig = context.to_signature
1817
+ fixnumtype = RubyType::BaseType.from_ruby_class(Fixnum)
1818
+ add_type(sig, fixnumtype)
1819
+ context
1820
+ end
1821
+ end
1822
+
1518
1823
  class SendToFNode<SendNode
1519
1824
  include AbsArch
1520
1825
 
@@ -1528,6 +1833,7 @@ module YTLJit
1528
1833
  end
1529
1834
 
1530
1835
  def compile(context)
1836
+ # @arguments[2].type = nil
1531
1837
  @arguments[2].decide_type_once(context.to_signature)
1532
1838
  rtype = @arguments[2].type
1533
1839
  rrtype = rtype.ruby_type
@@ -1565,6 +1871,7 @@ module YTLJit
1565
1871
  end
1566
1872
 
1567
1873
  def compile(context)
1874
+ # @arguments[2].type = nil
1568
1875
  @arguments[2].decide_type_once(context.to_signature)
1569
1876
  rtype = @arguments[2].type
1570
1877
  rrtype = rtype.ruby_type
@@ -1612,6 +1919,7 @@ module YTLJit
1612
1919
  end
1613
1920
 
1614
1921
  def compile(context)
1922
+ # @arguments[2].type = nil
1615
1923
  @arguments[2].decide_type_once(context.to_signature)
1616
1924
  rtype = @arguments[2].type
1617
1925
  rrtype = rtype.ruby_type
@@ -1653,9 +1961,16 @@ module YTLJit
1653
1961
  class SendRandNode<SendNode
1654
1962
  add_special_send_node :rand
1655
1963
  def collect_candidate_type_regident(context, slf)
1656
- sig = context.to_signature
1657
- floattype = RubyType::BaseType.from_ruby_class(Float)
1658
- add_type(sig, floattype)
1964
+ cursig = context.to_signature
1965
+ if @arguments[3] then
1966
+ # when argument is 0, type is Float
1967
+ # but ignor it by current version
1968
+ context = @arguments[3].collect_candidate_type(context)
1969
+ tt = RubyType::BaseType.from_ruby_class(Fixnum)
1970
+ else
1971
+ tt = RubyType::BaseType.from_ruby_class(Float)
1972
+ end
1973
+ add_type(cursig, tt)
1659
1974
  context
1660
1975
  end
1661
1976
  end
@@ -1679,12 +1994,12 @@ module YTLJit
1679
1994
  end
1680
1995
 
1681
1996
  def compile(context)
1682
- sig = context.to_signature
1683
- rtype = @arguments[2].decide_type_once(sig)
1997
+ cursig = context.to_signature
1998
+ @arguments[2].type = nil
1999
+ rtype = @arguments[2].decide_type_once(cursig)
1684
2000
  rrtype = rtype.ruby_type
1685
- decide_type_once(sig)
1686
- if rrtype == Range and !rtype.boxed and
1687
- @arguments[2].is_escape != :global_export then
2001
+ decide_type_once(cursig)
2002
+ if rrtype == Range and !rtype.boxed then
1688
2003
  context = @arguments[2].compile(context)
1689
2004
  slotoff = OpIndirect.new(TMPR, arg_offset)
1690
2005
  asm = context.assembler
@@ -1740,6 +2055,8 @@ module YTLJit
1740
2055
  end
1741
2056
 
1742
2057
  class SendSizeNode<SendNode
2058
+ include SendUtil
2059
+ include UnboxedArrayUtil
1743
2060
  add_special_send_node :size
1744
2061
  def collect_candidate_type_regident(context, slf)
1745
2062
  cursig = context.to_signature
@@ -1747,6 +2064,25 @@ module YTLJit
1747
2064
  add_type(cursig, tt)
1748
2065
  context
1749
2066
  end
2067
+
2068
+ def compile(context)
2069
+ sig = context.to_signature
2070
+ asm = context.assembler
2071
+ rtype = @arguments[2].decide_type_once(sig)
2072
+ rrtype = rtype.ruby_type
2073
+ if rrtype == Array and !rtype.boxed and
2074
+ @arguments[2].is_escape != :global_export then
2075
+ context = gen_ref_element(context, @arguments[2], -1)
2076
+ asm.with_retry do
2077
+ asm.mov(RETR, context.ret_reg)
2078
+ end
2079
+ context.ret_reg = RETR
2080
+ context.set_reg_content(RETR, self)
2081
+ @body.compile(context)
2082
+ else
2083
+ super
2084
+ end
2085
+ end
1750
2086
  end
1751
2087
 
1752
2088
  class SendSameArgTypeNode<SendNode
@@ -1764,16 +2100,67 @@ module YTLJit
1764
2100
  class SendDispTypeNode<SendNode
1765
2101
  add_special_send_node :disp_type
1766
2102
  def collect_candidate_type_regident(context, slf)
2103
+ #=begin
1767
2104
  sig = context.to_signature
1768
2105
  p debug_info
1769
2106
  p sig
1770
2107
  p @arguments[2].type_list(sig)
1771
- # p @arguments[2].instance_eval {@type_list}
2108
+ @arguments[2].type = nil
2109
+ p @arguments[2].decide_type_once(sig)
2110
+ # p @arguments[2].instance_eval {@type_list}
2111
+ p @arguments[2].is_escape
1772
2112
  p @arguments[2].class
2113
+ #=end
1773
2114
  context
1774
2115
  end
1775
2116
 
1776
2117
  def compile(context)
2118
+ =begin
2119
+ sig = context.to_signature
2120
+ p debug_info
2121
+ p sig
2122
+ p @arguments[2].type_list(sig)
2123
+ @arguments[2].type = nil
2124
+ p @arguments[2].decide_type_once(sig)
2125
+ # p @arguments[2].instance_eval {@type_list}
2126
+ p @arguments[2].is_escape
2127
+ p @arguments[2].class
2128
+ =end
2129
+ @body.compile(context)
2130
+ end
2131
+ end
2132
+
2133
+ class SendSelfOfCallerTypeNode<SendNode
2134
+ include NodeUtil
2135
+ add_special_send_node :self_of_caller
2136
+
2137
+ def initialize(parent, func, arguments, op_flag, seqno)
2138
+ super
2139
+ @frame_info = search_frame_info
2140
+ end
2141
+
2142
+ def collect_candidate_type_regident(context, slf)
2143
+ cursig = context.to_signature
2144
+ callersig = context.to_signature(-2)
2145
+ tt = callersig[2]
2146
+ add_type(cursig, tt)
2147
+ context
2148
+ end
2149
+
2150
+ def compile(context)
2151
+ asm = context.assembler
2152
+ prevenv = @frame_info.offset_arg(0, BPR)
2153
+ # offset of self is common, so it no nessery traverse
2154
+ # prev frame for @frame_info.
2155
+ slfarg = @frame_info.offset_arg(2, TMPR2)
2156
+ context.start_using_reg(TMPR2)
2157
+ asm.with_retry do
2158
+ asm.mov(TMPR2, prevenv)
2159
+ asm.mov(RETR, slfarg)
2160
+ end
2161
+ context.end_using_reg(TMPR2)
2162
+ context.ret_reg = RETR
2163
+ context.ret_node = self
1777
2164
  @body.compile(context)
1778
2165
  end
1779
2166
  end
@@ -1799,13 +2186,25 @@ module YTLJit
1799
2186
  end
1800
2187
  end
1801
2188
 
2189
+ class SendCloneNode<SendDupNode
2190
+ add_special_send_node :clone
2191
+ end
2192
+
1802
2193
  class SendSortNode<SendSameSelfTypeNode
1803
2194
  add_special_send_node :sort
1804
2195
  end
1805
2196
 
1806
- class SendSortNode<SendSameSelfTypeNode
2197
+ class SendUniqExNode<SendSameSelfTypeNode
1807
2198
  add_special_send_node :uniq!
1808
2199
  end
2200
+
2201
+ class SendSliceExNode<SendSameSelfTypeNode
2202
+ add_special_send_node :slice!
2203
+ end
2204
+
2205
+ class SendReverseNode<SendSameSelfTypeNode
2206
+ add_special_send_node :reverse
2207
+ end
1809
2208
 
1810
2209
  class SendMathFuncNode<SendNode
1811
2210
  include SendUtil
@@ -1831,11 +2230,19 @@ module YTLJit
1831
2230
  end
1832
2231
  context.set_reg_content(FUNC_FLOAT_ARG[0].dst_opecode,
1833
2232
  context.ret_node)
1834
- asm.with_retry do
1835
- asm.call_with_arg(fadd, 1)
1836
- asm.sub(SPR, 8)
1837
- asm.fstpl(INDIRECT_SPR)
1838
- asm.pop(XMM0)
2233
+ case $ruby_platform
2234
+ when /x86_64/
2235
+ asm.with_retry do
2236
+ asm.call_with_arg(fadd, 1)
2237
+ end
2238
+
2239
+ when /i.86/
2240
+ asm.with_retry do
2241
+ asm.call_with_arg(fadd, 1)
2242
+ asm.sub(SPR, 8)
2243
+ asm.fstpl(INDIRECT_SPR)
2244
+ asm.pop(XMM0)
2245
+ end
1839
2246
  end
1840
2247
  context.end_arg_reg
1841
2248
  context.end_arg_reg(FUNC_FLOAT_ARG)
@@ -1901,6 +2308,16 @@ module YTLJit
1901
2308
  end
1902
2309
  end
1903
2310
 
2311
+ class SendLogNode<SendMathFuncNode
2312
+ add_special_send_node :log
2313
+ def compile_main(context)
2314
+ context = compile_call_func(context, "log")
2315
+ context.ret_node = self
2316
+ context.ret_reg = XMM0
2317
+ context
2318
+ end
2319
+ end
2320
+
1904
2321
  class RawSendNode<SendNode
1905
2322
  def collect_candidate_type(context)
1906
2323
  @arguments.each do |arg|
@@ -1933,7 +2350,7 @@ module YTLJit
1933
2350
  if context.options[:compile_array_as_uboxed] and
1934
2351
  @element_node_list.size > 1 and
1935
2352
  @element_node_list[1..-1].all? {|e|
1936
- e[3]
2353
+ e[3] or e[2].class == BaseNode
1937
2354
  } then
1938
2355
  tt = tt.to_unbox
1939
2356
  end
@@ -1956,19 +2373,21 @@ module YTLJit
1956
2373
  if rrtype == Array and
1957
2374
  !rtype.boxed and
1958
2375
  @is_escape != :global_export then
1959
- siz = ((@element_node_list[1..-1].max_by {|a| a[3][0]})[3][0]) + 1
2376
+ sizent = @element_node_list[1..-1].max_by {|a| a[3] ? a[3][0] : -1}
2377
+ siz = sizent[3][0] + 1
1960
2378
  context = gen_alloca(context, siz)
1961
2379
 
1962
2380
  context.start_using_reg(TMPR2)
1963
2381
  asm = context.assembler
1964
2382
  asm.with_retry do
1965
2383
  asm.mov(TMPR2, THEPR)
2384
+ asm.mov(INDIRECT_TMPR2, siz)
2385
+ asm.add(TMPR2, 8)
1966
2386
  end
2387
+ context.set_reg_content(TMPR2, THEPR)
1967
2388
 
1968
2389
  @arguments[1..-1].each_with_index do |anode, idx|
1969
- context.start_using_reg(TMPR2)
1970
2390
  context = gen_set_element(context, nil, idx, anode)
1971
- context.end_using_reg(TMPR2)
1972
2391
  end
1973
2392
 
1974
2393
  asm.with_retry do