ytljit 0.0.8 → 0.0.9

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.
@@ -13,6 +13,8 @@ module YTLJit
13
13
  @current_file_name = nil
14
14
  @current_class_node = @the_top
15
15
  @current_method_node = nil
16
+
17
+ @send_nodes_with_block = []
16
18
 
17
19
  @enc_label = ""
18
20
  @enc_pos_in_source = ""
@@ -41,6 +43,8 @@ module YTLJit
41
43
  attr_accessor :current_file_name
42
44
  attr_accessor :current_class_node
43
45
  attr_accessor :current_method_node
46
+
47
+ attr :send_nodes_with_block
44
48
 
45
49
  attr_accessor :enc_label
46
50
  attr_accessor :enc_pos_in_source
@@ -125,6 +129,7 @@ module YTLJit
125
129
  end
126
130
  @iseqs.each do |code|
127
131
  pos = "#{code.header['filename']}:#{context.current_line_no}"
132
+ context.current_file_name = code.header['filename']
128
133
  context.enc_pos_in_source = pos
129
134
  if code.header['type'] == :block then
130
135
  lstr = context.enc_label + "+blk+" +
@@ -232,7 +237,13 @@ module YTLJit
232
237
  (arg_size - locals.size).times do
233
238
  locals.push nil
234
239
  end
240
+
235
241
  cnode = mtopnode.construct_frame_info(locals, arg_size, args)
242
+ # Get code space each optional argument label
243
+ cnode.opt_label.each do |lab|
244
+ cnode.opt_label_node.push get_vmnode_from_label(context, lab)
245
+ end
246
+
236
247
  exptab = code.header['exception_table']
237
248
  context.exception_table = {}
238
249
  if exptab.size != 0 then
@@ -264,14 +275,14 @@ module YTLJit
264
275
  top = context.top_nodes.last
265
276
  klassnode = context.current_class_node
266
277
  top.exception_table = context.exception_table
278
+ top.send_nodes_with_block = context.send_nodes_with_block
267
279
  if top.class == MethodTopNode then
280
+ SendNode.get_macro_tab[top.name] ||= {}
268
281
  if context.macro_method then
269
- code = top.to_ruby(ToRubyContext.new).ret_code.last
282
+ maccontext = ToRubyContext.new
283
+ code = top.to_ruby(maccontext).ret_code.last
270
284
  # print code
271
285
  proc = eval("lambda" + code)
272
- if SendNode.get_macro_tab[top.name] == nil then
273
- SendNode.get_macro_tab[top.name] = {}
274
- end
275
286
  SendNode.get_macro_tab[top.name][:last] = proc
276
287
  else
277
288
  if !SendNode.get_user_defined_method_tab[top.name] then
@@ -279,6 +290,7 @@ module YTLJit
279
290
  end
280
291
  klassobj = klassnode.klass_object
281
292
  SendNode.get_user_defined_method_tab[top.name].push klassobj
293
+ SendNode.get_macro_tab[top.name][:last] = top
282
294
  end
283
295
  end
284
296
  end
@@ -338,10 +350,34 @@ module YTLJit
338
350
  val = context.expstack.pop
339
351
  curnode = context.current_node
340
352
  offset = curcode.header['misc'][:local_size] + 3 - ins[1]
353
+
354
+ prev_var = nil
355
+ context.expstack.each_with_index do |ele, i|
356
+ if ele.is_a?(LocalVarRefNode) and
357
+ ele.offset == offset and ele.depth == dep then
358
+ prev_var ||= MultiplexNode.new(curnode, ele)
359
+ context.expstack[i] = prev_var
360
+ elsif ele.is_a?(SendNode) then
361
+ ele.traverse_node do |arg, args, j|
362
+ if arg.is_a?(LocalVarRefNode) and
363
+ arg.offset == offset and arg.depth == dep then
364
+ prev_var ||= MultiplexNode.new(ele, arg)
365
+ args[j] = prev_var
366
+ end
367
+ end
368
+ end
369
+ end
370
+
371
+ if prev_var then
372
+ mnode = MultiplexHolderNode.new(curnode, prev_var)
373
+ curnode.body = mnode
374
+ curnode = mnode
375
+ end
376
+
341
377
  node = LocalAssignNode.new(curnode, offset, dep, val)
342
378
  node.debug_info = context.debug_info
343
379
  if context.expstack[-1] == val then
