rubinius-ast 1.3.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module CodeTools
3
+ module Rubinius::ToolSet.current::TS
4
4
  module AST
5
5
  class Self < Node
6
6
  def bytecode(g)
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module CodeTools
3
+ module Rubinius::ToolSet.current::TS
4
4
  module AST
5
5
  class Send < Node
6
6
  attr_accessor :receiver, :name, :privately, :block, :variable, :vcall_style
@@ -65,11 +65,6 @@ module CodeTools
65
65
  end
66
66
 
67
67
  def defined(g)
68
- if @block.kind_of? For
69
- @block.defined(g)
70
- return
71
- end
72
-
73
68
  if @vcall_style and check_local_reference(g)
74
69
  g.push_literal "local-variable"
75
70
  return
@@ -264,8 +259,7 @@ module CodeTools
264
259
  g.push_state ClosedScope.new(@line)
265
260
  g.state.push_name :BEGIN
266
261
 
267
- g.push_rubinius
268
- g.find_const :Runtime
262
+ g.push_literal Compiler::Runtime
269
263
  @block.bytecode(g)
270
264
  g.send_with_block :pre_exe, 0, false
271
265
 
@@ -342,8 +336,7 @@ module CodeTools
342
336
  end
343
337
 
344
338
  def assignment_bytecode(g)
345
- g.push_block_arg
346
- convert(g)
339
+ g.push_proc
347
340
  @body.bytecode(g)
348
341
  end
349
342
 
@@ -810,10 +803,6 @@ module CodeTools
810
803
  var.variable = reference
811
804
  end
812
805
 
813
- def defined(g)
814
- g.push_literal "expression"
815
- end
816
-
817
806
  def sexp_name
818
807
  :for
819
808
  end
@@ -837,8 +826,7 @@ module CodeTools
837
826
 
838
827
  def bytecode(g)
839
828
  if @splat
840
- g.push_rubinius
841
- g.find_const :Runtime
829
+ g.push_literal Compiler::Runtime
842
830
  g.push_local 0
843
831
  g.send :unwrap_block_arg, 1
844
832
  else
@@ -1011,14 +999,7 @@ module CodeTools
1011
999
  end
1012
1000
 
1013
1001
  def to_sexp
1014
- args = @arguments.to_sexp
1015
- args << @block.to_sexp if @block
1016
- if @argument_count == 1 and !@yield_splat and @arguments.splat.nil? and
1017
- @arguments.array.first.kind_of? SplatValue
1018
- [:yield, [:array] + args]
1019
- else
1020
- [:yield] + args
1021
- end
1002
+ arguments_sexp :yield
1022
1003
  end
1023
1004
  end
1024
1005
 
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module CodeTools
3
+ module Rubinius::ToolSet.current::TS
4
4
  module AST
5
5
  module Transforms
6
6
  def self.register(category, name, klass)
@@ -249,6 +249,9 @@ module CodeTools
249
249
  class SendFastNew < SendWithArguments
250
250
  transform :default, :fast_new, "Fast SomeClass.new path"
251
251
 
252
+ # FIXME duplicated from kernel/common/compiled_code.rb
253
+ KernelMethodSerial = 47
254
+
252
255
  def self.match?(line, receiver, name, arguments, privately)
253
256
  # ignore vcall style
254
257
  return false if !arguments and privately
@@ -267,9 +270,9 @@ module CodeTools
267
270
  g.dup
268
271
 
269
272
  if @privately
270
- g.check_serial_private :new, Rubinius::CompiledCode::KernelMethodSerial
273
+ g.check_serial_private :new, KernelMethodSerial
271
274
  else
272
- g.check_serial :new, Rubinius::CompiledCode::KernelMethodSerial
275
+ g.check_serial :new, KernelMethodSerial
273
276
  end
274
277
  g.gif slow
275
278
 
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module CodeTools
3
+ module Rubinius::ToolSet.current::TS
4
4
  module AST
5
5
  class SplatValue < Node
6
6
  attr_accessor :value
@@ -12,83 +12,7 @@ module CodeTools
12
12
 
13
13
  def bytecode(g)
14
14
  @value.bytecode(g)
