ytljit 0.0.2 → 0.0.3
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/ytljit.h +2 -2
- data/lib/ytljit/asmext.rb +20 -0
- data/lib/ytljit/asmext_x64.rb +10 -2
- data/lib/ytljit/asmext_x86.rb +1 -1
- data/lib/ytljit/asmutil.rb +7 -1
- data/lib/ytljit/instruction_ia.rb +47 -5
- data/lib/ytljit/util.rb +1 -0
- data/lib/ytljit/vm.rb +405 -82
- data/lib/ytljit/vm_codegen.rb +12 -13
- data/lib/ytljit/vm_inline_method.rb +24 -21
- data/lib/ytljit/vm_sendnode.rb +361 -187
- data/lib/ytljit/vm_trans.rb +57 -10
- data/lib/ytljit/vm_type.rb +27 -18
- data/lib/ytljit/vm_type_gen.rb +0 -2
- data/test/vmtest.rb +5 -1
- metadata +3 -3
data/lib/ytljit/vm_sendnode.rb
CHANGED
@@ -53,7 +53,13 @@ module YTLJit
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def self.add_special_send_node(name)
|
56
|
-
@@special_node_tab[name]
|
56
|
+
oldcls = @@special_node_tab[name]
|
57
|
+
if oldcls == nil or self < oldcls then
|
58
|
+
@@special_node_tab[name] = self
|
59
|
+
|
60
|
+
else
|
61
|
+
raise "Illigal SendNode #{self} #{name}"
|
62
|
+
end
|
57
63
|
end
|
58
64
|
|
59
65
|
def self.make_send_node(parent, func, arguments, op_flag)
|
@@ -151,7 +157,7 @@ module YTLJit
|
|
151
157
|
if is_fcall or is_vcall then
|
152
158
|
mt = @func.method_top_node(@class_top, nil)
|
153
159
|
else
|
154
|
-
@arguments[2].decide_type_once(context.
|
160
|
+
@arguments[2].decide_type_once(context.to_signature)
|
155
161
|
slf = @arguments[2].type
|
156
162
|
if slf.instance_of?(RubyType::DefaultType0) then
|
157
163
|
# Chaos
|
@@ -162,8 +168,8 @@ module YTLJit
|
|
162
168
|
end
|
163
169
|
|
164
170
|
if mt then
|
165
|
-
same_type(self, mt, context.
|
166
|
-
same_type(mt, self, signat, context.
|
171
|
+
same_type(self, mt, context.to_signature, signat, context)
|
172
|
+
same_type(mt, self, signat, context.to_signature, context)
|
167
173
|
|
168
174
|
context.current_method_signature_node.push @arguments
|
169
175
|
mt.yield_node.map do |ynode|
|
@@ -202,167 +208,19 @@ module YTLJit
|
|
202
208
|
context.start_using_reg(TMPR2)
|
203
209
|
context.start_using_reg(TMPR3)
|
204
210
|
callconv = @func.calling_convention(context)
|
205
|
-
fnc = nil
|
206
211
|
|
207
212
|
case callconv
|
208
213
|
when :c_vararg
|
209
|
-
context
|
210
|
-
|
211
|
-
context = gen_make_argv(context) do |context, rarg|
|
212
|
-
context.start_using_reg(FUNC_ARG[0])
|
213
|
-
context.start_using_reg(FUNC_ARG[1])
|
214
|
-
context.start_using_reg(FUNC_ARG[2])
|
215
|
-
|
216
|
-
context.cpustack_pushn(3 * AsmType::MACHINE_WORD.size)
|
217
|
-
casm = context.assembler
|
218
|
-
# Method Select
|
219
|
-
# it is legal. use TMPR2 for method select
|
220
|
-
# use TMPR3 for store self
|
221
|
-
context = @func.compile(context)
|
222
|
-
fnc = context.ret_reg
|
223
|
-
casm.with_retry do
|
224
|
-
casm.mov(FUNC_ARG[0], rarg.size) # argc
|
225
|
-
casm.mov(FUNC_ARG[1], TMPR2) # argv
|
226
|
-
casm.mov(FUNC_ARG[2], TMPR3) # self
|
227
|
-
end
|
228
|
-
context.set_reg_content(FUNC_ARG[0], nil)
|
229
|
-
context.set_reg_content(FUNC_ARG[1], TMPR2)
|
230
|
-
context.set_reg_content(FUNC_ARG[2], context.ret_node)
|
231
|
-
|
232
|
-
context = gen_call(context, fnc, 3)
|
233
|
-
context.cpustack_popn(3 * AsmType::MACHINE_WORD.size)
|
234
|
-
|
235
|
-
context.end_using_reg(FUNC_ARG[2])
|
236
|
-
context.end_using_reg(FUNC_ARG[1])
|
237
|
-
context.end_using_reg(FUNC_ARG[0])
|
238
|
-
context.end_using_reg(TMPR2)
|
239
|
-
context.ret_reg = RETR
|
240
|
-
context.ret_node = self
|
241
|
-
|
242
|
-
decide_type_once(context.to_key)
|
243
|
-
context = @type.to_box.gen_unboxing(context)
|
244
|
-
|
245
|
-
context
|
246
|
-
end
|
214
|
+
context = compile_c_vararg(context)
|
247
215
|
|
248
216
|
when :c_fixarg
|
249
|
-
|
250
|
-
|
251
|
-
numarg.times do |i|
|
252
|
-
context.start_using_reg(FUNC_ARG[i])
|
253
|
-
end
|
254
|
-
context.cpustack_pushn(numarg * AsmType::MACHINE_WORD.size)
|
255
|
-
|
256
|
-
argpos = 0
|
257
|
-
cursrc = 0
|
258
|
-
@arguments.each do |arg|
|
259
|
-
# skip prevenv and block_argument
|
260
|
-
if cursrc < 2 then
|
261
|
-
cursrc = cursrc + 1
|
262
|
-
next
|
263
|
-
end
|
264
|
-
|
265
|
-
if cursrc == 2 then
|
266
|
-
# Self
|
267
|
-
# Method Select
|
268
|
-
# it is legal. use TMPR2 for method select
|
269
|
-
# use TMPR3 for store self
|
270
|
-
context = @func.compile(context)
|
271
|
-
fnc = context.ret_reg
|
272
|
-
casm = context.assembler
|
273
|
-
casm.with_retry do
|
274
|
-
casm.mov(FUNC_ARG[0], TMPR3)
|
275
|
-
end
|
276
|
-
context.set_reg_content(FUNC_ARG[0], context.ret_node)
|
277
|
-
else
|
278
|
-
# other arg.
|
279
|
-
context = arg.compile(context)
|
280
|
-
context.ret_node.decide_type_once(context.to_key)
|
281
|
-
rtype = context.ret_node.type
|
282
|
-
context = rtype.gen_boxing(context)
|
283
|
-
casm = context.assembler
|
284
|
-
casm.with_retry do
|
285
|
-
casm.mov(FUNC_ARG[argpos], context.ret_reg)
|
286
|
-
end
|
287
|
-
context.set_reg_content(FUNC_ARG[argpos], context.ret_node)
|
288
|
-
end
|
289
|
-
argpos = argpos + 1
|
290
|
-
cursrc = cursrc + 1
|
291
|
-
end
|
292
|
-
|
293
|
-
context = gen_call(context, fnc, numarg)
|
294
|
-
|
295
|
-
context.cpustack_popn(numarg * AsmType::MACHINE_WORD.size)
|
296
|
-
numarg.times do |i|
|
297
|
-
context.end_using_reg(FUNC_ARG[numarg - i - 1])
|
298
|
-
end
|
299
|
-
context.end_using_reg(fnc)
|
300
|
-
|
301
|
-
decide_type_once(context.to_key)
|
302
|
-
context = @type.to_box.gen_unboxing(context)
|
217
|
+
context = compile_c_fixarg(context)
|
303
218
|
|
304
219
|
when :ytl
|
305
|
-
|
306
|
-
|
307
|
-
numarg.times do |i|
|
308
|
-
context.start_using_reg(FUNC_ARG_YTL[i])
|
309
|
-
end
|
310
|
-
context.cpustack_pushn(numarg * 8)
|
311
|
-
|
312
|
-
# push prev env
|
313
|
-
casm = context.assembler
|
314
|
-
casm.with_retry do
|
315
|
-
casm.mov(FUNC_ARG_YTL[0], BPR)
|
316
|
-
end
|
317
|
-
context.set_reg_content(FUNC_ARG_YTL[0], BPR)
|
318
|
-
|
319
|
-
# block
|
320
|
-
# eval block
|
321
|
-
# local block
|
322
|
-
|
323
|
-
# compile block with other code space and context
|
324
|
-
tcontext = context.dup
|
325
|
-
@arguments[1].compile(tcontext)
|
326
|
-
|
327
|
-
casm = context.assembler
|
328
|
-
casm.with_retry do
|
329
|
-
entry = @arguments[1].code_space.var_base_immidiate_address
|
330
|
-
casm.mov(FUNC_ARG_YTL[1], entry)
|
331
|
-
end
|
332
|
-
context.set_reg_content(FUNC_ARG_YTL[1], nil)
|
333
|
-
|
334
|
-
# other arguments
|
335
|
-
@arguments[3..-1].each_with_index do |arg, i|
|
336
|
-
context = arg.compile(context)
|
337
|
-
casm = context.assembler
|
338
|
-
casm.with_retry do
|
339
|
-
casm.mov(FUNC_ARG_YTL[i + 3], context.ret_reg)
|
340
|
-
end
|
341
|
-
context.set_reg_content(FUNC_ARG_YTL[i + 3], context.ret_node)
|
342
|
-
end
|
343
|
-
|
344
|
-
# self
|
345
|
-
# Method Select
|
346
|
-
# it is legal. use TMPR2 for method select
|
347
|
-
# use TMPR3 for store self
|
348
|
-
context = @func.compile(context)
|
349
|
-
fnc = context.ret_reg
|
350
|
-
casm = context.assembler
|
351
|
-
casm.with_retry do
|
352
|
-
casm.mov(FUNC_ARG_YTL[2], TMPR3)
|
353
|
-
end
|
354
|
-
context.set_reg_content(FUNC_ARG_YTL[2], @arguments[2])
|
355
|
-
|
356
|
-
context = gen_call(context, fnc, numarg)
|
357
|
-
|
358
|
-
context.cpustack_popn(numarg * 8)
|
359
|
-
numarg.size.times do |i|
|
360
|
-
context.end_using_reg(FUNC_ARG_YTL[numarg - i])
|
361
|
-
end
|
362
|
-
context.end_using_reg(fnc)
|
220
|
+
context = compile_ytl(context)
|
363
221
|
end
|
364
222
|
|
365
|
-
decide_type_once(context.
|
223
|
+
decide_type_once(context.to_signature)
|
366
224
|
if @type.is_a?(RubyType::RubyTypeUnboxed) and
|
367
225
|
@type.ruby_type == Float then
|
368
226
|
context.ret_reg = XMM0
|
@@ -386,6 +244,8 @@ module YTLJit
|
|
386
244
|
if arguments[4].is_a?(LiteralNode) then
|
387
245
|
@new_method.name = arguments[4].value
|
388
246
|
@class_top.method_tab[arguments[4].value] = @new_method
|
247
|
+
else
|
248
|
+
raise "Not supported not literal method name"
|
389
249
|
end
|
390
250
|
end
|
391
251
|
|
@@ -416,26 +276,142 @@ module YTLJit
|
|
416
276
|
end
|
417
277
|
end
|
418
278
|
|
419
|
-
class
|
420
|
-
|
421
|
-
|
422
|
-
|
279
|
+
class SendAllocateNode<SendNode
|
280
|
+
add_special_send_node :allocate
|
281
|
+
|
282
|
+
def collect_candidate_type_regident(context, slf)
|
283
|
+
slfnode = @arguments[2]
|
284
|
+
if slf.ruby_type.is_a?(Class) then
|
285
|
+
case slfnode
|
286
|
+
when ConstantRefNode
|
287
|
+
case slfnode.value_node
|
288
|
+
when ClassTopNode
|
289
|
+
clstop = slfnode.value_node
|
290
|
+
tt = RubyType::BaseType.from_ruby_class(clstop.klass_object)
|
291
|
+
@type_list.add_type(context.to_signature, tt)
|
292
|
+
|
293
|
+
else
|
294
|
+
raise "Unkown node type in constant #{slfnode.value_node.class}"
|
295
|
+
end
|
296
|
+
|
297
|
+
else
|
298
|
+
raise "Unkonwn node type #{@arguments[2].class} "
|
299
|
+
end
|
300
|
+
end
|
301
|
+
context
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
class SendInitializeNode<SendNode
|
306
|
+
add_special_send_node :initialize
|
307
|
+
|
308
|
+
def compile(context)
|
309
|
+
context.start_using_reg(TMPR2)
|
310
|
+
context.start_using_reg(TMPR3)
|
311
|
+
callconv = @func.calling_convention(context)
|
312
|
+
|
313
|
+
case callconv
|
314
|
+
when :c_vararg
|
315
|
+
context = compile_c_vararg(context)
|
316
|
+
|
317
|
+
when :c_fixarg
|
318
|
+
context = compile_c_fixarg(context)
|
319
|
+
|
320
|
+
when :ytl
|
321
|
+
context = compile_ytl(context)
|
322
|
+
end
|
323
|
+
|
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
|
330
|
+
context.ret_node = self
|
331
|
+
context.end_using_reg(TMPR3)
|
332
|
+
context.end_using_reg(TMPR2)
|
333
|
+
|
334
|
+
context = @body.compile(context)
|
335
|
+
context
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
class SendNewNode<SendNode
|
340
|
+
add_special_send_node :new
|
423
341
|
|
424
342
|
def initialize(parent, func, arguments, op_flag)
|
425
343
|
super
|
344
|
+
allocfunc = MethodSelectNode.new(self, :allocate)
|
345
|
+
alloc = SendNode.make_send_node(self, allocfunc, arguments[0, 3], 0)
|
346
|
+
allocfunc.set_reciever(alloc)
|
347
|
+
initfunc = MethodSelectNode.new(self, :initialize)
|
348
|
+
initarg = arguments.dup
|
349
|
+
initarg[2] = alloc
|
350
|
+
init = SendNode.make_send_node(self, initfunc, initarg, op_flag)
|
351
|
+
initfunc.set_reciever(init)
|
352
|
+
alloc.parent = init
|
353
|
+
@initmethod = init
|
354
|
+
end
|
355
|
+
|
356
|
+
def traverse_childlen
|
357
|
+
@arguments.each do |arg|
|
358
|
+
yield arg
|
359
|
+
end
|
360
|
+
yield @func
|
361
|
+
yield @initmethod
|
362
|
+
end
|
363
|
+
|
364
|
+
def collect_candidate_type_regident(context, slf)
|
365
|
+
slfnode = @arguments[2]
|
366
|
+
if slf.ruby_type.is_a?(Class) then
|
367
|
+
case slfnode
|
368
|
+
when ConstantRefNode
|
369
|
+
context = @initmethod.collect_candidate_type(context)
|
370
|
+
case slfnode.value_node
|
371
|
+
when ClassTopNode
|
372
|
+
clstop = slfnode.value_node
|
373
|
+
tt = RubyType::BaseType.from_ruby_class(clstop.klass_object)
|
374
|
+
@type_list.add_type(context.to_signature, tt)
|
375
|
+
|
376
|
+
else
|
377
|
+
raise "Unkown node type in constant #{slfnode.value_node.class}"
|
378
|
+
end
|
379
|
+
|
380
|
+
else
|
381
|
+
raise "Unkonwn node type #{@arguments[2].class} "
|
382
|
+
end
|
383
|
+
end
|
384
|
+
context
|
385
|
+
end
|
386
|
+
|
387
|
+
def compile(context)
|
388
|
+
@arguments[2].decide_type_once(context.to_signature)
|
389
|
+
rtype = @arguments[2].type
|
390
|
+
rrtype = rtype.ruby_type
|
391
|
+
if rrtype.is_a?(Class) then
|
392
|
+
@initmethod.compile(context)
|
393
|
+
else
|
394
|
+
super
|
395
|
+
end
|
426
396
|
end
|
397
|
+
end
|
398
|
+
|
399
|
+
class SendPlusNode<SendNode
|
400
|
+
include ArithmeticOperationUtil
|
401
|
+
include SendUtil
|
402
|
+
add_special_send_node :+
|
427
403
|
|
428
404
|
def collect_candidate_type_regident(context, slf)
|
429
405
|
case [slf.ruby_type]
|
430
|
-
when [Fixnum], [Float], [String]
|
406
|
+
when [Fixnum], [Float], [String], [Array]
|
431
407
|
same_type(@arguments[3], @arguments[2],
|
432
|
-
context.
|
408
|
+
context.to_signature, context.to_signature, context)
|
433
409
|
same_type(@arguments[2], @arguments[3],
|
434
|
-
context.
|
410
|
+
context.to_signature, context.to_signature, context)
|
435
411
|
same_type(self, @arguments[2],
|
436
|
-
context.
|
412
|
+
context.to_signature, context.to_signature, context)
|
437
413
|
same_type(@arguments[2], self,
|
438
|
-
context.
|
414
|
+
context.to_signature, context.to_signature, context)
|
439
415
|
end
|
440
416
|
|
441
417
|
context
|
@@ -443,17 +419,18 @@ module YTLJit
|
|
443
419
|
|
444
420
|
#=begin
|
445
421
|
def compile(context)
|
446
|
-
@arguments[2].decide_type_once(context.
|
422
|
+
@arguments[2].decide_type_once(context.to_signature)
|
447
423
|
rtype = @arguments[2].type
|
424
|
+
rrtype = rtype.ruby_type
|
448
425
|
if rtype.is_a?(RubyType::DefaultType0) or
|
449
|
-
|
426
|
+
@class_top.search_method_with_super(@func.name, rrtype)[0] then
|
450
427
|
return super(context)
|
451
428
|
end
|
452
429
|
|
453
430
|
context.current_method_signature.push signature(context)
|
454
|
-
if
|
431
|
+
if rrtype == Fixnum then
|
455
432
|
context = gen_arithmetic_operation(context, :add, TMPR2, TMPR)
|
456
|
-
elsif
|
433
|
+
elsif rrtype == Float then
|
457
434
|
context = gen_arithmetic_operation(context, :addsd, XMM4, XMM0)
|
458
435
|
else
|
459
436
|
raise "Unkown method #{rtype.ruby_type}##{@func.name}"
|
@@ -464,32 +441,199 @@ module YTLJit
|
|
464
441
|
#=end
|
465
442
|
end
|
466
443
|
|
444
|
+
class SendMinusNode<SendNode
|
445
|
+
include ArithmeticOperationUtil
|
446
|
+
include SendUtil
|
447
|
+
add_special_send_node :-
|
448
|
+
|
449
|
+
def collect_candidate_type_regident(context, slf)
|
450
|
+
case [slf.ruby_type]
|
451
|
+
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)
|
460
|
+
end
|
461
|
+
|
462
|
+
context
|
463
|
+
end
|
464
|
+
|
465
|
+
def compile(context)
|
466
|
+
@arguments[2].decide_type_once(context.to_signature)
|
467
|
+
rtype = @arguments[2].type
|
468
|
+
rrtype = rtype.ruby_type
|
469
|
+
if rtype.is_a?(RubyType::DefaultType0) or
|
470
|
+
@class_top.search_method_with_super(@func.name, rrtype)[0] then
|
471
|
+
return super(context)
|
472
|
+
end
|
473
|
+
|
474
|
+
context.current_method_signature.push signature(context)
|
475
|
+
if rrtype == Fixnum then
|
476
|
+
context = gen_arithmetic_operation(context, :sub, TMPR2, TMPR)
|
477
|
+
elsif rrtype == Float then
|
478
|
+
context = gen_arithmetic_operation(context, :subsd, XMM4, XMM0)
|
479
|
+
else
|
480
|
+
raise "Unkown method #{rtype.ruby_type}##{@func.name}"
|
481
|
+
end
|
482
|
+
|
483
|
+
context.current_method_signature.pop
|
484
|
+
@body.compile(context)
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
class SendMultNode<SendNode
|
489
|
+
include ArithmeticOperationUtil
|
490
|
+
include SendUtil
|
491
|
+
add_special_send_node :*
|
492
|
+
|
493
|
+
def collect_candidate_type_regident(context, slf)
|
494
|
+
case [slf.ruby_type]
|
495
|
+
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)
|
504
|
+
|
505
|
+
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)
|
510
|
+
@arguments[3].add_type(context.to_signature, fixtype)
|
511
|
+
end
|
512
|
+
|
513
|
+
context
|
514
|
+
end
|
515
|
+
|
516
|
+
def compile(context)
|
517
|
+
@arguments[2].type = nil
|
518
|
+
@arguments[2].decide_type_once(context.to_signature)
|
519
|
+
rtype = @arguments[2].type
|
520
|
+
rrtype = rtype.ruby_type
|
521
|
+
if rtype.is_a?(RubyType::DefaultType0) or
|
522
|
+
@class_top.search_method_with_super(@func.name, rrtype)[0] then
|
523
|
+
return super(context)
|
524
|
+
end
|
525
|
+
|
526
|
+
context.current_method_signature.push signature(context)
|
527
|
+
if rrtype == Fixnum then
|
528
|
+
context = gen_arithmetic_operation(context, :imul, TMPR2,
|
529
|
+
TMPR) do |context|
|
530
|
+
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)
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
elsif rrtype == Float then
|
539
|
+
context = gen_arithmetic_operation(context, :mulsd, XMM4, XMM0)
|
540
|
+
else
|
541
|
+
raise "Unkown method #{rtype.ruby_type}##{@func.name}"
|
542
|
+
end
|
543
|
+
|
544
|
+
context.current_method_signature.pop
|
545
|
+
@body.compile(context)
|
546
|
+
end
|
547
|
+
end
|
548
|
+
|
549
|
+
class SendDivNode<SendNode
|
550
|
+
include ArithmeticOperationUtil
|
551
|
+
include SendUtil
|
552
|
+
add_special_send_node :/
|
553
|
+
|
554
|
+
def collect_candidate_type_regident(context, slf)
|
555
|
+
case [slf.ruby_type]
|
556
|
+
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)
|
565
|
+
end
|
566
|
+
|
567
|
+
context
|
568
|
+
end
|
569
|
+
|
570
|
+
def compile(context)
|
571
|
+
@arguments[2].type = nil
|
572
|
+
@arguments[2].decide_type_once(context.to_signature)
|
573
|
+
rtype = @arguments[2].type
|
574
|
+
rrtype = rtype.ruby_type
|
575
|
+
if rtype.is_a?(RubyType::DefaultType0) or
|
576
|
+
@class_top.search_method_with_super(@func.name, rrtype)[0] then
|
577
|
+
return super(context)
|
578
|
+
end
|
579
|
+
|
580
|
+
context.current_method_signature.push signature(context)
|
581
|
+
if rrtype == Fixnum then
|
582
|
+
context = gen_arithmetic_operation(context, :imul, TMPR2,
|
583
|
+
TMPR) do |context|
|
584
|
+
asm = context.assembler
|
585
|
+
asm.with_retry do
|
586
|
+
asm.mov(DBLLOR, TMPR2)
|
587
|
+
asm.cdq
|
588
|
+
asm.idiv(context.ret_reg)
|
589
|
+
asm.and(DBLHIR, DBLHIR)
|
590
|
+
asm.setnz(DBLHIR)
|
591
|
+
asm.neg(DBLHIR)
|
592
|
+
asm.and(DBLHIR, DBLLOR)
|
593
|
+
asm.setl(DBLHIR)
|
594
|
+
asm.sub(DBLLOR, DBLHIR)
|
595
|
+
context.end_using_reg(context.ret_reg)
|
596
|
+
end
|
597
|
+
end
|
598
|
+
|
599
|
+
elsif rrtype == Float then
|
600
|
+
context = gen_arithmetic_operation(context, :divsd, XMM4, XMM0)
|
601
|
+
else
|
602
|
+
raise "Unkown method #{rtype.ruby_type}##{@func.name}"
|
603
|
+
end
|
604
|
+
|
605
|
+
context.current_method_signature.pop
|
606
|
+
@body.compile(context)
|
607
|
+
end
|
608
|
+
end
|
609
|
+
|
467
610
|
class SendCompareNode<SendNode
|
468
611
|
include SendUtil
|
469
612
|
def collect_candidate_type_regident(context, slf)
|
470
613
|
same_type(@arguments[3], @arguments[2],
|
471
|
-
context.
|
614
|
+
context.to_signature, context.to_signature, context)
|
472
615
|
same_type(@arguments[2], @arguments[3],
|
473
|
-
context.
|
616
|
+
context.to_signature, context.to_signature, context)
|
474
617
|
tt = RubyType::BaseType.from_ruby_class(true)
|
475
|
-
@type_list.add_type(context.
|
618
|
+
@type_list.add_type(context.to_signature, tt)
|
476
619
|
tt = RubyType::BaseType.from_ruby_class(false)
|
477
|
-
@type_list.add_type(context.
|
620
|
+
@type_list.add_type(context.to_signature, tt)
|
478
621
|
|
479
622
|
context
|
480
623
|
end
|
481
624
|
|
482
625
|
def compile(context)
|
483
|
-
@arguments[2].decide_type_once(context.
|
626
|
+
@arguments[2].decide_type_once(context.to_signature)
|
484
627
|
rtype = @arguments[2].type
|
628
|
+
rrtype = rtype.ruby_type
|
485
629
|
if rtype.ruby_type.is_a?(RubyType::DefaultType0) or
|
486
|
-
|
630
|
+
@class_top.search_method_with_super(@func.name, rrtype)[0] then
|
487
631
|
return super(context)
|
488
632
|
end
|
489
633
|
|
490
634
|
context.current_method_signature.push signature(context)
|
491
635
|
context = gen_eval_self(context)
|
492
|
-
if
|
636
|
+
if rrtype == Fixnum then
|
493
637
|
context = compile_compare(context)
|
494
638
|
else
|
495
639
|
raise "Unkown method #{rtype.ruby_type} #{@func.name}"
|
@@ -531,29 +675,59 @@ module YTLJit
|
|
531
675
|
end
|
532
676
|
end
|
533
677
|
|
534
|
-
class
|
678
|
+
class SendElementRefNode<SendNode
|
535
679
|
include SendUtil
|
536
680
|
add_special_send_node :[]
|
537
681
|
def collect_candidate_type_regident(context, slf)
|
538
682
|
case [slf.ruby_type]
|
539
683
|
when [Array]
|
540
684
|
fixtype = RubyType::BaseType.from_ruby_class(Fixnum)
|
541
|
-
|
542
|
-
@arguments[
|
543
|
-
|
544
|
-
decide_type_once(
|
545
|
-
|
546
|
-
|
685
|
+
sig = context.to_signature
|
686
|
+
@arguments[3].add_type(sig, fixtype)
|
687
|
+
@arguments[2].add_element_node(sig, self, context)
|
688
|
+
decide_type_once(sig)
|
689
|
+
@arguments[2].type = nil
|
690
|
+
@arguments[2].decide_type_once(sig)
|
691
|
+
epare = @arguments[2].element_node_list[0]
|
692
|
+
esig = epare[0]
|
693
|
+
enode = epare[1]
|
694
|
+
if enode != self then
|
695
|
+
same_type(self, enode, sig, esig, context)
|
696
|
+
same_type(enode, self, esig, sig, context)
|
697
|
+
end
|
698
|
+
|
699
|
+
when [Hash]
|
700
|
+
@arguments[2].add_element_node(context.to_signature, self, context)
|
701
|
+
end
|
702
|
+
|
703
|
+
context
|
704
|
+
end
|
705
|
+
end
|
706
|
+
|
707
|
+
class SendElementAssignNode<SendNode
|
708
|
+
include SendUtil
|
709
|
+
add_special_send_node :[]=
|
710
|
+
def collect_candidate_type_regident(context, slf)
|
711
|
+
case [slf.ruby_type]
|
712
|
+
when [Array]
|
713
|
+
fixtype = RubyType::BaseType.from_ruby_class(Fixnum)
|
714
|
+
sig = context.to_signature
|
715
|
+
val = @arguments[4]
|
716
|
+
@arguments[3].add_type(sig, fixtype)
|
717
|
+
@arguments[2].add_element_node(sig, val, context)
|
718
|
+
decide_type_once(sig)
|
719
|
+
@arguments[2].type = nil
|
720
|
+
@arguments[2].decide_type_once(sig)
|
547
721
|
epare = @arguments[2].element_node_list[0]
|
548
|
-
|
722
|
+
esig = epare[0]
|
549
723
|
enode = epare[1]
|
550
724
|
if enode != self then
|
551
|
-
same_type(self, enode,
|
552
|
-
same_type(enode, self,
|
725
|
+
same_type(self, enode, sig, esig, context)
|
726
|
+
same_type(enode, self, esig, sig, context)
|
553
727
|
end
|
554
728
|
|
555
729
|
when [Hash]
|
556
|
-
@arguments[2].add_element_node(context.
|
730
|
+
@arguments[2].add_element_node(context.to_signature, self, context)
|
557
731
|
end
|
558
732
|
|
559
733
|
context
|