cast_off 0.2.0

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.
Files changed (58) hide show
  1. data/README +578 -0
  2. data/README.en +256 -0
  3. data/bin/CastOff +145 -0
  4. data/cast_off.gemspec +25 -0
  5. data/ext/cast_off/cast_off.c.rb +1386 -0
  6. data/ext/cast_off/cast_off.h +24 -0
  7. data/ext/cast_off/depend +70 -0
  8. data/ext/cast_off/extconf.rb +19 -0
  9. data/ext/cast_off/generated_c_include/inline_api.h +507 -0
  10. data/ext/cast_off/generated_c_include/iter_api.h +595 -0
  11. data/ext/cast_off/generated_c_include/unbox_api.h.rb +76 -0
  12. data/ext/cast_off/generated_c_include/vm_api.h +751 -0
  13. data/ext/cast_off/ruby_source/atomic.h +56 -0
  14. data/ext/cast_off/ruby_source/constant.h +34 -0
  15. data/ext/cast_off/ruby_source/debug.h +41 -0
  16. data/ext/cast_off/ruby_source/eval_intern.h +234 -0
  17. data/ext/cast_off/ruby_source/gc.h +98 -0
  18. data/ext/cast_off/ruby_source/id.h +175 -0
  19. data/ext/cast_off/ruby_source/insns.inc +179 -0
  20. data/ext/cast_off/ruby_source/insns_info.inc +695 -0
  21. data/ext/cast_off/ruby_source/internal.h +227 -0
  22. data/ext/cast_off/ruby_source/iseq.h +125 -0
  23. data/ext/cast_off/ruby_source/manual_update.h +135 -0
  24. data/ext/cast_off/ruby_source/method.h +105 -0
  25. data/ext/cast_off/ruby_source/node.h +503 -0
  26. data/ext/cast_off/ruby_source/thread_pthread.h +51 -0
  27. data/ext/cast_off/ruby_source/thread_win32.h +40 -0
  28. data/ext/cast_off/ruby_source/vm_core.h +756 -0
  29. data/ext/cast_off/ruby_source/vm_exec.h +184 -0
  30. data/ext/cast_off/ruby_source/vm_insnhelper.c +1748 -0
  31. data/ext/cast_off/ruby_source/vm_insnhelper.h +220 -0
  32. data/ext/cast_off/ruby_source/vm_opts.h +51 -0
  33. data/lib/cast_off.rb +15 -0
  34. data/lib/cast_off/compile.rb +629 -0
  35. data/lib/cast_off/compile/basicblock.rb +144 -0
  36. data/lib/cast_off/compile/cfg.rb +391 -0
  37. data/lib/cast_off/compile/code_manager.rb +284 -0
  38. data/lib/cast_off/compile/configuration.rb +2368 -0
  39. data/lib/cast_off/compile/dependency.rb +240 -0
  40. data/lib/cast_off/compile/information.rb +775 -0
  41. data/lib/cast_off/compile/instruction.rb +446 -0
  42. data/lib/cast_off/compile/ir/call_ir.rb +2348 -0
  43. data/lib/cast_off/compile/ir/guard_ir.rb +423 -0
  44. data/lib/cast_off/compile/ir/jump_ir.rb +223 -0
  45. data/lib/cast_off/compile/ir/operand.rb +934 -0
  46. data/lib/cast_off/compile/ir/param_ir.rb +98 -0
  47. data/lib/cast_off/compile/ir/return_ir.rb +92 -0
  48. data/lib/cast_off/compile/ir/simple_ir.rb +808 -0
  49. data/lib/cast_off/compile/ir/sub_ir.rb +212 -0
  50. data/lib/cast_off/compile/iseq.rb +454 -0
  51. data/lib/cast_off/compile/method_information.rb +1384 -0
  52. data/lib/cast_off/compile/namespace/namespace.rb +556 -0
  53. data/lib/cast_off/compile/namespace/uuid.rb +323 -0
  54. data/lib/cast_off/compile/stack.rb +65 -0
  55. data/lib/cast_off/compile/translator.rb +1562 -0
  56. data/lib/cast_off/suggestion.rb +98 -0
  57. data/lib/cast_off/util.rb +58 -0
  58. metadata +107 -0