15
- return if @value.kind_of? ArrayLiteral
16
-
17
- convert_to_ary(g)
18
- end
19
-
20
- def convert_to_ary(g)
21
- done = g.new_label
22
- coerce = g.new_label
23
- coerce_method = :to_ary
24
-
25
- kind_of_array(g, done)
26
-
27
- check_respond_to = g.new_label
28
-
29
- g.dup
30
- g.push :nil
31
- g.swap
32
- g.send :equal?, 1, true
33
- g.gif check_respond_to
34
-
35
- g.make_array 1
36
- g.goto done
37
-
38
- check_respond_to.set!
39
- g.dup
40
- g.push_literal :to_ary
41
- g.send :respond_to?, 1, true
42
- g.git coerce
43
-
44
- discard = g.new_label
45
- check_array = g.new_label
46
-
47
- make_array = g.new_label
48
- make_array.set!
49
- g.dup
50
- g.send :to_a, 0, true
51
- coerce_method = :to_a
52
- g.goto check_array
53
-
54
- coerce.set!
55
- g.dup
56
- g.send :to_ary, 0, true
57
-
58
- g.dup
59
- g.push :nil
60
- g.send :equal?, 1, true
61
- coerce_method = :to_ary
62
- g.gif check_array
63
-
64
- g.pop
65
- g.goto make_array
66
-
67
- check_array.set!
68
- kind_of_array(g, discard)
69
-
70
- g.push_type
71
- g.move_down 2
72
- g.push_literal coerce_method
73
- g.push_cpath_top
74
- g.find_const :Array
75
- g.send :coerce_to_type_error, 4, true
76
- g.goto done
77
-
78
- discard.set!
79
- g.swap
80
- g.pop
81
-
82
- done.set!
83
- end
84
-
85
- def kind_of_array(g, label)
86
- g.dup
87
- g.push_cpath_top
88
- g.find_const :Array
89
- g.swap
90
- g.kind_of
91
- g.git label
15
+ g.cast_array unless @value.kind_of? ArrayLiteral
92
16
  end
93
17
 
94
18
  def to_sexp
@@ -113,7 +37,7 @@ module CodeTools
113
37
  if @array
114
38
  @array.bytecode(g)
115
39
  @rest.bytecode(g)
116
- convert_to_ary(g)
40
+ g.cast_array
117
41
  g.send :+, 1
118
42
  else
119
43
  @rest.bytecode(g)
@@ -121,69 +45,6 @@ module CodeTools
121
45
  end
122
46
  end
123
47
 
124
- # TODO: de-dup
125
- def convert_to_ary(g)
126
- done = g.new_label
127
- coerce = g.new_label
128
- make_array = g.new_label
129
- coerce_method = :to_ary
130
-
131
- kind_of_array(g, done)
132
-
133
- g.dup
134
- g.push_literal :to_ary
135
- g.send :respond_to?, 1, true
136
- g.git coerce
137
-
138
- discard = g.new_label
139
- check_array = g.new_label
140
-
141
- make_array.set!
142
- g.dup
143
- g.send :to_a, 0, true
144
- coerce_method = :to_a
145
- g.goto check_array
146
-
147
- coerce.set!
148
- g.dup
149
- g.send :to_ary, 0, true
150
-
151
- g.dup
152
- g.push :nil
153
- g.send :equal?, 1, true
154
- coerce_method = :to_ary
155
- g.gif check_array
156
-
157
- g.pop
158
- g.goto make_array
159
-
160
- check_array.set!
161
- kind_of_array(g, discard)
162
-
163
- g.push_type
164
- g.move_down 2
165
- g.push_literal :to_ary
166
- g.push_cpath_top
167
- g.find_const :Array
168
- g.send :coerce_to_type_error, 4, true
169
- g.goto done
170
-
171
- discard.set!
172
- g.swap
173
- g.pop
174
-
175
- done.set!
176
- end
177
-
178
- def kind_of_array(g, label)
179
- g.dup
180
- g.push_cpath_top
181
- g.find_const :Array
182
- g.swap
183
- g.kind_of
184
- g.git label
185
- end
186
-
187
48
  # Dive down and try to find an array of regular values
188
49
  # that could construct the left side of a concatination.
