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/ext/code_alloc.c +39 -17
- data/ext/memory.c +170 -22
- data/ext/ytljit.c +57 -2
- data/ext/ytljit.h +15 -2
- data/lib/ytljit/asm.rb +21 -0
- data/lib/ytljit/asmext_x64.rb +1 -1
- data/lib/ytljit/asmutil.rb +1 -0
- data/lib/ytljit/instruction.rb +6 -0
- data/lib/ytljit/instruction_ia.rb +31 -2
- data/lib/ytljit/util.rb +5 -4
- data/lib/ytljit/vm.rb +771 -182
- data/lib/ytljit/vm_codegen.rb +76 -25
- data/lib/ytljit/vm_cruby_obj.rb +34 -13
- data/lib/ytljit/vm_inline_method.rb +154 -32
- data/lib/ytljit/vm_sendnode.rb +597 -112
- data/lib/ytljit/vm_trans.rb +148 -35
- data/lib/ytljit/vm_type.rb +5 -1
- data/lib/ytljit/vm_type_gen.rb +224 -51
- data/lib/ytljit.rb +5 -0
- data/test/test_assemble2.rb +35 -5
- metadata +3 -3
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
|
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
|
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 =
|
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 = [
|
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
|
-
@
|
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
|
268
|
+
def marge_type(dst, src)
|
265
269
|
res = dst
|
266
270
|
src.each do |sele|
|
267
|
-
if
|
268
|
-
res.
|
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 =
|
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 =
|
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
|
-
|
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
|
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
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
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,
|
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
|
379
|
-
|
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
|
-
|
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(
|
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
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
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
|
-
|
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.
|
531
|
-
res.push ele.
|
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(
|
613
|
-
|
614
|
-
|
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(
|
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
|
-
|
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
|
-
|
1212
|
-
|
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(
|
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.
|
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
|
1541
|
+
def get_arena_address
|
1270
1542
|
ar = @@local_object_area
|
1271
|
-
|
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
|
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
|
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
|
-
|
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 =
|
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
|
-
@
|
1629
|
-
@
|
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
|
-
|
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.
|
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
|
-
|
1692
|
-
asm.
|
1693
|
-
|
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
|
-
|
1716
|
-
|
2073
|
+
if @come_from.keys[0] == sender then
|
2074
|
+
@body.collect_candidate_type(context)
|
1717
2075
|
else
|
1718
2076
|
context
|
1719
2077
|
end
|
1720
|
-
|
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
|
-
@
|
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.
|
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
|
-
|
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
|
-
|
1885
|
-
asm.
|
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
|
-
@
|
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(
|
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 @
|
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][
|
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
|
-
|
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
|
-
|
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
|
2746
|
+
p sig
|
2248
2747
|
p @name
|
2249
|
-
|
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
|
-
|
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
|
-
|
2818
|
+
rnode = context.ret_node
|
2819
|
+
rtype = rnode.decide_type_once(context.to_signature)
|
2312
2820
|
if @calling_convention != :ytl then
|
2313
|
-
|
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
|
-
|
2327
|
-
|
2328
|
-
|
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
|
-
|
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,
|
2352
|
-
context.set_reg_content(TMPR2,
|
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
|
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 =
|
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 [
|
3093
|
+
nodepare.push [@var_from, self]
|
2569
3094
|
else
|
2570
|
-
nodepare = [[
|
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
|
-
|
2582
|
-
|
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
|
-
|
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.
|
2593
|
-
|
2594
|
-
|
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)
|
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.
|
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] = @
|
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
|