@@ -0,0 +1,934 @@
1
+ # coding=utf-8
2
+
3
+ module CastOff::Compiler
4
+ module SimpleIR
5
+ class TypeContainer
6
+ include CastOff::Util
7
+
8
+ undef_method(:==)
9
+ undef_method(:eql?)
10
+ undef_method(:hash)
11
+ undef_method(:to_s)
12
+
13
+ attr_reader :types, :state
14
+ # state = :undefined || :initialized || :dynamic || :static
15
+
16
+ # undefined は、何と交わっても、交わった相手の状態に変わる
17
+ # initialized は、dynamic と交わったときのみ、相手の状態に変わる
18
+ # dynamic は、何と交わっても dynamic のまま
19
+ # static は、何と交わっても static のまま
20
+
21
+ # ignore に入っていたら @types に加えない
22
+ # annotation に入っていたら dynamic にするときに、annotation で指定された型にする, ignore に含まれているものは加えない
23
+
24
+ def initialize()
25
+ @types = []
26
+ @state = :undefined
27
+ @annotation = []
28
+ @ignore = []
29
+ @unboxing_state = :undefined
30
+ @negative_cond_value = false
31
+ end
32
+
33
+ ### unboxing begin ###
34
+ def unbox()
35
+ case @unboxing_state
36
+ when :can_unbox
37
+ @unboxing_state = :unboxed
38
+ return true
39
+ when :unboxed
40
+ return false
41
+ end
42
+ bug()
43
+ end
44
+
45
+ def unboxed?
46
+ @unboxing_state == :unboxed
47
+ end
48
+
49
+ def box()
50
+ case @unboxing_state
51
+ when :unboxed, :can_unbox, :can_not_unbox
52
+ @unboxing_state = :boxed
53
+ return true
54
+ when :boxed
55
+ return false
56
+ end
57
+ bug()
58
+ end
59
+
60
+ def boxed?
61
+ @unboxing_state == :boxed
62
+ end
63
+
64
+ def can_unbox?
65
+ if instance_of?(LocalVariable) || instance_of?(TmpVariable) || instance_of?(Literal)
66
+ if dynamic? || @types.size != 1
67
+ false
68
+ else
69
+ true
70
+ end
71
+ else
72
+ # ConstWrapper, Self, Pointer, Argument, TmpBuffer
73
+ false
74
+ end
75
+ end
76
+
77
+ def can_not_unbox?
78
+ @unboxing_state == :can_not_unbox
79
+ end
80
+
81
+ def can_unbox()
82
+ bug() unless @unboxing_state == :undefined
83
+ @unboxing_state = :can_unbox
84
+ end
85
+
86
+ def can_not_unbox()
87
+ case @unboxing_state
88
+ when :undefined, :can_unbox
89
+ @unboxing_state = :can_not_unbox
90
+ true
91
+ when :can_not_unbox
92
+ false
93
+ else
94
+ bug()
95
+ end
96
+ end
97
+
98
+ def box_unbox_undefined?
99
+ @unboxing_state == :undefined
100
+ end
101
+ ### unboxing end ###
102
+
103
+ FloatWrapper = ClassWrapper.new(Float, true)
104
+ FixnumWrapper = ClassWrapper.new(Fixnum, true)
105
+ def declare_class()
106
+ case @unboxing_state
107
+ when :unboxed
108
+ bug() if dynamic?
109
+ bug() unless @types.size == 1
110
+ c = @types[0]
111
+ case c
112
+ when FloatWrapper
113
+ return :double
114
+ when FixnumWrapper
115
+ return :long
116
+ end
117
+ when :can_unbox, :can_not_unbox, :boxed
118
+ return :VALUE
119
+ end
120
+ bug()
121
+ end
122
+
123
+ def declare()
124
+ case declare_class()
125
+ when :double
126
+ return 'double'
127
+ when :long
128
+ return 'long'
129
+ when :VALUE
130
+ return 'VALUE'
131
+ end
132
+ bug()
133
+ end
134
+
135
+ def to_name()
136
+ bug()
137
+ end
138
+
139
+ def to_debug_string()
140
+ "#{self}(#{dynamic? ? 'dynamic' : @types.join(", ")})"
141
+ end
142
+
143
+ def to_s()
144
+ case declare_class()
145
+ when :double
146
+ return "#{to_name()}_Float"
147
+ when :long
148
+ return "#{to_name()}_Fixnum"
149
+ when :VALUE
150
+ return to_name()
151
+ end
152
+ bug()
153
+ end
154
+
155
+ def class_exact?
156
+ bug()
157
+ end
158
+
159
+ def is_class_exact()
160
+ bug()
161
+ end
162
+
163
+ def reset()
164
+ @ignore.clear()
165
+ case @state
166
+ when :undefined
167
+ bug()
168
+ when :initialized, :dynamic
169
+ @types = []
170
+ @state = :undefined
171
+ when :static
172
+ # nothing to do
173
+ else
174
+ bug()
175
+ end
176
+ end
177
+
178
+ def not_initialized()
179
+ # @ignore のせいで :undefined になっているものとしか交わらなかったため、initialize されなかったものがある。
180
+ # そのため、@ignore が空のときに、ここに来る場合がある。
181
+ @state = :dynamic
182
+ end
183
+
184
+ def is_not(types)
185
+ bug() if @state == :static
186
+ bug() unless (@types & @ignore).empty?
187
+ bug() if types.empty?
188
+ types = types.map{|t| convert(t)}
189
+ if (types - @ignore).empty?
190
+ false
191
+ else
192
+ @ignore |= types
193
+ @types -= types
194
+ true
195
+ end
196
+ end
197
+
198
+ def is_also(t)
199
+ t = convert(t)
200
+ return false if @ignore.include?(t)
201
+ case @state
202
+ when :undefined
203
+ @state = :initialized
204
+ bug() unless @types.empty?
205
+ @types << t
206
+ return true
207
+ when :initialized
208
+ bug() if @types.empty?
209
+ if @types.include?(t)
210
+ return false
211
+ else
212
+ @types << t
213
+ return true
214
+ end
215
+ when :static
216
+ bug() if @types.empty?
217
+ bug() unless @types.include?(t)
218
+ return false
219
+ when :dynamic
220
+ return false
221
+ else
222
+ bug()
223
+ end
224
+ bug()
225
+ end
226
+
227
+ def undefined?()
228
+ @state == :undefined
229
+ end
230
+
231
+ def dynamic?()
232
+ @state == :dynamic
233
+ end
234
+
235
+ def is_dynamic()
236
+ return false if @state == :dynamic
237
+ return false if @state == :static
238
+ if annotated?
239
+ if (@annotation - @ignore - @types).empty?
240
+ return false
241
+ else
242
+ @state = :initialized
243
+ @types |= (@annotation - @ignore)
244
+ return true
245
+ end
246
+ else
247
+ @state = :dynamic
248
+ return true
249
+ end
250
+ bug()
251
+ end
252
+
253
+ def static?()
254
+ @state == :static
255
+ end
256
+
257
+ def is_static(types)
258
+ bug() if types.empty?
259
+ types = types.map{|t| convert(t)}
260
+ bug() unless (@ignore & types).empty?
261
+ case @state
262
+ when :undefined
263
+ bug() unless @types.empty?
264
+ @types = types
265
+ @state = :static
266
+ return true
267
+ when :static
268
+ bug() unless @types == types
269
+ return false
270
+ end
271
+ bug()
272
+ end
273
+
274
+ def is_annotated(types)
275
+ # 代入の対象となるような変数(local, instance, class, global variable)は、
276
+ # static ではなく annotated とする。
277
+ # initialized にしちゃうと、dynamic と union したときに、dynamic になってしまうのがもどかしい。
278
+ bug() unless @state == :undefined
279
+ bug() unless @annotation.empty?
280
+ bug() unless @ignore.empty?
281
+ bug() if types.empty?
282
+ @annotation = types.map{|t| convert(t)}
283
+ @annotation.freeze()
284
+ end
285
+
286
+ def is_just?(c)
287
+ case c
288
+ when Class, ClassWrapper
289
+ return is_just_class(c)
290
+ when Array
291
+ return is_just_classes(c)
292
+ end
293
+ bug()
294
+ end
295
+
296
+ def is_also?(c)
297
+ case c
298
+ when Class, ClassWrapper
299
+ return is_also_class(c)
300
+ end
301
+ bug()
302
+ end
303
+
304
+ def union(v)
305
+ bug() if (v.types + @types).find{|t| not t.is_a?(ClassWrapper)}
306
+ union_types = v.types - @ignore
307
+ case @state
308
+ when :undefined
309
+ bug() unless @types.empty?
310
+ case v.state
311
+ when :undefined
312
+ return false
313
+ when :initialized, :static
314
+ return false if union_types.empty?
315
+ @state = :initialized
316
+ @types |= union_types
317
+ return true
318
+ when :dynamic
319
+ return is_dynamic()
320
+ else
321
+ bug()
322
+ end
323
+ when :initialized
324
+ bug() if @types.empty?
325
+ case v.state
326
+ when :undefined
327
+ return false
328
+ when :initialized, :static
329
+ if (union_types - @types).empty?
330
+ return false
331
+ else
332
+ @types |= union_types
333
+ return true
334
+ end
335
+ when :dynamic
336
+ return is_dynamic()
337
+ else
338
+ bug()
339
+ end
340
+ when :static
341
+ bug() if @types.empty?
342
+ case v.state
343
+ when :undefined, :dynamic
344
+ return false
345
+ when :initialized, :static
346
+ bug() unless (union_types - @types).empty? || negative_cond_value?
347
+ return false
348
+ else
349
+ bug()
350
+ end
351
+ when :dynamic
352
+ return false
353
+ else
354
+ bug()
355
+ end
356
+ bug()
357
+ end
358
+
359
+ def is_negative_cond_value
360
+ @negative_cond_value = true
361
+ end
362
+
363
+ private
364
+
365
+ def negative_cond_value?
366
+ @negative_cond_value
367
+ end
368
+
369
+ def is_just_classes(classes)
370
+ classes = classes.map{|c| convert(c)}
371
+ case @state
372
+ when :undefined
373
+ bug()
374
+ when :initialized, :static
375
+ bug() if @types.empty?
376
+ bug() if classes.empty?
377
+ return false unless (@types - classes).empty?
378
+ return false unless (classes - @types).empty?
379
+ return true
380
+ when :dynamic
381
+ return false
382
+ end
383
+ bug()
384
+ end
385
+
386
+ def is_just_class(klass)
387
+ klass = convert(klass)
388
+ case @state
389
+ when :undefined
390
+ bug()
391
+ when :initialized, :static
392
+ bug() if @types.empty?
393
+ return false if @types.size != 1
394
+ return false if @types[0] != klass
395
+ return true
396
+ when :dynamic
397
+ return false
398
+ end
399
+ bug()
400
+ end
401
+
402
+ def is_also_class(klass)
403
+ klass = convert(klass)
404
+ case @state
405
+ when :undefined
406
+ bug()
407
+ when :initialized, :static
408
+ bug() if @types.empty?
409
+ return @types.include?(klass)
410
+ when :dynamic
411
+ return false
412
+ end
413
+ bug()
414
+ end
415
+
416
+ def convert(t)
417
+ case t
418
+ when ClassWrapper
419
+ # nothing to do
420
+ when Class
421
+ t = ClassWrapper.new(t, true)
422
+ else
423
+ bug()
424
+ end
425
+ t
426
+ end
427
+
428
+ def annotated?
429
+ not @annotation.empty?
430
+ end
431
+ end
432
+
433
+ class ConstWrapper < TypeContainer
434
+ attr_reader :path
435
+
436
+ def initialize(flag, *ids, translator)
437
+ super()
438
+ @chain = ids
439
+ @flag = flag
440
+ @path = "#{@flag ? '::' : nil}#{@chain.join("::")}"
441
+ @translator = translator
442
+ @name = @translator.allocate_name("const_#{@path}")
443
+ @translator.declare_constant(@name)
444
+ conf = @translator.configuration
445
+ @cache_constant_p = @prefetch_constant_p = conf.prefetch_constant? && conf.has_binding?
446
+ if prefetch?
447
+ begin
448
+ val = conf.evaluate_by_passed_binding(@path)
449
+ c = ClassWrapper.new(val, false)
450
+ rescue
451
+ @prefetch_constant_p = false
452
+ c = nil
453
+ end
454
+ else
455
+ c = nil
456
+ end
457
+ if c && @translator.get_c_classname(c)
458
+ is_static([c])
459
+ else
460
+ is_dynamic()
461
+ end
462
+ end
463
+
464
+ def get_constant_chain
465
+ ret = []
466
+ ret << " cast_off_tmp = #{@flag ? 'rb_cObject' : 'Qnil'};"
467
+ @chain.each do |id|
468
+ ret << " cast_off_tmp = cast_off_get_constant(cast_off_tmp, #{@translator.allocate_id(id)});"
469
+ end
470
+ ret << " #{@name} = cast_off_tmp;"
471
+ ret.join("\n")
472
+ end
473
+
474
+ def cache?
475
+ @cache_constant_p
476
+ end
477
+
478
+ def prefetch?
479
+ @prefetch_constant_p
480
+ end
481
+
482
+ def class_exact?
483
+ false
484
+ end
485
+
486
+ def to_name
487
+ @name
488
+ end
489
+
490
+ def source
491
+ @path
492
+ end
493
+
494
+ def eql?(v)
495
+ return false unless v.is_a?(ConstWrapper)
496
+ @path == v.path
497
+ end
498
+
499
+ def ==(v)
500
+ eql?(v)
501
+ end
502
+
503
+ def hash
504
+ @path.to_s.hash
505
+ end
506
+ end
507
+
508
+ class Literal < TypeContainer
509
+ include CastOff::Util
510
+
511
+ attr_reader :val, :literal_value
512
+
513
+ def initialize(val, translator)
514
+ super()
515
+ case val
516
+ when NilClass
517
+ @val = "Qnil"
518
+ type = NilClass
519
+ @literal_value = nil
520
+ when Fixnum, Symbol, Bignum, Float, String, Regexp, Array, Range, TrueClass, FalseClass, Class
521
+ @val = translator.allocate_object(val)
522
+ type = val.class
523
+ @literal_value = val
524
+ else
525
+ bug("unexpected object #{val}")
526
+ end
527
+ is_static([type])
528
+ end
529
+
530
+ def to_s()
531
+ case declare_class()
532
+ when :double, :long
533
+ return "#{@literal_value}"
534
+ when :VALUE
535
+ return to_name()
536
+ end
537
+ bug()
538
+ end
539
+
540
+ def class_exact?
541
+ true
542
+ end
543
+
544
+ def to_name
545
+ @val
546
+ end
547
+
548
+ def source
549
+ @literal_value.inspect
550
+ end
551
+
552
+ def eql?(v)
553
+ return false unless v.is_a?(Literal)
554
+ @literal_value == v.literal_value
555
+ end
556
+
557
+ def ==(v)
558
+ eql?(v)
559
+ end
560
+
561
+ def hash()
562
+ @literal_value.hash()
563
+ end
564
+ end
565
+
566
+ class Self < TypeContainer
567
+ include CastOff::Util
568
+
569
+ def initialize(translator)
570
+ super()
571
+ reciever_class = translator.reciever_class
572
+ if reciever_class
573
+ #is_static(reciever_class)
574
+ reciever_class = [reciever_class] unless reciever_class.instance_of?(Array)
575
+ reciever_class.each{|c| is_also(c)}
576
+ else
577
+ is_dynamic()
578
+ end
579
+ end
580
+
581
+ def class_exact?
582
+ false
583
+ end
584
+
585
+ def to_name
586
+ "self"
587
+ end
588
+
589
+ def source
590
+ "self"
591
+ end
592
+
593
+ def eql?(v)
594
+ v.is_a?(Self)
595
+ end
596
+
597
+ def ==(v)
598
+ eql?(v)
599
+ end
600
+
601
+ def hash
602
+ self.to_name.hash
603
+ end
604
+ end
605
+
606
+ class Variable < TypeContainer
607
+ def initialize()
608
+ super()
609
+ @isclassexact = false
610
+ end
611
+
612
+ def class_exact?
613
+ @isclassexact
614
+ end
615
+
616
+ def is_class_exact()
617
+ bug() if @isclassexact
618
+ @isclassexact = true
619
+ end
620
+
621
+ def has_undefined_path()
622
+ # nothing to do
623
+ end
624
+
625
+ def declare?
626
+ self.is_a?(LocalVariable) || self.is_a?(TmpVariable) || self.is_a?(Pointer)
627
+ end
628
+ end
629
+
630
+ class TmpVariable < Variable
631
+ include CastOff::Util
632
+ attr_reader :index
633
+
634
+ def initialize(index)
635
+ super()
636
+ @index = index
637
+ end
638
+
639
+ def to_name
640
+ "tmp#{@index}"
641
+ end
642
+
643
+ def source
644
+ bug()
645
+ end
646
+
647
+ def eql?(v)
648
+ return false unless v.is_a?(TmpVariable)
649
+ @index == v.index
650
+ end
651
+
652
+ def ==(v)
653
+ eql?(v)
654
+ end
655
+
656
+ def hash
657
+ self.to_name.hash
658
+ end
659
+
660
+ def has_undefined_path()
661
+ bug()
662
+ end
663
+ end
664
+
665
+ class Pointer < Variable
666
+ def initialize
667
+ super()
668
+ end
669
+ end
670
+
671
+ class InstanceVariable < Pointer
672
+ attr_reader :id
673
+
674
+ def initialize(id, types)
675
+ super()
676
+ @id = id
677
+ @name = id.slice(1, id.size - 1)
678
+
679
+ if types
680
+ bug() unless types.is_a?(Array)
681
+ is_annotated(types)
682
+ end
683
+ end
684
+
685
+ def to_name
686
+ "instance_#{@name}"
687
+ end
688
+
689
+ def source
690
+ @id.to_s
691
+ end
692
+
693
+ def eql?(v)
694
+ return false unless v.is_a?(InstanceVariable)
695
+ @id == v.id
696
+ end
697
+
698
+ def ==(v)
699
+ eql?(v)
700
+ end
701
+
702
+ def hash
703
+ self.to_name.hash
704
+ end
705
+ end
706
+
707
+ class ClassVariable < Pointer
708
+ attr_reader :id
709
+
710
+ def initialize(id, types)
711
+ super()
712
+ @id = id
713
+ @name = id.slice(2, id.size - 2)
714
+
715
+ if types
716
+ bug() unless types.is_a?(Array)
717
+ is_annotated(types)
718
+ end
719
+ end
720
+
721
+ def to_name
722
+ "class_#{@name}"
723
+ end
724
+
725
+ def source
726
+ @id.to_s
727
+ end
728
+
729
+ def eql?(v)
730
+ return false unless v.is_a?(ClassVariable)
731
+ @id == v.id
732
+ end
733
+
734
+ def ==(v)
735
+ eql?(v)
736
+ end
737
+
738
+ def hash
739
+ self.to_name.hash
740
+ end
741
+ end
742
+
743
+ class GlobalVariable < Pointer
744
+ attr_reader :id
745
+
746
+ def initialize(gentry, types, translator)
747
+ super()
748
+ @id = gentry
749
+ @name = gentry.slice(1, gentry.size - 1)
750
+ @name = translator.allocate_name(@name)
751
+
752
+ if types
753
+ bug() unless types.is_a?(Array)
754
+ is_annotated(types)
755
+ end
756
+ end
757
+
758
+ def to_name
759
+ "global_#{@name}"
760
+ end
761
+
762
+ def source
763
+ @id.to_s
764
+ end
765
+
766
+ def eql?(v)
767
+ return false unless v.is_a?(GlobalVariable)
768
+ @id == v.id
769
+ end
770
+
771
+ def ==(v)
772
+ eql?(v)
773
+ end
774
+
775
+ def hash
776
+ self.to_name.hash
777
+ end
778
+ end
779
+
780
+ class DynamicVariable < Pointer
781
+ attr_reader :index, :level
782
+
783
+ def initialize(name, idx, op_idx, lv, types)
784
+ super()
785
+ @name = name
786
+ @index = idx
787
+ @op_idx = op_idx
788
+ @level = lv
789
+
790
+ if types
791
+ bug() unless types.is_a?(Array)
792
+ is_annotated(types)
793
+ end
794
+ end
795
+
796
+ def to_name
797
+ "dfp#{@level}[#{@op_idx}]"
798
+ end
799
+
800
+ def source
801
+ @name.to_s
802
+ end
803
+
804
+ def eql?(v)
805
+ return false unless v.is_a?(DynamicVariable)
806
+ @index == v.index && @level == v.level
807
+ end
808
+
809
+ def ==(v)
810
+ eql?(v)
811
+ end
812
+
813
+ def hash
814
+ self.to_name.hash
815
+ end
816
+
817
+ def declare?
818
+ false
819
+ end
820
+ end
821
+
822
+ class Argument < Variable
823
+ attr_reader :id, :lvar
824
+
825
+ def initialize(name, id, op_idx, lv, types)
826
+ super()
827
+ @name = name
828
+ @id = id
829
+ @op_idx = op_idx
830
+ @level = lv
831
+ @lvar = "local#{@id}_#{@name}" # FIXME
832
+
833
+ if types
834
+ bug() unless types.is_a?(Array)
835
+ is_static(types)
836
+ end
837
+ end
838
+
839
+ def to_name
840
+ "<Argument:#{@id}_#{@name}>"
841
+ end
842
+
843
+ def source
844
+ bug()
845
+ end
846
+
847
+ def eql?(v)
848
+ return false unless v.is_a?(Argument)
849
+ @id == v.id
850
+ end
851
+
852
+ def ==(v)
853
+ eql?(v)
854
+ end
855
+
856
+ def hash
857
+ self.to_name.hash
858
+ end
859
+ end
860
+
861
+ class LocalVariable < Variable
862
+ attr_reader :id, :name
863
+
864
+ def initialize(name, id, op_idx, lv, types)
865
+ super()
866
+ @name = name
867
+ @id = id
868
+ @op_idx = op_idx
869
+ @level = lv
870
+
871
+ if types
872
+ bug() unless types.is_a?(Array)
873
+ is_annotated(types)
874
+ end
875
+ end
876
+
877
+ def to_name
878
+ "local#{@id}_#{@name}"
879
+ end
880
+
881
+ def source
882
+ @name.to_s
883
+ end
884
+
885
+ def eql?(v)
886
+ return false unless v.is_a?(LocalVariable)
887
+ @id == v.id
888
+ end
889
+
890
+ def ==(v)
891
+ eql?(v)
892
+ end
893
+
894
+ def hash
895
+ self.to_name.hash
896
+ end
897
+
898
+ def has_undefined_path()
899
+ bug()
900
+ end
901
+ end
902
+
903
+ class TmpBuffer < Variable
904
+ attr_reader :index
905
+
906
+ def initialize(index)
907
+ super()
908
+ @index = index
909
+ end
910
+
911
+ def to_name
912
+ "cast_off_argv[#{@index}]"
913
+ end
914
+
915
+ def source
916
+ bug()
917
+ end
918
+
919
+ def eql?(v)
920
+ return false unless v.is_a?(TmpBuffer)
921
+ @index == v.index
922
+ end
923
+
924
+ def ==(v)
925
+ eql?(v)
926
+ end
927
+
928
+ def hash
929
+ self.to_name.hash
930
+ end
931
+ end
932
+ end
933
+ end
934
+