ytljit 0.0.5 → 0.0.6

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.
@@ -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)