ytljit 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,7 +8,7 @@ module YTLJit
8
8
  @top_nodes = [@the_top]
9
9
  @current_file_name = nil
10
10
  @current_class_node = the_top
11
- @current_method_name = nil
11
+ @current_method_node = nil
12
12
 
13
13
  @enc_label = ""
14
14
  @enc_pos_in_source = ""
@@ -22,6 +22,8 @@ module YTLJit
22
22
  @local_label_tab = {}
23
23
 
24
24
  @not_reached_pos = false
25
+
26
+ @macro_method = nil
25
27
  end
26
28
 
27
29
  attr_accessor :the_top
@@ -29,7 +31,7 @@ module YTLJit
29
31
 
30
32
  attr_accessor :current_file_name
31
33
  attr_accessor :current_class_node
32
- attr_accessor :current_method_name
34
+ attr_accessor :current_method_node
33
35
 
34
36
  attr_accessor :enc_label
35
37
  attr_accessor :enc_pos_in_source
@@ -44,6 +46,8 @@ module YTLJit
44
46
 
45
47
  attr_accessor :not_reached_pos
46
48
 
49
+ attr_accessor :macro_method
50
+
47
51
  def import_object(klass, name, value)
48
52
  ctn = ClassTopNode.get_class_top_node(klass)
49
53
  if ctn == nil then
@@ -52,6 +56,21 @@ module YTLJit
52
56
  valnode = LiteralNode.new(ctn, value)
53
57
  ctn.get_constant_tab[name] = valnode
54
58
  end
59
+
60
+ def debug_info
61
+ mname = nil
62
+ if @current_method_node then
63
+ mname = @current_method_node.get_constant_value
64
+ end
65
+ if mname then
66
+ mname = mname[0]
67
+ end
68
+
69
+ [@current_file_name,
70
+ @current_class_node.name,
71
+ mname,
72
+ @current_line_no]
73
+ end
55
74
  end
56
75
 
57
76
  class YARVTranslatorBase
@@ -68,7 +87,7 @@ module YTLJit
68
87
  context.enc_pos_in_source = pos
69
88
  if code.header['type'] == :block then
70
89
  lstr = context.enc_label + "+blk+" +
71
- context.current_method_name.to_s
90
+ context.current_method_node.to_s
72
91
  context.enc_label = lstr
73
92
  end
74
93
  translate_block(code, context)
@@ -77,8 +96,7 @@ module YTLJit
77
96
  context.the_top
78
97
  end
79
98
 
80
- def translate_block(code, context)
81
- visit_block_start(code, nil, context)
99
+ def translate_main(code, context)
82
100
  code.body.each do |ins|
83
101
  pos = "#{code.header['filename']}:#{context.current_line_no}"
84
102
  context.enc_pos_in_source = pos
@@ -96,6 +114,11 @@ module YTLJit
96
114
  send(("visit_" + opname).to_sym, code, ins, context)
97
115
  end
98
116
  end
117
+ end
118
+
119
+ def translate_block(code, context)
120
+ visit_block_start(code, nil, context)
121
+ translate_main(code, context)
99
122
  visit_block_end(code, nil, context)
100
123
  end
101
124
  end
@@ -108,12 +131,21 @@ module YTLJit
108
131
  nllab = context.local_label_tab[label]
109
132
  if nllab == nil then
110
133
  nllab = LocalLabel.new(curnode, label)
134
+ nllab.debug_info = context.debug_info
111
135
  context.local_label_tab[label] = nllab
112
136
  end
113
137
 
114
138
  nllab
115
139
  end
116
140
 
141
+ def gen_arg_node(context, sendnode, func, args)
142
+ curnode = context.current_node
143
+ nnode = sendnode.new(curnode, func, args, 0, 0)
144
+ nnode.debug_info = context.debug_info
145
+ func.parent = nnode
146
+ nnode
147
+ end
148
+
117
149
  def visit_symbol(code, ins, context)
