ytljit 0.0.6 → 0.0.7

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