ytljit 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -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