ytljit 0.0.6 → 0.0.7

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.
@@ -3,11 +3,15 @@ module YTLJit
3
3
  class YARVContext
4
4
  include Node
5
5
 
6
- def initialize
7
- @the_top = TopTopNode.new(nil, Object)
6
+ def initialize(oldcontext = nil)
7
+ if oldcontext and false then
8
+ @the_top = oldcontext.the_top
9
+ else
10
+ @the_top = TopTopNode.new(nil, Object)
11
+ end
8
12
  @top_nodes = [@the_top]
9
13
  @current_file_name = nil
10
- @current_class_node = the_top
14
+ @current_class_node = @the_top
11
15
  @current_method_node = nil
12
16
 
13
17
  @enc_label = ""
@@ -16,10 +20,15 @@ module YTLJit
16
20
  @current_local_label = nil
17
21
 
18
22
  @current_node = @the_top
23
+
19
24
  @vmtab = []
20
25
 
21
26
  @expstack = []
27
+
22
28
  @local_label_tab = {}
29
+ @local_label_list = []
30
+
31
+ @exception_table = {}
23
32
 
24
33
  @not_reached_pos = false
25
34
 
@@ -39,10 +48,14 @@ module YTLJit
39
48
  attr_accessor :current_local_label
40
49
 
41
50
  attr_accessor :current_node
51
+
42
52
  attr :vmtab
43
53
 
44
54
  attr :expstack
45
55
  attr :local_label_tab
56
+ attr :local_label_list
57
+
58
+ attr_accessor :exception_table
46
59
 
47
60
  attr_accessor :not_reached_pos
48
61
 
@@ -53,7 +66,19 @@ module YTLJit
53
66
  if ctn == nil then
54
67
  ctn = ClassTopNode.new(@the_top, klass, klass.name)
55
68
  end
56
- valnode = LiteralNode.new(ctn, value)
69
+
70
+ valnode = nil
71
+ if value.is_a?(Class) then
72
+ valnode = ClassTopNode.get_class_top_node(value)
73
+ if valnode == nil then
74
+ valnode = ClassTopNode.new(@the_top, value, value.name)
75
+ klassclass = valnode.klassclass
76
+ valnode.type = RubyType::BaseType.from_ruby_class(klassclass)
77
+ end
78
+ else
79
+ valnode = LiteralNode.new(ctn, value)
80
+ end
81
+
57
82
  ctn.get_constant_tab[name] = valnode
58
83
  end
59
84
 
@@ -71,6 +96,22 @@ module YTLJit
71
96
  mname,
72
97
  @current_line_no]
73
98
  end
99
+
100
+ def current_exception_table
101
+ result = {}
102
+ @exception_table.each do |kind, lst|
103
+ lst.each do |st, ed, cnt, body|
104
+ if @local_label_list.include?(st) and
105
+ !@local_label_list.include?(ed) and
106
+ body then
107
+ result[kind] = [st, ed, cnt, body]
108
+ break
109
+ end
110
+ end
111
+ end
112
+
113
+ result
114
+ end
74
115
  end
75
116
 
76
117
  class YARVTranslatorBase
@@ -131,6 +172,7 @@ module YTLJit
131
172
  nllab = context.local_label_tab[label]
132
173
  if nllab == nil then
133
174
  nllab = LocalLabel.new(curnode, label)
175
+ nllab.value_node = PhiNode.new(nllab)
134
176
  nllab.debug_info = context.debug_info
135
177
  context.local_label_tab[label] = nllab
136
178
  end
@@ -148,23 +190,26 @@ module YTLJit
148
190
 
149
191
  def visit_symbol(code, ins, context)
150
192
  context.current_local_label = ins
193
+ context.local_label_list.push ins
151
194
 
152
195
  curnode = context.current_node
153
196
  nllab = get_vmnode_from_label(context, ins)
154
197
 
155
- unless curnode.is_a?(JumpNode)
198
+ if !(curnode.is_a?(JumpNode) or
199
+ curnode.is_a?(MethodEndNode) or
200
+ curnode.is_a?(ThrowNode)) then
156
201
  jmpnode = JumpNode.new(curnode, nllab)
