ytljit 0.0.3 → 0.0.4
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 +6 -0
- data/ext/memory.c +82 -0
- data/ext/ytljit.c +9 -0
- data/ext/ytljit.h +18 -0
- data/lib/runtime/gc.rb +41 -0
- data/lib/runtime/object.rb +18 -0
- data/lib/ytljit.rb +9 -0
- data/lib/ytljit/arena.rb +63 -0
- data/lib/ytljit/asm.rb +5 -1
- data/lib/ytljit/asmext.rb +42 -6
- data/lib/ytljit/asmutil.rb +26 -0
- data/lib/ytljit/instruction_ia.rb +28 -2
- data/lib/ytljit/type.rb +11 -5
- data/lib/ytljit/vm.rb +620 -173
- data/lib/ytljit/vm_codegen.rb +123 -26
- data/lib/ytljit/vm_cruby_obj.rb +91 -0
- data/lib/ytljit/vm_inline_method.rb +27 -19
- data/lib/ytljit/vm_sendnode.rb +416 -136
- data/lib/ytljit/vm_trans.rb +79 -19
- data/lib/ytljit/vm_type.rb +25 -19
- data/lib/ytljit/vm_type_gen.rb +55 -2
- data/test/test_arena.rb +60 -0
- data/test/test_assemble2.rb +25 -2
- metadata +10 -3
@@ -749,12 +749,20 @@ module YTLJit
|
|
749
749
|
when OpRegXMM
|
750
750
|
rexseq, rexfmt = rex(dst, src)
|
751
751
|
modseq, modfmt = modrm(inst, dst, src, dst, src)
|
752
|
-
|
752
|
+
if op0 then
|
753
|
+
(rexseq + [op0, 0x0F, op1] + modseq).pack("#{rexfmt}C3#{modfmt}")
|
754
|
+
else
|
755
|
+
(rexseq + [0x0F, op1] + modseq).pack("#{rexfmt}C2#{modfmt}")
|
756
|
+
end
|
753
757
|
|
754
758
|
when OpIndirect
|
755
759
|
rexseq, rexfmt = rex(dst, src)
|
756
760
|
modseq, modfmt = modrm(inst, dst, src, dst, src)
|
757
|
-
|
761
|
+
if op0 then
|
762
|
+
(rexseq + [op0, 0x0F, op1] + modseq).pack("#{rexfmt}C3#{modfmt}")
|
763
|
+
else
|
764
|
+
(rexseq + [0x0F, op1] + modseq).pack("#{rexfmt}C2#{modfmt}")
|
765
|
+
end
|
758
766
|
|
759
767
|
else
|
760
768
|
return nosupported_addressing_mode(inst, dst, src)
|
@@ -1288,6 +1296,16 @@ module YTLJit
|
|
1288
1296
|
return nosupported_addressing_mode(:neg, src, nil, nil)
|
1289
1297
|
end
|
1290
1298
|
|
1299
|
+
def fstpl(dst)
|
1300
|
+
case dst
|
1301
|
+
when OpIndirect
|
1302
|
+
modseq, modfmt = modrm(:fstpl, 3, dst, dst, nil)
|
1303
|
+
return ([0xDD] + modseq).pack("C#{modfmt}")
|
1304
|
+
end
|
1305
|
+
|
1306
|
+
return nosupported_addressing_mode(:neg, src, nil, nil)
|
1307
|
+
end
|
1308
|
+
|
1291
1309
|
def cdq
|
1292
1310
|
[0x99].pack("C")
|
1293
1311
|
end
|
@@ -1333,6 +1351,14 @@ module YTLJit
|
|
1333
1351
|
common_arithxmm(dst, src, 0xF2, 0x5E, :divsd)
|
1334
1352
|
end
|
1335
1353
|
|
1354
|
+
def comiss(dst, src)
|
1355
|
+
common_arithxmm(dst, src, nil, 0x2F, :comiss)
|
1356
|
+
end
|
1357
|
+
|
1358
|
+
def comisd(dst, src)
|
1359
|
+
common_arithxmm(dst, src, 0x66, 0x2F, :comisd)
|
1360
|
+
end
|
1361
|
+
|
1336
1362
|
def int3
|
1337
1363
|
[0xcc].pack("C")
|
1338
1364
|
end
|
data/lib/ytljit/type.rb
CHANGED
@@ -19,24 +19,30 @@ module YTLJit
|
|
19
19
|
@alignment = align
|
20
20
|
@kind = kind
|
21
21
|
end
|
22
|
+
|
23
|
+
attr :kind
|
22
24
|
end
|
23
25
|
|
24
26
|
class PointedData<TypeCommon
|
25
27
|
def initialize(type, index, offset)
|
26
28
|
@type = type
|
27
29
|
@index = index
|
28
|
-
@offset = offset
|
30
|
+
@offset = offset + index * type.size
|
29
31
|
end
|
30
32
|
|
31
33
|
attr :index
|
32
34
|
attr :offset
|
33
35
|
|
34
36
|
def size
|
35
|
-
@
|
37
|
+
@type.size
|
38
|
+
end
|
39
|
+
|
40
|
+
def [](*args)
|
41
|
+
@type[*args]
|
36
42
|
end
|
37
43
|
|
38
44
|
def alignment
|
39
|
-
@
|
45
|
+
@type.alignment
|
40
46
|
end
|
41
47
|
end
|
42
48
|
|
@@ -54,7 +60,7 @@ module YTLJit
|
|
54
60
|
end
|
55
61
|
|
56
62
|
def [](n = 0, offset = 0)
|
57
|
-
PointedData.new(@
|
63
|
+
PointedData.new(@type, n, offset)
|
58
64
|
end
|
59
65
|
end
|
60
66
|
|
@@ -73,7 +79,7 @@ module YTLJit
|
|
73
79
|
end
|
74
80
|
|
75
81
|
def [](n = 0, offset = 0)
|
76
|
-
PointedData.new(@
|
82
|
+
PointedData.new(@type, n, offset)
|
77
83
|
end
|
78
84
|
end
|
79
85
|
|
data/lib/ytljit/vm.rb
CHANGED
@@ -91,9 +91,61 @@ LocalVarNode
|
|
91
91
|
module VM
|
92
92
|
# Expression of VM is a set of Nodes
|
93
93
|
module Node
|
94
|
+
module TypeListWithSignature
|
95
|
+
def type_list_initvar
|
96
|
+
TypeUtil::TypeContainer.new
|
97
|
+
end
|
98
|
+
|
99
|
+
def type_list(sig)
|
100
|
+
@type_list.type_list(sig).value
|
101
|
+
end
|
102
|
+
|
103
|
+
def set_type_list(sig, val, pos = 1)
|
104
|
+
@type_list.type_list(sig).value[pos] = val
|
105
|
+
end
|
106
|
+
|
107
|
+
def add_type(sig, type, pos = 0)
|
108
|
+
@type_list.add_type(sig, type, pos)
|
109
|
+
if type.have_element? then
|
110
|
+
if @my_element_node == nil then
|
111
|
+
@my_element_node = BaseNode.new(self)
|
112
|
+
end
|
113
|
+
@element_node_list = [[sig, @my_element_node]]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
module TypeListWithoutSignature
|
119
|
+
def type_list_initvar
|
120
|
+
[[], []]
|
121
|
+
end
|
122
|
+
|
123
|
+
def type_list(sig)
|
124
|
+
@type_list
|
125
|
+
end
|
126
|
+
|
127
|
+
def set_type_list(sig, val, pos = 1)
|
128
|
+
@type_list[pos] = val
|
129
|
+
end
|
130
|
+
|
131
|
+
def add_type(sig, type, pos = 0)
|
132
|
+
tvsv = @type_list[pos]
|
133
|
+
if !tvsv.include? type then
|
134
|
+
tvsv.push type
|
135
|
+
end
|
136
|
+
if type.have_element? then
|
137
|
+
if @my_element_node == nil then
|
138
|
+
@my_element_node = BaseNode.new(self)
|
139
|
+
end
|
140
|
+
@element_node_list = [[sig, @my_element_node]]
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
94
145
|
class BaseNode
|
95
146
|
include Inspect
|
96
147
|
include AbsArch
|
148
|
+
include TypeListWithSignature
|
97
149
|
|
98
150
|
def initialize(parent)
|
99
151
|
cs = CodeSpace.new
|
@@ -116,12 +168,14 @@ LocalVarNode
|
|
116
168
|
|
117
169
|
# iv for type inference
|
118
170
|
@type = nil
|
119
|
-
@type_list =
|
171
|
+
@type_list = type_list_initvar
|
120
172
|
@element_node_list = []
|
173
|
+
@my_element_node = nil
|
121
174
|
@type_inference_proc = cs
|
122
175
|
@type_cache = nil
|
123
176
|
|
124
177
|
@ti_observer = {}
|
178
|
+
@ti_observee = []
|
125
179
|
end
|
126
180
|
|
127
181
|
attr_accessor :parent
|
@@ -131,17 +185,8 @@ LocalVarNode
|
|
131
185
|
attr_accessor :type
|
132
186
|
attr_accessor :element_node_list
|
133
187
|
|
134
|
-
|
135
|
-
|
136
|
-
end
|
137
|
-
|
138
|
-
def type_list(sig)
|
139
|
-
@type_list.type_list(sig).value
|
140
|
-
end
|
141
|
-
|
142
|
-
def set_type_list(sig, val)
|
143
|
-
@type_list.type_list(sig).value = val
|
144
|
-
end
|
188
|
+
attr :ti_observer
|
189
|
+
attr :ti_observee
|
145
190
|
|
146
191
|
def collect_info(context)
|
147
192
|
if is_a?(HaveChildlenMixin) then
|
@@ -156,6 +201,7 @@ LocalVarNode
|
|
156
201
|
def ti_add_observer(dst, dsig, ssig, context)
|
157
202
|
if @ti_observer[dst] == nil then
|
158
203
|
@ti_observer[dst] = []
|
204
|
+
dst.ti_observee.push self
|
159
205
|
end
|
160
206
|
|
161
207
|
if @ti_observer[dst].all? {|edsig, essig, eprc|
|
@@ -174,10 +220,45 @@ LocalVarNode
|
|
174
220
|
end
|
175
221
|
end
|
176
222
|
|
223
|
+
def ti_reset(visitnode = {})
|
224
|
+
if visitnode[self] then
|
225
|
+
return
|
226
|
+
end
|
227
|
+
|
228
|
+
visitnode[self] = true
|
229
|
+
@ti_observer.each do |rec, lst|
|
230
|
+
lst.each do |dsig, ssig, prc|
|
231
|
+
rec.type_list(dsig)[1] = []
|
232
|
+
|
233
|
+
rec.ti_reset(visitnode)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
def ti_del_link(visitnode = {})
|
239
|
+
if visitnode[self] then
|
240
|
+
return
|
241
|
+
end
|
242
|
+
|
243
|
+
visitnode[self] = true
|
244
|
+
@ti_observer.each do |rec, lst|
|
245
|
+
delent = []
|
246
|
+
lst.each do |ent|
|
247
|
+
delent.push ent
|
248
|
+
|
249
|
+
rec.ti_del_link(visitnode)
|
250
|
+
end
|
251
|
+
|
252
|
+
delent.each do |ent|
|
253
|
+
lst.delete(ent)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
177
258
|
def merge_type(dst, src)
|
178
259
|
res = dst
|
179
260
|
src.each do |sele|
|
180
|
-
if !
|
261
|
+
if !res.include? sele then
|
181
262
|
res.push sele
|
182
263
|
end
|
183
264
|
end
|
@@ -186,18 +267,22 @@ LocalVarNode
|
|
186
267
|
end
|
187
268
|
|
188
269
|
def ti_update(dst, src, dsig, ssig, context)
|
189
|
-
|
190
|
-
|
270
|
+
dtlistorg = dst.type_list(dsig)
|
271
|
+
dtlist = dtlistorg.flatten
|
272
|
+
stlist = src.type_list(ssig).flatten
|
191
273
|
=begin
|
192
|
-
print
|
274
|
+
print "UPDATE TYPE\n"
|
275
|
+
print "#{src.class} #{ssig.inspect} -> #{dst.class} #{dsig.inspect}\n"
|
193
276
|
print dtlist.map(&:ruby_type), "\n"
|
194
277
|
print stlist.map(&:ruby_type), "\n"
|
195
278
|
=end
|
196
279
|
orgsize = dtlist.size
|
197
|
-
#
|
198
|
-
|
280
|
+
# pp "#{dst.class} #{src.class} #{dtlist} #{stlist}"
|
281
|
+
newdt = merge_type(dtlistorg[1], stlist)
|
282
|
+
dst.set_type_list(dsig, newdt)
|
283
|
+
dtsize = dtlistorg[0].size + newdt.size
|
199
284
|
|
200
|
-
if orgsize !=
|
285
|
+
if orgsize != dtsize then
|
201
286
|
dst.type = nil
|
202
287
|
dst.ti_changed
|
203
288
|
context.convergent = false
|
@@ -222,6 +307,9 @@ LocalVarNode
|
|
222
307
|
if dst.is_a?(LiteralNode) then
|
223
308
|
print "#{dst.value.inspect} \n"
|
224
309
|
end
|
310
|
+
if dst.is_a?(SendNode) then
|
311
|
+
print "#{dst.func.name} \n"
|
312
|
+
end
|
225
313
|
=end
|
226
314
|
|
227
315
|
if dst.is_a?(BaseNode) then
|
@@ -264,17 +352,25 @@ LocalVarNode
|
|
264
352
|
tlist[0].element_type = node.type
|
265
353
|
end
|
266
354
|
tlist[0]
|
267
|
-
|
355
|
+
|
356
|
+
when 2
|
357
|
+
if tlist[0].ruby_type == tlist[1].ruby_type and
|
358
|
+
tlist[0].boxed then
|
359
|
+
tlist[0]
|
360
|
+
else
|
361
|
+
tlist[1]
|
362
|
+
end
|
268
363
|
else
|
269
364
|
RubyType::DefaultType0.new
|
270
|
-
|
271
365
|
end
|
272
366
|
end
|
273
367
|
|
274
368
|
def decide_type_once(sig)
|
275
|
-
if @type.equal?(nil)
|
276
|
-
tlist =
|
369
|
+
if @type.equal?(nil) or @type.is_a?(RubyType::DefaultType0) then
|
370
|
+
tlist = type_list(sig).flatten.uniq
|
277
371
|
@type = decide_type_core(tlist)
|
372
|
+
else
|
373
|
+
@type
|
278
374
|
end
|
279
375
|
end
|
280
376
|
|
@@ -300,6 +396,10 @@ LocalVarNode
|
|
300
396
|
@code_space = context.code_space
|
301
397
|
context
|
302
398
|
end
|
399
|
+
|
400
|
+
def get_constant_value
|
401
|
+
nil
|
402
|
+
end
|
303
403
|
end
|
304
404
|
|
305
405
|
module HaveChildlenMixin
|
@@ -371,13 +471,35 @@ LocalVarNode
|
|
371
471
|
|
372
472
|
context.ret_node.decide_type_once(context.to_signature)
|
373
473
|
rtype = context.ret_node.type
|
374
|
-
rtype.
|
474
|
+
if !rtype.boxed then
|
475
|
+
context = rtype.gen_unboxing(context)
|
476
|
+
end
|
477
|
+
context
|
375
478
|
end
|
376
479
|
|
377
|
-
def signature(context)
|
480
|
+
def signature(context, args = @arguments)
|
378
481
|
res = []
|
379
|
-
|
380
|
-
|
482
|
+
cursig = context.to_signature
|
483
|
+
args[0].decide_type_once(cursig)
|
484
|
+
res.push args[0].type
|
485
|
+
|
486
|
+
mt, slf = get_send_method_node(cursig)
|
487
|
+
if mt and (ynode = mt.yield_node[0]) then
|
488
|
+
context.push_signature(args, mt)
|
489
|
+
args[1].type = nil
|
490
|
+
args[1].decide_type_once(ynode.signature(context))
|
491
|
+
res.push args[1].type
|
492
|
+
context.pop_signature
|
493
|
+
else
|
494
|
+
args[1].decide_type_once(cursig)
|
495
|
+
res.push args[1].type
|
496
|
+
args[2].decide_type_once(cursig)
|
497
|
+
slf = args[2].type
|
498
|
+
end
|
499
|
+
res.push slf
|
500
|
+
|
501
|
+
args[3..-1].each do |ele|
|
502
|
+
ele.decide_type_once(cursig)
|
381
503
|
res.push ele.type
|
382
504
|
end
|
383
505
|
|
@@ -395,18 +517,21 @@ LocalVarNode
|
|
395
517
|
|
396
518
|
context.cpustack_pushn(3 * AsmType::MACHINE_WORD.size)
|
397
519
|
casm = context.assembler
|
520
|
+
casm.with_retry do
|
521
|
+
casm.mov(FUNC_ARG[0], rarg.size) # argc
|
522
|
+
casm.mov(FUNC_ARG[1], TMPR2) # argv
|
523
|
+
end
|
524
|
+
context.set_reg_content(FUNC_ARG[0], nil)
|
525
|
+
context.set_reg_content(FUNC_ARG[1], TMPR2)
|
526
|
+
|
398
527
|
# Method Select
|
399
528
|
# it is legal. use TMPR2 for method select
|
400
529
|
# use TMPR3 for store self
|
401
530
|
context = @func.compile(context)
|
402
531
|
fnc = context.ret_reg
|
403
532
|
casm.with_retry do
|
404
|
-
casm.mov(FUNC_ARG[
|
405
|
-
casm.mov(FUNC_ARG[1], TMPR2) # argv
|
406
|
-
casm.mov(FUNC_ARG[2], TMPR3) # self
|
533
|
+
casm.mov(FUNC_ARG[2], context.ret_reg2) # self
|
407
534
|
end
|
408
|
-
context.set_reg_content(FUNC_ARG[0], nil)
|
409
|
-
context.set_reg_content(FUNC_ARG[1], TMPR2)
|
410
535
|
context.set_reg_content(FUNC_ARG[2], context.ret_node)
|
411
536
|
|
412
537
|
context = gen_call(context, fnc, 3)
|
@@ -420,7 +545,9 @@ LocalVarNode
|
|
420
545
|
context.ret_node = self
|
421
546
|
|
422
547
|
decide_type_once(context.to_signature)
|
423
|
-
|
548
|
+
if !@type.boxed then
|
549
|
+
context = @type.to_box.gen_unboxing(context)
|
550
|
+
end
|
424
551
|
|
425
552
|
context
|
426
553
|
end
|
@@ -453,7 +580,7 @@ LocalVarNode
|
|
453
580
|
fnc = context.ret_reg
|
454
581
|
casm = context.assembler
|
455
582
|
casm.with_retry do
|
456
|
-
casm.mov(FUNC_ARG[0],
|
583
|
+
casm.mov(FUNC_ARG[0], context.ret_reg2)
|
457
584
|
end
|
458
585
|
context.set_reg_content(FUNC_ARG[0], context.ret_node)
|
459
586
|
else
|
@@ -479,9 +606,14 @@ LocalVarNode
|
|
479
606
|
context.end_using_reg(FUNC_ARG[numarg - i - 1])
|
480
607
|
end
|
481
608
|
context.end_using_reg(fnc)
|
609
|
+
context.ret_reg = RETR
|
482
610
|
|
483
611
|
decide_type_once(context.to_signature)
|
484
|
-
|
612
|
+
if !@type.boxed then
|
613
|
+
context = @type.to_box.gen_unboxing(context)
|
614
|
+
end
|
615
|
+
|
616
|
+
context
|
485
617
|
end
|
486
618
|
|
487
619
|
def compile_ytl(context)
|
@@ -495,10 +627,19 @@ LocalVarNode
|
|
495
627
|
|
496
628
|
# push prev env
|
497
629
|
casm = context.assembler
|
498
|
-
|
499
|
-
|
630
|
+
if @func.is_a?(YieldNode) then
|
631
|
+
prevenv = @frame_info.offset_arg(0, BPR)
|
632
|
+
casm.with_retry do
|
633
|
+
casm.mov(TMPR, prevenv)
|
634
|
+
casm.mov(FUNC_ARG_YTL[0], TMPR)
|
635
|
+
end
|
636
|
+
context.set_reg_content(FUNC_ARG_YTL[0], prevenv)
|
637
|
+
else
|
638
|
+
casm.with_retry do
|
639
|
+
casm.mov(FUNC_ARG_YTL[0], BPR)
|
640
|
+
end
|
641
|
+
context.set_reg_content(FUNC_ARG_YTL[0], BPR)
|
500
642
|
end
|
501
|
-
context.set_reg_content(FUNC_ARG_YTL[0], BPR)
|
502
643
|
|
503
644
|
# block
|
504
645
|
# eval block
|
@@ -509,12 +650,7 @@ LocalVarNode
|
|
509
650
|
@arguments[1].compile(tcontext)
|
510
651
|
|
511
652
|
casm = context.assembler
|
512
|
-
|
513
|
-
entry = @arguments[1].code_space.var_base_immidiate_address
|
514
|
-
casm.mov(FUNC_ARG_YTL[1], entry)
|
515
|
-
end
|
516
|
-
context.set_reg_content(FUNC_ARG_YTL[1], nil)
|
517
|
-
|
653
|
+
|
518
654
|
# other arguments
|
519
655
|
@arguments[3..-1].each_with_index do |arg, i|
|
520
656
|
context = arg.compile(context)
|
@@ -525,6 +661,12 @@ LocalVarNode
|
|
525
661
|
context.set_reg_content(FUNC_ARG_YTL[i + 3], context.ret_node)
|
526
662
|
end
|
527
663
|
|
664
|
+
casm.with_retry do
|
665
|
+
entry = @arguments[1].code_space.var_base_immidiate_address
|
666
|
+
casm.mov(FUNC_ARG_YTL[1], entry)
|
667
|
+
end
|
668
|
+
context.set_reg_content(FUNC_ARG_YTL[1], nil)
|
669
|
+
|
528
670
|
# self
|
529
671
|
# Method Select
|
530
672
|
# it is legal. use TMPR2 for method select
|
@@ -533,10 +675,10 @@ LocalVarNode
|
|
533
675
|
fnc = context.ret_reg
|
534
676
|
casm = context.assembler
|
535
677
|
casm.with_retry do
|
536
|
-
casm.mov(FUNC_ARG_YTL[2],
|
678
|
+
casm.mov(FUNC_ARG_YTL[2], context.ret_reg2)
|
537
679
|
end
|
538
680
|
context.set_reg_content(FUNC_ARG_YTL[2], @arguments[2])
|
539
|
-
|
681
|
+
|
540
682
|
context = gen_call(context, fnc, numarg)
|
541
683
|
|
542
684
|
context.cpustack_popn(numarg * 8)
|
@@ -571,19 +713,24 @@ LocalVarNode
|
|
571
713
|
super(parent)
|
572
714
|
@name = name
|
573
715
|
@code_spaces = [] # [[nil, CodeSpace.new]]
|
574
|
-
@
|
716
|
+
@orig_modified_local_var = []
|
717
|
+
@yield_node = []
|
575
718
|
if @parent then
|
576
719
|
@classtop = search_class_top
|
577
720
|
else
|
578
721
|
@classtop = self
|
579
722
|
end
|
580
723
|
@end_nodes = []
|
724
|
+
@signature_cache = []
|
581
725
|
end
|
582
726
|
|
583
727
|
attr_accessor :name
|
584
728
|
attr :end_nodes
|
729
|
+
attr :orig_modified_local_var
|
585
730
|
attr :yield_node
|
586
731
|
|
732
|
+
attr :signature_cache
|
733
|
+
|
587
734
|
def modified_instance_var
|
588
735
|
search_end.modified_instance_var
|
589
736
|
end
|
@@ -616,9 +763,10 @@ LocalVarNode
|
|
616
763
|
|
617
764
|
def construct_frame_info(locals, argnum)
|
618
765
|
finfo = LocalFrameInfoNode.new(self)
|
766
|
+
finfo.system_num = 4 # BP ON Stack, BP, RET
|
619
767
|
|
620
768
|
# 3 means BP, BP and SP
|
621
|
-
lsize = locals.size +
|
769
|
+
lsize = locals.size + finfo.system_num
|
622
770
|
|
623
771
|
# construct frame
|
624
772
|
frame_layout = Array.new(lsize)
|
@@ -630,18 +778,22 @@ LocalVarNode
|
|
630
778
|
i += 1
|
631
779
|
end
|
632
780
|
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
781
|
+
curpos = fargstart - 1
|
782
|
+
frame_layout[curpos] = SystemValueNode.new(finfo,
|
783
|
+
:RET_ADDR, curpos)
|
784
|
+
curpos -= 1
|
785
|
+
frame_layout[curpos] = SystemValueNode.new(finfo,
|
786
|
+
:OLD_BP, curpos)
|
787
|
+
curpos -= 1
|
788
|
+
frame_layout[curpos] = SystemValueNode.new(finfo,
|
789
|
+
:FRAME_INFO, curpos)
|
790
|
+
curpos -= 1
|
791
|
+
frame_layout[curpos] = SystemValueNode.new(finfo,
|
792
|
+
:OLD_BPSTACK, curpos)
|
642
793
|
|
643
794
|
j = 0
|
644
|
-
|
795
|
+
lvarnum = lsize - finfo.system_num
|
796
|
+
while i < lvarnum do
|
645
797
|
lnode = LocalVarNode.new(finfo, locals[i], j)
|
646
798
|
frame_layout[j] = lnode
|
647
799
|
i += 1
|
@@ -649,7 +801,6 @@ LocalVarNode
|
|
649
801
|
end
|
650
802
|
finfo.frame_layout = frame_layout
|
651
803
|
finfo.argument_num = argnum
|
652
|
-
finfo.system_num = 3 # BP ON Stack, BP, RET
|
653
804
|
|
654
805
|
@body = finfo
|
655
806
|
finfo
|
@@ -657,7 +808,7 @@ LocalVarNode
|
|
657
808
|
|
658
809
|
def collect_info(context)
|
659
810
|
context.yield_node.push []
|
660
|
-
@body.collect_info(context)
|
811
|
+
context = @body.collect_info(context)
|
661
812
|
@yield_node = context.yield_node.pop
|
662
813
|
context
|
663
814
|
end
|
@@ -670,15 +821,18 @@ LocalVarNode
|
|
670
821
|
|
671
822
|
context.visited_top_node[self] = true
|
672
823
|
|
673
|
-
|
824
|
+
if !@signature_cache.include?(sig) then
|
825
|
+
@signature_cache.push sig
|
826
|
+
end
|
827
|
+
|
828
|
+
context.push_signature(signode, self)
|
674
829
|
context = @body.collect_candidate_type(context)
|
830
|
+
context.pop_signature
|
831
|
+
|
675
832
|
@end_nodes.each do |enode|
|
676
|
-
same_type(self, enode,
|
677
|
-
|
678
|
-
same_type(enode, self,
|
679
|
-
context.to_signature, context.to_signature, context)
|
833
|
+
same_type(self, enode, sig, sig, context)
|
834
|
+
same_type(enode, self, sig, sig, context)
|
680
835
|
end
|
681
|
-
context.current_method_signature_node.pop
|
682
836
|
context
|
683
837
|
end
|
684
838
|
|
@@ -687,8 +841,11 @@ LocalVarNode
|
|
687
841
|
print "#{@classtop.klass_object}##{@name} "
|
688
842
|
@code_spaces.each do |sig, cs|
|
689
843
|
print sig, " -> "
|
690
|
-
tl =
|
844
|
+
tl = type_list(sig).flatten.uniq
|
691
845
|
print decide_type_core(tl).inspect, "\n"
|
846
|
+
pp tl
|
847
|
+
# print "CodeSpace 0x#{cs.base_address.to_s(16)}\n"
|
848
|
+
print "CodeSpace #{cs.inspect}\n"
|
692
849
|
end
|
693
850
|
end
|
694
851
|
|
@@ -739,8 +896,11 @@ LocalVarNode
|
|
739
896
|
|
740
897
|
class BlockTopNode<MethodTopNode
|
741
898
|
def collect_info(context)
|
899
|
+
@orig_modified_local_var = context.modified_local_var.last.map {|e|
|
900
|
+
e.dup
|
901
|
+
}
|
742
902
|
context.modified_local_var.last.push Hash.new
|
743
|
-
context =
|
903
|
+
context = @body.collect_info(context)
|
744
904
|
context.modified_local_var.last.pop
|
745
905
|
context
|
746
906
|
end
|
@@ -749,6 +909,7 @@ LocalVarNode
|
|
749
909
|
end
|
750
910
|
|
751
911
|
class ClassTopNode<TopNode
|
912
|
+
include SendNodeCodeGen
|
752
913
|
include MethodTopCodeGen
|
753
914
|
@@class_top_tab = {}
|
754
915
|
|
@@ -756,43 +917,68 @@ LocalVarNode
|
|
756
917
|
@@class_top_tab[klass]
|
757
918
|
end
|
758
919
|
|
759
|
-
def collect_info(context)
|
760
|
-
context.modified_local_var.push [{}]
|
761
|
-
context.modified_instance_var = {}
|
762
|
-
context = super
|
763
|
-
context.modified_local_var.pop
|
764
|
-
context
|
765
|
-
end
|
766
|
-
|
767
920
|
def initialize(parent, klassobj, name = nil)
|
768
921
|
super(parent, name)
|
769
922
|
@constant_tab = {}
|
770
923
|
@method_tab = {}
|
771
924
|
@klass_object = klassobj
|
772
925
|
@klassclass = class << @klass_object; self; end
|
926
|
+
@klassclass_node = nil # Lazy
|
773
927
|
RubyType::define_wraped_class(@klassclass, RubyType::RubyTypeBoxed)
|
774
928
|
unless @@class_top_tab[klassobj]
|
775
929
|
@@class_top_tab[klassobj] = self
|
776
930
|
end
|
777
931
|
end
|
778
932
|
|
779
|
-
def
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
933
|
+
def collect_info(context)
|
934
|
+
context.modified_local_var.push [{}]
|
935
|
+
context.modified_instance_var = Hash.new {|hash, key| hash[key] = []}
|
936
|
+
context = super
|
937
|
+
context.modified_local_var.pop
|
938
|
+
if @klassclass_node then
|
939
|
+
@klassclass_node.collect_info(context)
|
940
|
+
end
|
941
|
+
context
|
942
|
+
end
|
943
|
+
|
944
|
+
def collect_candidate_type(context, signode, sig)
|
945
|
+
super
|
946
|
+
if @klassclass_node then
|
947
|
+
context = @klassclass_node.collect_candidate_type(context,
|
948
|
+
signode, sig)
|
949
|
+
end
|
950
|
+
context
|
951
|
+
end
|
952
|
+
|
953
|
+
def make_klassclass_node
|
954
|
+
clsclsnode = ClassTopNode.new(self, @klassclass, @klassclass.name)
|
955
|
+
clsclsnode.body = DummyNode.new
|
956
|
+
@klassclass_node = clsclsnode
|
957
|
+
end
|
958
|
+
|
959
|
+
def get_method_tab(klassobj = @klass_object)
|
960
|
+
ktop = @@class_top_tab[klassobj]
|
961
|
+
if ktop then
|
962
|
+
ktop.method_tab
|
787
963
|
else
|
788
|
-
|
964
|
+
{}
|
965
|
+
end
|
966
|
+
end
|
967
|
+
|
968
|
+
def get_constant_tab(klassobj = @klass_object)
|
969
|
+
ktop = @@class_top_tab[klassobj]
|
970
|
+
if ktop then
|
971
|
+
ktop.constant_tab
|
972
|
+
else
|
973
|
+
ktop.constant_tab = {}
|
974
|
+
ktop.constant_tab
|
789
975
|
end
|
790
976
|
end
|
791
977
|
|
792
978
|
def search_method_with_super(name, klassobj = @klass_object)
|
793
979
|
clsnode = @@class_top_tab[klassobj]
|
794
980
|
if clsnode then
|
795
|
-
mtab = clsnode.
|
981
|
+
mtab = clsnode.get_method_tab
|
796
982
|
if val = mtab[name] then
|
797
983
|
return [val, clsnode]
|
798
984
|
end
|
@@ -803,8 +989,23 @@ LocalVarNode
|
|
803
989
|
[nil, nil]
|
804
990
|
end
|
805
991
|
|
806
|
-
|
992
|
+
def search_constant_with_super(name, klassobj = @klass_object)
|
993
|
+
clsnode = @@class_top_tab[klassobj]
|
994
|
+
if clsnode then
|
995
|
+
ctab = clsnode.get_constant_tab
|
996
|
+
if val = ctab[name] then
|
997
|
+
return [val, clsnode]
|
998
|
+
end
|
999
|
+
|
1000
|
+
return search_constant_with_super(name, klassobj.superclass)
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
[nil, nil]
|
1004
|
+
end
|
1005
|
+
|
807
1006
|
attr :klass_object
|
1007
|
+
attr :constant_tab
|
1008
|
+
attr :method_tab
|
808
1009
|
|
809
1010
|
def construct_frame_info(locals, argnum)
|
810
1011
|
locals.unshift :_self
|
@@ -816,7 +1017,7 @@ LocalVarNode
|
|
816
1017
|
|
817
1018
|
def collect_candidate_type(context, signode, sig)
|
818
1019
|
@type = RubyType::BaseType.from_ruby_class(@klassclass)
|
819
|
-
|
1020
|
+
add_type(sig, @type)
|
820
1021
|
|
821
1022
|
if add_cs_for_signature(sig) == nil and
|
822
1023
|
context.visited_top_node[self] then
|
@@ -825,11 +1026,35 @@ LocalVarNode
|
|
825
1026
|
|
826
1027
|
context.visited_top_node[self] = true
|
827
1028
|
|
828
|
-
context.
|
1029
|
+
context.push_signature(signode, self)
|
829
1030
|
context = @body.collect_candidate_type(context)
|
830
|
-
context.
|
1031
|
+
context.pop_signature
|
1032
|
+
context
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
def compile(context)
|
1036
|
+
context = super(context)
|
1037
|
+
|
1038
|
+
cs = self.find_cs_by_signature(context.to_signature)
|
1039
|
+
if cs then
|
1040
|
+
asm = context.assembler
|
1041
|
+
add = lambda { @klassclass.address }
|
1042
|
+
var_klassclass = OpVarImmidiateAddress.new(add)
|
1043
|
+
asm.with_retry do
|
1044
|
+
asm.mov(FUNC_ARG_YTL[0], BPR)
|
1045
|
+
asm.mov(FUNC_ARG_YTL[1], 4)
|
1046
|
+
asm.mov(FUNC_ARG_YTL[2], var_klassclass)
|
1047
|
+
end
|
1048
|
+
add = cs.var_base_address
|
1049
|
+
context = gen_call(context, add, 3)
|
1050
|
+
end
|
1051
|
+
|
831
1052
|
context
|
832
1053
|
end
|
1054
|
+
|
1055
|
+
def get_constant_value
|
1056
|
+
[@klass_object]
|
1057
|
+
end
|
833
1058
|
end
|
834
1059
|
|
835
1060
|
class TopTopNode<ClassTopNode
|
@@ -841,6 +1066,24 @@ LocalVarNode
|
|
841
1066
|
@code_space_tab = []
|
842
1067
|
@asm_tab = {}
|
843
1068
|
@id.push 0
|
1069
|
+
|
1070
|
+
@unwind_proc = CodeSpace.new
|
1071
|
+
init_unwind_proc
|
1072
|
+
add_code_space(nil, @unwind_proc)
|
1073
|
+
end
|
1074
|
+
|
1075
|
+
def init_unwind_proc
|
1076
|
+
asm = Assembler.new(@unwind_proc)
|
1077
|
+
# Make linkage of frame pointer
|
1078
|
+
finfo = OpIndirect.new(TMPR3, AsmType::MACHINE_WORD.size)
|
1079
|
+
retadd = OpIndirect.new(TMPR3, AsmType::MACHINE_WORD.size)
|
1080
|
+
asm.with_retry do
|
1081
|
+
asm.mov(TMPR3, BPR)
|
1082
|
+
asm.mov(TMPR3, INDIRECT_TMPR3)
|
1083
|
+
asm.mov(TMPR, finfo)
|
1084
|
+
asm.mov(TMPR3, INDIRECT_TMPR3)
|
1085
|
+
asm.mov(TMPR2, retadd) # Return address store by call inst.
|
1086
|
+
end
|
844
1087
|
end
|
845
1088
|
|
846
1089
|
def add_code_space(oldcs, newcs)
|
@@ -950,7 +1193,6 @@ LocalVarNode
|
|
950
1193
|
traverse_childlen {|rec|
|
951
1194
|
context = rec.collect_candidate_type(context)
|
952
1195
|
}
|
953
|
-
@body.collect_candidate_type(context)
|
954
1196
|
end
|
955
1197
|
|
956
1198
|
def compile(context)
|
@@ -981,19 +1223,36 @@ LocalVarNode
|
|
981
1223
|
8
|
982
1224
|
end
|
983
1225
|
|
1226
|
+
def collect_info(context)
|
1227
|
+
flay = @parent.frame_layout
|
1228
|
+
fragstart = flay.size - @parent.argument_num
|
1229
|
+
if fragstart <= @offset then
|
1230
|
+
argoff = @offset - fragstart
|
1231
|
+
else
|
1232
|
+
argoff = @offset + @parent.argument_num
|
1233
|
+
end
|
1234
|
+
=begin
|
1235
|
+
# Assertion check for reverse of real_offset
|
1236
|
+
unless @offset == @parent.real_offset(argoff)
|
1237
|
+
raise
|
1238
|
+
end
|
1239
|
+
=end
|
1240
|
+
topnode = @parent.parent
|
1241
|
+
context.modified_local_var.last.last[argoff] = [[topnode, self]]
|
1242
|
+
context
|
1243
|
+
end
|
1244
|
+
|
984
1245
|
def collect_candidate_type(context)
|
985
1246
|
flay = @parent.frame_layout
|
986
1247
|
fragstart = flay.size - @parent.argument_num
|
987
1248
|
if fragstart <= @offset then
|
988
1249
|
argoff = @offset - fragstart
|
989
1250
|
tobj = context.current_method_signature_node.last[argoff]
|
1251
|
+
cursig = context.to_signature
|
1252
|
+
cursig2 = context.to_signature(-2)
|
990
1253
|
if tobj then
|
991
|
-
same_type(self, tobj,
|
992
|
-
|
993
|
-
context)
|
994
|
-
same_type(tobj, self,
|
995
|
-
context.to_signature(-2), context.to_signature,
|
996
|
-
context)
|
1254
|
+
same_type(self, tobj, cursig, cursig2, context)
|
1255
|
+
same_type(tobj, self, cursig2, cursig, context)
|
997
1256
|
end
|
998
1257
|
end
|
999
1258
|
context
|
@@ -1050,10 +1309,9 @@ LocalVarNode
|
|
1050
1309
|
end
|
1051
1310
|
|
1052
1311
|
def collect_candidate_type(context)
|
1053
|
-
|
1054
|
-
|
1055
|
-
same_type(@parent, self,
|
1056
|
-
context.to_signature, context.to_signature, context)
|
1312
|
+
cursig = context.to_signature
|
1313
|
+
same_type(self, @parent, cursig, cursig, context)
|
1314
|
+
same_type(@parent, self, cursig, cursig, context)
|
1057
1315
|
context
|
1058
1316
|
end
|
1059
1317
|
|
@@ -1085,6 +1343,8 @@ LocalVarNode
|
|
1085
1343
|
@value_node = valnode
|
1086
1344
|
end
|
1087
1345
|
|
1346
|
+
attr :value_node
|
1347
|
+
|
1088
1348
|
def traverse_childlen
|
1089
1349
|
yield @value_node
|
1090
1350
|
yield @body
|
@@ -1092,10 +1352,9 @@ LocalVarNode
|
|
1092
1352
|
|
1093
1353
|
def collect_candidate_type(context)
|
1094
1354
|
context = @value_node.collect_candidate_type(context)
|
1095
|
-
|
1096
|
-
|
1097
|
-
same_type(@value_node, self,
|
1098
|
-
context.to_signature, context.to_signature, context)
|
1355
|
+
cursig = context.to_signature
|
1356
|
+
same_type(self, @value_node, cursig, cursig, context)
|
1357
|
+
same_type(@value_node, self, cursig, cursig, context)
|
1099
1358
|
context = @body.collect_candidate_type(context)
|
1100
1359
|
context
|
1101
1360
|
end
|
@@ -1105,26 +1364,32 @@ LocalVarNode
|
|
1105
1364
|
context = @value_node.compile(context)
|
1106
1365
|
if context.ret_reg != RETR then
|
1107
1366
|
if context.ret_reg.is_a?(OpRegXMM) then
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1367
|
+
=begin
|
1368
|
+
decide_type_once(context.to_signature)
|
1369
|
+
context = @type.gen_boxing(context)
|
1370
|
+
if context.ret_reg != RETR then
|
1371
|
+
curas = context.assembler
|
1372
|
+
curas.with_retry do
|
1373
|
+
curas.mov(RETR, context.ret_reg)
|
1374
|
+
end
|
1375
|
+
|
1376
|
+
context.set_reg_content(RETR, context.ret_node)
|
1377
|
+
end
|
1378
|
+
=end
|
1379
|
+
context.set_reg_content(context.ret_reg, context.ret_node)
|
1118
1380
|
else
|
1119
1381
|
curas = context.assembler
|
1120
1382
|
curas.with_retry do
|
1121
1383
|
curas.mov(RETR, context.ret_reg)
|
1122
1384
|
end
|
1385
|
+
context.set_reg_content(RETR, context.ret_node)
|
1386
|
+
context.ret_reg = RETR
|
1123
1387
|
end
|
1124
|
-
|
1388
|
+
else
|
1389
|
+
context.set_reg_content(RETR, context.ret_node)
|
1390
|
+
context.ret_reg = RETR
|
1125
1391
|
end
|
1126
1392
|
|
1127
|
-
context.ret_reg = RETR
|
1128
1393
|
context = @body.compile(context)
|
1129
1394
|
|
1130
1395
|
context
|
@@ -1140,10 +1405,9 @@ LocalVarNode
|
|
1140
1405
|
def collect_candidate_type(context)
|
1141
1406
|
@local_label.come_from.values.each do |vnode|
|
1142
1407
|
if vnode then
|
1143
|
-
|
1144
|
-
|
1145
|
-
same_type(vnode, self,
|
1146
|
-
context.to_signature, context.to_signature, context)
|
1408
|
+
cursig = context.to_signature
|
1409
|
+
same_type(self, vnode, cursig, cursig, context)
|
1410
|
+
same_type(vnode, self, cursig, cursig, context)
|
1147
1411
|
end
|
1148
1412
|
end
|
1149
1413
|
context
|
@@ -1168,26 +1432,54 @@ LocalVarNode
|
|
1168
1432
|
@code_space = CodeSpace.new
|
1169
1433
|
@value_node = PhiNode.new(self)
|
1170
1434
|
@modified_local_var_list = []
|
1171
|
-
@modified_instance_var_list = []
|
1172
1435
|
end
|
1173
1436
|
|
1174
|
-
attr
|
1175
|
-
attr
|
1176
|
-
attr
|
1437
|
+
attr :name
|
1438
|
+
attr :come_from
|
1439
|
+
attr :value_node
|
1177
1440
|
|
1178
1441
|
def traverse_childlen
|
1179
|
-
yield @body
|
1180
1442
|
yield @value_node
|
1443
|
+
yield @body
|
1444
|
+
end
|
1445
|
+
|
1446
|
+
def lonly_node(node)
|
1447
|
+
while !node.is_a?(TopNode)
|
1448
|
+
if node.is_a?(LocalLabel) then
|
1449
|
+
if node.come_from.size == 0 then
|
1450
|
+
return true
|
1451
|
+
else
|
1452
|
+
return false
|
1453
|
+
end
|
1454
|
+
end
|
1455
|
+
|
1456
|
+
node = node.parent
|
1457
|
+
end
|
1458
|
+
|
1459
|
+
return false
|
1181
1460
|
end
|
1182
1461
|
|
1183
1462
|
def collect_info(context)
|
1463
|
+
if @modified_local_var_list.size == 0 then
|
1464
|
+
# first visit
|
1465
|
+
delnode = []
|
1466
|
+
fornode = []
|
1467
|
+
@come_from.keys.each do |ele|
|
1468
|
+
if lonly_node(ele) then
|
1469
|
+
delnode.push ele
|
1470
|
+
end
|
1471
|
+
end
|
1472
|
+
delnode.each do |ele|
|
1473
|
+
@come_from.delete(ele)
|
1474
|
+
end
|
1475
|
+
end
|
1476
|
+
|
1184
1477
|
modlocvar = context.modified_local_var.last.map {|ele| ele.dup}
|
1185
1478
|
@modified_local_var_list.push modlocvar
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1479
|
+
if @modified_local_var_list.size == 1 then
|
1480
|
+
@body.collect_info(context)
|
1481
|
+
elsif @modified_local_var_list.size == @come_from.size then
|
1189
1482
|
context.merge_local_var(@modified_local_var_list)
|
1190
|
-
context.merge_instance_var(@modified_instance_var_list)
|
1191
1483
|
@body.collect_info(context)
|
1192
1484
|
else
|
1193
1485
|
context
|
@@ -1233,9 +1525,8 @@ LocalVarNode
|
|
1233
1525
|
def compile(context)
|
1234
1526
|
context = super(context)
|
1235
1527
|
@come_from_val.push context.ret_reg
|
1236
|
-
|
1237
|
-
|
1238
|
-
if @come_from_val.size == @come_from.size then
|
1528
|
+
|
1529
|
+
if @come_from_val.size == 1 then
|
1239
1530
|
@body.compile(context)
|
1240
1531
|
else
|
1241
1532
|
context
|
@@ -1363,21 +1654,26 @@ LocalVarNode
|
|
1363
1654
|
|
1364
1655
|
# Literal
|
1365
1656
|
class LiteralNode<BaseNode
|
1657
|
+
include TypeListWithoutSignature
|
1658
|
+
|
1366
1659
|
def initialize(parent, val)
|
1367
1660
|
super(parent)
|
1368
1661
|
@value = val
|
1369
1662
|
@type = RubyType::BaseType.from_object(val)
|
1370
|
-
@my_element_node = BaseNode.new(self)
|
1371
1663
|
end
|
1372
1664
|
|
1373
1665
|
attr :value
|
1374
1666
|
|
1375
1667
|
def collect_candidate_type(context)
|
1376
|
-
|
1668
|
+
# ???
|
1669
|
+
if @type == nil then
|
1670
|
+
@type = RubyType::BaseType.from_object(@value)
|
1671
|
+
end
|
1672
|
+
|
1673
|
+
sig = context.to_signature
|
1674
|
+
add_type(sig, @type)
|
1377
1675
|
case @value
|
1378
1676
|
when Array
|
1379
|
-
sig = context.to_signature
|
1380
|
-
@element_node_list = [[sig, @my_element_node]]
|
1381
1677
|
@value.each do |ele|
|
1382
1678
|
etype = RubyType::BaseType.from_object(ele)
|
1383
1679
|
@element_node_list[0][1].add_type(sig, etype)
|
@@ -1428,6 +1724,10 @@ LocalVarNode
|
|
1428
1724
|
|
1429
1725
|
context
|
1430
1726
|
end
|
1727
|
+
|
1728
|
+
def get_constant_value
|
1729
|
+
[@value]
|
1730
|
+
end
|
1431
1731
|
end
|
1432
1732
|
|
1433
1733
|
class ClassValueNode<BaseNode
|
@@ -1446,7 +1746,15 @@ LocalVarNode
|
|
1446
1746
|
attr_accessor :define
|
1447
1747
|
|
1448
1748
|
def collect_candidate_type(context)
|
1449
|
-
|
1749
|
+
dmylit = LiteralNode.new(self, nil)
|
1750
|
+
arg = [dmylit, dmylit, @define]
|
1751
|
+
sig = []
|
1752
|
+
arg.each do |ele|
|
1753
|
+
ele.decide_type_once(context.to_signature)
|
1754
|
+
sig.push ele.type
|
1755
|
+
end
|
1756
|
+
context = @define.collect_candidate_type(context, arg, sig)
|
1757
|
+
|
1450
1758
|
context = @body.collect_candidate_type(context)
|
1451
1759
|
context
|
1452
1760
|
end
|
@@ -1514,10 +1822,18 @@ LocalVarNode
|
|
1514
1822
|
def compile(context)
|
1515
1823
|
context = super(context)
|
1516
1824
|
asm = context.assembler
|
1517
|
-
|
1825
|
+
# You can crash when you use yield in block.
|
1826
|
+
# You can fix this bug for traversing TMPR3 for method top.
|
1827
|
+
# But is is little troublesome. So it is not supported.
|
1828
|
+
prevenv = @frame_info.offset_arg(0, BPR)
|
1829
|
+
# offset of self is common, so it no nessery traverse prev frame
|
1830
|
+
# for @frame_info.
|
1831
|
+
slfarg = @frame_info.offset_arg(2, TMPR3)
|
1518
1832
|
asm.with_retry do
|
1833
|
+
asm.mov(TMPR3, prevenv)
|
1519
1834
|
asm.mov(TMPR3, slfarg)
|
1520
1835
|
end
|
1836
|
+
context.ret_reg2 = TMPR3
|
1521
1837
|
|
1522
1838
|
context.ret_reg = @frame_info.offset_arg(1, BPR)
|
1523
1839
|
context.ret_node = self
|
@@ -1533,11 +1849,12 @@ LocalVarNode
|
|
1533
1849
|
@calling_convention = :unkown
|
1534
1850
|
@reciever = nil
|
1535
1851
|
@send_node = nil
|
1852
|
+
@ruby_reciever = nil
|
1536
1853
|
end
|
1537
1854
|
|
1538
1855
|
def set_reciever(sendnode)
|
1539
1856
|
@send_node = sendnode
|
1540
|
-
if sendnode.is_fcall then
|
1857
|
+
if sendnode.is_fcall or sendnode.is_vcall then
|
1541
1858
|
@reciever = @parent.class_top
|
1542
1859
|
else
|
1543
1860
|
@reciever = sendnode.arguments[2]
|
@@ -1592,7 +1909,20 @@ LocalVarNode
|
|
1592
1909
|
if knode and knode.search_method_with_super(@name)[0] then
|
1593
1910
|
@calling_convention = :ytl
|
1594
1911
|
else
|
1595
|
-
|
1912
|
+
slfval = @reciever.get_constant_value
|
1913
|
+
mth = nil
|
1914
|
+
if slfval then
|
1915
|
+
begin
|
1916
|
+
mth = slfval[0].instance_method(@name)
|
1917
|
+
@ruby_reciever = slfval[0]
|
1918
|
+
rescue NameError
|
1919
|
+
end
|
1920
|
+
end
|
1921
|
+
if slfval == nil or mth == nil then
|
1922
|
+
mth = rklass.instance_method(@name)
|
1923
|
+
@ruby_reciever = rklass
|
1924
|
+
end
|
1925
|
+
|
1596
1926
|
if variable_argument?(mth.parameters) then
|
1597
1927
|
@calling_convention = :c_vararg
|
1598
1928
|
else
|
@@ -1607,10 +1937,12 @@ LocalVarNode
|
|
1607
1937
|
def compile(context)
|
1608
1938
|
context = super(context)
|
1609
1939
|
if @send_node.is_fcall or @send_node.is_vcall then
|
1940
|
+
slfop = @parent.frame_info.offset_arg(2, BPR)
|
1610
1941
|
asm = context.assembler
|
1611
1942
|
asm.with_retry do
|
1612
|
-
asm.mov(TMPR3,
|
1943
|
+
asm.mov(TMPR3, slfop)
|
1613
1944
|
end
|
1945
|
+
context.ret_reg2 = TMPR3
|
1614
1946
|
mtop = @reciever.search_method_with_super(@name)[0]
|
1615
1947
|
if mtop then
|
1616
1948
|
sig = @parent.signature(context)
|
@@ -1638,7 +1970,9 @@ LocalVarNode
|
|
1638
1970
|
context = @reciever.compile(context)
|
1639
1971
|
context.ret_node.decide_type_once(context.to_signature)
|
1640
1972
|
rtype = context.ret_node.type
|
1641
|
-
|
1973
|
+
if @calling_convention != :ytl then
|
1974
|
+
context = rtype.gen_boxing(context)
|
1975
|
+
end
|
1642
1976
|
recval = context.ret_reg
|
1643
1977
|
knode = ClassTopNode.get_class_top_node(rtype.ruby_type)
|
1644
1978
|
mtop = nil
|
@@ -1665,6 +1999,7 @@ LocalVarNode
|
|
1665
1999
|
asm.mov(TMPR2, RETR)
|
1666
2000
|
asm.pop(TMPR3)
|
1667
2001
|
end
|
2002
|
+
context.ret_reg2 = TMPR3
|
1668
2003
|
|
1669
2004
|
context.end_using_reg(FUNC_ARG[1])
|
1670
2005
|
context.end_using_reg(FUNC_ARG[0])
|
@@ -1677,8 +2012,18 @@ LocalVarNode
|
|
1677
2012
|
|
1678
2013
|
elsif knode and mtop = knode.search_method_with_super(@name)[0] then
|
1679
2014
|
asm = context.assembler
|
1680
|
-
|
1681
|
-
|
2015
|
+
if !rtype.boxed and rtype.ruby_type == Float then
|
2016
|
+
if recval != XMM0 then
|
2017
|
+
asm.with_retry do
|
2018
|
+
asm.mov(XMM0, recval)
|
2019
|
+
end
|
2020
|
+
end
|
2021
|
+
context.ret_reg2 = XMM0
|
2022
|
+
else
|
2023
|
+
asm.with_retry do
|
2024
|
+
asm.mov(TMPR3, recval)
|
2025
|
+
end
|
2026
|
+
context.ret_reg2 = TMPR3
|
1682
2027
|
end
|
1683
2028
|
|
1684
2029
|
sig = @parent.signature(context)
|
@@ -1689,12 +2034,27 @@ LocalVarNode
|
|
1689
2034
|
# regident type
|
1690
2035
|
|
1691
2036
|
asm = context.assembler
|
1692
|
-
|
1693
|
-
|
2037
|
+
if !rtype.boxed and rtype.ruby_type == Float then
|
2038
|
+
if recval != XMM0 then
|
2039
|
+
asm.with_retry do
|
2040
|
+
asm.mov(XMM0, recval)
|
2041
|
+
end
|
2042
|
+
end
|
2043
|
+
context.ret_reg2 = XMM0
|
2044
|
+
else
|
2045
|
+
asm.with_retry do
|
2046
|
+
asm.mov(TMPR3, recval)
|
2047
|
+
end
|
2048
|
+
context.ret_reg2 = TMPR3
|
1694
2049
|
end
|
1695
2050
|
|
1696
2051
|
addr = lambda {
|
1697
|
-
|
2052
|
+
if @ruby_reciever.class == Module then
|
2053
|
+
name = @name
|
2054
|
+
@ruby_reciever.send(:method_address_of, name)
|
2055
|
+
else
|
2056
|
+
@ruby_reciever.method_address_of(@name)
|
2057
|
+
end
|
1698
2058
|
}
|
1699
2059
|
if addr.call then
|
1700
2060
|
context.ret_reg = OpVarMemAddress.new(addr)
|
@@ -1745,13 +2105,14 @@ LocalVarNode
|
|
1745
2105
|
|
1746
2106
|
def collect_info(context)
|
1747
2107
|
vti = nil
|
1748
|
-
if context.modified_local_var.last[
|
1749
|
-
vti = context.modified_local_var.last[
|
2108
|
+
if context.modified_local_var.last[-@depth - 1] then
|
2109
|
+
vti = context.modified_local_var.last[-@depth - 1][@offset]
|
1750
2110
|
end
|
1751
2111
|
|
1752
2112
|
if vti then
|
1753
|
-
@var_type_info = vti.dup
|
2113
|
+
@var_type_info = vti.map {|e| e.dup }
|
1754
2114
|
else
|
2115
|
+
raise "maybe bug"
|
1755
2116
|
roff = @current_frame_info.real_offset(@offset)
|
1756
2117
|
@var_type_info = [@current_frame_info.frame_layout[roff]]
|
1757
2118
|
end
|
@@ -1760,9 +2121,11 @@ LocalVarNode
|
|
1760
2121
|
end
|
1761
2122
|
|
1762
2123
|
def collect_candidate_type(context)
|
1763
|
-
@var_type_info.each do |
|
1764
|
-
|
1765
|
-
|
2124
|
+
@var_type_info.each do |topnode, node|
|
2125
|
+
cursig = context.to_signature
|
2126
|
+
varsig = context.to_signature(topnode)
|
2127
|
+
same_type(self, node, cursig, varsig, context)
|
2128
|
+
same_type(node, self, varsig, cursig, context)
|
1766
2129
|
end
|
1767
2130
|
context
|
1768
2131
|
end
|
@@ -1772,15 +2135,34 @@ LocalVarNode
|
|
1772
2135
|
context = gen_pursue_parent_function(context, @depth)
|
1773
2136
|
base = context.ret_reg
|
1774
2137
|
offarg = @current_frame_info.offset_arg(@offset, base)
|
2138
|
+
|
2139
|
+
asm = context.assembler
|
2140
|
+
@type = nil
|
2141
|
+
rtype = decide_type_once(context.to_signature)
|
2142
|
+
if !rtype.boxed and rtype.ruby_type == Float then
|
2143
|
+
asm.with_retry do
|
2144
|
+
asm.mov(XMM0, offarg)
|
2145
|
+
end
|
2146
|
+
context.ret_reg = XMM0
|
2147
|
+
else
|
2148
|
+
asm.with_retry do
|
2149
|
+
asm.mov(TMPR, offarg)
|
2150
|
+
end
|
2151
|
+
context.ret_reg = TMPR
|
2152
|
+
end
|
2153
|
+
|
2154
|
+
if base == TMPR2 then
|
2155
|
+
context.end_using_reg(TMPR2)
|
2156
|
+
end
|
2157
|
+
|
1775
2158
|
context.ret_node = self
|
1776
|
-
context.ret_reg = offarg
|
1777
2159
|
context
|
1778
2160
|
end
|
1779
2161
|
end
|
1780
2162
|
|
1781
2163
|
class SelfRefNode<LocalVarRefNode
|
1782
2164
|
def initialize(parent)
|
1783
|
-
super(parent,
|
2165
|
+
super(parent, 2, 0)
|
1784
2166
|
@classtop = search_class_top
|
1785
2167
|
end
|
1786
2168
|
|
@@ -1793,12 +2175,12 @@ LocalVarNode
|
|
1793
2175
|
|
1794
2176
|
def collect_candidate_type(context)
|
1795
2177
|
@type = RubyType::BaseType.from_ruby_class(@classtop.klass_object)
|
1796
|
-
|
2178
|
+
add_type(context.to_signature, @type)
|
1797
2179
|
context
|
1798
2180
|
end
|
1799
2181
|
|
1800
2182
|
def compile(context)
|
1801
|
-
context = super(context)
|
2183
|
+
# context = super(context)
|
1802
2184
|
compile_main(context)
|
1803
2185
|
end
|
1804
2186
|
end
|
@@ -1818,14 +2200,31 @@ LocalVarNode
|
|
1818
2200
|
|
1819
2201
|
def collect_info(context)
|
1820
2202
|
context = @val.collect_info(context)
|
1821
|
-
|
2203
|
+
top = @frame_info.parent
|
2204
|
+
|
2205
|
+
nodepare = nil
|
2206
|
+
if @depth > 0 then
|
2207
|
+
nodepare = top.orig_modified_local_var[-@depth]
|
2208
|
+
end
|
2209
|
+
if nodepare then
|
2210
|
+
nodepare = nodepare[@offset]
|
2211
|
+
end
|
2212
|
+
if nodepare then
|
2213
|
+
nodepare.push [top, self]
|
2214
|
+
else
|
2215
|
+
nodepare = [[top, self]]
|
2216
|
+
end
|
2217
|
+
|
2218
|
+
context.modified_local_var.last[-@depth - 1][@offset] = nodepare
|
2219
|
+
|
1822
2220
|
@body.collect_info(context)
|
1823
2221
|
end
|
1824
2222
|
|
1825
2223
|
def collect_candidate_type(context)
|
1826
2224
|
context = @val.collect_candidate_type(context)
|
1827
|
-
|
1828
|
-
|
2225
|
+
cursig = context.to_signature
|
2226
|
+
same_type(self, @val, cursig, cursig, context)
|
2227
|
+
# same_type(@val, self, cursig, cursig, context)
|
1829
2228
|
@body.collect_candidate_type(context)
|
1830
2229
|
end
|
1831
2230
|
|
@@ -1887,20 +2286,18 @@ LocalVarNode
|
|
1887
2286
|
|
1888
2287
|
def collect_info(context)
|
1889
2288
|
vti = context.modified_instance_var[@name]
|
1890
|
-
|
1891
|
-
|
1892
|
-
else
|
1893
|
-
@var_type_info = nil
|
1894
|
-
end
|
2289
|
+
# Not dup so vti may update after.
|
2290
|
+
@var_type_info = vti
|
1895
2291
|
|
1896
2292
|
context
|
1897
2293
|
end
|
1898
2294
|
|
1899
2295
|
def collect_candidate_type(context)
|
1900
2296
|
@var_type_info.each do |src|
|
1901
|
-
|
1902
|
-
|
2297
|
+
cursig = context.to_signature
|
2298
|
+
same_type(self, src, cursig, cursig, context)
|
1903
2299
|
end
|
2300
|
+
|
1904
2301
|
context
|
1905
2302
|
end
|
1906
2303
|
|
@@ -1935,8 +2332,9 @@ LocalVarNode
|
|
1935
2332
|
|
1936
2333
|
def collect_candidate_type(context)
|
1937
2334
|
context = @val.collect_candidate_type(context)
|
1938
|
-
|
1939
|
-
|
2335
|
+
cursig = context.to_signature
|
2336
|
+
same_type(self, @val, cursig, cursig, context)
|
2337
|
+
# same_type(@val, self, cursig, cursig, context)
|
1940
2338
|
@body.collect_candidate_type(context)
|
1941
2339
|
end
|
1942
2340
|
|
@@ -1952,21 +2350,31 @@ LocalVarNode
|
|
1952
2350
|
|
1953
2351
|
class ConstantRefNode<VariableRefCommonNode
|
1954
2352
|
include NodeUtil
|
2353
|
+
include TypeListWithoutSignature
|
1955
2354
|
|
1956
2355
|
def initialize(parent, klass, name)
|
1957
2356
|
super(parent)
|
1958
2357
|
@name = name
|
1959
2358
|
@class_top = klass # .search_class_top
|
1960
|
-
@value_node = klass.
|
2359
|
+
@value_node, dummy = klass.search_constant_with_super(@name)
|
1961
2360
|
end
|
1962
2361
|
|
1963
2362
|
attr :value_node
|
1964
2363
|
|
1965
2364
|
def collect_candidate_type(context)
|
1966
|
-
|
1967
|
-
|
2365
|
+
if @value_node.is_a?(ClassTopNode) then
|
2366
|
+
add_type(context.to_signature, @value_node.type)
|
2367
|
+
else
|
2368
|
+
context = @value_node.collect_candidate_type(context)
|
2369
|
+
cursig = context.to_signature
|
2370
|
+
same_type(self, @value_node, cursig, cursig, context)
|
2371
|
+
end
|
1968
2372
|
context
|
1969
2373
|
end
|
2374
|
+
|
2375
|
+
def type
|
2376
|
+
@value_node.type
|
2377
|
+
end
|
1970
2378
|
|
1971
2379
|
def compile(context)
|
1972
2380
|
case @value_node
|
@@ -1982,6 +2390,45 @@ LocalVarNode
|
|
1982
2390
|
context.ret_node = self
|
1983
2391
|
context
|
1984
2392
|
end
|
2393
|
+
|
2394
|
+
def get_constant_value
|
2395
|
+
@value_node.get_constant_value
|
2396
|
+
end
|
2397
|
+
end
|
2398
|
+
|
2399
|
+
class ConstantAssignNode<VariableRefCommonNode
|
2400
|
+
include NodeUtil
|
2401
|
+
include HaveChildlenMixin
|
2402
|
+
|
2403
|
+
def initialize(parent, klass, name, value)
|
2404
|
+
super(parent)
|
2405
|
+
@name = name
|
2406
|
+
@class_top = klass # .search_class_top
|
2407
|
+
@value = value
|
2408
|
+
|
2409
|
+
if klass.is_a?(ClassTopNode) then
|
2410
|
+
klass.constant_tab[@name] = @value
|
2411
|
+
else
|
2412
|
+
pp klass.class
|
2413
|
+
raise "Not Implemented yet for set constant for dynamic class"
|
2414
|
+
end
|
2415
|
+
end
|
2416
|
+
|
2417
|
+
def traverse_childlen
|
2418
|
+
yield @body
|
2419
|
+
end
|
2420
|
+
|
2421
|
+
def collect_candidate_type(context)
|
2422
|
+
@body.collect_candidate_type(context)
|
2423
|
+
end
|
2424
|
+
|
2425
|
+
def type
|
2426
|
+
@value.type
|
2427
|
+
end
|
2428
|
+
|
2429
|
+
def compile(context)
|
2430
|
+
@body.compile(context)
|
2431
|
+
end
|
1985
2432
|
end
|
1986
2433
|
|
1987
2434
|
# Reference Register
|