189
50
  # This is used to minimize the splat doing a send.
@@ -281,49 +142,8 @@ module CodeTools
281
142
  def bytecode(g)
282
143
  pos(g)
283
144
 
284
- done = g.new_label
285
- coerce = g.new_label
286
-
287
145
  @value.bytecode(g)
288
- kind_of_array(g, done)
289
-
290
- g.dup
291
- g.push_literal :to_ary
292
- g.send :respond_to?, 1, true
293
- g.git coerce
294
-
295
- g.make_array 1
296
- g.goto done
297
-
298
- coerce.set!
299
- g.dup
300
- g.send :to_ary, 0, true
301
-
302
- discard = g.new_label
303
- kind_of_array(g, discard)
304
-
305
- g.push_type
306
- g.move_down 2
307
- g.push_literal :to_a
308
- g.push_cpath_top
309
- g.find_const :Array
310
- g.send :coerce_to_type_error, 4, true
311
- g.goto done
312
-
313
- discard.set!
314
- g.swap
315
- g.pop
316
-
317
- done.set!
318
- end
319
-
320
- def kind_of_array(g, label)
321
- g.dup
322
- g.push_cpath_top
323
- g.find_const :Array
324
- g.swap
325
- g.kind_of
326
- g.git label
146
+ g.cast_multi_value
327
147
  end
328
148
 
329
149
  def to_sexp
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: us-ascii -*-
2
2
 
3
- module CodeTools
3
+ module Rubinius::ToolSet.current::TS
4
4
  module AST
5
5
  class BackRef < Node
6
6
  attr_accessor :kind
@@ -45,7 +45,7 @@ module CodeTools
45
45
  g.is_nil
46
46
  g.git f
47
47
 
48
- g.push_literal "$#{@kind}"
48
+ g.push_literal "global-variable"
49
49
  g.string_dup
50
50
 
51
51
  g.goto done
@@ -87,7 +87,7 @@ module CodeTools
87
87
  g.is_nil
88
88
  g.git f
89
89
 
90
- g.push_literal "$#{@which}"
90
+ g.push_literal "global-variable"
91
91
  g.string_dup
92
92
 
93
93
  g.goto done
@@ -541,7 +541,7 @@ module CodeTools
541
541
  end
542
542
 
543
543
  class MultipleAssignment < Node
544
- attr_accessor :left, :right, :splat, :block
544
+ attr_accessor :left, :right, :splat, :block, :post
545
545
 
546
546
  def initialize(line, left, right, splat)
547
547
  @line = line
@@ -549,8 +549,17 @@ module CodeTools
549
549
  @right = right
550
550
  @splat = nil
551
551
  @block = nil # support for |&b|
552
-
553
- @fixed = right.kind_of?(ArrayLiteral) ? true : false
552
+ @post = nil # in `a,*b,c`, c is in post.
553
+
554
+ if splat.kind_of?(PostArg)
555
+ @fixed = false
556
+ @post = splat.rest
557
+ splat = splat.into
558
+ elsif right.kind_of?(ArrayLiteral)
559
+ @fixed = right.body.size > 1
560
+ else
561
+ @fixed = false
562
+ end
554
563
 
555
564
  if splat.kind_of? Node
556
565
  if @left
@@ -573,6 +582,44 @@ module CodeTools
573
582
  end
574
583
  end
575
584
 
585
+ def pad_short(g)
586
+ short = @left.body.size - @right.body.size
587
+ if short > 0
588
+ short.times { g.push :nil }
589
+ g.make_array 0 if @splat
590
+ end
591
+ end
592
+
593
+ def pop_excess(g)
594
+ excess = @right.body.size - @left.body.size
595
+ excess.times { g.pop } if excess > 0
596
+ end
597
+
598
+ def make_array(g)
599
+ size = @right.body.size - @left.body.size
600
+ g.make_array size if size >= 0
601
+ end
602
+
603
+ def make_retval(g)
604
+ size = @right.body.size
605
+ if @left and !@splat
606
+ lhs = @left.body.size
607
+ size = lhs if lhs > size
608
+ end
609
+ g.dup_many @right.body.size
610
+ g.make_array @right.body.size
611
+ g.move_down size
612
+ end
613
+
614
+ def rotate(g)
615
+ if @splat
616
+ size = @left.body.size + 1
617
+ else
618
+ size = @right.body.size
619
+ end
620
+ g.rotate size
621
+ end
622
+
576
623
  def iter_arguments