157
202
  jmpnode.debug_info = context.debug_info
158
203
  nllab.parent = jmpnode
159
204
 
160
205
  val = context.expstack.pop
161
206
  nllab.come_from[jmpnode] = val
162
-
207
+
163
208
  curnode.body = jmpnode
164
209
  jmpnode.body = nllab
165
210
  context.expstack.push nllab.value_node
166
211
  end
167
-
212
+
168
213
  context.current_node = nllab
169
214
  end
170
215
 
@@ -187,20 +232,53 @@ module YTLJit
187
232
  (arg_size - locals.size).times do
188
233
  locals.push nil
189
234
  end
190
-
191
235
  cnode = mtopnode.construct_frame_info(locals, arg_size, args)
236
+ exptab = code.header['exception_table']
237
+ context.exception_table = {}
238
+ if exptab.size != 0 then
239
+ exptab.each do |tag, body, st, ed, cont, sp|
240
+ context.exception_table[tag] ||= []
241
+ nbody = nil
242
+ if body then
243
+ ncontext = YARVContext.new(context)
244
+ nbody = ExceptionTopNode.new(mtopnode)
245
+ nbody.debug_info = context.debug_info
246
+ ncontext.current_node = nbody
247
+ ncontext.top_nodes.push nbody
248
+ ncontext.current_file_name = context.current_file_name
249
+ ncontext.current_class_node = context.current_class_node
250
+ ncontext.current_method_node = context.current_method_node
251
+ tr = self.class.new([VMLib::InstSeqTree.new(code, body)])
252
+ tr.translate(ncontext)
253
+ end
254
+ context.exception_table[tag].push [st, ed, cont, nbody]
255
+ end
256
+ end
257
+
258
+ context.not_reached_pos = false
192
259
  context.current_node = cnode
193
260
  end
194
261
 
195
262
  def visit_block_end(code, ins, context)
196
263
  curnode = context.current_node
197
264
  top = context.top_nodes.last
265
+ klassnode = context.current_class_node
266
+ top.exception_table = context.exception_table
198
267
  if top.class == MethodTopNode then
199
268
  if context.macro_method then
200
269
  code = top.to_ruby(ToRubyContext.new).ret_code.last
201
- # print code
270
+ # print code
202
271
  proc = eval("lambda" + code)
203
- SendNode.get_macro_tab[top.name] = proc
272
+ if SendNode.get_macro_tab[top.name] == nil then
273
+ SendNode.get_macro_tab[top.name] = {}
274
+ end
275
+ SendNode.get_macro_tab[top.name][:last] = proc
276
+ else
277
+ if !SendNode.get_user_defined_method_tab[top.name] then
278
+ SendNode.get_user_defined_method_tab[top.name] = []
279
+ end
280
+ klassobj = klassnode.klass_object
281
+ SendNode.get_user_defined_method_tab[top.name].push klassobj
204
282
  end
205
283
  end
206
284
  end
@@ -216,6 +294,9 @@ module YTLJit
216
294
  dep
217
295
  end
218
296
 
297
+ def visit_nop(code, ins, context)
298
+ end
299
+
219
300
  def visit_getlocal(code, ins, context)
220
301
  dep = depth_of_block(code)
221
302
  visit_getdynamic(code, [:getlocal, ins[1], dep], context)
@@ -237,8 +318,14 @@ module YTLJit
237
318
  curcode = curcode.parent
238
319
  end
239
320
  offset = curcode.header['misc'][:local_size] + 3 - ins[1]
240
- node = LocalVarRefNode.new(context.current_node, offset, dep)
241
- node.debug_info = context.debug_info
321
+ node = nil
322
+ if curcode.header['type'] == :ensure and offset == 3 then
323
+ node = LiteralNode.new(context.current_node, nil)
324
+ node.debug_info = context.debug_info
325
+ else
326
+ node = LocalVarRefNode.new(context.current_node, offset, dep)
327
+ node.debug_info = context.debug_info
328
+ end
242
329
  context.expstack.push node
243
330
  end
244
331
 