344
- varref = LocalVarRefNode.new(context.current_node, offset, dep)
380
+ varref = LocalVarRefNode.new(node, offset, dep)
345
381
  varref.debug_info = context.debug_info
346
382
  context.expstack[-1] = varref
347
383
  end
@@ -409,7 +445,7 @@ module YTLJit
409
445
  def visit_getglobal(code, ins, context)
410
446
  name = ins[1]
411
447
  curnode = context.current_node
412
- node = GlobalVarRefNode.new(curnode, name)
448
+ node = GlobalVarRefNode.instance(curnode, name)
413
449
  curnode.body = node
414
450
  context.expstack.push node
415
451
  end
@@ -602,7 +638,7 @@ module YTLJit
602
638
 
603
639
  def visit_dup(code, ins, context)
604
640
  orgnode = context.expstack.pop
605
- nnode = MultiplexNode.new(orgnode)
641
+ nnode = MultiplexNode.new(orgnode.parent, orgnode)
606
642
  context.expstack.push nnode
607
643
  context.expstack.push nnode
608
644
  end
@@ -612,7 +648,7 @@ module YTLJit
612
648
  n = ins[1]
613
649
  n.times do
614
650
  orgnode = context.expstack.pop
615
- nnode = MultiplexNode.new(orgnode)
651
+ nnode = MultiplexNode.new(orgnode.parent, orgnode)
616
652
  res.push nnode
617
653
  end
618
654
  res = res.reverse
@@ -642,7 +678,7 @@ module YTLJit
642
678
  def visit_setn(code, ins, context)
643
679
  n = ins[1] + 1
644
680
  orgnode = context.expstack.last
645
- nnode = MultiplexNode.new(orgnode)
681
+ nnode = MultiplexNode.new(orgnode.parent, orgnode)
646
682
  context.expstack[-n] = nnode
647
683
  context.expstack[-1] = nnode
648
684
  end
@@ -691,10 +727,10 @@ module YTLJit
691
727
  end
692
728
 
693
729
  case ins[3]
694
- when 0
730
+ when 0, 3
695
731
  klassobj = Class.new(supklass)
696
732
 
697
- when 2
733
+ when 2, 5
698
734
  klassobj = Module.new
699
735
  end
700
736
  end
@@ -742,8 +778,9 @@ module YTLJit
742
778
  if (op_flag & (0b11 << 3)) != 0 and # fcall, vcall
743
779
  slf.is_a?(LiteralNode) and
744
780
  slf.value == nil and
745
- context.current_class_node.name != :top then
781
+ (context.current_class_node.name != :top or true) then
746
782
  slf = SelfRefNode.new(curnode)
783
+ slf.debug_info = context.debug_info
747
784
  end
748
785
  arg.push slf
749
786
 
@@ -790,13 +827,16 @@ module YTLJit
790
827
  sn.debug_info = context.debug_info
791
828
  func.set_reciever(sn)
792
829
  context.expstack.push sn
830
+ if blk_iseq then
831
+ context.send_nodes_with_block.push sn
832
+ end
793
833
  else
794
834
  # macro(including eval method). execute in compile time and
795
835
  # compile eval strings.
796
836
  val, evalstr = sn
797
837
  evalstr = evalstr.join("\n")
798
838
  is = RubyVM::InstructionSequence.compile(
799
- evalstr, "macro #{ins[1]}", "", 0, YTL::ISEQ_OPTS).to_a
839
+ evalstr, "macro #{ins[1]}", "", 1, YTL::ISEQ_OPTS).to_a
800
840
  ncode = VMLib::InstSeqTree.new(code, is)
801
841
  ncode.body.pop # Chop leave instruction
802
842
  translate_main(ncode, context)
@@ -813,6 +853,7 @@ module YTLJit
813
853
  curnode = context.current_node
814
854
  func = YieldNode.new(curnode)
815
855
  func.debug_info = context.debug_info
856
+ func.depth = depth_of_block(code)
816
857
  numarg = ins[1]
817
858
  op_flag = ins[2]
818
859
  seqno = ins[3]
@@ -860,8 +901,11 @@ module YTLJit
860
901
 
861
902
  if context.top_nodes.last.name == :initialize then
862
903
  # This is necessary. So it decides type of new method
863
- visit_pop(code, ins, context)
904
+ vnode = context.expstack.pop
864
905
  curnode = context.current_node
906
+ nnode = SetResultNode.new(curnode, vnode)
907
+ curnode.body = nnode
908
+ curnode =nnode
865
909
  vnode = SelfRefNode.new(curnode)
