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.
@@ -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
- cursig = @current_method_signature_node[offset]
133
- res = cursig.map { |enode|
134
- if enode.is_a?(Node::BaseNode) then
135
- enode.decide_type_once(to_signature(offset - 1))
136
- enode.type
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
- enode
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
- p "foo"
210
- p dst
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
- asm.with_retry do
10
- if context.ret_reg.using(tempreg) then
11
- asm.mov(TMPR, context.ret_reg)
12
- context.end_using_reg(context.ret_reg)
13
- asm.mov(tempreg, TMPR)
14
- else
15
- asm.mov(tempreg, context.ret_reg)
16
- context.end_using_reg(context.ret_reg)
17
- end
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.decide_type_once(context.to_signature)
27
- rtype = context.ret_node.type
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, inst, tempreg, resreg)
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.decide_type_once(context.to_signature)
78
- rtype = context.ret_node.type
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 != resreg then
84
- asm.mov(resreg, context.ret_reg)
91
+ if context.ret_reg != tempreg2 then
92
+ asm.mov(tempreg2, context.ret_reg)
85
93
  end
86
- asm.cmp(resreg, tempreg)
87
- asm.send(inst, resreg)
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)
@@ -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
- traverse_childlen {|rec|
119
- context = rec.collect_info(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.method_tab[@func.name]
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
- mt = nil
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
- else
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, context.to_signature, signat, context)
172
- same_type(mt, self, signat, context.to_signature, context)
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.current_method_signature_node.push @arguments
186
- mt.yield_node.map do |ynode|
187
- yargs = ynode.arguments
188
- ysignat = ynode.signature(context)
189
- if blknode.is_a?(TopNode) then
190
- # Have block
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
- else
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.current_method_signature_node.pop
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.method_tab[arguments[4].value] = @new_method
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
- case slfnode.value_node
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
- @type_list.add_type(context.to_signature, tt)
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
- decide_type_once(context.to_signature)
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, arguments[0, 3], 0)
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, initarg, op_flag)
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
- case slfnode.value_node
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
- @type_list.add_type(context.to_signature, tt)
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
- same_type(@arguments[3], @arguments[2],
408
- context.to_signature, context.to_signature, context)
409
- same_type(@arguments[2], @arguments[3],
410
- context.to_signature, context.to_signature, context)
411
- same_type(self, @arguments[2],
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
- context.current_method_signature.pop
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
- same_type(@arguments[3], @arguments[2],
453
- context.to_signature, context.to_signature, context)
454
- same_type(@arguments[2], @arguments[3],
455
- context.to_signature, context.to_signature, context)
456
- same_type(self, @arguments[2],
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
- context.to_signature, context.to_signature, context)
498
- same_type(@arguments[2], @arguments[3],
499
- context.to_signature, context.to_signature, context)
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
- context.to_signature, context.to_signature, context)
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
- asm.with_retry do
532
- asm.mov(DBLLOR, TMPR2)
533
- asm.imul(context.ret_reg)
534
- context.end_using_reg(context.ret_reg)
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
- same_type(@arguments[3], @arguments[2],
558
- context.to_signature, context.to_signature, context)
559
- same_type(@arguments[2], @arguments[3],
560
- context.to_signature, context.to_signature, context)
561
- same_type(self, @arguments[2],
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, :imul, TMPR2,
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
- asm.mov(DBLLOR, TMPR2)
587
- asm.cdq
588
- asm.idiv(context.ret_reg)
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
- same_type(@arguments[3], @arguments[2],
614
- context.to_signature, context.to_signature, context)
615
- same_type(@arguments[2], @arguments[3],
616
- context.to_signature, context.to_signature, context)
617
- tt = RubyType::BaseType.from_ruby_class(true)
618
- @type_list.add_type(context.to_signature, tt)
619
- tt = RubyType::BaseType.from_ruby_class(false)
620
- @type_list.add_type(context.to_signature, tt)
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
- context.current_method_signature.pop
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
- context = gen_compare_operation(context , :setg, TMPR2, TMPR)
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
- context = gen_compare_operation(context , :setge, TMPR2, TMPR)
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
- context = gen_compare_operation(context , :setl, TMPR2, TMPR)
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
- context = gen_compare_operation(context , :setle, TMPR2, TMPR)
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