@@ -348,7 +435,7 @@ module YTLJit
348
435
  def visit_putiseq(code, ins, context)
349
436
  body = VMLib::InstSeqTree.new(code, ins[1])
350
437
  curnode = context.current_node
351
- ncontext = YARVContext.new
438
+ ncontext = YARVContext.new(context)
352
439
 
353
440
  case body.header['type']
354
441
  when :block
@@ -356,7 +443,7 @@ module YTLJit
356
443
  when :method
357
444
  mtopnode = MethodTopNode.new(curnode, body.header['name'].to_sym)
358
445
  when :class
359
- mtopnode = ClassTopNode.new(curnode, body.header['name'].to_sym)
446
+ mtopnode = ClassTopNode.new(curnode, Object, body.header['name'].to_sym)
360
447
  when :top
361
448
  raise "Maybe bug not appear top block."
362
449
  end
@@ -426,7 +513,8 @@ module YTLJit
426
513
 
427
514
  def visit_newarray(code, ins, context)
428
515
  curnode = context.current_node
429
- func = FixArgCApiNode.new(curnode, "rb_ary_new3", [:int, :VALUE, :"..."])
516
+ func = FixArgCApiNode.new(curnode, "rb_ary_new3",
517
+ [:int, :VALUE, :"..."])
430
518
  argnum = ins[1]
431
519
  argnumnode = LiteralNode.new(nil, argnum)
432
520
  args = []
@@ -453,7 +541,7 @@ module YTLJit
453
541
  # newhash
454
542
 
455
543
  def visit_newrange(code, ins, context)
456
- exclflag = LiteralNode.new(nil, ins[1] == 1)
544
+ exclflag = LiteralNode.new(nil, ins[1] != 0)
457
545
  context.expstack.push exclflag
458
546
  newinst_to_sendnode(3, Range, code, ins, context)
459
547
  end
@@ -483,7 +571,20 @@ module YTLJit
483
571
  end
484
572
 
485
573
  def visit_dupn(code, ins, context)
486
- raise "foo"
574
+ res = []
575
+ n = ins[1]
576
+ n.times do
577
+ orgnode = context.expstack.pop
578
+ nnode = MultiplexNode.new(orgnode)
579
+ res.push nnode
580
+ end
581
+ res = res.reverse
582
+ res.each do |ele|
583
+ context.expstack.push ele
584
+ end
585
+ res.each do |ele|
586
+ context.expstack.push ele
587
+ end
487
588
  end
488
589
 
489
590
  def visit_swap(code, ins, context)
@@ -568,7 +669,7 @@ module YTLJit
568
669
  context.current_class_node.constant_tab[name] = cnode
569
670
 
570
671
  body = VMLib::InstSeqTree.new(code, ins[2])
571
- ncontext = YARVContext.new
672
+ ncontext = YARVContext.new(context)
572
673
  ncontext.current_file_name = context.current_file_name
573
674
  ncontext.current_node = cnode
574
675
  ncontext.current_class_node = cnode
@@ -612,7 +713,7 @@ module YTLJit
612
713
  # block
613
714
  if blk_iseq then
614
715
  body = VMLib::InstSeqTree.new(code, blk_iseq)
615
- ncontext = YARVContext.new
716
+ ncontext = YARVContext.new(context)
616
717
  ncontext.current_file_name = context.current_file_name
617
718
  ncontext.current_class_node = context.current_class_node
618
719
  ncontext.current_method_node = context.current_method_node
@@ -639,32 +740,30 @@ module YTLJit
639
740
  arg = arg.reverse
640
741
 
641
742
  func = MethodSelectNode.new(curnode, ins[1])
642
- sn = SendNode.make_send_node(curnode, func, arg, op_flag, seqno)
643
- if sn.is_a?(SendEvalNode) then
644
- if context.macro_method == nil then
645
- context.macro_method = true
743
+ sn = SendNode.macro_expand(context, func, arg, op_flag, seqno)
744
+ if sn == nil then
745
+ sn = SendNode.make_send_node(curnode, func, arg, op_flag, seqno)
746
+ sn.current_exception_table = context.current_exception_table
747
+ if sn.is_a?(SendEvalNode) then
748
+ if context.macro_method == nil then
749
+ context.macro_method = true
750
+ end
646
751
  end