118
150
  context.current_local_label = ins
119
151
 
@@ -122,6 +154,7 @@ module YTLJit
122
154
 
123
155
  unless curnode.is_a?(JumpNode)
124
156
  jmpnode = JumpNode.new(curnode, nllab)
157
+ jmpnode.debug_info = context.debug_info
125
158
  nllab.parent = jmpnode
126
159
 
127
160
  val = context.expstack.pop
@@ -140,25 +173,43 @@ module YTLJit
140
173
  if !mtopnode.is_a?(TopNode) then
141
174
  oldtop = context.the_top
142
175
  mtopnode = TopTopNode.new(nil, Object)
176
+ mtopnode.debug_info = context.debug_info
143
177
  context.the_top = mtopnode
144
178
  oldtop.parent = mtopnode
145
179
  mtopnode.init_node = oldtop
146
180
  end
147
181
 
148
- locals = code.header['locals']
149
- args = code.header['misc'][:arg_size]
182
+ context.macro_method = nil
150
183
 
151
- context.current_node = mtopnode.construct_frame_info(locals, args)
184
+ locals = code.header['locals']
185
+ arg_size = code.header['misc'][:arg_size]
186
+ args = code.header['args']
187
+ (arg_size - locals.size).times do
188
+ locals.push nil
189
+ end
190
+
191
+ cnode = mtopnode.construct_frame_info(locals, arg_size, args)
192
+ context.current_node = cnode
152
193
  end
153
194
 
154
195
  def visit_block_end(code, ins, context)
196
+ curnode = context.current_node
197
+ top = context.top_nodes.last
198
+ if top.class == MethodTopNode then
199
+ if context.macro_method then
200
+ code = top.to_ruby(ToRubyContext.new).ret_code.last
201
+ # print code
202
+ proc = eval("lambda" + code)
203
+ SendNode.get_macro_tab[top.name] = proc
204
+ end
205
+ end
155
206
  end
156
207
 
157
208
  def depth_of_block(code)
158
209
  dep = 0
159
210
  ccode = code
160
211
  while ccode.header['type'] == :block
161
- ccode = code.parent
212
+ ccode = ccode.parent
162
213
  dep += 1
163
214
  end
164
215
 
@@ -187,6 +238,7 @@ module YTLJit
187
238
  end
188
239
  offset = curcode.header['misc'][:local_size] + 3 - ins[1]
189
240
  node = LocalVarRefNode.new(context.current_node, offset, dep)
241
+ node.debug_info = context.debug_info
190
242
  context.expstack.push node
191
243
  end
192
244
 
@@ -200,8 +252,10 @@ module YTLJit
200
252
  curnode = context.current_node
201
253
  offset = curcode.header['misc'][:local_size] + 3 - ins[1]
202
254
  node = LocalAssignNode.new(curnode, offset, dep, val)
255
+ node.debug_info = context.debug_info
203
256
  if context.expstack[-1] == val then
204
257
  varref = LocalVarRefNode.new(context.current_node, offset, dep)
258
+ varref.debug_info = context.debug_info
205
259
  context.expstack[-1] = varref
206
260
  end
207
261
  curnode.body = node
@@ -250,6 +304,7 @@ module YTLJit
250
304
  name = ins[1]
251
305
  curnode = context.current_node
252
306
  node = ConstantRefNode.new(curnode, klass, name)
307
+ node.debug_info = context.debug_info
253
308
  context.expstack.push node
254
309
  end
255
310
 
@@ -259,6 +314,7 @@ module YTLJit
259
314
  name = ins[1]
260
315
  curnode = context.current_node
261
316
  node = ConstantAssignNode.new(curnode, klass, name, value)
317
+ node.debug_info = context.debug_info
262
318
  curnode.body = node
263
319
  context.current_node = node
264
320
  end
@@ -268,17 +324,20 @@ module YTLJit
268
324
 
