ytljit 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -43,6 +43,15 @@ module YTLJit
43
43
  attr :local_label_tab
44
44
 
45
45
  attr_accessor :not_reached_pos
46
+
47
+ def import_object(klass, name, value)
48
+ ctn = ClassTopNode.get_class_top_node(klass)
49
+ if ctn == nil then
50
+ ctn = ClassTopNode.new(@the_top, klass, klass.name)
51
+ end
52
+ valnode = LiteralNode.new(ctn, value)
53
+ ctn.get_constant_tab[name] = valnode
54
+ end
46
55
  end
47
56
 
48
57
  class YARVTranslatorBase
@@ -164,16 +173,30 @@ module YTLJit
164
173
 
165
174
  def visit_getdynamic(code, ins, context)
166
175
  # + 3 mean prtv_env/pointer to block function/self
167
- offset = code.header['misc'][:local_size] + 3 - ins[1]
168
- node = LocalVarRefNode.new(context.current_node, offset, ins[2])
176
+ dep = ins[2]
177
+ curcode = code
178
+ dep.times do
179
+ curcode = curcode.parent
180
+ end
181
+ offset = curcode.header['misc'][:local_size] + 3 - ins[1]
182
+ node = LocalVarRefNode.new(context.current_node, offset, dep)
169
183
  context.expstack.push node
170
184
  end
171
185
 
172
186
  def visit_setdynamic(code, ins, context)
187
+ dep = ins[2]
188
+ curcode = code
189
+ dep.times do
190
+ curcode = curcode.parent
191
+ end
173
192
  val = context.expstack.pop
174
193
  curnode = context.current_node
175
- offset = code.header['misc'][:local_size] + 3 - ins[1]
176
- node = LocalAssignNode.new(curnode, offset, ins[2], val)
194
+ offset = curcode.header['misc'][:local_size] + 3 - ins[1]
195
+ node = LocalAssignNode.new(curnode, offset, dep, val)
196
+ if context.expstack[-1] == val then
197
+ varref = LocalVarRefNode.new(context.current_node, offset, dep)
198
+ context.expstack[-1] = varref
199
+ end
177
200
  curnode.body = node
178
201
  context.current_node = node
179
202
  end
@@ -188,23 +211,35 @@ module YTLJit
188
211
 
189
212
  # getclassvariable
190
213
  # setclassvariable
191
-
192
- def visit_getconstant(code, ins, context)
214
+
215
+ def get_self_object(context)
193
216
  klass = context.expstack.pop
194
217
  case klass
195
218
  when ConstantRefNode
196
219
  klass = klass.value_node
197
220
 
198
-
199
221
  when LiteralNode
200
222
  klass = klass.value
201
223
  if klass == nil then
202
224
  klass = context.current_class_node
203
225
  end
204
226
 
227
+ when SpecialObjectNode
228
+ if klass.kind == 3 then
229
+ klass = context.current_class_node
230
+ else
231
+ raise "Unkown special object kind = #{klass.kind}"
232
+ end
233
+
205
234
  else
206
235
  raise "Umkonwn node #{klass.class}"
207
236
  end
237
+
238
+ klass
239
+ end
240
+
241
+ def visit_getconstant(code, ins, context)
242
+ klass = get_self_object(context)
208
243
  name = ins[1]
209
244
  curnode = context.current_node
210
245
  node = ConstantRefNode.new(curnode, klass, name)
@@ -212,6 +247,13 @@ module YTLJit
212
247
  end
213
248
 
214
249
  def visit_setconstant(code, ins, context)
250
+ klass = get_self_object(context)
251
+ value = context.expstack.pop
252
+ name = ins[1]
253
+ curnode = context.current_node
254
+ node = ConstantAssignNode.new(curnode, klass, name, value)
255
+ curnode.body = node
256
+ context.current_node = node
215
257
  end
216
258
 
217
259
  # getglobal
@@ -246,9 +288,9 @@ module YTLJit
246
288
  when :block
247
289
  mtopnode = BlockTopNode.new(curnode)
248
290
  when :method
249
- mtopnode = MethodTopNode.new(curnode)
291
+ mtopnode = MethodTopNode.new(curnode, body.header['name'].to_sym)
250
292
  when :class
251
- mtopnode = ClassTopNode.new(curnode)
293
+ mtopnode = ClassTopNode.new(curnode, body.header['name'].to_sym)
252
294
  when :top
253
295
  raise "Maybe bug not appear top block."
254
296
  end
@@ -289,10 +331,17 @@ module YTLJit
289
331
 
290
332
  def visit_pop(code, ins, context)
291
333
  node = context.expstack.pop
