ytljit 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/ytljit/vm_codegen.rb
CHANGED
@@ -77,7 +77,7 @@ LO | | | |
|
|
77
77
|
def initialize(tnode)
|
78
78
|
@top_node = tnode
|
79
79
|
@modified_local_var = []
|
80
|
-
@modified_instance_var = {}
|
80
|
+
@modified_instance_var = Hash.new {|hash, key| hash[key] = []}
|
81
81
|
@yield_node = []
|
82
82
|
end
|
83
83
|
|
@@ -103,44 +103,126 @@ LO | | | |
|
|
103
103
|
|
104
104
|
@modified_local_var[-1] = res
|
105
105
|
end
|
106
|
-
|
107
|
-
def merge_instance_var(lvlist)
|
108
|
-
res = nil
|
109
|
-
lvlist.each do |lvs|
|
110
|
-
if res then
|
111
|
-
lvs.each do |name, vall|
|
112
|
-
res[name] = res[name] | vall
|
113
|
-
end
|
114
|
-
else
|
115
|
-
res = lvs.dup
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
@modified_instance_var = res
|
120
|
-
end
|
121
106
|
end
|
122
107
|
|
123
108
|
class TypeInferenceContext
|
124
109
|
def initialize(tnode)
|
125
110
|
@top_node = tnode
|
126
|
-
@current_method_signature_node = []
|
111
|
+
@current_method_signature_node = [[]]
|
112
|
+
@current_method = [tnode]
|
127
113
|
@convergent = false
|
128
114
|
@visited_top_node = {}
|
129
115
|
end
|
130
116
|
|
131
|
-
def to_signature(offset = -1)
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
117
|
+
def to_signature(offset = -1, cache = {})
|
118
|
+
if offset.is_a?(Node::TopNode) then
|
119
|
+
i = -1
|
120
|
+
while @current_method[i] and @current_method[i] != offset
|
121
|
+
i = i - 1
|
122
|
+
end
|
123
|
+
if @current_method[i] == offset then
|
124
|
+
offset = i
|
137
125
|
else
|
138
|
-
|
126
|
+
# This is legal this TopNode has only one signature
|
127
|
+
sigc = offset.signature_cache
|
128
|
+
if sigc.size == 1 then
|
129
|
+
return sigc[0]
|
130
|
+
else
|
131
|
+
raise "I can't type inference..."
|
132
|
+
end
|
139
133
|
end
|
134
|
+
end
|
135
|
+
|
136
|
+
cursignode = @current_method_signature_node[offset]
|
137
|
+
curmethod = @current_method[offset]
|
138
|
+
|
139
|
+
sigc = curmethod.signature_cache
|
140
|
+
if sigc.size == 1 then
|
141
|
+
return sigc[0]
|
142
|
+
end
|
143
|
+
|
144
|
+
if rsig = cache[cursignode] then
|
145
|
+
return rsig
|
146
|
+
end
|
147
|
+
|
148
|
+
if curmethod.is_a?(Node::ClassTopNode) then
|
149
|
+
rsig = to_signature_aux(cursignode, offset, cache)
|
150
|
+
cache[cursignode] = rsig
|
151
|
+
rsig
|
152
|
+
|
153
|
+
elsif curmethod.is_a?(Node::TopNode) then
|
154
|
+
prevsig = to_signature(offset - 1, cache)
|
155
|
+
rsig = to_signature_aux2(curmethod, cursignode,
|
156
|
+
prevsig, offset, cache)
|
157
|
+
cache[cursignode] = rsig
|
158
|
+
rsig
|
159
|
+
|
160
|
+
else
|
161
|
+
raise "Maybe bug"
|
162
|
+
=begin
|
163
|
+
prevsig = to_signature(offset - 1, cache)
|
164
|
+
mt, slf = curmethod.get_send_method_node(prevsig)
|
165
|
+
|
166
|
+
rsig = to_signature_aux2(mt, cursignode, prevsig, offset, cache)
|
167
|
+
cache[cursignode] = rsig
|
168
|
+
return rsig
|
169
|
+
=end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def to_signature_aux(cursignode, offset, cache)
|
174
|
+
res = cursignode.map { |enode|
|
175
|
+
enode.decide_type_once(to_signature(offset - 1, cache))
|
140
176
|
}
|
177
|
+
|
141
178
|
res
|
142
179
|
end
|
143
180
|
|
181
|
+
def to_signature_aux2(mt, args, cursig, offset, cache)
|
182
|
+
res = []
|
183
|
+
args.each do |ele|
|
184
|
+
ele.decide_type_once(cursig)
|
185
|
+
res.push ele.type
|
186
|
+
end
|
187
|
+
|
188
|
+
if mt and (ynode = mt.yield_node[0]) then
|
189
|
+
yargs = ynode.arguments
|
190
|
+
push_signature(args, mt)
|
191
|
+
ysig = to_signature_aux3(yargs, -1, cache)
|
192
|
+
args[1].type = nil
|
193
|
+
args[1].decide_type_once(ysig)
|
194
|
+
res[1] = args[1].type
|
195
|
+
pop_signature
|
196
|
+
end
|
197
|
+
|
198
|
+
res
|
199
|
+
end
|
200
|
+
|
201
|
+
def to_signature_aux3(cursignode, offset, cache)
|
202
|
+
if res = cache[cursignode] then
|
203
|
+
return res
|
204
|
+
end
|
205
|
+
|
206
|
+
res = cursignode.map { |enode|
|
207
|
+
cursignode = @current_method_signature_node[offset]
|
208
|
+
sig = to_signature_aux3(cursignode, offset - 1, cache)
|
209
|
+
enode.decide_type_once(sig)
|
210
|
+
}
|
211
|
+
cache[cursignode] = res
|
212
|
+
|
213
|
+
res
|
214
|
+
end
|
215
|
+
|
216
|
+
def push_signature(signode, method)
|
217
|
+
@current_method_signature_node.push signode
|
218
|
+
@current_method.push method
|
219
|
+
end
|
220
|
+
|
221
|
+
def pop_signature
|
222
|
+
@current_method.pop
|
223
|
+
@current_method_signature_node.pop
|
224
|
+
end
|
225
|
+
|
144
226
|
attr :top_node
|
145
227
|
attr :current_method_signature_node
|
146
228
|
attr_accessor :convergent
|
@@ -159,6 +241,7 @@ LO | | | |
|
|
159
241
|
|
160
242
|
# RETR(EAX, RAX) or RETFR(STO, XM0) or Immdiage object
|
161
243
|
@ret_reg = RETR
|
244
|
+
@ret_reg2 = RETR
|
162
245
|
@ret_node = nil
|
163
246
|
# @depth_reg = {}
|
164
247
|
@depth_reg = Hash.new(0)
|
@@ -179,6 +262,7 @@ LO | | | |
|
|
179
262
|
|
180
263
|
attr :depth_reg
|
181
264
|
attr_accessor :ret_reg
|
265
|
+
attr_accessor :ret_reg2
|
182
266
|
attr_accessor :ret_node
|
183
267
|
|
184
268
|
attr :reg_content
|
@@ -206,8 +290,8 @@ LO | | | |
|
|
206
290
|
cpustack_setn(dst.disp.value / wsiz, val)
|
207
291
|
end
|
208
292
|
else
|
209
|
-
|
210
|
-
|
293
|
+
pp "foo"
|
294
|
+
pp dst
|
211
295
|
end
|
212
296
|
end
|
213
297
|
|
@@ -336,6 +420,17 @@ LO | | | |
|
|
336
420
|
def to_signature(offset = -1)
|
337
421
|
@current_method_signature[offset]
|
338
422
|
end
|
423
|
+
|
424
|
+
def push_signature(signode, method)
|
425
|
+
sig = signode.map { |enode|
|
426
|
+
enode.decide_type_once(to_signature)
|
427
|
+
}
|
428
|
+
@current_method_signature.push sig
|
429
|
+
end
|
430
|
+
|
431
|
+
def pop_signature
|
432
|
+
@current_method_signature.pop
|
433
|
+
end
|
339
434
|
end
|
340
435
|
|
341
436
|
module Node
|
@@ -349,6 +444,7 @@ LO | | | |
|
|
349
444
|
# Make linkage of frame pointer
|
350
445
|
asm.push(BPR)
|
351
446
|
asm.mov(BPR, SPR)
|
447
|
+
asm.push(TMPR)
|
352
448
|
asm.push(BPR)
|
353
449
|
asm.mov(BPR, SPR)
|
354
450
|
end
|
@@ -490,6 +586,7 @@ LO | | | |
|
|
490
586
|
casm.with_retry do
|
491
587
|
dmy, callpos = casm.call_with_arg(fnc, numarg)
|
492
588
|
end
|
589
|
+
context.end_using_reg(fnc)
|
493
590
|
@var_return_address = casm.output_stream.var_base_address(callpos)
|
494
591
|
if context.options[:dump_context] then
|
495
592
|
dump_context(context)
|
@@ -0,0 +1,91 @@
|
|
1
|
+
module YTLJit
|
2
|
+
module VM
|
3
|
+
module Node
|
4
|
+
class CRubyInstanceVarRefNode<InstanceVarRefNode
|
5
|
+
include TypeListWithoutSignature
|
6
|
+
|
7
|
+
def initialize(parent, name)
|
8
|
+
super
|
9
|
+
@current_frame_info = search_frame_info
|
10
|
+
end
|
11
|
+
|
12
|
+
def compile_main(context)
|
13
|
+
slfoff = @current_frame_info.offset_arg(2, BPR)
|
14
|
+
asm = context.assembler
|
15
|
+
ivid = ((@name.object_id << 1) / InternalRubyType::RObject.size)
|
16
|
+
ivarget = OpMemAddress.new(address_of("rb_ivar_get"))
|
17
|
+
asm.with_retry do
|
18
|
+
asm.mov(FUNC_ARG[0], slfoff)
|
19
|
+
asm.mov(FUNC_ARG[1], ivid)
|
20
|
+
asm.call_with_arg(ivarget, 2)
|
21
|
+
end
|
22
|
+
|
23
|
+
context.ret_reg = RETR
|
24
|
+
context.ret_node = self
|
25
|
+
context
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class CRubyInstanceVarAssignNode<InstanceVarAssignNode
|
30
|
+
include TypeListWithoutSignature
|
31
|
+
|
32
|
+
def initialize(parent, name, val)
|
33
|
+
super
|
34
|
+
@current_frame_info = search_frame_info
|
35
|
+
end
|
36
|
+
|
37
|
+
def compile_main(context)
|
38
|
+
slfoff = @current_frame_info.offset_arg(2, BPR)
|
39
|
+
ivid = ((@name.object_id << 1) / InternalRubyType::RObject.size)
|
40
|
+
ivarset = OpMemAddress.new(address_of("rb_ivar_set"))
|
41
|
+
context = @val.compile(context)
|
42
|
+
rtype = @val.decide_type_once(context.to_signature)
|
43
|
+
context = rtype.gen_boxing(context)
|
44
|
+
|
45
|
+
asm = context.assembler
|
46
|
+
asm.with_retry do
|
47
|
+
asm.push(TMPR2)
|
48
|
+
asm.mov(TMPR2, context.ret_reg)
|
49
|
+
asm.mov(FUNC_ARG[0], slfoff)
|
50
|
+
asm.mov(FUNC_ARG[1], ivid)
|
51
|
+
asm.mov(FUNC_ARG[2], TMPR2)
|
52
|
+
asm.call_with_arg(ivarset, 3)
|
53
|
+
asm.pop(TMPR2)
|
54
|
+
end
|
55
|
+
|
56
|
+
context.ret_reg = RETR
|
57
|
+
context.ret_node = self
|
58
|
+
@body.compile(context)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
module YARVTranslatorCRubyObjectMixin
|
64
|
+
include Node
|
65
|
+
|
66
|
+
def visit_getinstancevariable(code, ins, context)
|
67
|
+
curnode = context.current_node
|
68
|
+
node = CRubyInstanceVarRefNode.new(curnode, ins[1])
|
69
|
+
context.expstack.push node
|
70
|
+
end
|
71
|
+
|
72
|
+
def visit_setinstancevariable(code, ins, context)
|
73
|
+
val = context.expstack.pop
|
74
|
+
curnode = context.current_node
|
75
|
+
node = CRubyInstanceVarAssignNode.new(curnode, ins[1], val)
|
76
|
+
if context.expstack[-1] == val then
|
77
|
+
context.expstack[-1] = CRubyInstanceVarRefNode.new(curnode, ins[1])
|
78
|
+
end
|
79
|
+
curnode.body = node
|
80
|
+
context.current_node = node
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class YARVTranslatorCRubyObject<YARVTranslatorBase
|
85
|
+
include YARVTranslatorSimpleMixin
|
86
|
+
include YARVTranslatorCRubyObjectMixin
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
|
@@ -5,16 +5,23 @@ module YTLJit
|
|
5
5
|
def gen_arithmetic_operation(context, inst, tempreg, resreg)
|
6
6
|
context.start_using_reg(tempreg)
|
7
7
|
context = gen_eval_self(context)
|
8
|
+
context.ret_node.type = nil
|
9
|
+
rtype = context.ret_node.decide_type_once(context.to_signature)
|
10
|
+
context = rtype.gen_unboxing(context)
|
8
11
|
asm = context.assembler
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
if context.ret_reg.using(tempreg) then
|
13
|
+
asm.with_retry do
|
14
|
+
asm.mov(TMPR, context.ret_reg)
|
15
|
+
end
|
16
|
+
context.end_using_reg(context.ret_reg)
|
17
|
+
asm.with_retry do
|
18
|
+
asm.mov(tempreg, TMPR)
|
19
|
+
end
|
20
|
+
else
|
21
|
+
asm.with_retry do
|
22
|
+
asm.mov(tempreg, context.ret_reg)
|
23
|
+
end
|
24
|
+
context.end_using_reg(context.ret_reg)
|
18
25
|
end
|
19
26
|
context.set_reg_content(tempreg, context.ret_node)
|
20
27
|
|
@@ -23,8 +30,8 @@ module YTLJit
|
|
23
30
|
# @arguments[3] is other
|
24
31
|
aele = @arguments[3]
|
25
32
|
context = aele.compile(context)
|
26
|
-
context.ret_node.
|
27
|
-
rtype = context.ret_node.
|
33
|
+
context.ret_node.type = nil
|
34
|
+
rtype = context.ret_node.decide_type_once(context.to_signature)
|
28
35
|
context = rtype.gen_unboxing(context)
|
29
36
|
|
30
37
|
asm = context.assembler
|
@@ -53,7 +60,7 @@ module YTLJit
|
|
53
60
|
decide_type_once(context.to_signature)
|
54
61
|
|
55
62
|
if @type.boxed then
|
56
|
-
context = @type.gen_boxing(context)
|
63
|
+
context = @type.to_unbox.gen_boxing(context)
|
57
64
|
end
|
58
65
|
|
59
66
|
context
|
@@ -61,7 +68,8 @@ module YTLJit
|
|
61
68
|
end
|
62
69
|
|
63
70
|
module CompareOperationUtil
|
64
|
-
def gen_compare_operation(context,
|
71
|
+
def gen_compare_operation(context, cinst, sinst,
|
72
|
+
tempreg, tempreg2, resreg)
|
65
73
|
context.start_using_reg(tempreg)
|
66
74
|
asm = context.assembler
|
67
75
|
asm.with_retry do
|
@@ -74,17 +82,17 @@ module YTLJit
|
|
74
82
|
# @arguments[3] is other arg
|
75
83
|
aele = @arguments[3]
|
76
84
|
context = aele.compile(context)
|
77
|
-
context.ret_node.
|
78
|
-
rtype = context.ret_node.
|
85
|
+
context.ret_node.type = nil
|
86
|
+
rtype = context.ret_node.decide_type_once(context.to_signature)
|
79
87
|
context = rtype.gen_unboxing(context)
|
80
88
|
|
81
89
|
asm = context.assembler
|
82
90
|
asm.with_retry do
|
83
|
-
if context.ret_reg !=
|
84
|
-
asm.mov(
|
91
|
+
if context.ret_reg != tempreg2 then
|
92
|
+
asm.mov(tempreg2, context.ret_reg)
|
85
93
|
end
|
86
|
-
asm.
|
87
|
-
asm.send(
|
94
|
+
asm.send(cinst, tempreg2, tempreg)
|
95
|
+
asm.send(sinst, resreg)
|
88
96
|
asm.add(resreg, resreg)
|
89
97
|
end
|
90
98
|
context.end_using_reg(tempreg)
|
data/lib/ytljit/vm_sendnode.rb
CHANGED
@@ -62,13 +62,13 @@ module YTLJit
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
def self.make_send_node(parent, func, arguments, op_flag)
|
65
|
+
def self.make_send_node(parent, func, arguments, op_flag, seqno)
|
66
66
|
spcl = @@special_node_tab[func.name]
|
67
67
|
newobj = nil
|
68
68
|
if spcl then
|
69
|
-
newobj = spcl.new(parent, func, arguments, op_flag)
|
69
|
+
newobj = spcl.new(parent, func, arguments, op_flag, seqno)
|
70
70
|
else
|
71
|
-
newobj = self.new(parent, func, arguments, op_flag)
|
71
|
+
newobj = self.new(parent, func, arguments, op_flag, seqno)
|
72
72
|
end
|
73
73
|
func.parent = newobj
|
74
74
|
arguments.each do |ele|
|
@@ -78,11 +78,12 @@ module YTLJit
|
|
78
78
|
newobj
|
79
79
|
end
|
80
80
|
|
81
|
-
def initialize(parent, func, arguments, op_flag)
|
81
|
+
def initialize(parent, func, arguments, op_flag, seqno)
|
82
82
|
super(parent)
|
83
83
|
@func = func
|
84
84
|
@arguments = arguments
|
85
85
|
@opt_flag = op_flag
|
86
|
+
@seq_no = seqno
|
86
87
|
@var_return_address = nil
|
87
88
|
@next_node = @@current_node
|
88
89
|
@@current_node = self
|
@@ -92,6 +93,9 @@ module YTLJit
|
|
92
93
|
|
93
94
|
@modified_instance_var = nil
|
94
95
|
@modified_local_var = [{}]
|
96
|
+
|
97
|
+
@result_cache = nil
|
98
|
+
@method_signature = []
|
95
99
|
end
|
96
100
|
|
97
101
|
attr_accessor :func
|
@@ -100,27 +104,58 @@ module YTLJit
|
|
100
104
|
attr :var_return_address
|
101
105
|
attr :next_node
|
102
106
|
attr :class_top
|
107
|
+
attr :frame_info
|
103
108
|
attr :modified_local_var
|
104
109
|
attr :modified_instance_var
|
110
|
+
attr_accessor :result_cache
|
111
|
+
attr :seq_no
|
105
112
|
|
106
113
|
def traverse_childlen
|
107
114
|
@arguments.each do |arg|
|
108
115
|
yield arg
|
109
116
|
end
|
110
117
|
yield @func
|
118
|
+
yield @body
|
119
|
+
end
|
120
|
+
|
121
|
+
def get_send_method_node(cursig)
|
122
|
+
mt = nil
|
123
|
+
@arguments[2].decide_type_once(cursig)
|
124
|
+
slf = @arguments[2].type
|
125
|
+
if slf.instance_of?(RubyType::DefaultType0) then
|
126
|
+
# Chaos
|
127
|
+
end
|
128
|
+
|
129
|
+
if is_fcall or is_vcall then
|
130
|
+
mt = @func.method_top_node(@class_top, nil)
|
131
|
+
|
132
|
+
else
|
133
|
+
|
134
|
+
mt = @func.method_top_node(@class_top, slf)
|
135
|
+
end
|
136
|
+
|
137
|
+
[mt, slf]
|
111
138
|
end
|
112
139
|
|
113
140
|
def collect_candidate_type_regident(context, slf)
|
114
141
|
context
|
115
142
|
end
|
116
143
|
|
144
|
+
# This is for reduce method call whose all arguments is constant.
|
145
|
+
# But all methods can't apply because the method may have side
|
146
|
+
# effect.
|
147
|
+
def fill_result_cache(context)
|
148
|
+
context
|
149
|
+
end
|
150
|
+
|
117
151
|
def collect_info(context)
|
118
|
-
|
119
|
-
context =
|
120
|
-
|
152
|
+
@arguments.each do |arg|
|
153
|
+
context = arg.collect_info(context)
|
154
|
+
end
|
155
|
+
context = @func.collect_info(context)
|
121
156
|
if is_fcall or is_vcall then
|
122
157
|
# Call method of same class
|
123
|
-
mt = @class_top.
|
158
|
+
mt = @class_top.get_method_tab[@func.name]
|
124
159
|
if mt then
|
125
160
|
miv = mt.modified_instance_var
|
126
161
|
if miv then
|
@@ -131,13 +166,59 @@ module YTLJit
|
|
131
166
|
end
|
132
167
|
end
|
133
168
|
|
134
|
-
@modified_local_var = context.modified_local_var.dup
|
169
|
+
@modified_local_var = context.modified_local_var.last.dup
|
135
170
|
@modified_instance_var = context.modified_instance_var.dup
|
136
171
|
|
172
|
+
context = fill_result_cache(context)
|
173
|
+
|
137
174
|
@body.collect_info(context)
|
138
175
|
end
|
139
176
|
|
177
|
+
def search_signature(cursig)
|
178
|
+
metsigent = nil
|
179
|
+
@method_signature.each do |tabent|
|
180
|
+
if cursig == tabent[0] then
|
181
|
+
metsigent = tabent
|
182
|
+
end
|
183
|
+
end
|
184
|
+
metsigent
|
185
|
+
end
|
186
|
+
|
187
|
+
def check_signature_changed(context, signat, metsigent, cursig)
|
188
|
+
if metsigent then
|
189
|
+
if metsigent[1][1] != signat[1] then
|
190
|
+
if metsigent[1][1].ruby_type < signat[1].ruby_type then
|
191
|
+
signat[1] = metsigent[1][1]
|
192
|
+
false
|
193
|
+
else
|
194
|
+
type_list(cursig)[1] = []
|
195
|
+
ti_reset
|
196
|
+
ti_del_link
|
197
|
+
context.convergent = false
|
198
|
+
metsigent[1] = signat
|
199
|
+
true
|
200
|
+
end
|
201
|
+
else
|
202
|
+
false
|
203
|
+
end
|
204
|
+
else
|
205
|
+
# Why not push, because it excepted type inference about
|
206
|
+
# this signature after. So reduce search loop.
|
207
|
+
@method_signature.unshift [cursig, signat]
|
208
|
+
false
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
140
212
|
def collect_candidate_type(context)
|
213
|
+
cursig = context.to_signature
|
214
|
+
|
215
|
+
# get saved original signature
|
216
|
+
metsigent = search_signature(cursig)
|
217
|
+
oldsignat = nil
|
218
|
+
if metsigent then
|
219
|
+
oldsignat = metsigent[1]
|
220
|
+
end
|
221
|
+
|
141
222
|
# prev env
|
142
223
|
context = @arguments[0].collect_candidate_type(context)
|
143
224
|
|
@@ -153,48 +234,32 @@ module YTLJit
|
|
153
234
|
context = @func.collect_candidate_type(context)
|
154
235
|
|
155
236
|
signat = signature(context)
|
156
|
-
|
157
|
-
if is_fcall or is_vcall then
|
158
|
-
mt = @func.method_top_node(@class_top, nil)
|
159
|
-
else
|
160
|
-
@arguments[2].decide_type_once(context.to_signature)
|
161
|
-
slf = @arguments[2].type
|
162
|
-
if slf.instance_of?(RubyType::DefaultType0) then
|
163
|
-
# Chaos
|
237
|
+
check_signature_changed(context, signat, metsigent, cursig)
|
164
238
|
|
165
|
-
|
166
|
-
mt = @func.method_top_node(@class_top, slf)
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
239
|
+
mt, slf = get_send_method_node(cursig)
|
170
240
|
if mt then
|
171
|
-
same_type(self, mt,
|
172
|
-
same_type(mt, self, signat,
|
173
|
-
|
174
|
-
context.current_method_signature_node.push @arguments
|
175
|
-
mt.yield_node.map do |ynode|
|
176
|
-
yargs = ynode.arguments
|
177
|
-
ysignat = ynode.signature(context)
|
178
|
-
same_type(blknode, ynode, ysignat, signat, context)
|
179
|
-
same_type(ynode, blknode, signat, ysignat, context)
|
180
|
-
end
|
181
|
-
context.current_method_signature_node.pop
|
241
|
+
same_type(self, mt, cursig, signat, context)
|
242
|
+
same_type(mt, self, signat, cursig, context)
|
182
243
|
|
183
244
|
context = mt.collect_candidate_type(context, @arguments, signat)
|
184
245
|
|
185
|
-
context.
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
246
|
+
context.push_signature(@arguments, mt)
|
247
|
+
if blknode.is_a?(TopNode) then
|
248
|
+
# Have block
|
249
|
+
mt.yield_node.map do |ynode|
|
250
|
+
yargs = ynode.arguments
|
251
|
+
ysignat = ynode.signature(context)
|
252
|
+
|
253
|
+
same_type(ynode, blknode, signat, ysignat, context)
|
191
254
|
context = blknode.collect_candidate_type(context,
|
192
255
|
yargs, ysignat)
|
193
|
-
|
194
|
-
context = blknode.collect_candidate_type(context)
|
256
|
+
|
195
257
|
end
|
258
|
+
else
|
259
|
+
context = blknode.collect_candidate_type(context)
|
196
260
|
end
|
197
|
-
context.
|
261
|
+
context.pop_signature
|
262
|
+
|
198
263
|
else
|
199
264
|
context = collect_candidate_type_regident(context, slf)
|
200
265
|
end
|
@@ -234,33 +299,93 @@ module YTLJit
|
|
234
299
|
context = @body.compile(context)
|
235
300
|
context
|
236
301
|
end
|
302
|
+
|
303
|
+
def get_constant_value
|
304
|
+
if @result_cache then
|
305
|
+
[@result_cache]
|
306
|
+
else
|
307
|
+
nil
|
308
|
+
end
|
309
|
+
end
|
237
310
|
end
|
238
311
|
|
239
312
|
class SendCoreDefineMethodNode<SendNode
|
240
313
|
add_special_send_node :"core#define_method"
|
241
|
-
def initialize(parent, func, arguments, op_flag)
|
314
|
+
def initialize(parent, func, arguments, op_flag, seqno)
|
315
|
+
super
|
316
|
+
@new_method = arguments[5]
|
317
|
+
if arguments[4].is_a?(LiteralNode) then
|
318
|
+
@new_method.name = arguments[4].value
|
319
|
+
@class_top.get_method_tab[arguments[4].value] = @new_method
|
320
|
+
else
|
321
|
+
raise "Not supported not literal method name"
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
def traverse_childlen
|
326
|
+
yield @body
|
327
|
+
yield @new_method
|
328
|
+
end
|
329
|
+
|
330
|
+
def collect_info(context)
|
331
|
+
context = @new_method.collect_info(context)
|
332
|
+
@body.collect_info(context)
|
333
|
+
end
|
334
|
+
|
335
|
+
def collect_candidate_type(context)
|
336
|
+
# type inference of @new method execute when "send" instruction.
|
337
|
+
@body.collect_candidate_type(context)
|
338
|
+
context
|
339
|
+
end
|
340
|
+
|
341
|
+
def compile(context)
|
342
|
+
context = @body.compile(context)
|
343
|
+
ocs = context.code_space
|
344
|
+
# Allocate new code space in compiling @new_method
|
345
|
+
context = @new_method.compile(context)
|
346
|
+
context.set_code_space(ocs)
|
347
|
+
|
348
|
+
context.ret_reg = 4 # nil
|
349
|
+
context.ret_node = self
|
350
|
+
|
351
|
+
context
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
class SendCoreDefineSigletonMethodNode<SendNode
|
356
|
+
add_special_send_node :"core#define_singleton_method"
|
357
|
+
|
358
|
+
def initialize(parent, func, arguments, op_flag, seqno)
|
242
359
|
super
|
243
360
|
@new_method = arguments[5]
|
244
361
|
if arguments[4].is_a?(LiteralNode) then
|
245
362
|
@new_method.name = arguments[4].value
|
246
|
-
@class_top.
|
363
|
+
@class_top.make_klassclass_node
|
247
364
|
else
|
248
365
|
raise "Not supported not literal method name"
|
249
366
|
end
|
250
367
|
end
|
251
368
|
|
252
369
|
def traverse_childlen
|
370
|
+
yield @arguments[3]
|
253
371
|
yield @body
|
254
372
|
yield @new_method
|
255
373
|
end
|
256
374
|
|
257
375
|
def collect_info(context)
|
376
|
+
context = @arguments[3].collect_info(context)
|
258
377
|
context = @new_method.collect_info(context)
|
259
378
|
@body.collect_info(context)
|
260
379
|
end
|
261
380
|
|
262
381
|
def collect_candidate_type(context)
|
263
382
|
# type inference of @new method execute when "send" instruction.
|
383
|
+
context = @arguments[3].collect_candidate_type(context)
|
384
|
+
@arguments[3].decide_type_once(context.to_signature)
|
385
|
+
rrtype = class << @arguments[3].type.ruby_type; self; end
|
386
|
+
clsnode = ClassTopNode.get_class_top_node(rrtype)
|
387
|
+
clsnode.get_method_tab[@new_method.name] = @new_method
|
388
|
+
|
264
389
|
@body.collect_candidate_type(context)
|
265
390
|
context
|
266
391
|
end
|
@@ -284,12 +409,14 @@ module YTLJit
|
|
284
409
|
if slf.ruby_type.is_a?(Class) then
|
285
410
|
case slfnode
|
286
411
|
when ConstantRefNode
|
287
|
-
|
412
|
+
clstop = slfnode.value_node
|
413
|
+
case clstop
|
288
414
|
when ClassTopNode
|
289
|
-
clstop = slfnode.value_node
|
290
415
|
tt = RubyType::BaseType.from_ruby_class(clstop.klass_object)
|
291
|
-
|
292
|
-
|
416
|
+
add_type(context.to_signature, tt)
|
417
|
+
when LiteralNode
|
418
|
+
tt = RubyType::BaseType.from_ruby_class(clstop.value)
|
419
|
+
add_type(context.to_signature, tt)
|
293
420
|
else
|
294
421
|
raise "Unkown node type in constant #{slfnode.value_node.class}"
|
295
422
|
end
|
@@ -321,12 +448,7 @@ module YTLJit
|
|
321
448
|
context = compile_ytl(context)
|
322
449
|
end
|
323
450
|
|
324
|
-
|
325
|
-
asm = context.assembler
|
326
|
-
asm.with_retry do
|
327
|
-
asm.mov(RETR, TMPR3)
|
328
|
-
end
|
329
|
-
context.ret_reg = RETR
|
451
|
+
context.ret_reg = RETR
|
330
452
|
context.ret_node = self
|
331
453
|
context.end_using_reg(TMPR3)
|
332
454
|
context.end_using_reg(TMPR2)
|
@@ -339,15 +461,17 @@ module YTLJit
|
|
339
461
|
class SendNewNode<SendNode
|
340
462
|
add_special_send_node :new
|
341
463
|
|
342
|
-
def initialize(parent, func, arguments, op_flag)
|
464
|
+
def initialize(parent, func, arguments, op_flag, seqno)
|
343
465
|
super
|
344
466
|
allocfunc = MethodSelectNode.new(self, :allocate)
|
345
|
-
alloc = SendNode.make_send_node(self, allocfunc,
|
467
|
+
alloc = SendNode.make_send_node(self, allocfunc,
|
468
|
+
arguments[0, 3], 0, seqno)
|
346
469
|
allocfunc.set_reciever(alloc)
|
347
470
|
initfunc = MethodSelectNode.new(self, :initialize)
|
348
471
|
initarg = arguments.dup
|
349
472
|
initarg[2] = alloc
|
350
|
-
init = SendNode.make_send_node(self, initfunc,
|
473
|
+
init = SendNode.make_send_node(self, initfunc,
|
474
|
+
initarg, op_flag, seqno)
|
351
475
|
initfunc.set_reciever(init)
|
352
476
|
alloc.parent = init
|
353
477
|
@initmethod = init
|
@@ -359,20 +483,26 @@ module YTLJit
|
|
359
483
|
end
|
360
484
|
yield @func
|
361
485
|
yield @initmethod
|
486
|
+
yield @body
|
362
487
|
end
|
363
488
|
|
364
489
|
def collect_candidate_type_regident(context, slf)
|
365
490
|
slfnode = @arguments[2]
|
491
|
+
|
366
492
|
if slf.ruby_type.is_a?(Class) then
|
367
493
|
case slfnode
|
368
494
|
when ConstantRefNode
|
369
495
|
context = @initmethod.collect_candidate_type(context)
|
370
|
-
|
496
|
+
clstop = slfnode.value_node
|
497
|
+
case clstop
|
371
498
|
when ClassTopNode
|
372
|
-
clstop = slfnode.value_node
|
373
499
|
tt = RubyType::BaseType.from_ruby_class(clstop.klass_object)
|
374
|
-
|
500
|
+
add_type(context.to_signature, tt)
|
375
501
|
|
502
|
+
when LiteralNode
|
503
|
+
tt = RubyType::BaseType.from_ruby_class(clstop.value)
|
504
|
+
add_type(context.to_signature, tt)
|
505
|
+
|
376
506
|
else
|
377
507
|
raise "Unkown node type in constant #{slfnode.value_node.class}"
|
378
508
|
end
|
@@ -389,7 +519,8 @@ module YTLJit
|
|
389
519
|
rtype = @arguments[2].type
|
390
520
|
rrtype = rtype.ruby_type
|
391
521
|
if rrtype.is_a?(Class) then
|
392
|
-
@initmethod.compile(context)
|
522
|
+
context = @initmethod.compile(context)
|
523
|
+
@body.compile(context)
|
393
524
|
else
|
394
525
|
super
|
395
526
|
end
|
@@ -404,14 +535,11 @@ module YTLJit
|
|
404
535
|
def collect_candidate_type_regident(context, slf)
|
405
536
|
case [slf.ruby_type]
|
406
537
|
when [Fixnum], [Float], [String], [Array]
|
407
|
-
|
408
|
-
|
409
|
-
same_type(@arguments[2], @arguments[3],
|
410
|
-
|
411
|
-
same_type(
|
412
|
-
context.to_signature, context.to_signature, context)
|
413
|
-
same_type(@arguments[2], self,
|
414
|
-
context.to_signature, context.to_signature, context)
|
538
|
+
cursig = context.to_signature
|
539
|
+
same_type(@arguments[3], @arguments[2], cursig, cursig, context)
|
540
|
+
same_type(@arguments[2], @arguments[3], cursig, cursig, context)
|
541
|
+
same_type(self, @arguments[2], cursig, cursig, context)
|
542
|
+
same_type(@arguments[2], self, cursig, cursig, context)
|
415
543
|
end
|
416
544
|
|
417
545
|
context
|
@@ -427,7 +555,6 @@ module YTLJit
|
|
427
555
|
return super(context)
|
428
556
|
end
|
429
557
|
|
430
|
-
context.current_method_signature.push signature(context)
|
431
558
|
if rrtype == Fixnum then
|
432
559
|
context = gen_arithmetic_operation(context, :add, TMPR2, TMPR)
|
433
560
|
elsif rrtype == Float then
|
@@ -435,7 +562,7 @@ module YTLJit
|
|
435
562
|
else
|
436
563
|
raise "Unkown method #{rtype.ruby_type}##{@func.name}"
|
437
564
|
end
|
438
|
-
|
565
|
+
|
439
566
|
@body.compile(context)
|
440
567
|
end
|
441
568
|
#=end
|
@@ -449,14 +576,11 @@ module YTLJit
|
|
449
576
|
def collect_candidate_type_regident(context, slf)
|
450
577
|
case [slf.ruby_type]
|
451
578
|
when [Fixnum], [Float], [Array]
|
452
|
-
|
453
|
-
|
454
|
-
same_type(@arguments[2], @arguments[3],
|
455
|
-
|
456
|
-
same_type(
|
457
|
-
context.to_signature, context.to_signature, context)
|
458
|
-
same_type(@arguments[2], self,
|
459
|
-
context.to_signature, context.to_signature, context)
|
579
|
+
cursig = context.to_signature
|
580
|
+
same_type(@arguments[3], @arguments[2], cursig, cursig, context)
|
581
|
+
same_type(@arguments[2], @arguments[3], cursig, cursig, context)
|
582
|
+
same_type(self, @arguments[2], cursig, cursig, context)
|
583
|
+
same_type(@arguments[2], self, cursig, cursig, context)
|
460
584
|
end
|
461
585
|
|
462
586
|
context
|
@@ -471,7 +595,6 @@ module YTLJit
|
|
471
595
|
return super(context)
|
472
596
|
end
|
473
597
|
|
474
|
-
context.current_method_signature.push signature(context)
|
475
598
|
if rrtype == Fixnum then
|
476
599
|
context = gen_arithmetic_operation(context, :sub, TMPR2, TMPR)
|
477
600
|
elsif rrtype == Float then
|
@@ -480,7 +603,6 @@ module YTLJit
|
|
480
603
|
raise "Unkown method #{rtype.ruby_type}##{@func.name}"
|
481
604
|
end
|
482
605
|
|
483
|
-
context.current_method_signature.pop
|
484
606
|
@body.compile(context)
|
485
607
|
end
|
486
608
|
end
|
@@ -491,22 +613,17 @@ module YTLJit
|
|
491
613
|
add_special_send_node :*
|
492
614
|
|
493
615
|
def collect_candidate_type_regident(context, slf)
|
616
|
+
cursig = context.to_signature
|
494
617
|
case [slf.ruby_type]
|
495
618
|
when [Fixnum], [Float]
|
496
|
-
same_type(@arguments[3], @arguments[2],
|
497
|
-
|
498
|
-
same_type(@arguments[2],
|
499
|
-
|
500
|
-
same_type(self, @arguments[2],
|
501
|
-
context.to_signature, context.to_signature, context)
|
502
|
-
same_type(@arguments[2], self,
|
503
|
-
context.to_signature, context.to_signature, context)
|
619
|
+
same_type(@arguments[3], @arguments[2], cursig, cursig, context)
|
620
|
+
same_type(@arguments[2], @arguments[3], cursig, cursig, context)
|
621
|
+
same_type(self, @arguments[2], cursig, cursig, context)
|
622
|
+
same_type(@arguments[2], self, cursig, cursig, context)
|
504
623
|
|
505
624
|
when [String]
|
506
|
-
same_type(self, @arguments[2],
|
507
|
-
|
508
|
-
same_type(@arguments[2], self,
|
509
|
-
context.to_signature, context.to_signature, context)
|
625
|
+
same_type(self, @arguments[2], cursig, cursig, context)
|
626
|
+
same_type(@arguments[2], self, cursig, cursig, context)
|
510
627
|
@arguments[3].add_type(context.to_signature, fixtype)
|
511
628
|
end
|
512
629
|
|
@@ -523,16 +640,24 @@ module YTLJit
|
|
523
640
|
return super(context)
|
524
641
|
end
|
525
642
|
|
526
|
-
context.current_method_signature.push signature(context)
|
527
643
|
if rrtype == Fixnum then
|
528
644
|
context = gen_arithmetic_operation(context, :imul, TMPR2,
|
529
645
|
TMPR) do |context|
|
530
646
|
asm = context.assembler
|
531
|
-
|
532
|
-
asm.
|
533
|
-
|
534
|
-
|
647
|
+
if context.ret_reg.is_a?(OpRegistor) then
|
648
|
+
asm.with_retry do
|
649
|
+
asm.push(context.ret_reg)
|
650
|
+
asm.mov(DBLLOR, TMPR2)
|
651
|
+
asm.imul(INDIRECT_SPR)
|
652
|
+
asm.add(SPR, AsmType::MACHINE_WORD.size)
|
653
|
+
end
|
654
|
+
else
|
655
|
+
asm.with_retry do
|
656
|
+
asm.mov(DBLLOR, TMPR2)
|
657
|
+
asm.imul(context.ret_reg)
|
658
|
+
end
|
535
659
|
end
|
660
|
+
context.end_using_reg(context.ret_reg)
|
536
661
|
end
|
537
662
|
|
538
663
|
elsif rrtype == Float then
|
@@ -541,7 +666,6 @@ module YTLJit
|
|
541
666
|
raise "Unkown method #{rtype.ruby_type}##{@func.name}"
|
542
667
|
end
|
543
668
|
|
544
|
-
context.current_method_signature.pop
|
545
669
|
@body.compile(context)
|
546
670
|
end
|
547
671
|
end
|
@@ -554,14 +678,11 @@ module YTLJit
|
|
554
678
|
def collect_candidate_type_regident(context, slf)
|
555
679
|
case [slf.ruby_type]
|
556
680
|
when [Fixnum], [Float]
|
557
|
-
|
558
|
-
|
559
|
-
same_type(@arguments[2], @arguments[3],
|
560
|
-
|
561
|
-
same_type(
|
562
|
-
context.to_signature, context.to_signature, context)
|
563
|
-
same_type(@arguments[2], self,
|
564
|
-
context.to_signature, context.to_signature, context)
|
681
|
+
cursig = context.to_signature
|
682
|
+
same_type(@arguments[3], @arguments[2], cursig, cursig, context)
|
683
|
+
same_type(@arguments[2], @arguments[3], cursig, cursig, context)
|
684
|
+
same_type(self, @arguments[2], cursig, cursig, context)
|
685
|
+
same_type(@arguments[2], self, cursig, cursig, context)
|
565
686
|
end
|
566
687
|
|
567
688
|
context
|
@@ -577,15 +698,22 @@ module YTLJit
|
|
577
698
|
return super(context)
|
578
699
|
end
|
579
700
|
|
580
|
-
context.current_method_signature.push signature(context)
|
581
701
|
if rrtype == Fixnum then
|
582
|
-
context = gen_arithmetic_operation(context,
|
702
|
+
context = gen_arithmetic_operation(context, nil, TMPR2,
|
583
703
|
TMPR) do |context|
|
584
704
|
asm = context.assembler
|
585
705
|
asm.with_retry do
|
586
|
-
|
587
|
-
|
588
|
-
|
706
|
+
if context.ret_reg == TMPR then
|
707
|
+
asm.push(TMPR)
|
708
|
+
asm.mov(DBLLOR, TMPR2)
|
709
|
+
asm.cdq
|
710
|
+
asm.idiv(INDIRECT_SPR)
|
711
|
+
asm.add(SPR, AsmType::MACHINE_WORD.size)
|
712
|
+
else
|
713
|
+
asm.mov(DBLLOR, TMPR2)
|
714
|
+
asm.cdq
|
715
|
+
asm.idiv(context.ret_reg)
|
716
|
+
end
|
589
717
|
asm.and(DBLHIR, DBLHIR)
|
590
718
|
asm.setnz(DBLHIR)
|
591
719
|
asm.neg(DBLHIR)
|
@@ -602,22 +730,36 @@ module YTLJit
|
|
602
730
|
raise "Unkown method #{rtype.ruby_type}##{@func.name}"
|
603
731
|
end
|
604
732
|
|
605
|
-
context.current_method_signature.pop
|
606
733
|
@body.compile(context)
|
607
734
|
end
|
608
735
|
end
|
609
736
|
|
610
737
|
class SendCompareNode<SendNode
|
611
738
|
include SendUtil
|
739
|
+
include CompareOperationUtil
|
612
740
|
def collect_candidate_type_regident(context, slf)
|
613
|
-
|
614
|
-
|
615
|
-
same_type(@arguments[2], @arguments[3],
|
616
|
-
|
617
|
-
tt
|
618
|
-
|
619
|
-
tt
|
620
|
-
|
741
|
+
cursig = context.to_signature
|
742
|
+
same_type(@arguments[3], @arguments[2], cursig, cursig, context)
|
743
|
+
same_type(@arguments[2], @arguments[3], cursig, cursig, context)
|
744
|
+
tt = RubyType::BaseType.from_object(true)
|
745
|
+
add_type(cursig, tt)
|
746
|
+
tt = RubyType::BaseType.from_object(false)
|
747
|
+
add_type(cursig, tt)
|
748
|
+
|
749
|
+
context
|
750
|
+
end
|
751
|
+
|
752
|
+
def commmon_compile_compare(context, rtype, fixcmp, flocmp)
|
753
|
+
rrtype = rtype.ruby_type
|
754
|
+
if rrtype == Fixnum then
|
755
|
+
context = gen_compare_operation(context, :cmp, fixcmp,
|
756
|
+
TMPR2, TMPR, RETR)
|
757
|
+
elsif rrtype == Float then
|
758
|
+
context = gen_compare_operation(context, :comisd, flocmp,
|
759
|
+
XMM4, XMM0, RETR)
|
760
|
+
else
|
761
|
+
raise "Unkowwn type #{rtype}"
|
762
|
+
end
|
621
763
|
|
622
764
|
context
|
623
765
|
end
|
@@ -631,47 +773,49 @@ module YTLJit
|
|
631
773
|
return super(context)
|
632
774
|
end
|
633
775
|
|
634
|
-
context.current_method_signature.push signature(context)
|
635
776
|
context = gen_eval_self(context)
|
777
|
+
context.ret_node.type = nil
|
778
|
+
srtype = context.ret_node.decide_type_once(context.to_signature)
|
779
|
+
context = srtype.gen_unboxing(context)
|
636
780
|
if rrtype == Fixnum then
|
637
|
-
context = compile_compare(context)
|
781
|
+
context = compile_compare(context, rtype)
|
782
|
+
|
783
|
+
elsif rrtype == Float then
|
784
|
+
context = compile_compare(context, rtype)
|
785
|
+
|
638
786
|
else
|
639
787
|
raise "Unkown method #{rtype.ruby_type} #{@func.name}"
|
640
788
|
end
|
641
|
-
|
789
|
+
|
642
790
|
@body.compile(context)
|
643
791
|
end
|
644
792
|
end
|
645
793
|
|
646
794
|
class SendGtNode<SendCompareNode
|
647
|
-
include CompareOperationUtil
|
648
795
|
add_special_send_node :<
|
649
|
-
def compile_compare(context)
|
650
|
-
|
796
|
+
def compile_compare(context, rtype)
|
797
|
+
commmon_compile_compare(context, rtype, :setg, :seta)
|
651
798
|
end
|
652
799
|
end
|
653
800
|
|
654
801
|
class SendGeNode<SendCompareNode
|
655
|
-
include CompareOperationUtil
|
656
802
|
add_special_send_node :<=
|
657
|
-
def compile_compare(context)
|
658
|
-
|
803
|
+
def compile_compare(context, rtype)
|
804
|
+
commmon_compile_compare(context, rtype, :setge, :setae)
|
659
805
|
end
|
660
806
|
end
|
661
807
|
|
662
808
|
class SendLtNode<SendCompareNode
|
663
|
-
include CompareOperationUtil
|
664
809
|
add_special_send_node :>
|
665
|
-
def compile_compare(context)
|
666
|
-
|
810
|
+
def compile_compare(context, rtype)
|
811
|
+
commmon_compile_compare(context, rtype, :setl, :setb)
|
667
812
|
end
|
668
813
|
end
|
669
814
|
|
670
815
|
class SendLeNode<SendCompareNode
|
671
|
-
include CompareOperationUtil
|
672
816
|
add_special_send_node :>=
|
673
|
-
def compile_compare(context)
|
674
|
-
|
817
|
+
def compile_compare(context, rtype)
|
818
|
+
commmon_compile_compare(context, rtype, :setle, :setbe)
|
675
819
|
end
|
676
820
|
end
|
677
821
|
|
@@ -698,6 +842,9 @@ module YTLJit
|
|
698
842
|
|
699
843
|
when [Hash]
|
700
844
|
@arguments[2].add_element_node(context.to_signature, self, context)
|
845
|
+
|
846
|
+
else
|
847
|
+
raise "Unkown type #{slf.ruby_type} in :[]"
|
701
848
|
end
|
702
849
|
|
703
850
|
context
|
@@ -733,6 +880,139 @@ module YTLJit
|
|
733
880
|
context
|
734
881
|
end
|
735
882
|
end
|
883
|
+
|
884
|
+
class SendToFNode<SendNode
|
885
|
+
add_special_send_node :to_f
|
886
|
+
def collect_candidate_type_regident(context, slf)
|
887
|
+
sig = context.to_signature
|
888
|
+
floattype = RubyType::BaseType.from_ruby_class(Float)
|
889
|
+
floattype = floattype.to_box
|
890
|
+
add_type(sig, floattype)
|
891
|
+
context
|
892
|
+
end
|
893
|
+
end
|
894
|
+
|
895
|
+
class SendToINode<SendNode
|
896
|
+
add_special_send_node :to_i
|
897
|
+
def collect_candidate_type_regident(context, slf)
|
898
|
+
sig = context.to_signature
|
899
|
+
fixnumtype = RubyType::BaseType.from_ruby_class(Fixnum)
|
900
|
+
fixnumtype = fixnumtype.to_box
|
901
|
+
add_type(sig, fixnumtype)
|
902
|
+
context
|
903
|
+
end
|
904
|
+
end
|
905
|
+
|
906
|
+
class SendAMNode<SendNode
|
907
|
+
add_special_send_node :-@
|
908
|
+
def collect_candidate_type_regident(context, slf)
|
909
|
+
sig = context.to_signature
|
910
|
+
same_type(self, @arguments[2], sig, sig, context)
|
911
|
+
context
|
912
|
+
end
|
913
|
+
end
|
914
|
+
|
915
|
+
class SendRandNode<SendNode
|
916
|
+
add_special_send_node :rand
|
917
|
+
def collect_candidate_type_regident(context, slf)
|
918
|
+
sig = context.to_signature
|
919
|
+
floattype = RubyType::BaseType.from_ruby_class(Float)
|
920
|
+
add_type(sig, floattype)
|
921
|
+
context
|
922
|
+
end
|
923
|
+
end
|
924
|
+
|
925
|
+
class SendSameArgTypeNode<SendNode
|
926
|
+
def collect_candidate_type_regident(context, slf)
|
927
|
+
sig = context.to_signature
|
928
|
+
same_type(self, @arguments[3], sig, sig, context)
|
929
|
+
context
|
930
|
+
end
|
931
|
+
end
|
932
|
+
|
933
|
+
class SendPNode<SendSameArgTypeNode
|
934
|
+
add_special_send_node :p
|
935
|
+
end
|
936
|
+
|
937
|
+
class SendMathFuncNode<SendNode
|
938
|
+
include SendUtil
|
939
|
+
def collect_candidate_type_regident(context, slf)
|
940
|
+
sig = context.to_signature
|
941
|
+
floattype = RubyType::BaseType.from_ruby_class(Float)
|
942
|
+
add_type(sig, floattype)
|
943
|
+
context
|
944
|
+
end
|
945
|
+
|
946
|
+
def compile_call_func(context, fname)
|
947
|
+
fadd = address_of(fname)
|
948
|
+
asm = context.assembler
|
949
|
+
asm.with_retry do
|
950
|
+
asm.mov(FUNC_FLOAT_ARG[0], context.ret_reg)
|
951
|
+
asm.call_with_arg(fadd, 1)
|
952
|
+
asm.sub(SPR, 8)
|
953
|
+
asm.fstpl(INDIRECT_SPR)
|
954
|
+
asm.pop(XMM0)
|
955
|
+
end
|
956
|
+
context
|
957
|
+
end
|
958
|
+
|
959
|
+
def compile(context)
|
960
|
+
@arguments[2].decide_type_once(context.to_signature)
|
961
|
+
rtype = @arguments[2].type
|
962
|
+
rrtype = rtype.ruby_type
|
963
|
+
if rtype.ruby_type.is_a?(RubyType::DefaultType0) or
|
964
|
+
@class_top.search_method_with_super(@func.name, rrtype)[0] then
|
965
|
+
return super(context)
|
966
|
+
end
|
967
|
+
|
968
|
+
@arguments[3].decide_type_once(context.to_signature)
|
969
|
+
rtype = @arguments[3].type
|
970
|
+
rrtype = rtype.ruby_type
|
971
|
+
context = @arguments[3].compile(context)
|
972
|
+
context = rtype.gen_unboxing(context)
|
973
|
+
compile_main(context)
|
974
|
+
end
|
975
|
+
end
|
976
|
+
|
977
|
+
class SendSqrtNode < SendMathFuncNode
|
978
|
+
add_special_send_node :sqrt
|
979
|
+
def compile_main(context)
|
980
|
+
context = compile_call_func(context, "sqrt")
|
981
|
+
context.ret_node = self
|
982
|
+
context.ret_reg = XMM0
|
983
|
+
context
|
984
|
+
end
|
985
|
+
end
|
986
|
+
|
987
|
+
class SendSinNode < SendMathFuncNode
|
988
|
+
add_special_send_node :sin
|
989
|
+
def compile_main(context)
|
990
|
+
context = compile_call_func(context, "sin")
|
991
|
+
context.ret_node = self
|
992
|
+
context.ret_reg = XMM0
|
993
|
+
context
|
994
|
+
end
|
995
|
+
end
|
996
|
+
|
997
|
+
class SendCosNode < SendMathFuncNode
|
998
|
+
add_special_send_node :cos
|
999
|
+
def compile_main(context)
|
1000
|
+
context = compile_call_func(context, "cos")
|
1001
|
+
context.ret_node = self
|
1002
|
+
context.ret_reg = XMM0
|
1003
|
+
context
|
1004
|
+
end
|
1005
|
+
end
|
1006
|
+
|
1007
|
+
class SendTanNode < SendMathFuncNode
|
1008
|
+
add_special_send_node :tan
|
1009
|
+
def compile_main(context)
|
1010
|
+
context = compile_call_func(context, "tan")
|
1011
|
+
context.ret_node = self
|
1012
|
+
context.ret_reg = XMM0
|
1013
|
+
context
|
1014
|
+
end
|
1015
|
+
end
|
736
1016
|
end
|
737
1017
|
end
|
738
1018
|
end
|