866
910
  else
867
911
  curnode = context.current_node
@@ -932,7 +976,7 @@ module YTLJit
932
976
 
933
977
  node = BranchIfNode.new(curnode, cond, nllab)
934
978
  node.debug_info = context.debug_info
935
- nllab.come_from[node] = nil
979
+ nllab.come_from[node] = context.expstack.last
936
980
 
937
981
  curnode.body = node
938
982
  context.current_node = node
@@ -946,7 +990,7 @@ module YTLJit
946
990
 
947
991
  node = BranchUnlessNode.new(curnode, cond, nllab)
948
992
  node.debug_info = context.debug_info
949
- nllab.come_from[node] = nil
993
+ nllab.come_from[node] = context.expstack.last
950
994
 
951
995
  curnode.body = node
952
996
  context.current_node = node
@@ -13,8 +13,8 @@ module YTLJit
13
13
  if key == cnode.key then
14
14
  return cnode
15
15
  end
16
-
17
- if key.zip(cnode.key).all? {|k, n| k.is_a?(n.class)} then
16
+
17
+ if false and 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)
@@ -38,7 +38,7 @@ module YTLJit
38
38
  return cnode
39
39
  end
40
40
 
41
- if key.zip(cnode.key).all? {|a, b|
41
+ if false and key.zip(cnode.key).all? {|a, b|
42
42
  if a then
43
43
  atype = a.ruby_type
44
44
 
@@ -61,6 +61,20 @@ module YTLJit
61
61
 
62
62
  nil
63
63
  end
64
+
65
+ def search_valid_node
66
+ cnode = @node
67
+
68
+ while cnode
69
+ if cnode.value != [[], []] then
70
+ return cnode
71
+ end
72
+
73
+ cnode = cnode.next_klass
74
+ end
75
+
76
+ nil
77
+ end
64
78
  end
65
79
 
66
80
  class KlassTreeNode
@@ -91,13 +105,16 @@ module YTLJit
91
105
  @types_tree.search(key)
92
106
  end
93
107
 
108
+ def search_valid_node
109
+ @types_tree.search_valid_node
110
+ end
111
+
94
112
  def add_type(key, type, pos)
95
113
  tvs = @types_tree.search(key)
96
114
  if tvs then
97
115
  tvsv = tvs.value[pos]
98
- if !tvsv.include? type then
99
- tvsv.push type
100
- end
116
+ tvsv.delete(type)
117
+ tvsv.push type
101
118
  else
102
119
  # inherit types of most similar signature
103
120
  ival = [[], []]
@@ -182,21 +199,22 @@ module YTLJit
182
199
 
183
200
  klass.ancestors.reverse.each do |curcls|
184
201
  box_unbox = base.name.gsub(/.*::Ruby/, "")
185
- mixinname = curcls.name + box_unbox + "CodeGen"
202
+ curclsn = curcls.name.gsub(/:/, '')
203
+ mixinname = curclsn + box_unbox + "CodeGen"
186
204
  begin
187
205
  mixin = VM::TypeCodeGen.const_get(mixinname)
188
206
  baseslf.extend mixin
189
207
  rescue NameError
190
208
  end
191
209
 
192
- mixinname = curcls.name + "TypeBoxedCodeGen"
210
+ mixinname = curclsn + "TypeBoxedCodeGen"
193
211
  begin
194
212
  mixin = VM::TypeCodeGen.const_get(mixinname)
195
213
  boxslf.extend mixin
196
214
  rescue NameError
197
215
  end
198
216
 
199
- mixinname = curcls.name + "TypeUnboxedCodeGen"
217
+ mixinname = curclsn + "TypeUnboxedCodeGen"
200
218
  begin
201
219
  mixin = VM::TypeCodeGen.const_get(mixinname)
202
220
  unboxslf.extend mixin
@@ -325,6 +343,8 @@ module YTLJit
325
343
  define_wraped_class(String, RubyTypeBoxed)
326
344
  define_wraped_class(Array, RubyTypeBoxed)
327
345
  define_wraped_class(Hash, RubyTypeBoxed)
346
+ define_wraped_class(IO, RubyTypeBoxed)
347
+ define_wraped_class(File, RubyTypeBoxed)
328
348
  define_wraped_class(Module, RubyTypeBoxed)
329
349
  define_wraped_class(Class, RubyTypeBoxed)
330
350
  define_wraped_class(Object, RubyTypeBoxed)
@@ -1,7 +1,37 @@
1
1
  module YTLJit
2
2
  module VM
3
3
  module TypeCodeGen
4
+ module TypeUtil
5
+ include AbsArch
6
+ include CommonCodeGen
7
+
8
+ def gen_copy_common(context, func)
9
+ asm = context.assembler
10
+ val = context.ret_reg
11
+ vnode = context.ret_node
12
+ context.start_arg_reg
13
+ addr = lambda {
14
+ a = address_of(func)
15
+ $symbol_table[a] = func
16
+ a
17
+ }
18
+ rbstrdup = OpVarMemAddress.new(addr)
19
+ asm.with_retry do
20
+ asm.mov(FUNC_ARG[0], val)
21
+ end
22
+ context.set_reg_content(FUNC_ARG[0].dst_opecode, vnode)
23
+ context = gen_save_thepr(context)
24
+ context = gen_call(context, rbstrdup, 1, vnode)
25
+ context.end_arg_reg
26
+ context.ret_reg = RETR
27
+
28
+ context
29
+ end
30
+ end
31
+
4
32
  module DefaultTypeCodeGen
33
+ include TypeUtil
34
+
5
35
  def instance
6
36
  self
7
37
  end
@@ -27,7 +57,7 @@ module YTLJit
27
57
  end
28
58
 
29
59
  def gen_copy(context)
30
- context
60
+ gen_copy_common(context, 'rb_obj_dup')
31
61
  end
32
62
 
33
63
  def inspect
@@ -38,9 +68,80 @@ module YTLJit
38
68
  # Do not copy. It is immutable
39
69
  self
40
70
  end
71
+
72
+ def ==(other)
73
+ other and
74
+ self.ruby_type == other.ruby_type and
75
+ self.boxed == other.boxed
76
+ end
77
+ end
78
+
79
+ module NilClassTypeBoxedCodeGen
80
+ include TypeUtil
81
+
82
+ def gen_copy(context)
83
+ context
84
+ end
85
+ end
86
+
87
+ module SymbolTypeBoxedCodeGen
88
+ include TypeUtil
89
+
90
+ def gen_copy(context)
91
+ context
92
+ end
93
+ end
94
+
95
+ module FalseClassTypeBoxedCodeGen
96
+ include TypeUtil
97
+
98
+ def gen_copy(context)
99
+ context
100
+ end
101
+ end
102
+
103
+ module TrueClassTypeBoxedCodeGen
104
+ include TypeUtil
105
+
106
+ def gen_copy(context)
107
+ context
108
+ end
109
+ end
110
+
111
+ module ModuleTypeBoxedCodeGen
112
+ include TypeUtil
113
+
114
+ def gen_copy(context)
115
+ context
116
+ end
117
+ end
118
+
119
+ module ModuleTypeUnoxedCodeGen
120
+ include TypeUtil
121
+
122
+ def gen_copy(context)
123
+ context
124
+ end
125
+ end
126
+
127
+ module ClassTypeBoxedCodeGen
128
+ include TypeUtil
129
+
130
+ def gen_copy(context)
131
+ context
132
+ end
133
+ end
134
+
135
+ module ClassTypeUnboxedCodeGen
136
+ include TypeUtil
137
+
138
+ def gen_copy(context)
139
+ context
140
+ end
41
141
  end
42
142
 
43
143
  module FixnumTypeUnboxedCodeGen
144
+ include TypeUtil
44
145
  include AbsArch
45
146
  include CommonCodeGen
46
147
 
@@ -68,9 +169,14 @@ module YTLJit
68
169
  def gen_unboxing(context)
69
170
  context
70
171
  end
172
+
173
+ def gen_copy(context)
174
+ context
175
+ end
71
176
  end
72
177
 
73
178
  module FixnumTypeBoxedCodeGen
179
+ include TypeUtil
74
180
  include AbsArch
75
181
  include CommonCodeGen
76
182
 
@@ -93,9 +199,14 @@ module YTLJit
93
199
  context.ret_reg = TMPR
94
200
  context
95
201
  end
202
+
203
+ def gen_copy(context)
204
+ context
205
+ end
96
206
  end
97
207
 
98
208
  module FloatTypeBoxedCodeGen
209
+ include TypeUtil
99
210
  include AbsArch
100
211
  include CommonCodeGen
101
212
 
@@ -113,9 +224,14 @@ module YTLJit
113
224
  context.ret_reg = XMM0
114
225
  context
115
226
  end
227
+
228
+ def gen_copy(context)
229
+ context
230
+ end
116
231
  end
117
232
 
118
233
  module FloatTypeUnboxedCodeGen
234
+ include TypeUtil
119
235
  include AbsArch
120
236
  include CommonCodeGen
121
237
 
@@ -159,9 +275,15 @@ module YTLJit
159
275
  def gen_unboxing(context)
160
276
  context
161
277
  end
278
+
279
+ def gen_copy(context)
280
+ context
281
+ end
162
282
  end
163
283
 
164
284
  module ArrayTypeCommonCodeGen
285
+ include TypeUtil
286
+
165
287
  def init
166
288
  @element_type = nil
167
289
  end
@@ -180,26 +302,12 @@ module YTLJit
180
302
  ((other.element_type == nil and
181
303
  @element_type == nil) or
182
304
  (other.element_type and @element_type and
183
- @element_type[nil] == other.element_type[nil])) and
184
- boxed == other.boxed
185
- else
186
- false
187
- end
188
- end
189
-
190
- =begin
191
- def eql?(other)
192
- if other then
193
- oc = other.ruby_type
194
- sc = self.ruby_type
195
-
196
- sc == oc and
305
+ @element_type[nil][0] == other.element_type[nil][0])) and
197
306
  boxed == other.boxed