334
+ if node == nil then
335
+ # Maybe push instruction deleted by optimize
336
+ node = LiteralNode.new(nil, nil)
337
+ end
338
+
292
339
  curnode = context.current_node
293
340
  node.parent = curnode
294
341
  curnode.body = node
295
- context.current_node = node
342
+ if node.is_a?(HaveChildlenMixin) then
343
+ context.current_node = node
344
+ end
296
345
 
297
346
  context
298
347
  end
@@ -370,6 +419,7 @@ module YTLJit
370
419
  end
371
420
  RubyType::define_wraped_class(klassobj, RubyType::RubyTypeBoxed)
372
421
  cnode = ClassTopNode.new(context.current_class_node, klassobj, name)
422
+ context.current_class_node.constant_tab[name] = cnode
373
423
 
374
424
  body = VMLib::InstSeqTree.new(code, ins[2])
375
425
  ncontext = YARVContext.new
@@ -381,7 +431,6 @@ module YTLJit
381
431
  tr = self.class.new([body])
382
432
  tr.translate(ncontext)
383
433
 
384
- context.current_class_node.constant_tab[name] = cnode
385
434
  curnode = context.current_node
386
435
  cvnode = ClassValueNode.new(curnode, cnode)
387
436
  context.expstack.push cvnode
@@ -393,6 +442,7 @@ module YTLJit
393
442
  blk_iseq = ins[3]
394
443
  curnode = context.current_node
395
444
  numarg = ins[2]
445
+ seqno = ins[5]
396
446
 
397
447
  # regular arguments
398
448
  arg = []
@@ -409,7 +459,7 @@ module YTLJit
409
459
  body = VMLib::InstSeqTree.new(code, blk_iseq)
410
460
  ncontext = YARVContext.new
411
461
  ncontext.current_file_name = context.current_file_name
412
- ncontext.current_class_node = curnode
462
+ ncontext.current_class_node = context.current_class_node
413
463
  btn = ncontext.current_node = BlockTopNode.new(curnode)
414
464
  ncontext.top_nodes.push btn
415
465
 
@@ -427,7 +477,7 @@ module YTLJit
427
477
 
428
478
  func = MethodSelectNode.new(curnode, ins[1])
429
479
  op_flag = ins[4]
430
- sn = SendNode.make_send_node(curnode, func, arg, op_flag)
480
+ sn = SendNode.make_send_node(curnode, func, arg, op_flag, seqno)
431
481
  func.set_reciever(sn)
432
482
  context.expstack.push sn
433
483
 
@@ -442,6 +492,7 @@ module YTLJit
442
492
  func = YieldNode.new(curnode)
443
493
  numarg = ins[1]
444
494
  op_flag = ins[2]
495
+ seqno = ins[3]
445
496
 
446
497
  # regular arguments
447
498
  args = []
@@ -455,17 +506,17 @@ module YTLJit
455
506
  framelayout = frameinfo.frame_layout
456
507
 
457
508
  # self
458
- args.push framelayout[roff + 2]
509
+ args.push LiteralNode.new(curnode, nil)
459
510
 
460
511
  # block
461
- args.push framelayout[roff + 1]
512
+ args.push LiteralNode.new(curnode, nil)
462
513
 
463
514
  # perv env
464
- args.push framelayout[roff]
515
+ args.push LiteralNode.new(curnode, nil)
465
516
 
466
517
  args = args.reverse
467
518
 
468
- nnode = SendNode.new(curnode, func, args, op_flag)
519
+ nnode = SendNode.new(curnode, func, args, op_flag, seqno)
469
520
  func.parent = nnode
470
521
  context.expstack.push nnode
471
522
 
@@ -473,9 +524,17 @@ module YTLJit
473
524
  end
474
525
 
475
526
  def visit_leave(code, ins, context)
476
- curnode = context.current_node
527
+ curnode = nil
528
+ vnode = nil
529
+ if context.top_nodes.last.name == :initialize then
530
+ visit_pop(code, ins, context)
531
+ curnode = context.current_node
532
+ vnode = SelfRefNode.new(curnode)
533
+ else
534
+ curnode = context.current_node
535
+ vnode = context.expstack.pop
536
+ end
477
537
 
478
- vnode = context.expstack.pop
479
538
  srnode = SetResultNode.new(curnode, vnode)
480
539
  curnode.body = srnode
481
540
 
@@ -504,6 +563,7 @@ module YTLJit
504
563
  nllab = get_vmnode_from_label(context, ins[1])
505
564
 
506
565
  jpnode = JumpNode.new(curnode, nllab)
566
+ jpnode.body = nllab
507
567
 
508
568
  val = context.expstack.pop
509
569
  nllab.come_from[jpnode] = val