269
325
  def visit_putnil(code, ins, context)
270
326
  nnode = LiteralNode.new(nil, nil)
327
+ nnode.debug_info = context.debug_info
271
328
  context.expstack.push nnode
272
329
  end
273
330
 
274
331
  def visit_putself(code, ins, context)
275
332
  curnode = context.current_node
276
333
  nnode = SelfRefNode.new(curnode)
334
+ nnode.debug_info = context.debug_info
277
335
  context.expstack.push nnode
278
336
  end
279
337
 
280
338
  def visit_putobject(code, ins, context)
281
339
  nnode = LiteralNode.new(nil, ins[1])
340
+ nnode.debug_info = context.debug_info
282
341
  context.expstack.push nnode
283
342
  end
284
343
 
@@ -301,31 +360,89 @@ module YTLJit
301
360
  when :top
302
361
  raise "Maybe bug not appear top block."
303
362
  end
363
+ mtopnode.debug_info = context.debug_info
304
364
  ncontext.current_node = mtopnode
305
365
  ncontext.top_nodes.push mtopnode
306
366
 
307
367
  ncontext.current_file_name = context.current_file_name
308
368
  ncontext.current_class_node = context.current_class_node
309
369
  mname = context.expstack.last
310
- ncontext.current_method_name = mname
370
+ ncontext.current_method_node = mname
311
371
 
312
372
  tr = self.class.new([body])
313
373
  tr.translate(ncontext)
374
+ context.macro_method = ncontext.macro_method
314
375
  context.expstack.push mtopnode
315
376
  end
316
377
 
317
378
  def visit_putstring(code, ins, context)
318
379
  nnode = LiteralNode.new(nil, ins[1])
380
+ nnode.debug_info = context.debug_info
381
+ context.expstack.push nnode
382
+ end
383
+
384
+ def visit_concatstrings(code, ins, context)
385
+ curnode = context.current_node
386
+ numarg = ins[1]
387
+ nnode = context.expstack[-numarg]
388
+ (numarg - 1).times do |i|
389
+ func = FixArgCApiNode.new(curnode, "rb_str_append", [:VALUE, :VALUE])
390
+ args = [nnode, context.expstack[i - numarg + 1]]
391
+ nnode = gen_arg_node(context, RetStringSendNode, func, args)
392
+ end
393
+
394
+ numarg.times do
395
+ context.expstack.pop
396
+ end
397
+ context.expstack.push nnode
398
+ end
399
+
400
+ def visit_tostring(code, ins, context)
401
+ curnode = context.current_node
402
+ func = FixArgCApiNode.new(curnode, "rb_obj_as_string", [:VALUE])
403
+ args = []
404
+ argele = context.expstack.pop
405
+ args.push argele
406
+ nnode = gen_arg_node(context, RetStringSendNode, func, args)
319
407
  context.expstack.push nnode
320
408
  end
321
409
 
322
- # concatstrings
323
- # tostring
324
410
  # toregexp
325
- # newarray
411
+
412
+ def newinst_to_sendnode(argnum, klass, code, ins, context)
413
+ arg = []
414
+ argnum.times {
415
+ arg.push context.expstack.pop
416
+ }
417
+ curnode = context.current_node
418
+ arg.push ConstantRefNode.new(curnode, nil, klass.name.to_sym)
419
+
420
+ arg.reverse.each do |c|
421
+ context.expstack.push c
422
+ end
423
+
424
+ visit_send(code, [:send, :new, argnum, nil, 0, nil], context)
425
+ end
426
+
427
+ def visit_newarray(code, ins, context)
428
+ curnode = context.current_node
429
+ func = FixArgCApiNode.new(curnode, "rb_ary_new3", [:int, :VALUE, :"..."])
430
+ argnum = ins[1]
431
+ argnumnode = LiteralNode.new(nil, argnum)
432
+ args = []
433
+ argnum.times do
434
+ argele = context.expstack.pop
435
+ args.push argele
436
+ end
437
+ args.push argnumnode
438
+ args = args.reverse
439
+ nnode = gen_arg_node(context, RetArraySendNode, func, args)
440
+ context.expstack.push nnode
441
+ end
326
442
 