577
624
  @iter_arguments = true
578
625
  end
@@ -601,233 +648,83 @@ module CodeTools
601
648
  end
602
649
 
603
650
  def bytecode(g, array_on_stack=false)
604
- declare_local_scope(g.state.scope)
605
-
606
- case @right
607
- when ArrayLiteral, ConcatArgs
608
- @right.bytecode(g)
609
- when SplatValue
610
- @right.bytecode(g)
611
- convert_to_ary(g)
612
- when ToArray
613
- @right.bytecode(g)
614
- when nil
615
- convert_to_ary(g)
616
- else
617
- @right.bytecode(g)
618
- convert_to_a(g)
651
+ unless array_on_stack
652
+ g.cast_array unless @right or (@splat and not @left)
619
653
  end
620
654
 
621
- size = g.new_stack_local
622
- g.dup
623
- g.send :size, 0, true
624
- g.set_stack_local size
625
- g.pop
626
-
627
- index = g.new_stack_local
628
- g.push 0
629
- g.set_stack_local index
630
- g.pop
631
-
632
- g.state.push_masgn
633
-
634
- if @left
635
- @left.body.each do |x|
636
- convert_to_ary(g) if x.kind_of? MultipleAssignment
637
-
638
- get_element(g, index)
639
-
640
- x.bytecode(g)
641
- g.pop
642
- end
643
- end
644
-
645
- if @splat
646
- g.dup
647
-
648
- convert_to_ary(g) if @splat.kind_of? SplatValue
649
-
650
- g.push_stack_local index
651
-
652
- check_count = g.new_label
653
-
654
- g.push_stack_local size
655
- g.push_stack_local index
656
- g.send :-, 1, true
655
+ declare_local_scope(g.state.scope)
657
656
 
658
- g.goto check_count
657
+ if @fixed
658
+ pad_short(g) if @left and !@splat
659
+ @right.body.each { |x| x.bytecode(g) }
659
660
 
660
- underflow = g.new_label
661
- assign_splat = g.new_label
661
+ if @left
662
+ make_retval(g)
662
663
 
663
- underflow.set!
664
- g.pop_many 3
665
- g.make_array 0
664
+ if @splat
665
+ pad_short(g)
666
+ make_array(g)
667
+ end
666
668
 
667
- g.goto assign_splat
669
+ rotate(g)
668
670
 
669
- check_count.set!
670
- g.dup
671
- g.push 0
672
- g.send :<, 1, true
673
- g.git underflow
671
+ g.state.push_masgn
672
+ @left.body.each do |x|
673
+ x.bytecode(g)
674
+ g.pop
675
+ end
676
+ g.state.pop_masgn
674
677
 
675
- g.dup
676
- g.push_stack_local index
677
- g.send :+, 1, true
678
- g.set_stack_local index
679
- g.pop
678
+ pop_excess(g) unless @splat
679
+ end
680
+ else
681
+ if @right
682
+ if @right.kind_of? ArrayLiteral and @right.body.size == 1
683
+ @right.body.first.bytecode(g)
684
+ g.cast_multi_value
685
+ else
686
+ @right.bytecode(g)
687
+ end
680
688
 
681
- g.send :[], 2, true
689
+ g.cast_array unless @right.kind_of? ToArray
690
+ g.dup # Use the array as the return value
691
+ end
682
692
 
683
- assign_splat.set!
693
+ if @left
694
+ g.state.push_masgn
695
+ @left.body.each do |x|
696
+ g.shift_array
697
+ g.cast_array if x.kind_of? MultipleAssignment and x.left
698
+ x.bytecode(g)
699
+ g.pop
700
+ end
701
+ g.state.pop_masgn
702
+ end
684
703
 
