ytljit 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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