198
307
  else
199
308
  false
200
309
  end
201
310
  end
202
- =end
203
311
 
204
312
  def inspect
205
313
  etype = @element_type.inspect
@@ -220,26 +328,7 @@ module YTLJit
220
328
  end
221
329
 
222
330
  def gen_copy(context)
223
- asm = context.assembler
224
- val = context.ret_reg
225
- vnode = context.ret_node
226
- context.start_arg_reg
227
- addr = lambda {
228
- a = address_of("rb_ary_dup")
229
- $symbol_table[a] = "rb_ary_dup"
230
- a
231
- }
232
- rbarydup = OpVarMemAddress.new(addr)
233
- asm.with_retry do
234
- asm.mov(FUNC_ARG[0], val)
235
- end
236
- context.set_reg_content(FUNC_ARG[0].dst_opecode, vnode)
237
- context = gen_save_thepr(context)
238
- context = gen_call(context, rbarydup, 1, vnode)
239
- context.end_arg_reg
240
- context.ret_reg = RETR
241
-
242
- context
331
+ gen_copy_common(context, 'rb_ary_dup')
243
332
  end
244
333
 
245
334
  def copy_type
@@ -333,34 +422,18 @@ module YTLJit
333
422
  end
334
423
 
335
424
  module StringTypeBoxedCodeGen