685
- # TODO: Fix nodes to work correctly.
686
- case @splat
687
- when EmptySplat
688
- # nothing
689
- when SplatArray, SplatWrapped
690
- @splat.value.bytecode(g)
691
- else
692
- @splat.bytecode(g)
704
+ if @post
705
+ g.state.push_masgn
706
+ @post.body.each do |x|
707
+ g.dup
708
+ g.send :pop, 0
709
+ g.cast_array if x.kind_of? MultipleAssignment and x.left
710
+ x.bytecode(g)
711
+ g.pop
712
+ end
713
+ g.state.pop_masgn
693
714
  end
694
- g.pop
695
715
  end
696
716
 
697
- g.state.pop_masgn
698
- end
699
-
700
- def convert_to_a(g)
701
- done = g.new_label
702
- check_array = g.new_label
703
-
704
- kind_of_array(g, done)
705
-
706
- wrap_tuple = g.new_label
707
- kind_of_tuple(g, wrap_tuple)
708
-
709
- g.dup
710
- g.send :to_a, 0, true
711
- g.goto check_array
712
-
713
- wrap_tuple.set!
714
- g.dup
715
- g.make_array 0
716
- g.dup
717
- g.move_down 2
718
- g.swap
719
- g.push_literal :@tuple
720
- g.swap
721
- g.invoke_primitive :object_set_ivar, 3
722
- g.send :size, 0, true
723
- g.push_literal :@total
724
- g.swap
725
- g.invoke_primitive :object_set_ivar, 3
726
- g.pop
727
- g.goto done
728
-
729
- discard = g.new_label
730
-
731
- check_array.set!
732
- kind_of_array(g, discard)
733
-
734
- g.push_type
735
- g.move_down 2
736
- g.push_literal :to_a
737
- g.push_cpath_top
738
- g.find_const :Array
739
- g.send :coerce_to_type_error, 4, true
740
- g.goto done
741
-
742
- discard.set!
743
- g.swap
744
- g.pop
745
-
746
- done.set!
747
- end
748
-
749
- def convert_to_ary(g)
750
- done = g.new_label
751
- coerce = g.new_label
752
- make_array = g.new_label
753
- coerce_method = :to_ary
754
-
755
- kind_of_array(g, done)
756
-
757
- g.dup
758
- g.push_literal :to_ary
759
- g.send :respond_to?, 1, true
760
- g.git coerce
761
-
762
- discard = g.new_label
763
- check_array = g.new_label
764
-
765
- make_array.set!
766
- g.dup
767
- g.send :to_a, 0, true
768
- coerce_method = :to_a
769
- g.goto check_array
770
-
771
- coerce.set!
772
- g.dup
773
- g.send :to_ary, 0, true
774
-
775
- g.dup
776
- g.push :nil
777
- g.send :equal?, 1, true
778
- coerce_method = :to_ary
779
- g.gif check_array
780
-
781
- g.pop
782
- g.goto make_array
783
-
784
- check_array.set!
785
- kind_of_array(g, discard)
786
-
787
- g.push_type
788
- g.move_down 2
789
- g.push_literal coerce_method
790
- g.push_cpath_top
791
- g.find_const :Array
792
- g.send :coerce_to_type_error, 4, true
793
- g.goto done
794
-
795
- discard.set!
796
- g.swap
797
- g.pop
798
-
799
- done.set!
800
- end
801
-
802
- def kind_of_array(g, label)
803
- g.dup
804
- g.push_cpath_top
805
- g.find_const :Array
806
- g.swap
807
- g.kind_of
808
- g.git label
809
- end
810
-
811
- def kind_of_tuple(g, label)
812
- g.dup
813
- g.push_rubinius
814
- g.find_const :Tuple
815
- g.swap
816
- g.kind_of
817
- g.git label
818
- end
717
+ if @splat
718
+ g.state.push_masgn
719
+ @splat.bytecode(g)
819
720
 
820
- def get_element(g, index)
821
- g.dup
822
- g.push_stack_local index
721
+ # Use the array as the return value
722
+ g.dup if @fixed and !@left
823
723
 
824
- g.dup
825
- g.push 1
826
- g.send :+, 1, true
827
- g.set_stack_local index
828
- g.pop
724
+ g.state.pop_masgn
725
+ end
829
726
 
830
- g.send :[], 1, true
727
+ g.pop if @right and (!@fixed or @splat)
831
728
  end
832
729
 
833
730
  def defined(g)