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
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
|