327
443
  def visit_duparray(code, ins, context)
328
444
  nnode = LiteralNode.new(nil, ins[1])
445
+ nnode.debug_info = context.debug_info
329
446
  context.expstack.push nnode
330
447
  end
331
448
 
@@ -334,8 +451,13 @@ module YTLJit
334
451
  # splatarray
335
452
  # checkincludearray
336
453
  # newhash
337
- # newrange
338
454
 
455
+ def visit_newrange(code, ins, context)
456
+ exclflag = LiteralNode.new(nil, ins[1] == 1)
457
+ context.expstack.push exclflag
458
+ newinst_to_sendnode(3, Range, code, ins, context)
459
+ end
460
+
339
461
  def visit_pop(code, ins, context)
340
462
  node = context.expstack.pop
341
463
  if node == nil then
@@ -354,21 +476,37 @@ module YTLJit
354
476
  end
355
477
 
356
478
  def visit_dup(code, ins, context)
357
- context.expstack.push context.expstack.last
479
+ orgnode = context.expstack.pop
480
+ nnode = MultiplexNode.new(orgnode)
481
+ context.expstack.push nnode
482
+ context.expstack.push nnode
358
483
  end
359
484
 
360
485
  def visit_dupn(code, ins, context)
486
+ raise "foo"
361
487
  end
362
488
 
363
489
  def visit_swap(code, ins, context)
490
+ val0 = context.expstack.pop
491
+ val1 = context.expstack.pop
492
+ context.expstack.push val0
493
+ context.expstack.push val1
364
494
  end
365
495
 
366
496
  # reput
367
497
 
368
498
  def visit_topn(code, ins, context)
499
+ raise
500
+ n = ins[1] + 1
501
+ context.expstack.push context.expstack[-n]
369
502
  end
370
503
 
371
504
  def visit_setn(code, ins, context)
505
+ n = ins[1] + 1
506
+ orgnode = context.expstack.last
507
+ nnode = MultiplexNode.new(orgnode)
508
+ context.expstack[-n] = nnode
509
+ context.expstack[-1] = nnode
372
510
  end
373
511
 
374
512
  # adjuststack
@@ -426,6 +564,7 @@ module YTLJit
426
564
  end
427
565
  RubyType::define_wraped_class(klassobj, RubyType::RubyTypeBoxed)
428
566
  cnode = ClassTopNode.new(context.current_class_node, klassobj, name)
567
+ cnode.debug_info = context.debug_info
429
568
  context.current_class_node.constant_tab[name] = cnode
430
569
 
431
570
  body = VMLib::InstSeqTree.new(code, ins[2])
@@ -440,15 +579,17 @@ module YTLJit
440
579
 
441
580
  curnode = context.current_node
442
581
  cvnode = ClassValueNode.new(curnode, cnode)
582
+ cvnode.debug_info = context.debug_info
443
583
  context.expstack.push cvnode
444
584
 
445
585
  context
446
586
  end
447
587
 
448
588
  def visit_send(code, ins, context)
449
- blk_iseq = ins[3]
450
589
  curnode = context.current_node
451
590
  numarg = ins[2]
591
+ blk_iseq = ins[3]
592
+ op_flag = ins[4]
452
593
  seqno = ins[5]
453
594
 
454
595
  # regular arguments
@@ -459,7 +600,14 @@ module YTLJit
459
600
  end
460
601
 
461
602
  # self