647
- end
648
-
649
- if sn.is_a?(SendNode) then
752
+
650
753
  sn.debug_info = context.debug_info
651
754
  func.set_reciever(sn)
652
755
  context.expstack.push sn
653
-
654
- elsif sn.is_a?(Array)
756
+ else
655
757
  # macro(including eval method). execute in compile time and
656
758
  # compile eval strings.
657
759
  val, evalstr = sn
658
760
  evalstr = evalstr.join("\n")
659
761
  is = RubyVM::InstructionSequence.compile(
660
- evalstr, "macro #{ins[1]}", "", 0, YTL::ISEQ_OPTS
661
- ).to_a
762
+ evalstr, "macro #{ins[1]}", "", 0, YTL::ISEQ_OPTS).to_a
662
763
  ncode = VMLib::InstSeqTree.new(code, is)
663
764
  ncode.body.pop # Chop leave instruction
664
765
  translate_main(ncode, context)
665
- # context.expstack.push val
666
- else
667
- raise "Unexcepted data type #{sn.class}"
766
+ # context.expstack.push val
668
767
  end
669
768
 
670
769
  context
@@ -710,6 +809,7 @@ module YTLJit
710
809
  args = args.reverse
711
810
 
712
811
  nnode = SendNode.new(curnode, func, args, op_flag, seqno)
812
+ nnode.current_exception_table = context.current_exception_table
713
813
  nnode.debug_info = context.debug_info
714
814
  func.parent = nnode
715
815
  context.expstack.push nnode
@@ -726,13 +826,16 @@ module YTLJit
726
826
  visit_pop(code, ins, context)
727
827
  curnode = context.current_node
728
828
  vnode = SelfRefNode.new(curnode)
729
- vnode.debug_info = context.debug_info
730
829
  else
731
830
  curnode = context.current_node
732
831
  vnode = context.expstack.pop
733
- vnode.debug_info = context.debug_info
734
832
  end
735
833
 
834
+ if vnode then
835
+ vnode.debug_info = context.debug_info
836
+ else
837
+ vnode = LiteralNode.new(curnode, nil)
838
+ end
736
839
  srnode = SetResultNode.new(curnode, vnode)
737
840
  srnode.debug_info = context.debug_info
738
841
  curnode.body = srnode
@@ -748,14 +851,24 @@ module YTLJit
748
851
  nnode = ClassEndNode.new(srnode)
749
852
  when :top
750
853
  nnode = ClassEndNode.new(srnode)
854
+ else
855
+ raise "unkown type #{code.header['type']}"
751
856
  end
752
857
  nnode.debug_info = context.debug_info
753
858
 
754
859
  context.top_nodes.last.end_nodes.push nnode
755
860
  srnode.body = nnode
861
+ context.current_node = nnode
862
+ context.not_reached_pos = true
756
863
  end
757
864
 
758
865
  def visit_throw(code, ins, context)
866
+ curnode = context.current_node
867
+ exceptobj = context.expstack.pop
868
+
869
+ thnode = ThrowNode.new(curnode, ins[1], exceptobj)
870
+ curnode.body = thnode
871
+ context.current_node = thnode
759
872
  end
760
873
 
761
874
  def visit_jump(code, ins, context)
@@ -14,7 +14,7 @@ module YTLJit
14
14
  return cnode
15
15
  end
16
16
 
17
- if key.zip(cnode.key).all? {|k, n| k.is_a?(n.class)} and false then
17
+ if key.zip(cnode.key).all? {|k, n| k.is_a?(n.class)} then
18
18
  cnode = cnode.same_klass
19
19
  if cnode == nil then
20
20
  ocnode.same_klass = KlassTreeNode.new(key, value)
@@ -245,6 +245,10 @@ module YTLJit
245
245
  @ruby_type
246
246
  end
247
247
 
248
+ def abnormal?
249
+ @@base_type_tab[ruby_type].boxed != boxed
250
+ end
251
+
248
252
  attr_writer :ruby_type
249
253
  end
250
254