Some refactoring in 'Arguments' implementation
[rbx.git] / lib / compiler / bytecode.rb
blob6b0cb3b92a85da76a0c1e42a673c53a15daf36d9
1 # Implements methods on each Node subclass for generatng bytecode
2 # from itself.
4 require 'compiler/generator'
6 class Compiler
8   ##
9   # The precursor to a CompiledMethod
11   class MethodDescription
12     def initialize(gen_class, locals)
13       @generator = gen_class.new
14       @locals = locals
15       @required = 0
16       @optional = 0
17       @name = :__unknown__
18     end
20     attr_reader :generator, :locals
21     attr_accessor :required, :optional, :name, :args
23     def run(container, body)
24       @generator.run(body)
25       @required, @optional = container.argument_info
26       @name = container.name
27     end
29     def ==(desc)
30       desc.kind_of? MethodDescription and @generator == desc.generator
31     end
33     def to_cmethod
34       @generator.to_cmethod(self)
35     end
37     def inspect
38       [:method_description, @name, @required, @optional, @generator].inspect
39     end
40   end
43 # Parent class of all AST classes used by the compiler.  Contains utility
44 # classes used by nodes.
46 class Node
48   def show_errors(gen, &block)
49     @compiler.show_errors(gen, &block)
50   end
52   class ClosedScope
54     def new_description
55       MethodDescription.new(@compiler.generator_class, self.locals)
56     end
58     def to_description(name = nil)
59       desc = new_description()
60       desc.name = name if name
61       gen = desc.generator
63       show_errors(gen) do
64         desc.run(self, self)
65         gen.close
66       end
67       return desc
68     end
70     def argument_info
71       [0, 0]
72     end
74     def push_self_or_class(meth)
75       is_module = meth.new_label
76       meth.push :self
77       meth.push_cpath_top
78       meth.find_const :Module
79       meth.push :self
80       meth.kind_of
81       meth.git is_module
82       meth.send :class, 0
83       is_module.set!
84     end
86     def attach_and_call(g, name)
87       # If the body is empty, then don't bother with it.
88       return if @body.empty?
90       desc = new_description()
91       meth = desc.generator
93       prelude(g, meth)
95       push_self_or_class(meth)
96       meth.set_encloser
98       set(:scope, self) do
99         show_errors(meth) do
100           desc.run self, @body
101         end
102       end
104       meth.sret
105       meth.close
107       g.dup
108       g.push_literal desc
109       g.swap
110       g.attach_method name
111       g.pop
112       g.send name, 0
113       g.push_encloser
114     end
116     def prelude(orig, g)
118       if orig
119         g.set_line orig.line, orig.file
120       end
122       # Allocate some stack to store locals.
124       if @alloca > 0
125         g.allocate_stack @alloca
126       end
127     end
128   end
130   class Snippit
131     def bytecode(g)
132       set(:scope, self) do
133         prelude(nil, g)
134         @body.bytecode(g)
135       end
136     end
137   end
139   class Expression
140     def bytecode(g)
141       set(:scope, self) do
142         prelude(nil, g)
143         @body.bytecode(g)
144         g.sret
145       end
146     end
147   end
149   # REFACTOR See if there is a sane way to call 'super' here
150   # We need to call 'push_encloser' before 'sret', hence the copy-and-paste
151   class EvalExpression
152     def bytecode(g)
153       set(:scope, self) do
154         prelude(nil, g)
155         @body.bytecode(g)
156         g.sret
157       end
158       enlarge_context
159     end
160   end
162   class Script
163     def bytecode(g)
164       set(:scope, self) do
165         prelude(nil, g)
166         @body.bytecode(g)
167         g.pop
168         g.push :true
169         g.sret
170       end
171     end
172   end
174   class Newline
175     def bytecode(g)
176       g.set_line @line, @file
177       @child.bytecode(g) if @child
178     end
180     def call_bytecode(g)
181       g.set_line @line, @file
182       @child.call_bytecode(g)
183     end
184   end
186   # TESTED
187   class True
188     def bytecode(g)
189       g.push :true
190     end
191   end
193   # TESTED
194   class False
195     def bytecode(g)
196       g.push :false
197     end
198   end
200   # TESTED
201   class Nil
202     def bytecode(g)
203       g.push :nil
204     end
205   end
207   # TESTED
208   class Self
209     def bytecode(g)
210       g.push :self
211     end
212   end
214   # TESTED
215   class And
216     def bytecode(g, use_gif=true)
217       @left.bytecode(g)
218       g.dup
219       lbl = g.new_label
221       if use_gif
222         g.gif lbl
223       else
224         g.git lbl
225       end
227       g.pop
228       @right.bytecode(g)
229       lbl.set!
230     end
231   end
233   # TESTED
234   class Or
235     def bytecode(g)
236       super(g, false)
237     end
238   end
240   # TESTED
241   class Not
242     def bytecode(g)
243       @child.bytecode(g)
244       tr = g.new_label
245       ed = g.new_label
246       g.git tr
247       g.push :true
248       g.goto ed
249       tr.set!
250       g.push :false
251       ed.set!
252     end
253   end
255   # TESTED
256   class Negate
257     def bytecode(g)
258       if @child.is? NumberLiteral
259         g.push -@child.value
260       else
261         @child.bytecode(g)
262         g.send :"-@", 0
263       end
264     end
265   end
267   # TESTED
268   class NumberLiteral
269     def bytecode(g)
270       g.push @value
271     end
272   end
274   # TESTED
275   class Literal
276     def bytecode(g)
277       g.push_unique_literal @value
278     end
279   end
281   # TESTED
282   class ArrayLiteral
283     def bytecode(g)
284       @body.each do |x|
285         x.bytecode(g)
286       end
288       g.make_array @body.size
289     end
290   end
292   # TESTED
293   class EmptyArray
294     def bytecode(g)
295       g.make_array 0
296     end
297   end
299   # TESTED
300   class HashLiteral
301     def bytecode(g)
302       count = @body.size
303       i = count - 1
305       while i > 0
306         v = @body[i]
307         k = @body[i - 1]
309         v.bytecode(g)
310         k.bytecode(g)
311         i -= 2
312       end
314       g.push_cpath_top
315       g.find_const :Hash
316       g.send :[], count
317     end
318   end
320   # TESTED
321   class StringLiteral
322     def bytecode(g)
323       g.push_literal @string
324       g.string_dup
325     end
326   end
328   # TESTED
329   class ExecuteString
330     def bytecode(g)
331       super(g)
332       g.push :self
333       g.send :`, 1, true # ` (silly vim/emacs)
334     end
335   end
337   # TESTED
338   class ToString
339     def bytecode(g)
340       @child.bytecode(g)
341       g.send :to_s, 0, true
342     end
343   end
345   # TESTED
346   class DynamicString
347     def bytecode(g)
348       @body.reverse_each do |x|
349         x.bytecode(g)
350       end
351       g.push_literal @string
352       g.string_dup
354       @body.size.times do
355         g.string_append
356       end
357     end
358   end
360   # TESTED
361   class DynamicExecuteString
362     def bytecode(g)
363       super(g)
364       g.push :self
365       g.send :`, 1, true #`
366     end
367   end
369   # TESTED
370   class DynamicSymbol
371     def bytecode(g)
372       @string.bytecode(g)
373       g.send :to_sym, 0, true
374     end
375   end
377   # TESTED
378   class RegexLiteral
379     def bytecode(g)
380       # A regex literal should only be converted to a Regexp the first time it
381       # is encountered. We push a literal nil here, and then overwrite the
382       # literal value with the created Regexp if it is nil, i.e. the first time
383       # only. Subsequent encounters will use the previously created Regexp
384       idx = g.add_literal(nil)
385       g.push_literal_at idx
386       g.dup
387       g.is_nil
389       lbl = g.new_label
390       g.gif lbl
391       g.pop
392       g.push @options
393       g.push_literal @source
394       g.push_const :Regexp
395       g.send :new, 2
396       g.set_literal idx
397       lbl.set!
398     end
399   end
401   # TESTED
402   class DynamicRegex
403     def bytecode(g)
404       g.push @options
406       super(g)
408       g.push_const :Regexp
409       g.send :new, 2
410     end
411   end
413   # TESTED
414   class DynamicOnceRegex
415     def bytecode(g)
416       idx = g.add_literal(nil)
417       g.push_literal_at idx
418       g.dup
419       g.is_nil
421       lbl = g.new_label
422       g.gif lbl
423       g.pop
425       super(g)
427       g.set_literal idx
428       lbl.set!
429     end
430   end
432   # Implicit match against $_
433   class Match
434     def bytecode(generator)
435       @target.bytecode generator
436       @pattern.bytecode generator
437       generator.send :=~, 1
438     end
439   end
441   # TESTED
442   class Match2
443     def bytecode(g)
444       @target.bytecode(g)
445       @pattern.bytecode(g)
446       g.send :=~, 1
447     end
448   end
450   # TESTED
451   class Match3
452     def bytecode(g)
453       @pattern.bytecode(g)
454       @target.bytecode(g)
455       g.send :=~, 1
456     end
457   end
459   # TESTED
460   class BackRef
461     def bytecode(g)
462       g.push_literal @kind
463       g.push_context
464       g.send :back_ref, 1
465     end
466   end
468   # TESTED
469   class NthRef
470     def bytecode(g)
471       g.push @which
472       g.push_context
473       g.send :nth_ref, 1
474     end
475   end
477   # TESTED
478   class Block
479     def bytecode(g)
480       if @body.empty?
481         g.push :nil
482         return
483       end
485       count = @body.size - 1
486       i = 0
487       while i < count
488         ip = g.ip
489         @body[i].bytecode(g)
491         # guards for things that plugins might optimize away.
492         g.pop if g.advanced_since?(ip)
493         i += 1
494       end
495       @body[count].bytecode(g)
496     end
497   end
499   # TESTED
500   class Scope
501     def bytecode(g)
502       if @block.nil?
503         g.push :nil
504         return
505       end
507       @block.bytecode(g)
508     end
509   end
511   # TESTED
512   class If
513     def bytecode(g)
514       ed = g.new_label
515       el = g.new_label
517       @condition.bytecode(g)
519       if @then and @else
520         g.gif el
521         @then.bytecode(g)
522         g.goto ed
523         el.set!
524         @else.bytecode(g)
525       elsif @then
526         g.gif el
527         @then.bytecode(g)
528         g.goto ed
529         el.set!
530         g.push :nil
531       elsif @else
532         g.git el
533         @else.bytecode(g)
534         g.goto ed
535         el.set!
536         g.push :nil
537       else
538         # An if with no code. Sweet.
539         g.pop
540         g.push :nil
541         return
542       end
544       ed.set!
545     end
546   end
548   # TESTED
549   class While
550     def bytecode(g, use_gif=true)
551       g.push_modifiers
553       top = g.new_label
554       bot = g.new_label
555       g.break = g.new_label
557       if @check_first
558         g.redo = g.new_label
559         g.next = top
561         top.set!
563         @condition.bytecode(g)
564         if use_gif
565           g.gif bot
566         else
567           g.git bot
568         end
570         g.redo.set!
572         @body.bytecode(g)
573         g.pop
574       else
575         g.next = g.new_label
576         g.redo = top
578         top.set!
580         @body.bytecode(g)
581         g.pop
583         g.next.set!
584         @condition.bytecode(g)
585         if use_gif
586           g.gif bot
587         else
588           g.git bot
589         end
590       end
592       g.goto top
594       bot.set!
595       g.push :nil
596       g.break.set!
598       g.pop_modifiers
599     end
600   end
602   # TESTED
603   class Until
604     def bytecode(g)
605       super(g, false)
606     end
607   end
609   # TESTED
610   class Loop
611     def bytecode(g)
612       g.push_modifiers
614       g.break = g.new_label
615       g.next = g.redo = top = g.new_label
616       top.set!
618       if @body              # Empty loop
619         @body.bytecode(g)
620         g.pop
621       end
623       g.goto top
625       g.break.set!
626       g.pop_modifiers
627     end
628   end
630   # TESTED
631   class Iter
632     def argument_info
633       [@arguments.arity, @arguments.optional.size]
634     end
636     def bytecode(g)
637       desc = MethodDescription.new @compiler.generator_class, @locals
638       desc.name = :__block__
639       desc.required, desc.optional = argument_info
640       sub = desc.generator
642       # Push line info down.
643       sub.set_line g.line, g.file
645       show_errors(sub) do
646         if @arguments
647           @arguments.bytecode(sub)
648         else
649           # Remove the block args.
650           sub.pop
651         end
652         sub.push_modifiers
653         sub.break = nil
654         sub.next = nil
655         sub.redo = sub.new_label
656         sub.redo.set!
657         @body.bytecode(sub)
658         sub.pop_modifiers
659         sub.soft_return
660         sub.close
661       end
663       g.push_literal desc
664       g.create_block2
665     end
666   end
668   # TESTED
669   class BlockPass
670     def bytecode(g)
671       @block.bytecode(g)
672       nil_block = g.new_label
673       g.dup
674       g.is_nil
675       g.git nil_block
677       g.push_cpath_top
678       g.find_const :Proc
679       g.send :__from_block__, 1
681       nil_block.set!
682     end
683   end
685   # TESTED
686   class Break
688     def do_value(g)
689       if @value
690         @value.bytecode(g)
691       else
692         g.push :nil
693       end
694     end
696     def jump_error(g, msg)
697       g.push_literal msg
698       g.push_const :LocalJumpError
699       g.push :self
700       g.send :raise, 2, true
701     end
703     def bytecode(g)
704       do_value(g)
706       if g.break
707         g.goto g.break
708       elsif @in_block
709         # Set the return value from @value above.
710         g.push_local @check_var.slot
711         g.send :break_value=, 1
712         g.pop
714         # Now raise it.
715         g.push_local @check_var.slot
716         g.raise_exc
717       else
718         g.pop
719         g.push_const :Compile
720         g.send :__unexpected_break__, 0
721       end
722     end
723   end
725   # TESTED
726   class Redo
727     def bytecode(g)
728       if g.redo
729         g.goto g.redo
730       else
731         jump_error g, "redo used in invalid context"
732       end
733     end
734   end
736   class Next
737     def bytecode(g)
738       if g.next
739         g.goto g.next
740       elsif @in_block
741         if @value
742           @value.bytecode(g)
743         else
744           g.push :nil
745         end
746         g.soft_return
747       else
748         jump_error g, "next used in invalid context"
749       end
750     end
751   end
753   class Retry
754     def bytecode(g)
755       if g.retry
756         g.goto g.retry
757       else
758         jump_error g, "retry used in invalid context"
759       end
760     end
761   end
763   # TESTED
764   class When
765     # The bytecode to test a when condition is different, depending on whether
766     # or not the case statement has a receiver, i.e.
767     #   case foo; when ...
768     # vs
769     #   case; when ...
770     def condition_bytecode(g, has_receiver, cond)
771       if has_receiver
772         # Case
773         g.dup
774         cond.bytecode(g)
775         g.send :===, 1
776       else
777         # ManyIf - no receiver
778         cond.bytecode(g)
779       end
780     end
782     def bytecode(g, has_receiver, nxt, fin)
783       if @conditions.size == 1 and !@splat
784         condition_bytecode(g, has_receiver, @conditions.first)
785         g.gif nxt
786       else
787         body = g.new_label
789         @conditions.each do |c|
790           condition_bytecode(g, has_receiver, c)
791           g.git body
792         end
794         if @splat
795           if @splat.kind_of? Array
796             @splat.each do |c|
797               condition_bytecode(g, has_receiver, c)
798               g.git body
799             end
800           elsif has_receiver
801             g.dup
802             @splat.bytecode(g)
803             g.cast_array
804             g.send :__matches_when__, 1
805             g.git body
806           else
807             raise Error, "encountered splat on many-if!"
808           end
809         end
811         g.goto nxt
813         body.set!
814       end
816       # Remove the thing we've been testing.
817       g.pop if has_receiver
818       @body.bytecode(g)
819       g.goto fin
820     end
821   end
823   # TESTED
824   class Case
825     def bytecode(g)
826       fin = g.new_label
828       @receiver.bytecode(g) if has_receiver?
829       @whens.each do |w|
830         nxt = g.new_label
831         w.bytecode(g, has_receiver?, nxt, fin)
832         nxt.set!
833       end
835       # The condition is still on the stack
836       g.pop if has_receiver?
837       if @else
838         @else.bytecode(g)
839       else
840         g.push :nil
841       end
843       fin.set!
844     end
845   end
847   # TESTED
848   class LocalAssignment
849     def bytecode(g)
850       if @value
851         @value.bytecode(g)
852       end
854       # No @value means assume that someone else put the value on the
855       # stack (ie, an masgn)
857       if @variable.on_stack?
858         if @variable.argument?
859           raise Error, "Invalid access semantics for argument: #{@name}"
860         end
862         g.set_local_fp @variable.stack_position
863       elsif @variable.created_in_block?
864         g.set_local_depth @depth, @variable.slot
865       else
866         g.set_local @variable.slot
867       end
868     end
869   end
871   # TESTED
872   class LocalAccess
873     def bytecode(g)
874       if @variable.on_stack?
875         if @variable.argument?
876           g.from_fp @variable.stack_position
877         else
878           g.get_local_fp @variable.stack_position
879         end
880       elsif @variable.created_in_block?
881         g.push_local_depth @depth, @variable.slot
882       else
883         g.push_local @variable.slot
884       end
885     end
886   end
888   class BlockAsArgument
889     def bytecode(g)
890       g.set_local @variable.slot
891     end
892   end
894   # TESTED
895   class SValue
896     def bytecode(g)
897       @child.bytecode(g)
898       g.cast_array
900       # If the array has 1 or 0 elements, grab the 0th element.
901       # otherwise, leave the array on the stack.
903       g.dup
904       g.send :size, 0
905       g.push 1
906       g.send :<, 1
908       lbl = g.new_label
909       g.git lbl
911       g.push 0
912       g.swap
913       g.send :at, 1
915       lbl.set!
916     end
917   end
919   # TESTED
920   class Splat
921     def bytecode(g)
922       @child.bytecode(g)
923       g.cast_array
924     end
926     # Bytecode generation when a splat is used as a method arg
927     def call_bytecode(g)
928       @child.bytecode(g)
929       g.cast_array_for_args 0
930       g.push_array
931     end
932   end
934   # TESTED
935   class OpAssignOr
936     def bytecode(g, use_gif=false)
937       if @left.is? CVar then
938         @left.check_first_bytecode(g)
939       else
940         @left.bytecode(g)
941       end
942       lbl = g.new_label
943       g.dup
944       if use_gif
945         g.gif lbl
946       else
947         g.git lbl
948       end
949       g.pop
950       @right.bytecode(g)
951       lbl.set!
952     end
953   end
955   # TESTED
956   class OpAssignAnd
957     def bytecode(g)
958       super(g, true)
959     end
960   end
962   # TESTED
963   class OpAssign1
964     def index_bytecode(g)
965       @index.reverse.each do |idx|
966         idx.bytecode(g)
967         g.swap
968       end
969     end
971     def bytecode(g)
972       fnd = g.new_label
973       fin = g.new_label
975       @object.bytecode(g)
976       g.dup
977       index_bytecode(g)
978       g.send :[], @index.size
980       if @kind == :or or @kind == :and
981         g.dup
982         if @kind == :or
983           g.git fnd
984         else
985           g.gif fnd
986         end
987         g.pop
988         @value.bytecode(g)
989       else
990         @value.bytecode(g)
991         g.swap
992         g.send @kind, 1
993         g.swap
994         index_bytecode(g)
995         g.send :[]=, @index.size + 1
996         return
997       end
999       g.swap
1000       index_bytecode(g)
1001       g.send :[]=, @index.size + 1
1002       g.goto fin
1004       fnd.set!
1005       g.swap
1006       g.pop
1008       fin.set!
1009     end
1010   end
1012   # TESTED
1013   class OpAssign2
1014     def bytecode(g)
1015       fnd = g.new_label
1016       fin = g.new_label
1017       @object.bytecode(g)
1018       g.dup
1019       g.send @method, 0
1021       if @kind == :or or @kind == :and
1022         g.dup
1023         if @kind == :or
1024           g.git fnd
1025         else
1026           g.gif fnd
1027         end
1028         g.pop
1029         @value.bytecode(g)
1030       else
1031         @value.bytecode(g)
1032         g.swap
1033         g.send @kind, 1
1034         g.swap
1035         g.send @assign, 1
1036         return
1037       end
1039       g.swap
1040       g.send @assign, 1
1041       g.goto fin
1043       fnd.set!
1044       g.swap
1045       g.pop
1047       fin.set!
1048     end
1049   end
1051   # TESTED
1052   class ConcatArgs
1053     def call_bytecode(g)
1054       @array.bytecode(g)
1055       g.cast_array_for_args @rest.size
1056       g.push_array
1057       g.get_args
1058       @rest.reverse_each do |x|
1059         x.bytecode(g)
1060         g.swap
1061       end
1062     end
1064     def bytecode(g)
1065       @array.bytecode(g)
1066       g.cast_array
1067       @rest.each do |x|
1068         x.bytecode(g)
1069       end
1070       g.make_array @rest.size
1071       g.send :+, 1
1072     end
1074   end
1076   # TESTED
1077   class PushArgs
1078     def bytecode(g)
1079       @item.bytecode(g)
1080       @array.bytecode(g)
1081       g.cast_array_for_args 1
1082       g.push_array
1083     end
1085     # Used for h[*x] = 3
1086     def attr_bytecode(g)
1087       @item.bytecode(g)
1088       g.dup
1089       @array.bytecode(g)
1090       g.cast_array_for_args 1
1091       g.push_array
1092     end
1093   end
1095   # TESTED
1096   class AccessSlot
1097     def bytecode(g)
1098       g.push_my_field @index
1099     end
1100   end
1102   # TESTED
1103   class SetSlot
1104     def bytecode(g)
1105       @value.bytecode(g)
1106       g.store_my_field @index
1107     end
1108   end
1110   # TESTED
1111   class IVar
1112     def bytecode(g)
1113       g.push_ivar @name
1114     end
1115   end
1117   # TESTED
1118   class IVarAssign
1119     def bytecode(g)
1120       @value.bytecode(g) if @value
1121       g.set_ivar @name
1122     end
1123   end
1125   # TESTED
1126   class GVar
1127     def bytecode(g)
1128       if @name == :$!
1129         g.push_exception
1130       elsif @name == :$~
1131         g.push_cpath_top
1132         g.find_const :Regexp
1133         g.send :last_match, 0
1134       else
1135         g.push_literal @name
1136         g.push_cpath_top
1137         g.find_const :Globals
1138         g.send :[], 1
1139       end
1140     end
1141   end
1143   # TESTED
1144   class GVarAssign
1145     def bytecode(g)
1146       @value.bytecode(g) if @value
1148       if @name == :$!
1149         g.raise_exc
1150         return
1151       elsif @name == :$~
1152         g.push_cpath_top
1153         g.find_const :Regexp
1154         g.send :my_last_match=, 1
1155         return
1156       end
1158       g.push_literal @name
1159       g.push_cpath_top
1160       g.find_const :Globals
1161       g.send :[]=, 2
1162     end
1163   end
1165   # TESTED
1166   class ConstFind
1167     def bytecode(g)
1168       g.push_const @name
1169     end
1170   end
1172   # TESTED
1173   class ConstAccess
1174     def bytecode(g)
1175       @parent.bytecode(g)
1176       g.find_const @name
1177     end
1178   end
1180   # TESTED
1181   class ConstAtTop
1182     def bytecode(g)
1183       g.push_cpath_top
1184       g.find_const @name
1185     end
1186   end
1188   # TESTED
1189   class ConstSet
1190     def bytecode(g)
1191       if @compiler.kernel?
1192         if @parent
1193           @parent.bytecode(g)
1194           @value.bytecode(g)
1195           g.set_const @name, true
1196         elsif @from_top
1197           g.push_cpath_top
1198           @value.bytecode(g)
1199           g.set_const @name, true
1200         else
1201           @value.bytecode(g) if @value
1202           g.set_const @name
1203         end
1204       else
1205         @value.bytecode(g) if @value
1206         g.push_literal @name
1208         if @parent
1209           @parent.bytecode(g)
1210         elsif @from_top
1211           g.push_cpath_top
1212         else
1213           g.push_context
1214         end
1216         g.send :__const_set__, 2
1217       end # @compiler.kernel?
1218     end
1219   end
1221   # TESTED
1222   class ToArray
1223     def bytecode(g)
1224       @child.bytecode(g)
1225       g.cast_array
1226     end
1227   end
1229   # TESTED
1230   class SClass
1231     def bytecode(g)
1232      @object.bytecode(g)
1233      g.dup
1234      g.send :__verify_metaclass__, 0
1235      g.pop
1236      g.open_metaclass
1238      attach_and_call g, :__metaclass_init__
1239     end
1240   end
1242   # TESTED
1243   class Class
1245     def superclass_bytecode(g)
1246       if @superclass
1247         @superclass.bytecode(g)
1248       else
1249         g.push :nil
1250       end
1251     end
1253     def bytecode(g)
1254       if @parent
1255         @parent.bytecode(g)
1256         superclass_bytecode(g)
1257         g.open_class_under @name
1258       else
1259         superclass_bytecode(g)
1260         g.open_class @name
1261       end
1263       attach_and_call g, :__class_init__
1264     end
1265   end
1267   # TESTED
1268   class Module
1270     def bytecode(g)
1271       if @parent
1272         @parent.bytecode(g)
1273         g.open_module_under @name
1274       else
1275         g.open_module @name
1276       end
1278       attach_and_call g, :__module_init__
1279     end
1280   end
1282   class Defined
1283     NODE_TYPES = {:self => "self", :nil => "nil", :true => "true", :false => "false", :gasgn => "assignment", :iasgn => "assignment", :cdecl => "assignment", :cvdecl => "assignment", :cvasgn => "assignment", :lvar => "local-variable", :str => "expression", :array => "expression", :hash => "expression", :yield => "yield", :ivar => "instance-variable", :gvar => "global-variable", :cvar => "class variable", :fcall => "method", :call => "method", :vcall => "method", :const => "constant", :colon2 => "constant", :colon3 => "constant", :lasgn => "assignment", :fixnum => "expression", :lit => "expression"}
1285     def bytecode(g)
1286       # Imported directly from compiler1 and reworked to use g.
1288       expr = @expression.dup
1290       # if something is defined, !something is too.
1291       # if !something is undefined, then so is something.
1292       expr.shift if expr[0] == :not
1294       # grouped expression == evil
1295       # TODO - Verify that this is still a sane way to detect such things
1296       if expr.flatten.include?(:newline)
1297         reject(g)
1298         return
1299       end
1301       node = expr.shift
1303       case node
1304       when :call
1305         receiver = expr.shift
1306         msg = expr.shift # method name
1308         # Make sure there are no args.
1309         unless expr.empty?
1310           reject(g)
1311           return
1312         end
1314         # defined?(DoesNotExist.puts) should not raise NameError
1315         if receiver.is?(ConstFind) then
1316           no_const = g.new_label
1317           done = g.new_label
1318           g.push_literal receiver.name
1319           g.push_context
1320           g.send :const_defined?, 1
1321           g.gif no_const
1323           g.push :true
1324           g.push_literal msg
1325           receiver.bytecode(g)
1326           g.send :__respond_to_eh__, 2
1327           g.goto done
1329           no_const.set!
1330           g.push_nil
1331           done.set!
1332         else
1333           g.push :true
1334           g.push_literal msg
1335           receiver.bytecode(g)
1336           g.send :__respond_to_eh__, 2
1337         end
1338       when :vcall, :fcall
1339         msg = expr.shift
1341         # Make sure there are no args.
1342         unless expr.empty?
1343           reject(g)
1344           return
1345         end
1347         g.push :true
1348         g.push_literal msg
1349         g.push :self
1350         g.send :__respond_to_eh__, 2
1351       when :cvar
1352         cvar = expr.shift
1353         g.push_literal cvar
1354         # class vars as symbols, not strings
1355         g.push :true
1356         g.push :self
1357         g.send :class_variables, 1
1358         g.send :include?, 1
1359       when :gvar
1360         g.push_literal expr.shift
1361         g.push_const :Globals
1362         g.send :key?, 1
1363       when :ivar
1364         ivar = expr.shift
1365         g.push_literal ivar
1366         g.push :self
1367         g.send :__instance_variable_defined_eh__, 1
1368       when :yield
1369         g.push_block
1370       when :const
1371         g.push_literal expr.shift
1372         g.push_context
1373         g.send :const_defined?, 1
1374       when :colon2
1375         str = ""
1376         until expr.empty?
1377           # Convert the constant parse tree into a string like ::Object::SomeClass
1378           str = const_to_string(expr, str)
1379         end
1380         g.push_literal str
1381         g.push_context
1382         g.send :const_path_defined?, 1
1383       when :colon3
1384         str = ""
1385         until expr.empty?
1386           # Convert the constant parse tree into a string like ::Object::SomeClass
1387           str = const_to_string(expr, str)
1388         end
1389         g.push_literal str
1390         g.push_const :Object
1391         g.send :const_path_defined?, 1
1392       else
1393         if NODE_TYPES.key?(node)
1394           g.push :true
1395         else
1396           reject(g)
1397           return
1398         end
1399       end
1400       push_return_value(g, node)
1401     end
1403     # Return the correct string based on the node type
1404     def push_return_value(g, node)
1405       defined = g.new_label
1406       done = g.new_label
1407       g.git defined
1408       g.push_nil
1409       g.goto done
1410       defined.set!
1411       lit = NODE_TYPES[node].dup
1412       g.push_literal lit
1413       done.set!
1414     end
1416     # e.g. [[:const, :Object], :Blah]
1417     # e.g. [[:colon3, :Foo], :Bar]
1418     # e.g. [[:colon2, [:colon3, :Faz], :Boo], :Batch]
1419     # e.g. [[:colon2, [:const, :Zizz], :Koom], :Yonk]
1420     # TODO - There is probably a better way, but it is late. Really late.
1421     def const_to_string(tree, str)
1422       return str if tree.empty?
1423       piece = tree.shift
1424       unless str[-2,2] == "::" || str == ""
1425         str << "::"
1426       end
1427       if piece.is_a?(Array)
1428         str = const_to_string(piece, str) until piece.empty?
1429         str
1430       elsif [:const, :colon2].include?(piece)
1431         str
1432       elsif piece == :colon3
1433         "::" + str
1434       else
1435         str << "#{piece}"
1436       end
1437     end
1439     def reject(g)
1440       if $DEBUG
1441         STDERR << "Passed a complex expression to 'defined?'"
1442       end
1444       g.push :false
1445     end
1447   end
1449   class Begin
1450     def bytecode(g)
1451       @body.bytecode(g)
1452     end
1453   end
1455   # TESTED
1456   class RescueCondition
1457     def bytecode(g, top_if_false, if_done)
1458       body = g.new_label
1460       if @conditions
1461         @conditions.each do |x|
1462           g.push_exception
1463           x.bytecode(g)
1464           g.send :===, 1
1465           g.git body
1466         end
1467       end
1469       if @splat
1470         g.push_exception
1471         @splat.bytecode(g)
1472         g.cast_array
1473         g.send :__rescue_match__, 1
1474         g.git body
1475       end
1477       if @next
1478         # There are rescues
1479         if_false = g.new_label
1481         g.goto if_false
1482         body.set!
1483         @body.bytecode(g)
1484         g.goto if_done
1486         if_false.set!
1487         @next.bytecode(g, top_if_false, if_done)
1488       else
1489         # This is the last rescue
1490         g.goto top_if_false
1492         body.set!
1493         @body.bytecode(g)
1494         g.clear_exception
1495         g.goto if_done
1496       end
1497     end
1498   end
1500   # TESTED
1501   class Rescue
1502     def bytecode(g)
1503       g.push_modifiers
1504       if @body.nil?
1505         if @else.nil?
1506           # Stupid. No body and no else.
1507           g.push :nil
1508         else
1509           # Only an else, run it.
1510           @else.bytecode(g)
1511         end
1512       else
1513         g.retry = g.new_label
1514         rr  = g.new_label
1515         fls = g.new_label
1516         els = g.new_label
1517         last = g.new_label
1519         g.exceptions do |ex|
1520           g.retry.set!
1521           @body.bytecode(g)
1522           g.goto els
1524           ex.handle!
1525           @rescue.bytecode(g, rr, last)
1526           rr.set!
1527           g.push_exception
1528           g.raise_exc
1529         end
1531         els.set!
1532         if @else
1533           g.pop
1534           @else.bytecode(g)
1535         end
1536         last.set!
1537       end
1538       g.pop_modifiers
1539     end
1540   end
1542   class Ensure
1543     def bytecode(g)
1544       if @body.nil?
1545         # So dumb. Oh well.
1547         if @ensure
1548           # Well, run it.
1549           @ensure.bytecode(g)
1550           g.pop
1551         end
1553         g.push :nil
1555         return
1556       end
1558       # No ensure? dumb.
1559       if @ensure.nil?
1560         @body.bytecode(g)
1561         return
1562       end
1564       ok = g.new_label
1565       g.exceptions do |ex|
1566         @body.bytecode(g)
1567         g.goto ok
1569         ex.handle!
1570         g.push_exception
1572         @ensure.bytecode(g)
1573         g.pop
1574         # Re-raise the exception
1575         if @did_return and !@outer_ensure
1576           g.dup
1577           g.push_const :ReturnException
1578           g.send :===, 1
1580           after = g.new_label
1581           g.gif after
1582           g.send :return_value, 0
1583           g.clear_exception
1585           # Emit the special code for doing a return in a block.
1586           if @in_block
1587             Return.emit_lre(g, @check_var)
1588           else
1589             g.sret
1590           end
1592           after.set!
1593         end
1595         g.raise_exc
1596       end
1598       ok.set!
1600       # Now, re-emit the code for the ensure which will run if there was no
1601       # exception generated.
1602       @ensure.bytecode(g)
1603       g.pop
1604     end
1605   end
1607   # TESTED
1608   class Return
1609     def bytecode(g, force=false)
1610       if @in_rescue
1611         g.clear_exception
1612       end
1614       if @value
1615         @value.bytecode(g)
1616       else
1617         g.push :nil
1618       end
1620       if !force and @in_ensure
1621         g.push_cpath_top
1622         g.find_const :ReturnException
1623         g.send :new, 1
1624         g.raise_exc
1625         return
1626       end
1628       if @in_block
1629         Return.emit_lre(g, @check_var)
1630       else
1631         g.sret
1632       end
1633     end
1635     def self.emit_lre(g, var)
1636       # Set the return value from @value above.
1637       g.push_local var.slot
1638       g.send :return_value=, 1
1639       g.pop
1641       # Now raise it.
1642       g.push_local var.slot
1643       g.raise_exc
1644     end
1645   end
1647   # TESTED
1648   class IterArgs
1649     def bytecode(g)
1650       case @child
1651       when MAsgn
1652         g.cast_for_multi_block_arg unless @child.splat_only?
1653         @child.in_block = true
1654         @child.bytecode(g)
1655       when LocalAssignment, IVarAssign, GVarAssign
1656         g.cast_for_single_block_arg
1657         @child.bytecode(g)
1658         g.pop
1659       when AttrAssign
1660         g.cast_for_single_block_arg
1661         @child.bytecode(g, true)
1662         g.pop
1663       when Fixnum, nil
1664         g.pop
1665       else
1666         raise Error, "Unknown form of block args: #{@child.class}"
1667       end
1668     end
1669   end
1671   # TESTED
1672   class MAsgn
1673     # MAsgn rules:
1674     # - MAsgn sexps always contain either 2 or 3 values
1675     # - If the masgn contains only 2 values:
1676     #   - it means there are no lasgns, i.e. the lhs consists solely of a splat
1677     #     arg.
1678     #   - the first arg is the lhs splat arg, and cannot be nil; however, it
1679     #     may be just the value true, in the case of a block anonymous splat arg,
1680     #     i.e. |*|
1681     #   - the second arg is either one of [:array, :splat, :argscat, :to_ary], or
1682     #     nil if the masgn represents block arguments.
1683     # - If the masgn contains 3 values:
1684     #   - the first arg is an array of lasgns with a minimum of one lasgn.
1685     #   - the second arg is the lhs splat arg, or nil if there are no splats
1686     #   - the third arg is either one of [:array, :splat, :argscat, :to_ary], or
1687     #     nil if the masgn represents block arguments.
1688     # - An MAsgn may contain nested masgns, e.g. a,(b,c) = 1,[2,3]. The nested
1689     #   masgn(s) will have nil for their @assigns, since the assigns come from
1690     #   the outermost masgn.
1691     def bytecode(g)
1692       if @source
1693         if @source.is? ArrayLiteral
1694           if @splat
1695             array_bytecode(g)
1696           else
1697             flip_assign_bytecode(g)
1698           end
1699         else
1700           statement_bytecode(g)
1701         end
1702       elsif @in_block
1703         block_arg_bytecode(g)
1704       else
1705         statement_bytecode(g)
1706       end
1707     end
1709     # Pad stack if there are insufficient source values for the assigns
1710     def pad_stack(g)
1711       diff = -@source.body.size
1712       if @assigns
1713         diff += @assigns.body.size
1714         if diff > 0
1715           diff.times { g.push :nil }
1716         end
1717       end
1718       return diff
1719     end
1721     # The easiest case for a normal masgn.
1722     # a,b = c,d
1723     # a = c,d
1724     # a,b,c = d,e
1725     def flip_assign_bytecode(g)
1726       # Pad the stack with extra nils if there are more assigns
1727       # than sources
1728       diff = pad_stack(g)
1730       @source.body.each do |x|
1731         x.bytecode(g)
1732       end
1734       g.rotate @source.body.size
1736       # Now all the source data is on the stack.
1738       @assigns.body.each do |x|
1739         if x.is? AttrAssign
1740           x.bytecode(g, true)
1741         else
1742           x.bytecode(g)
1743         end
1744         g.pop
1745       end
1747       # Clean up the stack if there was extra sources
1748       if diff < 0
1749         # unary - has binds strangly
1750         (-diff).times { g.pop }
1751       end
1753       g.push :true
1754     end
1756     def array_bytecode(g)
1757       @source.body.each do |x|
1758         x.bytecode(g)
1759       end
1761       diff = pad_stack(g)
1763       if diff >= 0
1764         sz = 0
1765       else
1766         sz = -diff
1767       end
1769       g.make_array sz
1770       @splat.bytecode(g) unless @splat.kind_of? TrueClass  # e.g. * = 1,2
1771       g.pop
1772       if @assigns
1773         @assigns.body.reverse_each do |x|
1774           if x.is? AttrAssign
1775             x.bytecode(g, true)
1776           else
1777             x.bytecode(g)
1778           end
1779           g.pop
1780         end
1781       end
1783       g.push :true
1784     end
1786     def statement_bytecode(g)
1787       if @source.nil?
1788         # skip
1789       elsif @source.is? Splat or @source.is? ToArray
1790         @source.child.bytecode(g)
1791       elsif @source.is? ConcatArgs
1792         @source.bytecode(g)
1793       elsif @source
1794         raise Error, "Unknown form: #{@source.class}"
1795       end
1796       g.cast_tuple
1798       if @assigns
1799         @assigns.body.each do |x|
1800           g.unshift_tuple
1801           if x.is? AttrAssign
1802             x.bytecode(g, true)
1803           else
1804             x.bytecode(g)
1805           end
1806           g.pop
1807         end
1808       end
1810       if @splat
1811         g.cast_array
1812         @splat.bytecode(g) unless @splat.kind_of? TrueClass # HACK dup
1813       end
1814       g.pop
1816       g.push :true
1817     end
1819     def block_arg_bytecode(g)
1820       if @assigns
1821         @assigns.body.each do |x|
1822           g.unshift_tuple
1823           x.bytecode(g)
1824           g.pop
1825         end
1826       end
1828       if @splat and !@splat.kind_of? TrueClass
1829         g.cast_array
1830         @splat.bytecode(g)
1831       end
1833       g.pop
1834     end
1836     def splat_only?
1837       @assigns.nil? and @splat
1838     end
1839   end
1841   # TESTED
1842   class FCall
1843     def allow_private?
1844       true
1845     end
1847     def receiver_bytecode(g)
1848       g.push :self
1849     end
1851   end
1853   # TESTED
1854   class AttrAssign
1855     def bytecode(g, in_masgn = false)
1856       if in_masgn
1857         @in_masgn = true
1858         super(g)
1859       else
1860         super(g)
1861         g.pop
1862         # The dup'd rhs is on the top of the stack now
1863       end
1864     end
1866     def emit_args(g)
1867       if @in_masgn
1868         if @rhs_expression
1869           extra = 2
1870           @rhs_expression.bytecode(g)
1871         else
1872           extra = 1
1873         end
1875         super(g)
1877         @argcount += extra
1878       elsif @rhs_expression
1879         @rhs_expression.bytecode(g)
1880         g.dup
1881         super(g)
1882         @argcount += 1
1883       else
1884         # PushArgs only for this branch
1885         @arguments.attr_bytecode(g)
1886         g.get_args
1887         @dynamic = true
1888       end
1889     end
1890   end
1892   # TESTED
1893   class Call
1894     def allow_private?
1895       false
1896     end
1898     def receiver_bytecode(g)
1899       @object.bytecode(g)
1900     end
1902     def emit_args(g)
1903       @dynamic = false
1904       if @arguments
1905         if @arguments.kind_of? Array
1906           @arguments.reverse_each do |x|
1907             x.bytecode(g)
1908           end
1909           @argcount = @arguments.size
1910         elsif @arguments.is? ConcatArgs
1911           @arguments.call_bytecode(g)
1912           # ConcatArgs calls get_args on its own, so we don't need to
1913           @dynamic = true
1914         else
1915           if @arguments.is? Splat
1916             @arguments.call_bytecode(g)
1917           else
1918             @arguments.bytecode(g)
1919           end
1920           g.get_args
1921           @dynamic = true
1922         end
1923       else
1924         @argcount = 0
1925       end
1926     end
1928     def bytecode(g)
1929       return if use_plugin(g, :call)
1931       emit_args(g)
1933       if @block
1934         @block.bytecode(g)
1935       elsif @dynamic
1936         g.push :nil
1937       end
1939       g.swap if @dynamic
1941       receiver_bytecode(g)
1943       # @block might be BlockPass, and we don't generate the
1944       # LongReturnException detection code for that.
1945       if @block and @block.is? Iter
1946         block_bytecode(g)
1947       elsif @dynamic
1948         g.swap
1949         g.set_args
1950         g.send_with_register @method, allow_private?
1951       elsif @block
1952         # Only BlockPass currently
1953         g.send_with_block @method, @argcount, allow_private?
1954       else
1955         g.send @method, @argcount, allow_private?
1956       end
1957     end
1959     def block_bytecode(g)
1960       ok = g.new_label
1961       g.exceptions do |ex|
1963         # We pre-create the exception.
1964         g.push_cpath_top
1965         g.find_const :LongReturnException
1966         g.send :allocate, 0
1967         g.set_local @check_var.slot
1968         g.pop
1970         if @dynamic
1971           g.swap
1972           g.set_args
1973           g.send_with_register @method, allow_private?
1974         else
1975           g.send_with_block @method, @argcount, allow_private?
1976         end
1978         g.goto ok
1980         ex.handle!
1982         g.push_exception
1983         g.dup
1984         g.push_local @check_var.slot
1985         g.equal
1987         after = g.new_label
1988         g.gif after
1989         g.clear_exception
1991         # This is also used for break in a block. If break was used,
1992         # is_return is false, so we just leave the value on the stack.
1993         leave = g.new_label
1994         g.dup
1995         g.send :is_return, 0
1996         g.gif leave
1998         # If this is occuring already in a block, keep it raising.
1999         unless @in_block
2000           g.send :value, 0
2001           g.sret
2002         end
2004         after.set!
2006         g.raise_exc
2008         leave.set!
2009         g.send :value, 0
2010       end
2012       ok.set!
2013     end
2014   end
2016   # TESTED
2017   class Yield
2018     def bytecode(g)
2019       emit_args(g)
2021       if @dynamic
2022         g.set_args
2023         g.push :nil
2024         g.push_block
2025         g.send_with_register :call, false
2026       else
2027         g.push_block
2028         g.meta_send_call @argcount
2029       end
2031     end
2032   end
2034   class Super
2035     def bytecode(g)
2036       emit_args(g)
2038       if @block
2039         @block.bytecode(g)
2040       else
2041         # Even if we're specifying new args, the original block
2042         # is passed up.
2043         g.push_block
2044       end
2046       if @dynamic
2047         g.swap
2048         g.set_args
2049         g.send_super @method.name
2050       else
2051         g.send_super @method.name, @argcount
2052       end
2053     end
2054   end
2056   class ZSuper
2058     def bytecode(g)
2059       args = []
2061       @method.arguments.required.each do |var|
2062         la = LocalAccess.new @compiler
2063         la.from_variable var
2064         args << la
2065       end
2067       @method.arguments.optional.each do |var|
2068         la = LocalAccess.new @compiler
2069         la.from_variable var
2070         args << la
2071       end
2073       if @method.arguments.splat
2074         cc = ConcatArgs.new @compiler
2075         la = LocalAccess.new @compiler
2076         la.from_variable @method.arguments.splat
2078         cc.args args, la
2079         @arguments = cc
2080       else
2081         @arguments = args
2082       end
2084       super(g)
2085     end
2086   end
2088   # TESTED
2089   class Undef
2090     def bytecode(g)
2091       g.push_literal @name
2092       g.push :self
2093       unless @in_module
2094         g.send :metaclass, 0
2095       end
2096       g.send :undef_method, 1
2097     end
2098   end
2100   # TESTED
2101   class Alias
2102     def bytecode(g)
2103       g.push_literal @current
2104       g.push_literal @new
2105       g.push_context
2106       g.send :alias_method, 2, true
2107     end
2108   end
2110   class VAlias
2111     def bytecode(g)
2112       g.push_literal @new
2113       g.push_literal @current
2114       g.push_cpath_top
2115       g.find_const :Globals
2116       g.send :add_alias, 2
2117     end
2118   end
2120   # Represents the argument list of a method definition
2121   # See +nodes.rb+ for details.
2122   class Arguments
2123     def bytecode(g)
2124       # Minimum number of arguments to be supplied
2125       min = @required.size
2126       if @splat
2127         # There is no upper bound, check is in instructions.gen
2128         max = -1
2129       else
2130         # Maximum unsplatted argument count
2131         max = min + @optional.size
2132       end
2134       # Check these min and max argument counts at runtime
2135       g.check_argcount min, max
2137       process_required_args(g)
2138       process_optional_args(g)
2139       process_rest_arg(g) if @splat.kind_of?(Local)
2140       process_block_arg(g) if @block_arg
2141     end
2143     # Emit a local setup instruction for each required argument
2144     def process_required_args(g)
2145       @required.each do |var|
2146         g.set_local_from_fp var.slot, var.stack_position
2147       end
2148     end
2150     # Emit bytecode to handle any optional arguments
2151     def process_optional_args(g)
2152       @optional.each do |var|
2154         assign = @mapped_defaults[var.name]
2156         use_passed = g.new_label
2157         done = g.new_label
2158         g.passed_arg var.stack_position
2159         g.git use_passed
2160         assign.bytecode(g)
2161         g.pop
2162         g.goto done
2164         use_passed.set!
2165         g.set_local_from_fp var.slot, var.stack_position
2167         done.set!
2168       end
2169     end
2171     # Emit bytecode to handle a 'rest' (a.k.a. 'splat') argument
2172     def process_rest_arg(g)
2173       g.make_rest_fp @required.size + @optional.size
2174       lv = LocalAssignment.new(@compiler)
2175       lv.from_variable @splat
2176       lv.bytecode(g)
2177       g.pop
2178     end
2180     # Emit bytecode to handle a block argument (&block syntax)
2181     def process_block_arg(g)
2182       g.push_block
2183       g.dup
2184       g.is_nil
2186       after = g.new_label
2187       g.git after
2189       g.push_const :Proc
2190       g.send :__from_block__, 1
2192       after.set!
2194       @block_arg.bytecode(g)
2195       g.pop
2196     end
2197   end
2199   # TESTED
2200   class Define
2202     def argument_info
2203       [@arguments.arity, @arguments.optional.size]
2204     end
2206     def compile_body(g)
2207       desc = new_description()
2208       meth = desc.generator
2210       prelude(g, meth)
2212       set(:scope, nil) do
2213         show_errors(meth) do
2214           @arguments.bytecode(meth)
2215           desc.run self, @body
2216         end
2217       end
2219       args = Tuple.new(3)
2220       if @arguments.required and @arguments.required.size > 0
2221         required =  Tuple.new(@arguments.required.size)
2222         @arguments.required.each_with_index {|x,i| required.put(i, x.name)}
2223         args.put(0, required)
2224       end
2225       if @arguments.optional and @arguments.optional.size > 0
2226         optional = Tuple.new(@arguments.optional.size)
2227         @arguments.optional.each_with_index {|x,i| optional.put(i, x.name)}
2228         args.put(1, optional)
2229       end
2230       args.put(2, @arguments.splat.name) if @arguments.splat
2231       desc.args = args
2233       meth.sret
2234       meth.close
2236       use_plugin g, :method, desc
2238       return desc
2239     end
2241     def bytecode(g)
2242       g.push_literal compile_body(g)
2244       if @compiler.kernel?
2245         g.push :self
2246         g.add_method @name
2247       else
2248         g.push_literal @name
2249         g.push_context
2250         g.send :__add_method__, 2
2251       end
2252     end
2253   end
2255   # TESTED
2256   class DefineSingleton
2257     def bytecode(g)
2258       g.push_literal compile_body(g)
2259       if @compiler.kernel?
2260         @object.bytecode(g)
2261         g.attach_method @name
2262       else
2263         g.push_literal @name
2264         @object.bytecode(g)
2265         g.send :metaclass, 0
2266         g.send :attach_method, 2
2267       end
2268     end
2269   end
2271   # TESTED
2272   class Range
2273     def bytecode(g)
2274       @finish.bytecode(g)
2275       @start.bytecode(g)
2276       g.push_cpath_top
2277       g.find_const :Range
2278       g.send :new, 2
2279     end
2280   end
2282   # TESTED
2283   class RangeExclude
2284     def bytecode(g)
2285       g.push :true
2286       @finish.bytecode(g)
2287       @start.bytecode(g)
2289       g.push_cpath_top
2290       g.find_const :Range
2291       g.send :new, 3
2292     end
2293   end
2295   class CVarAssign
2296     def bytecode(g)
2297       @value.bytecode(g)
2298       g.push_literal @name
2299       if @in_module
2300         g.push :self
2301       else
2302         g.push_context
2303       end
2304       g.send :class_variable_set, 2
2305     end
2306   end
2308   class CVar
2309     def prepare_receiver(g)
2310       if @in_module
2311         g.push :self
2312       else
2313         g.push_context
2314       end
2315     end
2317     def bytecode(g)
2318       g.push_literal @name
2319       prepare_receiver(g)
2320       g.send :class_variable_get, 1
2321     end
2323     def check_first_bytecode(g)
2324       g.push_literal @name
2325       prepare_receiver(g)
2326       g.send :class_variable_defined?, 1
2328       no_cvar = g.new_label
2329       g.gif no_cvar
2331       g.push_literal @name
2332       prepare_receiver(g)
2333       g.send :class_variable_get, 1
2334       done = g.new_label
2335       g.goto done
2337       no_cvar.set!
2338       g.push :nil
2340       done.set!
2341     end
2342   end
2344   ##
2345   # __FILE__ node.
2347   class File
2348     def bytecode(g)
2349       g.push_context
2350       g.send :active_path, 0
2351     end
2352   end