462
- arg.push context.expstack.pop
603
+ slf = context.expstack.pop
604
+ if (op_flag & (0b11 << 3)) != 0 and # fcall, vcall
605
+ slf.is_a?(LiteralNode) and
606
+ slf.value == nil and
607
+ context.current_class_node.name != :top then
608
+ slf = SelfRefNode.new(curnode)
609
+ end
610
+ arg.push slf
463
611
 
464
612
  # block
465
613
  if blk_iseq then
@@ -467,26 +615,57 @@ module YTLJit
467
615
  ncontext = YARVContext.new
468
616
  ncontext.current_file_name = context.current_file_name
469
617
  ncontext.current_class_node = context.current_class_node
618
+ ncontext.current_method_node = context.current_method_node
470
619
  btn = ncontext.current_node = BlockTopNode.new(curnode)
471
620
  ncontext.top_nodes.push btn
472
621
 
473
622
  tr = self.class.new([body])
474
623
  tr.translate(ncontext)
624
+ btn.debug_info = context.debug_info
625
+ context.macro_method = ncontext.macro_method
626
+
475
627
  arg.push btn # block
476
628
  else
477
- arg.push LiteralNode.new(curnode, nil) # block(dymmy)
629
+ argnode = LiteralNode.new(curnode, nil)
630
+ argnode.debug_info = context.debug_info
631
+ arg.push argnode # block(dymmy)
478
632
  end
479
633
 
480
634
  # perv env
481
- arg.push LiteralNode.new(curnode, nil)
635
+ argnode = LiteralNode.new(curnode, nil)
636
+ argnode.debug_info = context.debug_info
637
+ arg.push argnode
482
638
 
483
639
  arg = arg.reverse
484
640
 
485
641
  func = MethodSelectNode.new(curnode, ins[1])
486
- op_flag = ins[4]
487
642
  sn = SendNode.make_send_node(curnode, func, arg, op_flag, seqno)
488
- func.set_reciever(sn)
489
- context.expstack.push sn
643
+ if sn.is_a?(SendEvalNode) then
644
+ if context.macro_method == nil then
645
+ context.macro_method = true
646
+ end
647
+ end
648
+
649
+ if sn.is_a?(SendNode) then
650
+ sn.debug_info = context.debug_info
651
+ func.set_reciever(sn)
652
+ context.expstack.push sn
653
+
654
+ elsif sn.is_a?(Array)
655
+ # macro(including eval method). execute in compile time and
656
+ # compile eval strings.
657
+ val, evalstr = sn
658
+ evalstr = evalstr.join("\n")
659
+ is = RubyVM::InstructionSequence.compile(
660
+ evalstr, "macro #{ins[1]}", "", 0, YTL::ISEQ_OPTS
661
+ ).to_a
662
+ ncode = VMLib::InstSeqTree.new(code, is)
663
+ ncode.body.pop # Chop leave instruction
664
+ translate_main(ncode, context)
665
+ # context.expstack.push val
666
+ else
667
+ raise "Unexcepted data type #{sn.class}"
668
+ end
490
669
 
491
670
  context
492
671
  end
@@ -497,6 +676,7 @@ module YTLJit
497
676
  def visit_invokeblock(code, ins, context)
498
677
  curnode = context.current_node
499
678
  func = YieldNode.new(curnode)
679
+ func.debug_info = context.debug_info
500
680
  numarg = ins[1]
501
681
  op_flag = ins[2]
502
682
  seqno = ins[3]
@@ -513,17 +693,24 @@ module YTLJit
513
693
  framelayout = frameinfo.frame_layout
514
694
 
515
695
  # self
516
- args.push LiteralNode.new(curnode, nil)
696
+ argnode = LiteralNode.new(curnode, nil)
697
+ argnode.debug_info = context.debug_info
698
+ args.push argnode
517
699
 
518
700
  # block
519
- args.push LiteralNode.new(curnode, nil)
701
+ argnode = LiteralNode.new(curnode, nil)
702
+ argnode.debug_info = context.debug_info
703
+ args.push argnode
520
704
 