@@ -1,13 +1,12 @@
1
1
  module YTLJit
2
2
  module TypeUtil
3
3
  class KlassTree
4
- def initialize(defkey = [], defval = [])
4
+ def initialize(defkey = [], defval = [[], []])
5
5
  @node = KlassTreeNode.new(defkey, defval)
6
6
  end
7
7
 
8
8
  def add(key, value)
9
9
  cnode = @node
10
- snode = @node
11
10
  ocnode = nil
12
11
  while cnode
13
12
  ocnode = cnode
@@ -15,13 +14,11 @@ module YTLJit
15
14
  return cnode
16
15
  end
17
16
 
18
- if key.zip(cnode.key).all? {|k, n| k.is_a?(n.class)} then
17
+ if key.zip(cnode.key).all? {|k, n| k.is_a?(n.class)} and false then
19
18
  cnode = cnode.same_klass
20
19
  if cnode == nil then
21
20
  ocnode.same_klass = KlassTreeNode.new(key, value)
22
21
  return ocnode.same_klass
23
- else
24
- snode = cnode
25
22
  end
26
23
  else
27
24
  cnode = cnode.next_klass
@@ -35,13 +32,13 @@ module YTLJit
35
32
 
36
33
  def search(key)
37
34
  cnode = @node
38
-
35
+
39
36
  while cnode
40
37
  if key == cnode.key then
41
38
  return cnode
42
39
  end
43
40
 
44
- if key.zip(cnode.key).all? {|a, b|
41
+ if key.zip(cnode.key).all? {|a, b|
45
42
  if a then
46
43
  atype = a.ruby_type
47
44
 
@@ -52,9 +49,10 @@ module YTLJit
52
49
  nil
53
50
  end
54
51
  else
52
+ raise "foo"
55
53
  return !b
56
54
  end
57
- } then
55
+ } and false then
58
56
  cnode = cnode.same_klass
59
57
  else
60
58
  cnode = cnode.next_klass
@@ -77,7 +75,7 @@ module YTLJit
77
75
  attr_accessor :same_klass
78
76
  attr_accessor :next_klass
79
77
  attr :key
80
- attr_accessor :value
78
+ attr :value
81
79
  end
82
80
 
83
81
  class TypeContainer
@@ -93,16 +91,16 @@ module YTLJit
93
91
  @types_tree.search(key)
94
92
  end
95
93
 
96
- def add_type(key, type)
94
+ def add_type(key, type, pos)
97
95
  tvs = @types_tree.search(key)
98
96
  if tvs then
99
- tvsv = tvs.value
97
+ tvsv = tvs.value[pos]
100
98
  if !tvsv.include? type then
101
99
  tvsv.push type
102
100
  end
103
101
  else
104
102
  # inherit types of most similar signature
105
- ival = []
103
+ ival = [[], []]
106
104
  simnode = @types_tree.add(key, ival)
107
105
  =begin
108
106
  simnode.value.each do |ele|
@@ -111,14 +109,14 @@ module YTLJit
111
109
  =end
112
110
 
113
111
  if !ival.include? type then
114
- ival.push type
112
+ ival[pos].push type
115
113
  end
116
114
  end
117
115
  end
118
116
 
119
117
  def add_node(key)
120
118
  # inherit types of most similar signature
121
- ival = []
119
+ ival = [[], []]
122
120
  simnode = @types_tree.add(key, ival)
123
121
  =begin
124
122
  simnode.value.each do |ele|
@@ -134,7 +132,7 @@ module YTLJit
134
132
  if res == nil then
135
133
  res = add_node(key)
136
134
  end
137
-
135
+
138
136
  res
139
137
  end
140
138
  end
@@ -173,6 +171,11 @@ module YTLJit
173
171
  end
174
172
 
175
173
  def self.related_ruby_class(klass, base)
174
+ if @@base_type_tab[klass] then
175
+ return [@@base_type_tab[klass],
176
+ @@boxed_type_tab[klass],
177
+ @@unboxed_type_tab[klass]]
178
+ end
176
179
  baseslf = base.new(klass)
177
180
  boxslf = RubyTypeBoxed.new(klass)
178
181
  unboxslf = RubyTypeUnboxed.new(klass)
@@ -205,7 +208,7 @@ module YTLJit
205
208
  @@boxed_type_tab[klass] = boxslf
206
209
  @@unboxed_type_tab[klass] = unboxslf
207
210
 
208
- [boxslf, unboxslf]
211
+ [baseslf, boxslf, unboxslf]
209
212
  end
210
213
 
211
214
  def self.from_object(obj)
@@ -215,7 +218,9 @@ module YTLJit
215
218
  def self.from_ruby_class(rcls)
216
219
  tobj = @@base_type_tab[rcls]