425
+ include TypeUtil
336
426
  include AbsArch
337
427
  include CommonCodeGen
338
428
 
339
429
  def gen_copy(context)
340
- asm = context.assembler
341
- val = context.ret_reg
342
- vnode = context.ret_node
343
- context.start_arg_reg
344
- addr = lambda {
345
- a = address_of("rb_str_dup")
346
- $symbol_table[a] = "rb_str_dup"
347
- a
348
- }
349
- rbstrdup = OpVarMemAddress.new(addr)
350
- asm.with_retry do
351
- asm.mov(FUNC_ARG[0], val)
352
- end
353
- context.set_reg_content(FUNC_ARG[0].dst_opecode, vnode)
354
- context = gen_save_thepr(context)
355
- context = gen_call(context, rbstrdup, 1, vnode)
356
- context.end_arg_reg
357
- context.ret_reg = RETR
358
-
359
- context
430
+ gen_copy_common(context, 'rb_str_dup')
360
431
  end
361
432
  end
362
433
 
363
434
  module RangeTypeCommonCodeGen
435
+ include TypeUtil
436
+
364
437
  def init
365
438
  @args = nil
366
439
  @element_type = nil
@@ -385,6 +458,7 @@ module YTLJit
385
458
  end
386
459
 
387
460
  module RangeTypeBoxedCodeGen
461
+ include TypeUtil
388
462
  include RangeTypeCommonCodeGen
389
463
 
390
464
  def instance
@@ -404,6 +478,7 @@ module YTLJit
404
478
  end
405
479
 
406
480
  module RangeTypeUnboxedCodeGen
481
+ include TypeUtil
407
482
  include AbsArch
408
483
  include CommonCodeGen
409
484
  include RangeTypeCommonCodeGen