521
705
  # perv env
522
- args.push LiteralNode.new(curnode, nil)
706
+ argnode = LiteralNode.new(curnode, nil)
707
+ argnode.debug_info = context.debug_info
708
+ args.push argnode
523
709
 
524
710
  args = args.reverse
525
711
 
526
712
  nnode = SendNode.new(curnode, func, args, op_flag, seqno)
713
+ nnode.debug_info = context.debug_info
527
714
  func.parent = nnode
528
715
  context.expstack.push nnode
529
716
 
@@ -533,16 +720,21 @@ module YTLJit
533
720
  def visit_leave(code, ins, context)
534
721
  curnode = nil
535
722
  vnode = nil
723
+
536
724
  if context.top_nodes.last.name == :initialize then
725
+ # This is necessary. So it decides type of new method
537
726
  visit_pop(code, ins, context)
538
727
  curnode = context.current_node
539
728
  vnode = SelfRefNode.new(curnode)
729
+ vnode.debug_info = context.debug_info
540
730
  else
541
731
  curnode = context.current_node
542
732
  vnode = context.expstack.pop
733
+ vnode.debug_info = context.debug_info
543
734
  end
544
735
 
545
736
  srnode = SetResultNode.new(curnode, vnode)
737
+ srnode.debug_info = context.debug_info
546
738
  curnode.body = srnode
547
739
 
548
740
  context.current_node = srnode
@@ -557,6 +749,7 @@ module YTLJit
557
749
  when :top
558
750
  nnode = ClassEndNode.new(srnode)
559
751
  end
752
+ nnode.debug_info = context.debug_info
560
753
 
561
754
  context.top_nodes.last.end_nodes.push nnode
562
755
  srnode.body = nnode
@@ -570,6 +763,7 @@ module YTLJit
570
763
  nllab = get_vmnode_from_label(context, ins[1])
571
764
 
572
765
  jpnode = JumpNode.new(curnode, nllab)
766
+ jpnode.debug_info = context.debug_info
573
767
  jpnode.body = nllab
574
768
 
575
769
  val = context.expstack.pop
@@ -587,6 +781,7 @@ module YTLJit
587
781
  cond = context.expstack.pop
588
782
 
589
783
  node = BranchIfNode.new(curnode, cond, nllab)
784
+ node.debug_info = context.debug_info
590
785
  nllab.come_from[node] = nil
591
786
 
592
787
  curnode.body = node
@@ -600,6 +795,7 @@ module YTLJit
600
795
  cond = context.expstack.pop
601
796
 
602
797
  node = BranchUnlessNode.new(curnode, cond, nllab)
798
+ node.debug_info = context.debug_info
603
799
  nllab.come_from[node] = nil
604
800
 
605
801
  curnode.body = node
@@ -52,7 +52,7 @@ module YTLJit
52
52
  raise "foo"
53
53
  return !b
54
54
  end
55
- } and false then
55
+ } then
56
56
  cnode = cnode.same_klass
57
57
  else
58
58
  cnode = cnode.next_klass
@@ -241,6 +241,10 @@ module YTLJit
241
241
  end
242
242
  end
243
243
 
244
+ def ruby_type_raw
245
+ @ruby_type
246
+ end
247
+
244
248
  attr_writer :ruby_type
245
249
  end
246
250
 
@@ -310,6 +314,7 @@ module YTLJit
310
314
  define_wraped_class(NilClass, RubyTypeBoxed)
311
315
  define_wraped_class(Fixnum, RubyTypeUnboxed)
312
316
  define_wraped_class(Float, RubyTypeUnboxed)
317
+ define_wraped_class(Range, RubyTypeUnboxed)
313
318
  define_wraped_class(TrueClass, RubyTypeBoxed)
314
319
  define_wraped_class(FalseClass, RubyTypeBoxed)
315
320
  define_wraped_class(Symbol, RubyTypeBoxed)