217
220
  if tobj == nil then
218
- DefaultType0.new
221
+ RubyType::define_wraped_class(rcls, RubyTypeBoxed)
222
+ tobj = @@base_type_tab[rcls]
223
+ tobj.instance
219
224
  else
220
225
  tobj.instance
221
226
  end
@@ -242,11 +247,11 @@ module YTLJit
242
247
  end
243
248
 
244
249
  def to_unbox
245
- self
250
+ @@unboxed_type_tab[@ruby_type].instance
246
251
  end
247
252
 
248
253
  def to_box
249
- self
254
+ @@boxed_type_tab[@ruby_type].instance
250
255
  end
251
256
 
252
257
  def ==(other)
@@ -304,5 +309,6 @@ module YTLJit
304
309
  define_wraped_class(Hash, RubyTypeBoxed)
305
310
  define_wraped_class(Module, RubyTypeBoxed)
306
311
  define_wraped_class(Class, RubyTypeBoxed)
312
+ define_wraped_class(Object, RubyTypeBoxed)
307
313
  end
308
314
  end
@@ -86,7 +86,13 @@ module YTLJit
86
86
  end
87
87
 
88
88
  def gen_unboxing(context)
89
- p "inboxing"
89
+ asm = context.assembler
90
+ fobj = TypedData.new(InternalRubyType::RFloat, context.ret_reg)
91
+ asm.with_retry do
92
+ asm.movsd(XMM0, fobj[:float_value])
93
+ end
94
+
95
+ context.ret_reg = XMM0
90
96
  context
91
97
  end
92
98
  end
@@ -98,6 +104,8 @@ module YTLJit
98
104
  asm = context.assembler
99
105
  val = context.ret_reg
100
106
  vnode = context.ret_node
107
+ context.start_using_reg(TMPR2)
108
+ context.start_using_reg(TMPR3)
101
109
  context.start_using_reg(FUNC_FLOAT_ARG[0])
102
110
  rbfloatnew = OpMemAddress.new(address_of("rb_float_new"))
103
111
  asm.with_retry do
@@ -105,6 +113,8 @@ module YTLJit
105
113
  asm.call_with_arg(rbfloatnew, 1)
106
114
  end
107
115
  context.end_using_reg(FUNC_FLOAT_ARG[0])
116
+ context.end_using_reg(TMPR3)
117
+ context.end_using_reg(TMPR2)
108
118
  context.ret_reg = RETR
109
119
  context
110
120
  end
@@ -135,7 +145,21 @@ module YTLJit
135
145
  end
136
146
 
137
147
  def gen_copy(context)
138
- p "copy"
148
+ asm = context.assembler
149
+ val = context.ret_reg
150
+ context.start_using_reg(TMPR2)
151
+ context.start_using_reg(TMPR3)
152
+ context.start_using_reg(FUNC_ARG[0])
153
+ rbarydup = OpMemAddress.new(address_of("rb_ary_dup"))
154
+ asm.with_retry do
155
+ asm.mov(FUNC_ARG[0], val)
156
+ asm.call_with_arg(rbarydup, 1)
157
+ end
158
+ context.end_using_reg(FUNC_ARG[0])
159
+ context.end_using_reg(TMPR3)
160
+ context.end_using_reg(TMPR2)
161
+ context.ret_reg = RETR
162
+
139
163
  context
140
164
  end
141
165
 
@@ -144,6 +168,35 @@ module YTLJit
144
168
  self.class == other.class and
145
169
  @element_type == other.element_type
146
170
  end
171
+
172
+ def eql?(other)
173
+ other.is_a?(self.class) and
174
+ self.class == other.class and
175
+ @element_type == other.element_type
176
+ end
177
+ end
178
+
179
+ module StringTypeBoxedCodeGen
180
+ include AbsArch
181
+
182
+ def gen_copy(context)
183
+ asm = context.assembler
184
+ val = context.ret_reg
185
+ context.start_using_reg(TMPR2)
186
+ context.start_using_reg(TMPR3)
187
+ context.start_using_reg(FUNC_ARG[0])
188
+ rbstrresurrect = OpMemAddress.new(address_of("rb_str_resurrect"))
189
+ asm.with_retry do
190
+ asm.mov(FUNC_ARG[0], val)
191
+ asm.call_with_arg(rbstrresurrect, 1)
192
+ end
193
+ context.end_using_reg(FUNC_ARG[0])
194
+ context.end_using_reg(TMPR3)
195
+ context.end_using_reg(TMPR2)
196
+ context.ret_reg = RETR
197
+
198
+ context
199
+ end
147
200
  end
148
201
 
149
202
  module ArrayTypeUnboxedCodeGen