Added spec:commit task to commit changes to spec/ruby sources.
[rbx.git] / shotgun / lib / instructions.rb
blobaf3bcdcc23d20611f1481ea18e4a400c3df84ccb
1 require "#{File.dirname(__FILE__)}/../../kernel/core/iseq"
3 class ShotgunInstructions
5   def generate_switch(fd, op="op")
6     fd.puts "switch(#{op}) {"
7     InstructionSet::OpCodes.each do |ins|
8       code = send(ins.opcode) rescue nil
9       if code
10         fd.puts "   case #{ins.bytecode}: { /* #{ins.opcode} */"
11         fd.puts code
12         if ins.check_interrupts?
13           fd.puts "   goto check_interrupts;"
14         elsif ins.terminator?
15           fd.puts "   goto insn_start;"
16         else
17           fd.puts "   goto next_op;"
18         end
19         fd.puts "   }"
20       else
21         STDERR.puts "Problem with opcode: #{ins.opcode}"
22       end
23     end
24     fd.puts "default: printf(\"Invalid bytecode: %d\\n\", (int)op); sassert(0);\n"
25     fd.puts "}"
26     fd.puts
27   end
29   def generate_threaded(fd, op="op")
30     InstructionSet::OpCodes.each do |ins|
31       code = send(ins.opcode) rescue nil
32       if code
33         fd.puts "   insn_#{ins.bytecode}: {"
34         fd.puts code
35         if ins.check_interrupts?
36           fd.puts "   goto check_interrupts;"
37         elsif ins.terminator?
38           fd.puts "   goto insn_start;"
39         else
40           fd.puts "   NEXT_OP;"
41         end
42         fd.puts "   }"
44       else
45         STDERR.puts "Problem with opcode: #{ins.opcode}"
46       end
47     end
48     fd.puts
49   end
51   def generate_dter
52     code = "static int _ip_size(uint32_t bc) {\nswitch(bc) {\n"
53     InstructionSet::OpCodes.each do |ins|
54       if ins.arg_count == 2
55         code << "  case #{ins.bytecode}:\n"
56       end
57     end
58     code << "    return 3;\n"
60     InstructionSet::OpCodes.each do |ins|
61       if ins.arg_count == 1
62         code << "  case #{ins.bytecode}:\n"
63       end
64     end
65     code << "   return 2;\n"
67     code << "}\nreturn 1;\n}\n\n"
69     code << "#define DT_ADDRESSES static void* _dt_addresses[#{InstructionSet::OpCodes.size + 1}]; static int _dt_size = #{InstructionSet::OpCodes.size};\n"
70     code << "#define SETUP_DT_ADDRESSES "
72     InstructionSet::OpCodes.each do |ins|
73       code << "_dt_addresses[#{ins.bytecode}] = &&insn_#{ins.bytecode}; "
74     end
75     code << "\n"
77     code << <<-CODE
79     static inline uint32_t read_int_from_be(uint8_t *str) {
80       return (uint32_t)((str[0] << 24)
81                       | (str[1] << 16)
82                       | (str[2] << 8 )
83                       |  str[3]      );
84     }
86     static void calculate_into_gotos(STATE, OBJECT iseq, OBJECT output, void* addrs[], int size) {
87       uint8_t *insn;
88       uint32_t op;
89       uintptr_t *compiled;
91       int i, f, offset, sz;
93       f = bytearray_bytes(state, iseq);
94       insn = (uint8_t*)bytearray_byte_address(state, iseq);
95       compiled = (uintptr_t*)bytearray_byte_address(state, output);
97       offset = 0;
98       for(offset = 0; offset < f; offset += 4) {
99 #if CONFIG_BIG_ENDIAN
100         op = *((uint32_t*)(insn + offset));
101 #else
102         op = read_int_from_be(insn + offset);
103 #endif
104         /* Protect against errant data */
105         if(op > size) op = 0;
106         *compiled++ = (uintptr_t)addrs[op];
107         /* copy the instruction args */
108         sz = _ip_size(op) - 1;
109         for(i = 0; i < sz; i++) {
110           offset += 4;
111 #if CONFIG_BIG_ENDIAN
112           op = *((uint32_t*)(insn + offset));
113 #else
114           op = read_int_from_be(insn + offset);
115 #endif
116           *compiled++ = (uintptr_t)op;
117         }
118       }
119     }
121     CODE
123     code
124   end
126   def generate_declarations(fd)
127     fd.puts "int _int;"
128     fd.puts "native_int j, k, m;"
129     fd.puts "OBJECT _lit, t1, t2, t3, t4;"
130     fd.puts "struct message msg;"
131   end
133   def generate_names
134     str = "static const char instruction_names[] = {\n"
135     InstructionSet::OpCodes.each do |ins|
136       str << "  \"#{ins.opcode.to_s}\\0\"\n"
137     end
138     str << "};\n\n"
139     offset = 0
140     str << "static const unsigned short instruction_name_offsets[] = {\n"
141     InstructionSet::OpCodes.each_with_index do |ins, index|
142       str << ",\n" if index > 0
143       str << "  #{offset}"
144       offset += ins.opcode.to_s.length + 1
145     end
146     str << "\n};\n\n"
147     str << <<CODE
148 const char *get_instruction_name(int op) {
149   return instruction_names + instruction_name_offsets[op];
151 CODE
152   end
154   def generate_names_header
155     str = "const char *get_instruction_name(int op);\n"
157     InstructionSet::OpCodes.each do |ins|
158       str << "#define CPU_INSTRUCTION_#{ins.opcode.to_s.upcase} #{ins.bytecode}\n" unless ins.opcode == :unused
159     end
161     str
162   end
164   # [Operation]
165   #   Performs a no-op, i.e. does nothing.
166   # [Format]
167   #   \noop
168   # [Stack Before]
169   #   * ...
170   # [Stack After]
171   #   * ...
172   # [Description]
173   #   The classic no-op operator; performs no actions, and does not modify the
174   #   stack.
175   #
176   #   To consume an item from the stack, but otherwise do nothing, use
177   #   pop.
178   # [See Also]
179   #   * pop
181   def noop
182     ""
183   end
185   # [Operation]
186   #   Pushes an integer literal value onto the stack
187   # [Format]
188   #   \push_int value
189   # [Stack Before]
190   #   * ...
191   # [Stack After]
192   #   * value
193   #   * ...
194   # [Description]
195   #   Pushes the value of the integer literal onto the stack.
196   # [See Also]
197   #   * meta_push_0
198   #   * meta_push_1
199   #   * meta_push_2
200   #   * meta_push_neg_1
201   # [Notes]
202   #   Certain common cases (i.e. -1, 0, 1, and 2) are optimised to avoid the
203   #   lookup of the literal value in the literals tuple.
205   def push_int
206     <<-CODE
207     next_int;
208     stack_push(I2N(_int));
209     CODE
210   end
212   # [Operation]
213   #   Pushes -1 onto the stack
214   # [Format]
215   #   \meta_push_neg_1
216   # [Stack Before]
217   #   * ...
218   # [Stack After]
219   #   * -1
220   #   * ...
221   # [Description]
222   #   Fast push of -1 (negative 1) onto the stack. This is an optimisation
223   #   applied whenever a literal -1 is encountered by the compiler. It is
224   #   equivalent to 'push -1', but faster because there is no need to lookup
225   #   the literal value in the literals tuple.
227   def meta_push_neg_1
228     <<-CODE
229     stack_push(I2N(-1));
230     CODE
231   end
233   # [Operation]
234   #   Pushes 0 onto the stack
235   # [Format]
236   #   \meta_push_0
237   # [Stack Before]
238   #   * ...
239   # [Stack After]
240   #   * 0
241   #   * ...
242   # [Description]
243   #   Fast push of 0 (zero) onto the stack. This is an optimisation applied
244   #   whenever a literal 0 is encountered by the compiler. It is equivalent to
245   #   'push 0', but faster because there is no need to lookup the literal
246   #   value in the literals tuple.
248   def meta_push_0
249     <<-CODE
250     stack_push(I2N(0));
251     CODE
252   end
254   # [Operation]
255   #   Pushes 1 onto the stack
256   # [Format]
257   #   \meta_push_1
258   # [Stack Before]
259   #   * ...
260   # [Stack After]
261   #   * 1
262   #   * ...
263   # [Description]
264   #   Fast push of 1 (one) onto the stack. This is an optimisation applied
265   #   whenever a literal 1 is encountered by the compiler. It is equivalent to
266   #   'push 1', but faster because there is no need to lookup the literal
267   #   value in the literals tuple.
269   def meta_push_1
270     <<-CODE
271     stack_push(I2N(1));
272     CODE
273   end
275   # [Operation]
276   #   Pushes 2 onto the stack
277   # [Format]
278   #   \meta_push_2
279   # [Stack Before]
280   #   * ...
281   # [Stack After]
282   #   * 2
283   #   * ...
284   # [Description]
285   #   Fast push of 2 (two) onto the stack. This is an optimisation applied
286   #   whenever a literal 2 is encountered by the compiler. It is equivalent to
287   #   'push 2', but faster because there is no need to lookup the literal
288   #   value in the literals tuple.
290   def meta_push_2
291     <<-CODE
292     stack_push(I2N(2));
293     CODE
294   end
296   # [Operation]
297   #   Puts nil on the stack
298   # [Format]
299   #   \push_nil
300   # [Stack Before]
301   #   * ...
302   # [Stack After]
303   #   * nil
304   #   * ...
305   # [Description]
306   #   The special object nil is pushed onto the stack.
308   def push_nil
309     "stack_push(Qnil);"
310   end
312   # [Operation]
313   #   Pushes true onto the stack
314   # [Format]
315   #   \push_true
316   # [Stack Before]
317   #   * ...
318   # [Stack After]
319   #   * true
320   #   * ...
321   # [Description]
322   #   The special value true is pushed onto the stack.
324   def push_true
325     "stack_push(Qtrue);"
326   end
328   # [Operation]
329   #   Pushes false onto the stack
330   # [Format]
331   #   \push_false
332   # [Stack Before]
333   #   * ...
334   # [Stack After]
335   #   * false
336   #   * ...
337   # [Description]
338   #   The special object false is pushed onto the stack.
340   def push_false
341     "stack_push(Qfalse);"
342   end
344   # [Operation]
345   #   Pushes the current method context onto the stack
346   # [Format]
347   #   \push_context
348   # [Stack Before]
349   #   * ...
350   # [Stack After]
351   #   * methodctxt
352   #   * ...
353   # [Description]
354   #   Creates a reference to the current method execution context, and pushes
355   #   it onto the stack.
357   def push_context
358     <<-CODE
359     methctx_reference(state, c->active_context);
360     stack_push(c->active_context);
361     CODE
362   end
364   # [Operation]
365   #   Pushes a literal from the current state onto the stack.
366   # [Format]
367   #   \push_literal index
368   # [Stack Before]
369   #   * ...
370   # [Stack After]
371   #   * literal
372   #   * ...
373   # [Description]
374   #   The literal identified by the opcode argument (+index+) in the current
375   #   state literals tuple is retrieved and placed onto the stack.
376   #
377   #   The literals tuple is part of the machine state, and holds all literal
378   #   objects defined or used within a particular scope.
380   def push_literal
381     <<-CODE
382     next_int;
383     t1 = cpu_current_literals(state, c);
384     t2 = fast_fetch(t1, _int);
385     stack_push(t2);
386     CODE
387   end
389   # [Operation]
390   #   Sets a literal to the specified value
391   # [Format]
392   #   \set_literal lit
393   # [Stack Before]
394   #   * regexlit
395   #   * ...
396   # [Stack After]
397   #   * regex
398   #   * ...
399   # [Description]
400   #   Used to set the value of a literal that is a regular expression. The
401   #   Regexp object to which the literal is to be set is copied from the top
402   #   of the stack, but is not consumed.
403   # [Notes]
404   #   Unlike other literals such as strings and numbers, creating a Regexp
405   #   literal (i.e. via the /regex/ syntax) is a two step process to create
406   #   the literal slot for the Regexp, create a literal for the string between
407   #   the '/' delimiters and create a new Regexp object passing it the string.
408   #   Only then can the literal value be set, using the set_literal opcode.
410   def set_literal
411     <<-CODE
412     next_int;
413     tuple_put(state, cpu_current_literals(state, c), _int, stack_top());
414     CODE
415   end
417   # [Operation]
418   #   Pushes a reference to the current self object onto the stack.
419   # [Format]
420   #   \push_self
421   # [Stack Before]
422   #   * ...
423   # [Stack After]
424   #   * self
425   #   * ...
426   # [Description]
427   #   The current self object is pushed onto the stack.
429   def push_self
430     "stack_push(c->self);"
431   end
433   # [Operation]
434   #   Pushes the value of a local variable onto the stack
435   # [Format]
436   #   \push_local local
437   # [Stack Before]
438   #   * ...
439   # [Stack After]
440   #   * local_value
441   #   * ...
442   # [Description]
443   #   Retrieves the current value (+local_value+) of the referenced local
444   #   variable (+local+), and pushes it onto the stack.
446   def push_local
447     <<-CODE
448     next_int;
449     stack_push(fast_fetch(c->locals, _int));
450     CODE
452     # "next_int; stack_push(fast_fetch(cpu_current_locals(state, c), _int));"
453   end
455   # [Operation]
456   #   Pushes the value of a local from an enclosing scope onto the stack
457   # [Format]
458   #   \push_local_depth depth local
459   # [Stack Before]
460   #   * ...
461   # [Stack After]
462   #   * localval
463   #   * ...
464   # [Description]
465   #   Retrieves the value of a local variable from a context enclosing the
466   #   current context, and pushes it onto the stack.
467   # [Example]
468   #   <code>
469   #     foo.each do |i|
470   #       bar.each do |j|
471   #         i = i + j  # i is a local variable from enclosing scope at depth 1
472   #       end
473   #     end
474   #   </code>
476   def push_local_depth
477     <<-CODE
478     next_int;
479     k = (native_int)_int;
480     next_int;
481     t1 = c->active_context;
482     for(j = 0; j < k; j++) {
483       t2 = blokctx_env(state, t1);
484       t1 = blokenv_get_home_block(t2);
485     }
486     stack_push(tuple_at(state, blokctx_locals(state, t1), _int));
487     CODE
488   end
490   # [Operation]
491   #   Pushes the current exception onto the stack
492   # [Format]
493   #   \push_exception
494   # [Stack Before]
495   #   * ...
496   # [Stack After]
497   #   * exception
498   #   * ...
499   # [Description]
500   #   Pushes the current exception onto the stack, so that it can be used for
501   #   some purpose, such as checking the exception type, setting an exception
502   #   variable in a rescue clause, etc.
503   # [See Also]
504   #   * raise_exc
505   # [Example]
506   #   <code>
507   #     begin
508   #       foo = BAR        # BAR is not defined
509   #     rescue NameError   # push_exception used to check type of exception (via ===)
510   #       puts "No BAR"
511   #     end
512   #   </code>
514   def push_exception
515     "stack_push(c->exception);"
516   end
518   # [Operation]
519   #   Clears any exceptions from the current execution context
520   # [Format]
521   #   \clear_exception
522   # [Stack Before]
523   #   * ...
524   # [Stack After]
525   #   * ...
526   # [Description]
527   #   Clears any exceptions from the current execution context. The stack is
528   #   untouched by this opcode.
530   def clear_exception
531     <<-CODE
532     c->exception = Qnil;
533     CODE
534   end
536   # [Operation]
537   #   Pushes a block onto the stack
538   # [Format]
539   #   \push_block
540   # [Stack Before]
541   #   * ...
542   # [Stack After]
543   #   * block
544   #   * ...
545   # [Description]
546   #   Pushes the current block onto the stack. Used when a block passed to a
547   #   method is used.
548   # [Example]
549   #   <code>
550   #     def takes_block
551   #       yield # yields to the block passed to the method, which causes
552   #             # push_block to be called
553   #     end
554   #   </code>
556   def push_block
557     "stack_push(cpu_current_block(state, c));"
558   end
560   # [Operation]
561   #   Pushes an instance variable onto the stack
562   # [Format]
563   #   \push_ivar lit
564   # [Stack Before]
565   #   * ...
566   # [Stack After]
567   #   * value
568   #   * ...
569   # [Description]
570   #   Pushes the instance variable identified by +lit+ onto the stack.
572   def push_ivar
573     <<-CODE
574     next_literal;
575     stack_push(object_get_ivar(state, c->self, _lit));
576     CODE
577   end
579   # [Operation]
580   #   Allocate space for a new object
581   # [Format]
582   #   \allocate
583   # [Stack Before]
584   #   * count
585   #   * ...
586   # [Stack After]
587   #   * object
588   #   * ...
589   # [Description]
590   #   Pop a field +count+ and \allocate space for an object with the
591   #   appropriate header and field space. The object created will be
592   #   uninitialized; it will have its parent \class and all fields initialized
593   #   to +nil+.
595   def allocate
596     <<-CODE
597     _lit = stack_pop();
598     stack_push(NEW_OBJECT(Qnil, N2I(_lit)));
599     CODE
600   end
602   # [Operation]
603   #   Sets a literal to reference the specified \class
604   # [Format]
605   #   \set_class
606   # [Stack Before]
607   #   * literal
608   #   * class
609   #   * ...
610   # [Stack After]
611   #   * literal
612   #   * ...
613   # [Description]
614   #   Pops a literal reference and a \class off the top of the stack, sets the
615   #   \class of the literal to the new \class, and then pushes it back onto
616   #   the stack.
618   def set_class
619     <<-CODE
620     _lit = stack_pop();
621     t1 = stack_pop();
622     SET_CLASS(_lit, t1);
623     stack_push(_lit);
624     CODE
625   end
627   # [Operation]
628   #   Store a value into the specified object field
629   # [Format]
630   #   \store_field
631   # [Stack Before]
632   #   * field
633   #   * value
634   #   * object
635   #   * ...
636   # [Stack After]
637   #   * object
638   #   * ...
639   # [Description]
640   #   Overwrite the value of a particular field slot with the specified
641   #   object. The object reference is left on the stack.
643   def store_field
644     <<-CODE
645     t1 = stack_pop();
646     t2 = stack_pop();
647     t3 = stack_pop();
648     SET_FIELD(t3, N2I(t1), t2);
649     stack_push(t3);
650     CODE
651   end
653   # [Operation]
654   #   Retrieve the value within the field of the specified object
655   # [Format]
656   #   \fetch_field
657   # [Stack Before]
658   #   * field
659   #   * object
660   #   * ...
661   # [Stack After]
662   #   * value
663   #   * ...
664   # [Description]
665   #   Retrieve the object of the specified object field number.
667   def fetch_field
668     <<-CODE
669     t1 = stack_pop();
670     t2 = stack_pop();
671     stack_push(NTH_FIELD(t2, N2I(t1)));
672     CODE
673   end
675   # [Operation]
676   #   Pushes a value from an object field onto the stack
677   # [Format]
678   #   \push_my_field fld
679   # [Stack Before]
680   #   * ...
681   # [Stack After]
682   #   * value
683   #   * ...
684   # [Description]
685   #   Pushes the value of the specified field in the current object onto the
686   #   stack.
687   # [Notes]
688   #   Fields are similar to instance variables, but have dedicated storage
689   #   allocated. They are primarily used on core or bootstap classes.
690   #   Accessing a field is slightly faster than accessing an ivar.
692   def push_my_field
693     <<-CODE
694     next_int;
695     stack_push(NTH_FIELD(c->self, _int));
696     CODE
697   end
699   # [Operation]
700   #   Store a value into a field of self
701   # [Format]
702   #   \store_my_field fld
703   # [Stack Before]
704   #   * value
705   #   * ...
706   # [Stack After]
707   #   * value
708   #   * ...
709   # [Description]
710   #   Stores the value at the top of the stack into the field specified by
711   #   +fld+ on +self+.
712   #
713   #   The stack is left unmodified.
715   def store_my_field
716     <<-CODE
717     next_int;
718     SET_FIELD(c->self, _int, stack_top());
719     CODE
720   end
722   # [Operation]
723   #   Calls a primitive method
724   # [Format]
725   #   \send_primitive primitive_index argc
726   # [Stack Before]
727   #   * receiver
728   #   * arg1
729   #   * arg2
730   #   * ...
731   #   * argN
732   #   * ...
733   # [Stack After]
734   #   * retval
735   #   * ...
736   # [Description]
737   #   Execute a primitive method on the receiver (+receiver+). The index of the
738   #   primitive to execute (+primitive_index+), and the number of arguments
739   #   being passed (+argc+) are  specified as paramters.
740   #
741   #   When the primitive returns, the return value will be on top of the
742   #   stack.
743   # [Notes]
744   #   The implementation of the primitive is responsible for consuming the
745   #   receiver and any arguments that are on the stack, and for placing a
746   #   return value onto the stack.
748   def send_primitive
749     <<-CODE
750     next_int;
751     j = (native_int)_int; // primitive index
752     next_int;
753     k = (native_int)_int; // num_args
755     // Should the OBJECT parameter be removed since a primitive is not necesarily
756     // performed on an object? Or should we state that the semantics of a primitive
757     // will always have an object or else it needs to be an opcode... ?
758     // If the primitive fails raise an exception
760     msg.name = Qnil;
761     msg.args = k;
762     msg.method = Qnil;
763     msg.module = Qnil;
764     if(!cpu_perform_system_primitive(state, c, j, &msg))
765     {
766       cpu_raise_primitive_failure(state, c, j);
767     }
768     CODE
769   end
771   # [Operation]
772   #   Unconditionally jump execution to the position specified by the label
773   # [Format]
774   #   \goto label
775   # [Stack Before]
776   #   * ...
777   # [Stack After]
778   #   * ...
779   # [Description]
780   #   Moves the instruction pointer to the instruction following the specified
781   #   label without disturbing the stack.
782   # [See Also]
783   #   * goto_if_true
784   #   * goto_if_false
785   #   * goto_if_defined
787   def goto
788     <<-CODE
789     next_int;
790     c->ip = _int;
791     cpu_cache_ip(c);
792     CODE
793   end
795   # [Operation]
796   #   Jump execution to the position specified by the label if the top of the
797   #   stack evaluates to false.
798   # [Format]
799   #   \goto_if_false label
800   # [Stack Before]
801   #   * value
802   #   * ...
803   # [Stack After]
804   #   * ...
805   # [Description]
806   #   Remove the top item on the stack, and if +nil+ or +false+, jump to the
807   #   instruction following the specified label; otherwise, continue.
808   # [See Also]
809   #   * goto
810   #   * goto_if_false
811   #   * goto_if_defined
813   def goto_if_false
814     <<-CODE
815     next_int;
816     t1 = stack_pop();
817     if(!RTEST(t1)) {
818       c->ip = _int;
819       cpu_cache_ip(c);
820     }
821     CODE
822   end
824   # [Operation]
825   #   Jump execution to the position specified by the label if the top of the
826   #   stack evaluates to true.
827   # [Format]
828   #   \goto_if_true label
829   # [Stack Before]
830   #   * value
831   #   * ...
832   # [Stack After]
833   #   * ...
834   # [Description]
835   #   Remove the top item on the stack, and if not +nil+ or +false+, jump to
836   #   the instruction following the specified label; otherwise, continue.
837   # [See Also]
838   #   * goto
839   #   * goto_if_false
840   #   * goto_if_defined
842   def goto_if_true
843     <<-CODE
844     next_int;
845     t1 = stack_pop();
846     if(RTEST(t1)) {
847       c->ip = _int;
848       cpu_cache_ip(c);
849     }
850     CODE
851   end
853   # [Operation]
854   #   Jump execution to the position specified by the label if the top of the
855   #   stack is not undefined.
856   # [Format]
857   #   \goto_if_defined label
858   # [Stack Before]
859   #   * value
860   #   * ...
861   # [Stack After]
862   #   * ...
863   # [Description]
864   #   Remove the top item on the stack, and if it is not the special value
865   #   +undefined+, jump to the instruction following the specified label;
866   #   otherwise, continue.
867   # [See Also]
868   #   * goto
869   #   * goto_if_true
870   #   * goto_if_false
872   def goto_if_defined
873     <<-CODE
874     next_int;
875     t1 = stack_pop();
876     if(t1 != Qundef) {
877       c->ip = _int;
878       cpu_cache_ip(c);
879     }
880     CODE
881   end
883   # [Operation]
884   #   Swap the top two stack values
885   # [Format]
886   #   \swap_stack
887   # [Stack Before]
888   #   * value1
889   #   * value2
890   #   * ...
891   # [Stack After]
892   #   * value2
893   #   * value1
894   #   * ...
895   # [Description]
896   #   Swaps the top two items on the stack, so that the second item becomes
897   #   the first, and the first item becomes the second.
899   def swap_stack
900     <<-CODE
901     t1 = stack_pop();
902     t2 = stack_pop();
903     stack_push(t1);
904     stack_push(t2);
905     CODE
906   end
908   # [Operation]
909   #   Duplicate the top item on the stack
910   # [Format]
911   #   \dup_top
912   # [Stack Before]
913   #   * value
914   #   * ...
915   # [Stack After]
916   #   * value
917   #   * value
918   #   * ...
919   # [Description]
920   #   Duplicate the top value on the operand stack and push the duplicated
921   #   value onto the operand stack.
923   def dup_top
924     <<-CODE
925     t1 = stack_top();
926     stack_push(t1);
927     CODE
928   end
930   # [Operation]
931   #   Pop an item off the stack and discard
932   # [Format]
933   #   \pop
934   # [Stack Before]
935   #   * value
936   #   * ...
937   # [Stack After]
938   #   * ...
939   # [Description]
940   #   Removes the top item from the stack, discarding it.
941   # [Notes]
942   #   Pop is typically used when the return value of another opcode is not
943   #   required.
945   def pop
946     "    (void)stack_pop();"
947   end
949   # [Operation]
950   #   Sets the value of a local variable
951   # [Format]
952   #   \set_local local
953   # [Stack Before]
954   #   * value
955   #   * ...
956   # [Stack After]
957   #   * value
958   #   * ...
959   # [Description]
960   #   Pops +value+ off the stack, and uses it to set the value of the local
961   #   variable identified by the literal +local+. The value is then pushed back
962   #   onto the stack, to represent the return value from the expression.
964   def set_local
965     <<-CODE
966     next_int;
967     t1 = stack_pop();
968     // printf("Set local %d to %s\\n", _int, _inspect(t1));
969     t2 = c->locals;
970     if(t2->gc_zone == 0) {
971       sassert(_int < NUM_FIELDS(t2) && "locals tuple sized wrong");
972       fast_unsafe_set(t2, _int, t1);
973     } else {
974       tuple_put(state, t2, _int, t1);
975     }
976     stack_push(t1);
977     CODE
978   end
980   # [Operation]
981   #   Sets a method argument local from the caller's stack
982   # [Format]
983   #   \set_local_from_fp local arg
984   # [Stack Before]
985   #   * ...
986   # [Stack After]
987   #   * ...
988   # [Description]
989   #   Copies the value of method argument +arg+ into the local variable
990   #   +local+. Method arguments are accessed from the caller's stack via
991   #   negative offsets from the frame pointer, where 0 is the first argument,
992   #   1 is the second, etc.
993   #
994   #   This opcode is now deprecated, and is not currently used under
995   #   compiler2.
996   # [See Also]
997   #   * from_fp
998   # [Notes]
999   #   Under compiler1, this opcode was used to copy method args into stack
1000   #   locals if the method arg was modified, but not captured. The use of
1001   #   stack and frame locals has been deprecated under compiler2, and all
1002   #   locals are now allocated in the execution context locals tuple. This
1003   #   opcode has thus been modified to store a frame referenced method arg in
1004   #   the locals tuple.
1006   def set_local_from_fp
1007     <<-CODE
1008     next_int;
1009     k = (native_int)_int;
1010     next_int;
1012     t1 = c->stack_top[c->fp - _int];
1014     t2 = cpu_current_locals(state, c);
1015     if(t2->gc_zone == 0) {
1016       sassert(k < NUM_FIELDS(t2) && "locals tuple sized wrong");
1017       fast_unsafe_set(t2, k, t1);
1018     } else {
1019       tuple_put(state, t2, k, t1);
1020     }
1021     CODE
1022   end
1024   # [Operation]
1025   #   Updates the value of a local variable contained in an enclosing scope
1026   # [Format]
1027   #   \set_local_depth depth local
1028   # [Stack Before]
1029   #   * value
1030   #   * ...
1031   # [Stack After]
1032   #   * value
1033   #   * ...
1034   # [Description]
1035   #   Uses the +value+ on the top of the stack to update the value of the
1036   #   local variable +local+ in an enclosing scope. The value is then pushed
1037   #   back onto the stack, to represent the return value from the expression.
1038   # [Example]
1039   #   <code>
1040   #     foo.each do |i|
1041   #       bar.each do |j|
1042   #         i = i + j  # i is a local variable from enclosing scope at depth 1
1043   #       end
1044   #     end
1045   #   </code>
1047   def set_local_depth
1048     <<-CODE
1049     next_int;
1050     k = (native_int)_int;
1051     next_int;
1052     t3 = stack_pop();
1053     t1 = c->active_context;
1055     for(j = 0; j < k; j++) {
1056       t2 = blokctx_env(state, t1);
1057       t1 = blokenv_get_home_block(t2);
1058     }
1060     t2 = blokctx_locals(state, t1);
1061     if(t2->gc_zone == 0) {
1062       sassert(_int < NUM_FIELDS(t2) && "locals tuple sized wrong");
1063       fast_unsafe_set(t2, _int, t3);
1064     } else {
1065       tuple_put(state, t2, _int, t3);
1066     }
1067     stack_push(t3);
1069     CODE
1070   end
1072   # [Operation]
1073   #   Create an array and populate with items on the stack
1074   # [Format]
1075   #   \make_array argc
1076   # [Stack Before]
1077   #   * valueN
1078   #   * ...
1079   #   * value2
1080   #   * value1
1081   #   * ...
1082   # [Stack After]
1083   #   * [value1, value2, ..., valueN]
1084   #   * ...
1085   # [Description]
1086   #   Creates a new array, populating its contents with the number of items
1087   #   (+argc+) specified in the opcode. The contents of the new array are
1088   #   taken from the stack, with the top item on the stack becoming the last
1089   #   item in the array. The resulting array is added back to the stack.
1091   def make_array
1092     <<-CODE
1093     next_int;
1094     t1 = array_new(state, _int);
1095     j = _int - 1;
1096     for(; j >= 0; j--) {
1097       t2 = stack_pop();
1098       array_set(state, t1, j, t2);
1099     }
1101     cpu_perform_hook(state, c, BASIC_CLASS(array),
1102                      global->sym_from_literal, t1);
1103     stack_push(t1);
1104     CODE
1105   end
1107   # [Operation]
1108   #   Unpack the array on the top of the stack into individual items on the
1109   #   stack
1110   # [Format]
1111   #   \push_array
1112   # [Stack Before]
1113   #   * [value1, value2, ..., valueN]
1114   #   * ...
1115   # [Stack After]
1116   #   * value1
1117   #   * value2
1118   #   * ...
1119   #   * valueN
1120   #   * ...
1121   # [Description]
1122   #   Removes the array currently on top of the stack, and replaces it with
1123   #   the contents of the array, such that the first item in the array ends up
1124   #   on top of the stack.
1125   # [See Also]
1126   #   * make_array
1127   # [Notes]
1128   #   Push array places the contents of the array onto the stack in reverse
1129   #   order to the order in which items on the stack are added to an array by
1130   #   make_array.
1132   def push_array
1133     <<-CODE
1134     t1 = stack_pop();
1135     j = N2I(array_get_total(t1));
1136     for(j--; j >= 0; j--) {
1137       stack_push(array_get(state, t1, j));
1138     }
1139     CODE
1140   end
1142   # [Operation]
1143   #   Convert a tuple to an array, or wrap an object within an array
1144   # [Format]
1145   #   \cast_array
1146   # [Stack Before]
1147   #   * value
1148   #   * ...
1149   # [Stack After]
1150   #   * array
1151   #   * ...
1152   # [Description]
1153   #   Removes the object on the top of the stack, and:
1154   #
1155   #   If the input is a tuple, a new array object is created based on the
1156   #   tuple data.
1157   #
1158   #   If the input is an array, it is unmodified.
1159   #
1160   #   If the input is any other type, that type is wrapped within a new array
1161   #   of length one.
1162   #
1163   #   The resulting array is then pushed back onto the stack.
1165   def cast_array
1166     <<-CODE
1167     t1 = stack_pop();
1168     if(REFERENCE_P(t1) && object_kind_of_p(state, t1, global->tuple)) {
1169       t1 = array_from_tuple(state, t1);
1170     } else if(!REFERENCE_P(t1) || !object_kind_of_p(state, t1, global->array)) {
1171       t2 = array_new(state, 1);
1172       array_set(state, t2, 0, t1);
1173       t1 = t2;
1174     }
1175     stack_push(t1);
1176     CODE
1177   end
1179   # [Operation]
1180   #   Casts the value on the top of the stack into an array to be used as
1181   #   method args
1182   # [Format]
1183   #   \cast_array_for_args size
1184   # [Stack Before]
1185   #   * value
1186   #   * ...
1187   # [Stack After]
1188   #   * array
1189   #   * ...
1190   # [Description]
1191   #   Removes the object on the top of the stack, and:
1192   #
1193   #   If the object is a tuple, it is cast to an array.
1194   #
1195   #   If the object is already an array, it is left unmodified.
1196   #
1197   #   If the object is any other type, it is wrapped in a 1-element array with
1198   #   the object as the value of the single element.
1199   #
1200   #   The resulting array is then pushed back onto the stack, and the size of
1201   #   the array is added to the argument +size+ that was specified with the
1202   #   opcode, and saved as the current method argument count.
1203   #
1204   #   This opcode will always be followed by a push_array instruction that
1205   #   unpacks the array elements into discrete stack entries prior to calling
1206   #   either send_with_arg_register or send_super_with_arg_register.
1207   # [See Also]
1208   #   * push_array
1209   #   * get_args
1210   # [Notes]
1211   #   This opcode exists to handle argscat and argspush, where a splat arg is
1212   #   specified in addition to one or more discrete arguments.
1214   def cast_array_for_args
1215     <<-CODE
1216     next_int;
1217     c->args = _int;
1218     t1 = stack_pop();
1219     if(REFERENCE_P(t1) && object_kind_of_p(state, t1, global->tuple)) {
1220       t1 = array_from_tuple(state, t1);
1221     } else if(!REFERENCE_P(t1) || !object_kind_of_p(state, t1, global->array)) {
1222       t2 = array_new(state, 1);
1223       array_set(state, t2, 0, t1);
1224       t1 = t2;
1225     }
1226     stack_push(t1);
1227     c->args += N2I(array_get_total(t1));
1228     CODE
1229   end
1231   # [Operation]
1232   #   Convert stack object to a tuple
1233   # [Format]
1234   #   \cast_tuple
1235   # [Stack Before]
1236   #   * value
1237   #   * ...
1238   # [Stack After]
1239   #   * tuple
1240   #   * ...
1241   # [Description]
1242   #   If stack object is an array, create a new tuple from the array data
1243   #
1244   #   If the stack value is a tuple, leave the stack unmodified
1245   #
1246   #   Otherwise, create a unary tuple from the value on the stack
1248   def cast_tuple
1249     <<-CODE
1250     t1 = stack_pop();
1251     if(REFERENCE_P(t1) && object_kind_of_p(state, t1, global->array)) {
1252       j = N2I(array_get_total(t1));
1253       t2 = tuple_new(state, j);
1255       for(k = 0; k < j; k++) {
1256         tuple_put(state, t2, k, array_get(state, t1, k));
1257       }
1258       t1 = t2;
1259     } else if(!REFERENCE_P(t1) || !object_kind_of_p(state, t1, global->tuple)) {
1260       t2 = tuple_new(state, 1);
1261       tuple_put(state, t2, 0, t1);
1262       t1 = t2;
1263     }
1264     stack_push(t1);
1265     CODE
1266   end
1268   # [Operation]
1269   #   Converts the item on the top of the stack into an argument for a block
1270   #   taking one arg
1271   # [Format]
1272   #   \cast_for_single_block_arg
1273   # [Stack Before]
1274   #   * arg
1275   #   * ...
1276   # [Stack After]
1277   #   * block_arg
1278   #   * ...
1279   # [Description]
1280   #   The item on the top of the stack is popped, and:
1281   #
1282   #   If it has no fields, the result is nil
1283   #
1284   #   If the item contains a single field, the result is the value in the
1285   #   first field
1286   #
1287   #   If the item is a tuple, the result is an array created from the tuple.
1288   #
1289   #   The result is then pushed onto the stack.
1291   def cast_for_single_block_arg
1292     <<-CODE
1293     t1 = stack_pop();
1294     k = NUM_FIELDS(t1);
1295     if(k == 0) {
1296       stack_push(Qnil);
1297     } else if(k == 1) {
1298       stack_push(tuple_at(state, t1, 0));
1299     } else {
1300       stack_push(array_from_tuple(state, t1));
1301     }
1302     CODE
1303   end
1305   # [Operation]
1306   #   Converts a block argument single-valued tuple into multiple arguments if
1307   #   the arg is an array
1308   # [Format]
1309   #   \cast_for_multi_block_arg
1310   # [Stack Before]
1311   #   * tuple[array[el1,el2,...,eln]]
1312   #   * ...
1313   # [Stack After]
1314   #   * tuple[el1,el2,...,eln]
1315   #   * ...
1316   # [Description]
1317   #   If the tuple on the top of the stack has only a single element, and that
1318   #   element is an array, a new tuple is created containing the contents of
1319   #   the array, and this new tuple is used to update the top of the stack.
1320   # [Example]
1321   #   <code>
1322   #     [[1,2,3]].each do |i,j,k|
1323   #       # do something
1324   #     end
1325   #   </code>
1327   def cast_for_multi_block_arg
1328     <<-CODE
1329     t1 = stack_top();
1330     k = NUM_FIELDS(t1);
1331     /* If there is only one thing in the tuple... */
1332     if(k == 1) {
1333       t1 = tuple_at(state, t1, 0);
1334       /* and that thing is an array... */
1335       if(RISA(t1, array)) {
1336         /* make a tuple out of the array contents... */
1337         j = N2I(array_get_total(t1));
1338         t2 = tuple_new(state, j);
1340         for(k = 0; k < j; k++) {
1341           tuple_put(state, t2, k, array_get(state, t1, k));
1342         }
1344         /* and put it on the top o the stack. */
1345         stack_set_top(t2);
1346       }
1347     }
1348     CODE
1349   end
1351   # [Operation]
1352   #   Create a hash and populate with items on the stack
1353   # [Format]
1354   #   \make_hash argc
1355   # [Stack Before]
1356   #   * keyN
1357   #   * valueN
1358   #   * ...
1359   #   * key2
1360   #   * value2
1361   #   * key1
1362   #   * value1
1363   #   * ...
1364   # [Stack After]
1365   #   * { key1 => value1, key2 => value2, ..., keyN => valueN }
1366   #   * ...
1367   # [Description]
1368   #   Creates a new hash, populating its contents with the number of items
1369   #   (+argc+) specified in the opcode. The contents of the new hash are taken
1370   #   from the stack, with the top item on the stack becoming the last key in
1371   #   the hash, the second top item becoming the last value, and so on. The
1372   #   resulting hash is added back to the stack.
1374   def make_hash
1375     <<-CODE
1376     next_int;
1377     t1 = hash_new(state);
1378     j = _int - 1;
1379     while(j >= 0) {
1380       t2 = stack_pop();
1381       t3 = stack_pop();
1382       hash_set(state, t1, t2, t3);
1383       j -= 2;
1384     }
1386     cpu_perform_hook(state, c, BASIC_CLASS(hash),
1387                      global->sym_from_literal, t1);
1389     stack_push(t1);
1390     CODE
1391   end
1393   # [Operation]
1394   #   Sets an instance variable on self
1395   # [Format]
1396   #   \set_ivar ivar
1397   # [Stack Before]
1398   #   * value
1399   #   * ...
1400   # [Stack After]
1401   #   * value
1402   #   * ...
1403   # [Description]
1404   #   Pops a value off the stack, and uses it to set the value of the instance
1405   #   variable identifies by the literal +ivar+ on the current +self+ object.
1406   #   The value popped off the stack is then pushed back on again.
1408   def set_ivar
1409     <<-CODE
1410     next_literal;
1411     t2 = stack_pop();
1412     object_set_ivar(state, c->self, _lit, t2);
1413     stack_push(t2);
1414     CODE
1415   end
1417   # [Operation]
1418   #   Pushes a constant onto the stack
1419   # [Format]
1420   #   \push_const constant
1421   # [Stack Before]
1422   #   * ...
1423   # [Stack After]
1424   #   * const
1425   #   * ...
1426   # [Description]
1427   #   Locates the constant indicated by the literal +constant+ from the
1428   #   current context, and pushes it onto the stack. If the constant cannot be
1429   #   found in the current context, nothing is pushed onto the stack, and a
1430   #   NameError exception is raised.
1431   # [Example]
1432   #   <code>
1433   #     engine = RUBY_ENGINE # RUBY_ENGINE is a constant defined by Rubinius
1434   #   </code>
1436   def push_const
1437     <<-CODE
1438     next_literal;
1439     t1 = cpu_const_get_in_context(state, c, _lit);
1440     if(AUTOLOAD_P(t1)) {
1441       cpu_send(state, c, t1, state->global->sym_call, 0, Qnil);
1442     } else if(t1 != Qundef) {
1443       stack_push(t1);
1444     }
1445     CODE
1446   end
1448   # [Operation]
1449   #   Finds a constant
1450   # [Format]
1451   #   \find_const constant
1452   # [Stack Before]
1453   #   * ns
1454   #   * ...
1455   # [Stack After]
1456   #   * const
1457   #   * ...
1458   # [Description]
1459   #   Pops the module or \class +ns+ off the stack, and searches within it's
1460   #   namespace for the constant identified by the literal +constant+. If
1461   #   found, it is pushed onto the stack; otherwise, nothing is pushed onto
1462   #   the stack, and a NameError exception is raised.
1463   # [Example]
1464   #   <code>
1465   #     str = "abc"
1466   #     enum = Enumerable::Enumerator(str, :each_byte)
1467   #   </code>
1469   def find_const
1470     <<-CODE
1471     t1 = stack_pop();
1472     next_literal;
1473     t2 = cpu_const_get_from(state, c, _lit, t1);
1474     if(AUTOLOAD_P(t2)) {
1475       cpu_send(state, c, t2, state->global->sym_call, 0, Qnil);
1476     } else if(t2 != Qundef) {
1477       stack_push(t2);
1478     }
1479     CODE
1480   end
1482   # [Operation]
1483   #   Sets a literal to refer to a constant
1484   # [Format]
1485   #   \set_const lit
1486   # [Stack Before]
1487   #   * item
1488   #   * ...
1489   # [Stack After]
1490   #   * const
1491   #   * ...
1492   # [Description]
1493   #   Pops an object off the stack, and sets the literal referenced in the
1494   #   opcode to refer to the object as a constant. The constant is pushed back
1495   #   onto the stack.
1497   def set_const
1498     <<-CODE
1499     next_literal;
1500     t1 = stack_pop();
1501     t2 = staticscope_get_module(cpu_current_scope(state, c));
1502     stack_push(cpu_const_set(state, c, _lit, t1, t2));
1503     CODE
1504   end
1506   # [Operation]
1507   #   Sets the value of a constant under a module
1508   # [Format]
1509   #   \set_const_at lit
1510   # [Stack Before]
1511   #   * value
1512   #   * module
1513   #   * ...
1514   # [Stack After]
1515   #   * ...
1516   # [Description]
1517   #   Pops the new +value+ for a constant identified by the +lit+ index in the
1518   #   literals tuple, in the scope of +module+, which is also popped from the
1519   #   stack.
1521   def set_const_at
1522     <<-CODE
1523     next_literal;
1524     t2 = stack_pop();
1525     t3 = stack_pop();
1526     stack_push(cpu_const_set(state, c, _lit, t2, t3));
1527     CODE
1528   end
1530   # [Operation]
1531   #   Pushes the top level global object onto the stack
1532   # [Format]
1533   #   \push_cpath_top
1534   # [Stack Before]
1535   #   * ...
1536   # [Stack After]
1537   #   * cpathtop
1538   #   * ...
1539   # [Description]
1540   #   Pushes the top-level global object that represents the top-level
1541   #   namespace for constants. Used when a global variable is referenced.
1542   # [Example]
1543   #   <code>
1544   #     puts $: # Global variables are looked up on the top-level Globals object
1545   #   </code>
1547   def push_cpath_top
1548     "stack_push(global->object);"
1549   end
1551   # [Operation]
1552   #   Sets the enclosing class/module when opening a class/module
1553   # [Format]
1554   #   \set_encloser
1555   # [Stack Before]
1556   #   * class
1557   #   * ...
1558   # [Stack After]
1559   #   * ...
1560   # [Description]
1561   #   Pops +\class+ off the stack, and uses it as the enclosing scope for
1562   #   subsequent \class or module definitions.
1563   # [See Also]
1564   #   * push_encloser
1565   # [Example]
1566   #   <code>
1567   #     module A    # encloser is set to A after this line
1568   #       module B  # encloser is set to B after this line
1569   #       end       # encloser is reset to A after this line
1570   #     end
1571   #   </code>
1573   def set_encloser
1574     <<-CODE
1575     t1 = stack_pop();
1576     cpu_set_encloser_path(state, c, t1);
1577     CODE
1578   end
1580   # [Operation]
1581   #   Resets the current class/module to the parent class/module
1582   # [Format]
1583   #   \push_encloser
1584   # [Stack Before]
1585   #   * ...
1586   # [Stack After]
1587   #   * ...
1588   # [Description]
1589   #   Resets the current enclosing \class or module to the parent \class or
1590   #   module in the enclosing scope path. Used when a \class or module
1591   #   definition ends, to \pop up a level in the enclosure stack.
1592   # [See Also]
1593   #   * set_encloser
1594   # [Example]
1595   #   <code>
1596   #     module A    # encloser is set to A after this line
1597   #       module B  # encloser is set to B after this line
1598   #       end       # encloser is reset to A after this line
1599   #     end
1600   #   </code>
1602   def push_encloser
1603     <<-CODE
1604     cpu_push_encloser(state, c);
1605     CODE
1606   end
1608   # [Operation]
1609   #   Creates or re-opens a \class.
1610   # [Format]
1611   #   \open_class_under \class
1612   # [Stack Before]
1613   #   * super
1614   #   * enclosing_class
1615   #   * ...
1616   # [Stack After]
1617   #   * class
1618   #   * ...
1619   # [Description]
1620   #   Creates or re-opens a \class, popping the superclass (or nil) and the
1621   #   enclosing \class from the stack. Upon return, the new \class is pushed
1622   #   onto the stack.
1623   #
1624   #   The +\class+ argument to the opcode is the \class literal identifying
1625   #   the \class to be opened.
1626   # [See Also]
1627   #   * open_class
1628   # [Example]
1629   #   <code>
1630   #     class A
1631   #     end
1632   #
1633   #     class A::B < C
1634   #     end
1635   #     # Stack transition:
1636   #     # [...,A,C] => [...,B]
1637   #   </code>
1639   def open_class_under
1640     <<-CODE
1641     int created;
1642     t1 = stack_pop();
1643     t2 = stack_pop();
1644     next_literal;
1645     t3 = cpu_open_class(state, c, t2, t1, _lit, &created);
1647     if(AUTOLOAD_P(t3)) {
1648       cpu_send(state, c, t3, state->global->sym_call, 0, Qnil);
1649     } else if(t3 != Qundef) {
1650       stack_push(t3);
1651       if(created) cpu_perform_hook(state, c, t3, global->sym_opened_class, t1);
1652     }
1653     CODE
1654   end
1656   # [Operation]
1657   #   Creates or re-opens a \class.
1658   # [Format]
1659   #   \open_class class_name
1660   # [Stack Before]
1661   #   * super
1662   #   * ...
1663   # [Stack After]
1664   #   * class
1665   #   * ...
1666   # [Description]
1667   #   Creates or re-opens a \class, taking the superclass (or nil) from the
1668   #   stack. Upon return, the new \class is pushed onto the stack.
1669   #
1670   #   The +class_name+ argument to the opcode is the \class literal
1671   #   identifying the \class to be opened.
1672   # [See Also]
1673   #   * push_encloser
1674   #   * open_class_under
1675   # [Notes]
1676   #   The enclosing \class (if any) will be the current enclosing \class in
1677   #   the current execution context. Typically, this will have been set by
1678   #   executing the opcode push_encloser.
1679   # [Example]
1680   #   <code>
1681   #     class A
1682   #       class B
1683   #       end
1684   #     end
1685   #     # Stack transition:
1686   #     # [...,A] => [...,B]
1687   #   </code>
1689   def open_class
1690     <<-CODE
1691     int created;
1692     t1 = stack_pop();
1693     t2 = staticscope_get_module(cpu_current_scope(state, c));
1694     next_literal;
1695     t3 = cpu_open_class(state, c, t2, t1, _lit, &created);
1697     if(AUTOLOAD_P(t3)) {
1698       cpu_send(state, c, t3, state->global->sym_call, 0, Qnil);
1699     } else if(t3 != Qundef) {
1700       stack_push(t3);
1701       if(created) cpu_perform_hook(state, c, t3, global->sym_opened_class, t1);
1702     }
1703     CODE
1704   end
1706   # [Operation]
1707   #   Creates or opens a module nested under another module
1708   # [Format]
1709   #   \open_module_under name
1710   # [Stack Before]
1711   #   * parent
1712   #   * ...
1713   # [Stack After]
1714   #   * module
1715   #   * ...
1716   # [Description]
1717   #   Pops an enclosing \class or module from the stack, and creates or
1718   #   re-opens the module identified by the literal +name+. The module is then
1719   #   pushed onto the  stack.
1720   # [Example]
1721   #   <code>
1722   #     module X::Y    # Opens module Y under the module X
1723   #     end
1724   #   </code>
1726   def open_module_under
1727     <<-CODE
1728     next_literal;
1729     t1 = stack_pop();
1730     t2 = cpu_open_module(state, c, t1, _lit);
1732     if(AUTOLOAD_P(t2)) {
1733       cpu_send(state, c, t2, state->global->sym_call, 0, Qnil);
1734     } else {
1735       stack_push(t2);
1736     }
1737     CODE
1738   end
1740   # [Operation]
1741   #   Creates or reopens a module
1742   # [Format]
1743   #   \open_module module
1744   # [Stack Before]
1745   #   * ...
1746   # [Stack After]
1747   #   * module
1748   #   * ...
1749   # [Description]
1750   #   Creates or re-opens the module referenced by the literal +module+, and
1751   #   pushes it onto the stack.
1752   # [See Also]
1753   #   * open_class
1754   # [Example]
1755   #   <code>
1756   #     module A   # Creates module A (or re-opens it if it already exists)
1757   #     end
1758   #   </code>
1760   def open_module
1761     <<-CODE
1762     next_literal;
1763     t2 = staticscope_get_module(cpu_current_scope(state, c));
1764     t1 = cpu_open_module(state, c, t2, _lit);
1765     if(AUTOLOAD_P(t1)) {
1766       cpu_send(state, c, t1, state->global->sym_call, 0, Qnil);
1767     } else {
1768       stack_push(t1);
1769     }
1770     CODE
1771   end
1773   # [Operation]
1774   #   Returns the metaclass for an object
1775   # [Format]
1776   #   \open_metaclass
1777   # [Stack Before]
1778   #   * obj
1779   #   * ...
1780   # [Stack After]
1781   #   * metaclass
1782   #   * ...
1783   # [Description]
1784   #   Pops an object off the stack, obtains it's metaclass (creating it if
1785   #   necessary), and pushes it onto the stack.
1786   # [Notes]
1787   #   An object metaclass is it's singleton class, i.e. the class that is used
1788   #   to hold object specific methods. In Rubinius, any object can call the
1789   #   +metaclass+ method to obtain its metaclass.
1790   # [Example]
1791   #   <code>
1792   #     o.metclass   # returns o's metaclass
1793   #   </code>
1795   def open_metaclass
1796     <<-CODE
1797     t1 = stack_pop();
1798     stack_push(object_metaclass(state, t1));
1799     CODE
1800   end
1802   # [Operation]
1803   #   Attaches a method definition to an object's singleton \class
1804   # [Format]
1805   #   \attach_method name
1806   # [Stack Before]
1807   #   * receiver
1808   #   * method
1809   #   * ...
1810   # [Stack After]
1811   #   * method
1812   #   * ...
1813   # [Description]
1814   #   Hooks up a compiled method to an object instance via it's singleton
1815   #   \class.
1816   #
1817   #   The object the method is to be added to (+receiver+) and the compiled
1818   #   method object (+method+) are popped from the stack, while the name of
1819   #   the  method is an argument to the opcode (+name+). On return, the
1820   #   compiled method is pushed back onto the stack.
1821   # [See Also]
1822   #   * add_method
1823   # [Notes]
1824   #   Class/module methods are handled by add_method.
1826   def attach_method
1827     <<-CODE
1828     next_literal;
1829     t1 = stack_pop();
1830     t2 = stack_pop();
1831     cpu_attach_method(state, c, t1, _lit, t2);
1832     stack_push(t2);
1833     cpu_perform_hook(state, c, t1, global->sym_s_method_added, _lit);
1834     CODE
1835   end
1837   # [Operation]
1838   #   Adds a method to a \class or module
1839   # [Format]
1840   #   \add_method name
1841   # [Stack Before]
1842   #   * receiver
1843   #   * method
1844   #   * ...
1845   # [Stack After]
1846   #   * method
1847   #   * ...
1848   # [Description]
1849   #   Hooks up a compiled method to a \class or module.
1850   #
1851   #   The \class or module the method is to be added to (+receiver+) and the
1852   #   compiled method object (+method+) are popped from the stack, while the
1853   #   name of the method is an argument to the opcode (+name+). On return, the
1854   #   compiled method is pushed back onto the stack.
1855   # [See Also]
1856   #   * attach_method
1857   # [Notes]
1858   #   Singleton methods are handled by attach_method.
1860   def add_method
1861     <<-CODE
1862     next_literal;
1863     t1 = stack_pop();
1864     t2 = stack_pop();
1865     cpu_add_method(state, c, t1, _lit, t2);
1866     stack_push(t2);
1867     cpu_perform_hook(state, c, t1, global->sym_method_added, _lit);
1868     CODE
1869   end
1871   # [Operation]
1872   #   Activates a cached method on an object in preparation for execution.
1873   # [Format]
1874   #   \activate_method argc
1875   # [Stack Before]
1876   #   * receiver
1877   #   * method
1878   #   * size
1879   #   * locals
1880   #   * block
1881   #   * arg1
1882   #   * arg2
1883   #   * ...
1884   #   * argN
1885   #   * ...
1886   # [Stack After]
1887   #   * retval
1888   #   * ...
1889   # [Description]
1890   #   Pops the top five items off the stack, using these to identify the
1891   #   object on which to invoke the method (+receiver+), the CompiledMethod
1892   #   instance to execute (+method+, i.e. +self+), the number of argments the
1893   #   method defines (+size+), the +locals+ currently in scope, and any
1894   #   +block+ passed to the method.
1895   #
1896   #   Additionally, the actual arguments to be passed to the method must also
1897   #   be on the stack as an array, with the number of actual arguments passed
1898   #   (+argc+) specified alongside the opcode; these arguments will be
1899   #   consumed from the stack and pushed into locals when the method starts
1900   #   executing.
1901   #
1902   #   When the method returns, the return value will be on top of the stack.
1903   # [Notes]
1904   #   Used by CompiledMethod#activate.
1906   def activate_method
1907     <<-CODE
1908     next_int;
1909     msg.recv   = stack_pop();
1910     msg.method = stack_pop();
1911     msg.module = stack_pop();
1912     msg.args   = N2I(stack_pop());
1913     msg.name   = cmethod_get_name(msg.method);
1914     t3 = stack_pop(); /* locals */
1915     msg.block  = stack_pop();
1917     cpu_activate_method(state, c, &msg);
1918     if(RTEST(t3)) {
1919       if(NIL_P(cpu_current_locals(state, c)) || NUM_FIELDS(t3) >= NUM_FIELDS(cpu_current_locals(state, c))) {
1920         cpu_set_locals(state, c, t3);
1921       }
1922     }
1924     CODE
1925   end
1927   # [Operation]
1928   #   Sends a message with no args to a receiver
1929   # [Format]
1930   #   \send_method method_name
1931   # [Stack Before]
1932   #   * receiver
1933   #   * ...
1934   # [Stack After]
1935   #   * retval
1936   #   * ...
1937   # [Description]
1938   #   Pops an object off the top of the stack (+receiver+), and sends it the no
1939   #   arg message +method_name+.
1940   #
1941   #   When the method returns, the return value will be on top of the stack.
1942   # [See Also]
1943   #   * send_with_arg_register
1944   # [Notes]
1945   #   This form of send is for methods that take no arguments.
1946   #
1947   #   Make primitives safer by having the opcode be aware of the number of
1948   #   args sent.  This way we can remove the dependency of primitives being
1949   #   embedded in methods.
1951   def send_method
1952     <<-CODE
1953     next_literal_into(msg.send_site);
1954     msg.recv = stack_pop();
1955     msg.block = Qnil;
1956     msg.args = 0;
1957     goto perform_send;
1958     CODE
1959   end
1961   # [Operation]
1962   #   Placeholder for a removed opcode
1963   # [Format]
1964   #   \unused
1965   # [Stack Before]
1966   #   * ...
1967   # [Stack After]
1968   #   * ...
1969   # [Description]
1970   #    Raises an assert failure if used.
1971   # [Notes]
1972   #   This opcode is used wherever a previously used opcode has been removed.
1973   #   It ensures that removing an opcode does not change the numbering of
1974   #   succeeding opcodes.
1975   #
1976   #   The same opcode symbol (:unused) and instruction body can be used anywhere
1977   #   an opcode has been removed.
1979   def unused
1980     <<-CODE
1981     sassert(0 && "deprecated opcode was encountered!");
1982     CODE
1983   end
1985   # [Operation]
1986   #   Sends a message with arguments on the stack
1987   # [Format]
1988   #   \send_stack method argc
1989   # [Stack Before]
1990   #   * receiver
1991   #   * arg1
1992   #   * arg2
1993   #   * ...
1994   #   * argN
1995   #   * ...
1996   # [Stack After]
1997   #   * retval
1998   #   * ...
1999   # [Description]
2000   #   Pops the receiver and the block to be passed off the stack, and sends
2001   #   the message +method+ with +argc+ arguments. The arguments to the method
2002   #   remain on the stack, ready to be converted to locals when the method is
2003   #   activated.
2004   #
2005   #   When the method returns, the return value will be on top of the stack.
2006   # [See Also]
2007   #   * send_stack_with_block
2008   # [Notes]
2009   #   This opcode does not pass a block to the receiver; see
2010   #   send_stack_with_block for the equivalent op code used when a block is to
2011   #   be passed.
2013   def send_stack
2014     <<-CODE
2015     next_literal_into(msg.send_site);
2016     msg.recv = stack_pop();
2017     msg.block = Qnil;
2018     next_int_into(msg.args);
2020     goto perform_send;
2021     CODE
2022   end
2024   # [Operation]
2025   #   Sends a message with arguments and a block on the stack
2026   # [Format]
2027   #   \send_stack_with_block method argc
2028   # [Stack Before]
2029   #   * receiver
2030   #   * block
2031   #   * arg1
2032   #   * arg2
2033   #   * ...
2034   #   * argN
2035   #   * ...
2036   # [Stack After]
2037   #   * retval
2038   #   * ...
2039   # [Description]
2040   #   Pops the receiver +receiver+ and a block off the stack, and sends the
2041   #   message +method+ with +argc+ arguments. The arguments to the method
2042   #   remain on the stack, ready to be converted to locals as part of method
2043   #   activation.
2044   #
2045   #   When the method returns, the return value will be on top of the stack.
2046   # [See Also]
2047   #   * send_stack
2048   # [Notes]
2049   #   This opcode passes a block to the receiver; see send_stack for the
2050   #   equivalent op code used when no block is to be passed.
2052   def send_stack_with_block
2053     <<-CODE
2054     next_literal_into(msg.send_site);
2055     msg.recv = stack_pop();
2056     msg.block = stack_pop();
2057     next_int_into(msg.args);
2059     goto perform_send;
2060     CODE
2061   end
2063   # [Operation]
2064   #   Sends a message with args to a receiver
2065   # [Format]
2066   #   \send_with_arg_register method
2067   # [Stack Before]
2068   #   * receiver
2069   #   * block
2070   #   * arg1
2071   #   * arg2
2072   #   * ...
2073   #   * argN
2074   #   * ...
2075   # [Stack After]
2076   #   * retval
2077   #   * ...
2078   # [Description]
2079   #   Pops the receiver +receiver+ and a block +block+ off the top of the stack,
2080   #   and sends the message +method+. The number of arguments taken by the
2081   #   method must have previously been set in the args register, and the arg
2082   #   values themselves remain on the top of the stack, to be converted to
2083   #   locals as part of method activation.
2084   #
2085   #   When the method returns, the return value will be on top of the stack.
2086   # [See Also]
2087   #   * send_method
2088   #   * set_args
2089   #   * cast_array_for_args
2090   # [Notes]
2091   #   The number of arguments to be passed to the method in +args+ must have
2092   #   been set previously via a call to either set_args or
2093   #   cast_array_for_args.
2095   def send_with_arg_register
2096     <<-CODE
2097     next_literal_into(msg.send_site);
2098     msg.recv = stack_pop();
2099     msg.block = stack_pop();
2100     msg.args = c->args;
2102     perform_send:
2104     msg.priv = c->call_flags;
2105     msg.klass = _real_class(state, msg.recv);
2107     c->call_flags = 0;
2109     cpu_send_message(state, c, &msg);
2110     CODE
2111   end
2113   # [Operation]
2114   #   Call a method on the superclass with a block
2115   # [Format]
2116   #   \send_super_stack_with_block method argc
2117   # [Stack Before]
2118   #   * block
2119   #   * arg1
2120   #   * arg2
2121   #   * ...
2122   #   * argN
2123   #   * ...
2124   # [Stack After]
2125   #   * retval
2126   #   * ...
2127   # [Description]
2128   #   Pops a block off the stack, and sends the message +method+ with +argc+
2129   #   arguments. The arguments to the method remain on the stack, ready to be
2130   #   converted into locals when the method is activated.
2131   #
2132   #   When the method returns, the return value will be on top of the stack.
2133   # [Notes]
2134   #   The receiver is not specified for a call to super; it is the superclass
2135   #   of the current object that will receive the message.
2137   def send_super_stack_with_block
2138     <<-CODE
2139     next_literal;
2140     next_int;
2141     j = _int;
2143     goto perform_super_send;
2144     CODE
2145   end
2147   # [Operation]
2148   #   Call a method on the superclass, passing args plus a block
2149   # [Format]
2150   #   \send_super_with_arg_register method
2151   # [Stack Before]
2152   #   * block
2153   #   * arg1
2154   #   * arg2
2155   #   * ...
2156   #   * argN
2157   #   * ...
2158   # [Stack After]
2159   #   * retval
2160   #   * ...
2161   # [Description]
2162   #   Pops a block off the stack, and sends the message +method+ to the current
2163   #   objects  superclass. The arguments to the method areleft on the top of
2164   #   the stack, ready to be converted into locals when the method is
2165   #   activated.
2166   #
2167   #   When the method returns, the return value will be on top of the stack.
2168   # [See Also]
2169   #   * set_args
2170   #   * cast_array_for_args
2171   # [Notes]
2172   #   The args register must have previously been set to the count of the
2173   #   number of arguments in +args+ via either set_args or
2174   #   cast_array_for_args.
2176   def send_super_with_arg_register
2177     <<-CODE
2178     next_literal;
2179     j = c->args;
2181     perform_super_send:
2183     msg.send_site = _lit;
2184     msg.recv = c->self;
2185     msg.block = stack_pop();
2186     msg.args = j;
2187     msg.priv = TRUE;
2189     msg.klass = class_get_superclass(cpu_current_module(state, c));
2191     cpu_send_message(state, c, &msg);
2192     CODE
2193   end
2195   # [Operation]
2196   #   Calls the method specified on the top of the stack on an object
2197   # [Format]
2198   #   \send_off_stack
2199   # [Stack Before]
2200   #   * method
2201   #   * block
2202   #   * receiver
2203   #   * arg1
2204   #   * arg2
2205   #   * ...
2206   #   * argN
2207   #   * ...
2208   # [Stack After]
2209   #   * retval
2210   #   * ...
2211   # [Description]
2212   #   Pops the name of the method +method+ to call off the stack, and if
2213   #   necessary, converts it to a symbol. Then pops +block+ and the receiver
2214   #   +receiver+ off the stack. Any arguments required by the method must have
2215   #   been placed on the stack previously, and the number of arguments set in
2216   #   the args register. The arguments will be popped from the stack and
2217   #   converted to locals when the method is activated.
2218   #
2219   #   When the method returns, the return value will be on top of the stack.
2220   # [See Also]
2221   #   * set_args
2222   #   * cast_array_for_args
2223   # [Notes]
2224   #   The number of arguments to be passed to the method in +args+ must have
2225   #   been set previously via a call to either set_args or
2226   #   cast_array_for_args.
2228   def send_off_stack
2229     <<-CODE
2230     t3 = stack_pop();
2231     if(!SYMBOL_P(t3)) {
2232       if(RISA(t3, string)) {
2233         t3 = string_to_sym(state, t3);
2234       } else {
2235         t2 = stack_pop();
2236         t1 = stack_pop();
2237         stack_push(t3);
2238         _lit = global->sym_send;
2239         j = c->args;
2240         goto perform_send;
2241       }
2242     }
2243     t2 = stack_pop();
2244     t1 = stack_pop();
2245     _lit = t3;
2246     j = c->args;
2247     goto perform_send;
2248     CODE
2249   end
2251   # [Operation]
2252   #   Locates a method by searching the \class hierarchy from a specified
2253   #   object
2254   # [Format]
2255   #   \locate_method
2256   # [Stack Before]
2257   #   * include_private
2258   #   * method_name
2259   #   * self
2260   #   * ...
2261   # [Stack After]
2262   #   * method
2263   #   * ...
2264   # [Description]
2265   #   Pops a flag indicating whether or not to search in private methods, the
2266   #   method name, and the object to search from off the stack. If a matching
2267   #   method is located, it is pushed onto the stack; otherwise, nil is pushed
2268   #   onto the stack.
2270   def locate_method
2271     <<-CODE
2272     t1 = stack_pop(); // include_private
2273     t2 = stack_pop(); // meth
2274     t3 = stack_pop(); // self
2275     stack_push(cpu_locate_method_on(state, c, t3, t2, t1));
2276     CODE
2277   end
2279   # [Operation]
2280   #   Implementation of + optimised for fixnums
2281   # [Format]
2282   #   \meta_send_op_plus
2283   # [Stack Before]
2284   #   * value1
2285   #   * value2
2286   #   * ...
2287   # [Stack After]
2288   #   * value1 + value2
2289   #   * ...
2290   # [Description]
2291   #   Pops +value1+ and +value2+ off the stack, and pushes the logical result
2292   #   of (+value1+ + +value2+). If +value1+ and +value2+ are both fixnums, the
2293   #   addition is done directly via the fixnum_add primitive; otherwise, the +
2294   #   method is called on +value1+, passing +value2+ as the argument.
2296   def meta_send_op_plus
2297     <<-CODE
2298     t1 = stack_pop();
2299     t2 = stack_back(0);
2300     if(FIXNUM_P(t1) && FIXNUM_P(t2)) {
2301       stack_set_top(fixnum_add(state, t1, t2));
2302     } else {
2303       _lit = global->sym_plus;
2304       t2 = Qnil;
2305       j = 1;
2306       goto perform_no_ss_send;
2307     }
2308     CODE
2309   end
2311   # [Operation]
2312   #   Implementation of - optimised for fixnums
2313   # [Format]
2314   #   \meta_send_op_minus
2315   # [Stack Before]
2316   #   * value1
2317   #   * value2
2318   #   * ...
2319   # [Stack After]
2320   #   * value1 - value2
2321   #   * ...
2322   # [Description]
2323   #   Pops +value1+ and +value2+ off the stack, and pushes the logical result
2324   #   of (+value1+ - +value2+). If +value1+ and +value2+ are both fixnums, the
2325   #   subtraction is done directly via the fixnum_sub primitive; otherwise,
2326   #   the - method is called on +value1+, passing +value2+ as the argument.
2328   def meta_send_op_minus
2329     <<-CODE
2330     t1 = stack_pop();
2331     t2 = stack_back(0);
2332     if(FIXNUM_P(t1) && FIXNUM_P(t2)) {
2333       stack_set_top(fixnum_sub(state, t1, t2));
2334     } else {
2335       _lit = global->sym_minus;
2336       t2 = Qnil;
2337       j = 1;
2338       goto perform_no_ss_send;
2339     }
2340     CODE
2341   end
2343   # [Operation]
2344   #   Implementation of == optimised for fixnums and symbols
2345   # [Format]
2346   #   \meta_send_op_equal
2347   # [Stack Before]
2348   #   * value1
2349   #   * value2
2350   #   * ...
2351   # [Stack After]
2352   #   * true | false
2353   #   * ...
2354   # [Description]
2355   #   Pops +value1+ and +value2+ off the stack, and pushes the logical result
2356   #   of (+value1+ == +value2+). If +value1+ and +value2+ are both fixnums or
2357   #   both symbols, the comparison is done directly; otherwise, the == method
2358   #   is called on +value1+, passing +value2+ as the argument.
2360   def meta_send_op_equal
2361     <<-CODE
2362     t1 = stack_pop();
2363     t2 = stack_back(0);
2364     /* If both are not references, compare them directly. */
2365     if(!REFERENCE_P(t1) && !REFERENCE_P(t2)) {
2366       stack_set_top((t1 == t2) ? Qtrue : Qfalse);
2367     } else {
2368       _lit = global->sym_equal;
2369       t2 = Qnil;
2370       j = 1;
2371       goto perform_no_ss_send;
2372     }
2373     CODE
2374   end
2376   # [Operation]
2377   #   Implementation of != optimised for fixnums and symbols
2378   # [Format]
2379   #   \meta_send_op_nequal
2380   # [Stack Before]
2381   #   * value1
2382   #   * value2
2383   #   * ...
2384   # [Stack After]
2385   #   * true | false
2386   #   * ...
2387   # [Description]
2388   #   Pops +value1+ and +value2+ off the stack, and pushes the logical result
2389   #   of !(+value1+ == +value2+). If +value1+ and +value2+ are both fixnums or
2390   #   both symbols, the comparison is done directly; otherwise, the != method
2391   #   is called on +value1+, passing +value2+ as the argument.
2392   # [Notes]
2393   #   Is this correct? Shouldn't the non-optimised case call ==, and negate
2394   #   the result?
2396   def meta_send_op_nequal
2397     <<-CODE
2398     t1 = stack_pop();
2399     t2 = stack_back(0);
2400     /* If both are not references, compare them directly. */
2401     if(!REFERENCE_P(t1) && !REFERENCE_P(t2)) {
2402       stack_set_top((t1 == t2) ? Qfalse : Qtrue);
2403     } else {
2404       _lit = global->sym_nequal;
2405       t2 = Qnil;
2406       j = 1;
2407       goto perform_no_ss_send;
2408     }
2409     CODE
2410   end
2412   # [Operation]
2413   #   Implementation of === (triple \equal) optimised for fixnums and symbols
2414   # [Format]
2415   #   \meta_send_op_tequal
2416   # [Stack Before]
2417   #   * value1
2418   #   * value2
2419   #   * ...
2420   # [Stack After]
2421   #   * true | false
2422   #   * ...
2423   # [Description]
2424   #   Pops +value1+ and +value2+ off the stack, and pushes the logical result
2425   #   of (+value1+ === +value2+). If +value1+ and +value2+ are both fixnums or
2426   #   both symbols, the comparison is done directly; otherwise, the === method
2427   #   is called on +value1+, passing +value2+ as the argument.
2428   # [Notes]
2429   #   Exactly like equal, except calls === if it can't handle it directly.
2431   def meta_send_op_tequal
2432     <<-CODE
2433     t1 = stack_pop();
2434     t2 = stack_back(0);
2435     /* If both are fixnums, or both are symbols, compare the ops directly. */
2436     if((FIXNUM_P(t1) && FIXNUM_P(t2)) || (SYMBOL_P(t1) && SYMBOL_P(t2))) {
2437       stack_set_top((t1 == t2) ? Qtrue : Qfalse);
2438     } else {
2439       _lit = global->sym_tequal;
2440       t2 = Qnil;
2441       j = 1;
2442       goto perform_no_ss_send;
2443     }
2444     CODE
2445   end
2447   # [Operation]
2448   #   Implementation of < optimised for fixnums
2449   # [Format]
2450   #   \meta_send_op_lt
2451   # [Stack Before]
2452   #   * value1
2453   #   * value2
2454   #   * ...
2455   # [Stack After]
2456   #   * true | false
2457   #   * ...
2458   # [Description]
2459   #   Pops +value1+ and +value2+ off the stack, and pushes the logical result
2460   #   of (+value1+ < +value2+). If +value1+ and +value2+ are both fixnums, the
2461   #   comparison is done directly; otherwise, the < method is called on
2462   #   +value1+, passing +value2+ as the argument.
2464   def meta_send_op_lt
2465     <<-CODE
2466     t1 = stack_pop();
2467     t2 = stack_back(0);
2468     if(FIXNUM_P(t1) && FIXNUM_P(t2)) {
2469       j = N2I(t1);
2470       k = N2I(t2);
2471       stack_set_top((j < k) ? Qtrue : Qfalse);
2472     } else {
2473       _lit = global->sym_lt;
2474       t2 = Qnil;
2475       j = 1;
2476       goto perform_no_ss_send;
2477     }
2478     CODE
2479   end
2481   # [Operation]
2482   #   Implementation of > optimised for fixnums
2483   # [Format]
2484   #   \meta_send_op_gt
2485   # [Stack Before]
2486   #   * value1
2487   #   * value2
2488   #   * ...
2489   # [Stack After]
2490   #   * true | false
2491   #   * ...
2492   # [Description]
2493   #   Pops +value1+ and +value2+ off the stack, and pushes the logical result
2494   #   of (+value1+ > +value2+). If +value1+ and +value2+ are both fixnums, the
2495   #   comparison is done directly; otherwise, the > method is called on
2496   #   +value1+, passing +value2+ as the argument.
2498   def meta_send_op_gt
2499     <<-CODE
2500     t1 = stack_pop();
2501     t2 = stack_back(0);
2502     if(FIXNUM_P(t1) && FIXNUM_P(t2)) {
2503       j = N2I(t1);
2504       k = N2I(t2);
2505       stack_set_top((j > k) ? Qtrue : Qfalse);
2506     } else {
2507       _lit = global->sym_gt;
2508       t2 = Qnil;
2509       j = 1;
2510       goto perform_no_ss_send;
2511     }
2512     CODE
2513   end
2515   def meta_send_call
2516     <<-CODE
2517     next_int;
2518     t1 = stack_pop();
2520     if(REFERENCE_P(t1) && t1->obj_type == BlockEnvType) {
2521       blokenv_call(state, c, t1, _int);
2522     } else {
2523       _lit = global->sym_call;
2524       t2 = Qnil;
2525       j = _int;
2527 perform_no_ss_send:
2528       cpu_send(state, c, t1, _lit, j, t2);
2529     }
2530     CODE
2531   end
2533   # [Operation]
2534   #   Soft return from a block
2535   # [Format]
2536   #   \soft_return
2537   # [Stack Before]
2538   #   * retval
2539   #   * ...
2540   # [Stack After]
2541   #   * ...
2542   # [Description]
2543   #   Pops the return value from the stack, and returns to the calling method
2544   #   or block. The return value is pushed onto the stack of the caller during
2545   #   the return.
2546   # [See Also]
2547   #   * sret
2548   #   * ret
2549   #   * caller_return
2550   # [Notes]
2551   #   Unlike ret, this return opcode does not consider non-local returns. It
2552   #   simply returns to the calling block or method context. Thus, it is used
2553   #   when, for example, breaking from a loop, or upon the normal completion
2554   #   of a block.
2556   def soft_return
2557     <<-CODE
2558     t1 = stack_pop();
2559     cpu_simple_return(state, c, t1);
2560     CODE
2561   end
2563   # [Operation]
2564   #   Raises an exception
2565   # [Format]
2566   #   \raise_exc
2567   # [Stack Before]
2568   #   * exception
2569   #   * ...
2570   # [Stack After]
2571   #   * ...
2572   # [Description]
2573   #   Pops an exception instance +exception+ off the stack, and uses it to
2574   #   raise an exception in the machine.
2576   def raise_exc
2577     <<-CODE
2578     t1 = stack_pop();
2579     cpu_raise_exception(state, c, t1);
2580     CODE
2581   end
2583   # [Operation]
2584   #   Simple return from a method (only)
2585   # [Format]
2586   #   \sret
2587   # [Stack Before]
2588   #   * retval
2589   #   * ...
2590   # [Stack After]
2591   #   * ...
2592   # [Description]
2593   #   Pops the top value from the stack, and uses it as the return value from
2594   #   a method.
2595   # [See Also]
2596   #   * ret
2597   #   * caller_return
2598   #   * soft_return
2599   #   * raise_exc
2600   # [Notes]
2601   #   \sret is an optimised version of the more general ret. It works only
2602   #   with method (MethodContext) returns, but as a result, can skip the
2603   #   extra work to figure out how to long return from a block.
2605   def sret
2606     <<-CODE
2607     t1 = stack_pop();
2608     cpu_simple_return(state, c, t1);
2609     CODE
2610   end
2612   # [Operation]
2613   #   Shifts the first item in a tuple onto the stack
2614   # [Format]
2615   #   \unshift_tuple
2616   # [Stack Before]
2617   #   * [value1, value2, ..., valueN]
2618   #   * ...
2619   # [Stack After]
2620   #   * value1
2621   #   * [value2, ..., valueN]
2622   #   * ...
2623   # [Description]
2624   #   Pops a tuple off the top of the stack. If the tuple is empty, the tuple
2625   #   is pushed back onto the stack, followed by nil. Otherwise, the tuple is
2626   #   shifted, with the tuple then pushed back onto the stack, followed by the
2627   #   item that was previously at the head of the tuple.
2628   # [Notes]
2629   #   This opcode is poorly named; it actually performs a shift, rather than
2630   #   an unshift.
2632   def unshift_tuple
2633     <<-CODE
2634     t1 = stack_pop();
2635     sassert(REFERENCE_P(t1));
2636     if(NUM_FIELDS(t1) == 0) {
2637       stack_push(t1);
2638       stack_push(Qnil);
2639     } else {
2640       j = NUM_FIELDS(t1) - 1;
2641       t3 = tuple_at(state, t1, 0);
2642       t2 = tuple_new(state, j);
2643       object_copy_fields_from(state, t1, t2, 1, j);
2644       stack_push(t2);
2645       stack_push(t3);
2646     }
2647     CODE
2648   end
2650   # [Operation]
2651   #   Converts multiple individual caller arguments into an array for a rest
2652   #   argument
2653   # [Format]
2654   #   \make_rest argc
2655   # [Stack Before]
2656   #   * rest1
2657   #   * rest2
2658   #   * ...
2659   #   * restn
2660   #   * ...
2661   # [Stack After]
2662   #   * [rest1, rest2, ..., restN]
2663   #   * ...
2664   # [Description]
2665   #   Pops 0 or more rest arguments from the top of the stack into an array to
2666   #   be used as a rest argument to a method whose last (non-block) parameter
2667   #   is a splat.
2668   #
2669   #   The number of arguments to place into the rest array is determined by
2670   #   how many actual args have been passed to the method, less the number of
2671   #   arguments +argc+ required by the method. If this is less than or \equal to
2672   #   0, an empty array is pushed onto the stack. If the number is greater
2673   #   than 0, arguments are popped from the stack so that the first rest arg
2674   #   is at the start of the array, and the last rest arg is at the end.
2675   # [Notes]
2676   #   This opcode is performed after the non-splat arguments have been dealt
2677   #   with, so that the top of the stack contains the first rest argument
2678   #   (remembering that arguments are pushed onto the stack in right to left
2679   #   order).
2680   # [Example]
2681   #   <code>
2682   #     def foo(a,b,*c)
2683   #       ...
2684   #     end
2685   #
2686   #     foo(1,2,3,4,5)
2687   #
2688   #     # In foo, c = [3,4,5]
2689   #     # On the top of the stack after this opcode is [3,4,5]
2690   #   </code>
2692   def make_rest
2693     <<-CODE
2694     next_int;
2695     j = cpu_current_argcount(c) - _int;
2696     if(j < 0) j = 0;
2697     t1 = array_new(state, j);
2698     for(k = 0; k < j; k++) {
2699       array_set(state, t1, k, stack_pop());
2700     }
2701     stack_push(t1);
2702     CODE
2703   end
2705   # [Operation]
2706   #   Converts multiple individual caller arguments into an array for a rest
2707   #   argument
2708   # [Format]
2709   #   \make_rest_fp argc
2710   # [Stack Before]
2711   #   * ...
2712   # [Stack After]
2713   #   * [rest1, rest2, ..., restN]
2714   #   * ...
2715   # [Description]
2716   #   Copies multiple individual arguments to a method from the caller's stack
2717   #   into an array to be used as a rest argument. Used when the method to be
2718   #   called has a rest argument (i.e. the last defined method parameter is a
2719   #   splat).
2720   #
2721   #   The number of arguments to place into the rest array is determined by
2722   #   how many actual args have been passed to the method, less the number of
2723   #   arguments +argc+ required by the method. If this is less than or \equal to
2724   #   0, an empty array is pushed onto the stack. If the number is greater
2725   #   than 0, arguments are copied from before the frame pointer into the
2726   #   array, so that the first rest arg is at the start of the array, and the
2727   #   last rest arg is at the end.
2728   # [Example]
2729   #   <code>
2730   #     def foo(a,b,*c)
2731   #       ...
2732   #     end
2733   #
2734   #     foo(1,2,3,4,5)
2735   #
2736   #     # In foo, c = [3,4,5]
2737   #     # On the top of the stack after this opcode is [3,4,5]
2738   #   </code>
2740   def make_rest_fp
2741     <<-CODE
2742     next_int;
2743     j = cpu_current_argcount(c) - _int;
2744     if(j < 0) j = 0;
2745     t1 = array_new(state, j);
2746     for(k = _int, m = 0; k < cpu_current_argcount(c); k++, m++) {
2747       array_set(state, t1, m, c->stack_top[c->fp - k]);
2748     }
2749     stack_push(t1);
2750     CODE
2751   end
2753   # [Operation]
2754   #   Verify the number of arguments is between the acceptable range
2755   # [Format]
2756   #   \check_argcount min max
2757   # [Stack Before]
2758   #   * ...
2759   # [Stack After]
2760   #   * ...
2761   # [Description]
2762   #   If the number of arguments is less than +min+, or greater than +max+, an
2763   #   ArgumentError is raised.
2765   def check_argcount
2766     <<-CODE
2767     next_int; /* min */
2768     j = _int;
2769     next_int; /* max */
2771     if(cpu_current_argcount(c) < (unsigned long int)j) {
2772       cpu_raise_arg_error(state, c, cpu_current_argcount(c), j);
2773     } else if(_int >= 0 && cpu_current_argcount(c) > (unsigned long int)_int) {
2774       cpu_raise_arg_error(state, c, cpu_current_argcount(c), _int);
2775     }
2776     CODE
2777   end
2779   # [Operation]
2780   #   Test to determine whether an argument was passed
2781   # [Format]
2782   #   \passed_arg index
2783   # [Stack Before]
2784   #   * ...
2785   # [Stack After]
2786   #   * true | false
2787   #   * ...
2788   # [Description]
2789   #   Checks if the number of arguments passed to a method is greater than the
2790   #   specified argument index +index+ (0-based), and pushes the result of the
2791   #   test onto the stack.
2793   def passed_arg
2794     <<-CODE
2795     next_int;
2796     if((unsigned long int)_int < cpu_current_argcount(c)) {
2797       stack_push(Qtrue);
2798     } else {
2799       stack_push(Qfalse);
2800     }
2801     CODE
2802   end
2804   # [Operation]
2805   #   Test to determine whether a block argument was passed
2806   # [Format]
2807   #   \passed_blockarg index
2808   # [Stack Before]
2809   #   * ...
2810   # [Stack After]
2811   #   * true | false
2812   #   * ...
2813   # [Description]
2814   #   Checks if a block was passed to a method, and pushes the result of the
2815   #   test onto the stack.
2817   def passed_blockarg
2818     <<-CODE
2819     next_int;
2820     if((unsigned long int)_int == c->blockargs) {
2821       stack_push(Qtrue);
2822     } else {
2823       stack_push(Qfalse);
2824     }
2825     CODE
2826   end
2828   # [Operation]
2829   #   Appends two stings together to form a single string
2830   # [Format]
2831   #   \string_append
2832   # [Stack Before]
2833   #   * string1
2834   #   * string2
2835   #   * ...
2836   # [Stack After]
2837   #   * string1string2
2838   #   * ...
2839   # [Description]
2840   #   Pops two strings off the stack, appends the second to the first, and
2841   #   then pushes the combined string back onto the stack.
2842   # [Notes]
2843   #   The original string is modified by the append.
2845   def string_append
2846     <<-CODE
2847     t1 = stack_pop();
2848     t2 = stack_pop();
2849     string_append(state, t1, t2);
2850     stack_push(t1);
2851     CODE
2852   end
2854   # [Operation]
2855   #   Create a new string with the same contents as the string currently on
2856   #   the stack
2857   # [Format]
2858   #   \string_dup
2859   # [Stack Before]
2860   #   * original
2861   #   * ...
2862   # [Stack After]
2863   #   * duplicate
2864   #   * ...
2865   # [Description]
2866   #   Consume the string on the stack, replacing it with a duplicate. Mutating
2867   #   operations on the original string will not affect the duplicate, and
2868   #   vice-versa.
2870   def string_dup
2871     <<-CODE
2872     t1 = stack_pop();
2873     stack_push(string_dup(state, t1));
2874     CODE
2875   end
2877   # [Operation]
2878   #   Sets the number of args from the stack
2879   # [Format]
2880   #   \set_args
2881   # [Stack Before]
2882   #   * argc
2883   #   * ...
2884   # [Stack After]
2885   #   * ...
2886   # [Description]
2887   #   Pops a fixnum off the top of the stack, and uses its value to set the
2888   #   argument count for a method prior to executing it.
2889   # [See Also]
2890   #   * send_with_arg_register
2891   #   * send_super_with_arg_register
2892   # [Notes]
2893   #   Used prior to send_with_arg_register and send_super_with_arg_register to
2894   #   set the number of arguments being passed to a method.
2896   def set_args
2897     <<-CODE
2898     t1 = stack_pop();
2899     c->args = N2I(t1);
2900     CODE
2901   end
2903   # [Operation]
2904   #   Pushes the number of arguments passed to a method onto the stack
2905   # [Format]
2906   #   \get_args
2907   # [Stack Before]
2908   #   * ...
2909   # [Stack After]
2910   #   * argc
2911   #   * ...
2912   # [Description]
2913   #   Pushes the number of arguments +argc+ actually passed to a method onto
2914   #   the stack.
2915   # [See Also]
2916   #   * set_args
2918   def get_args
2919     <<-CODE
2920     stack_push(I2N(c->args));
2921     CODE
2922   end
2924   # [Operation]
2925   #   Sets call flags prior to a send operation
2926   # [Format]
2927   #   \set_call_flags flags
2928   # [Stack Before]
2929   #   * ...
2930   # [Stack After]
2931   #   * ...
2932   # [Description]
2933   #   The call flags on the current execution context are set to the opcode
2934   #   argument +flags+.
2935   # [Notes]
2936   #   Currently, the only call flag is 1, which instructs the machine to
2937   #   include private methods when looking for a method that responds to a
2938   #   message.
2940   def set_call_flags
2941     <<-CODE
2942     next_int;
2943     c->call_flags = _int;
2944     CODE
2945   end
2947   # [Operation]
2948   #   Creates a compiler2 style block
2949   # [Format]
2950   #   \create_block2
2951   # [Stack Before]
2952   #   * compiled_method
2953   #   * ...
2954   # [Stack After]
2955   #   * block_env
2956   #   * ...
2957   # [Description]
2958   #   Pops +compiled_method+ off of the stack, and converts it into a
2959   #   block environment +block_env+, which is then pushed back onto the stack.
2960   # [See Also]
2961   #   * create_block
2962   # [Notes]
2963   #   This opcode replaces create_block, which is used under compiler1, but
2964   #   deprecated under compiler2. Unlike create_block which uses the same
2965   #   instruction sequence as the enclosing method context, \create_block2
2966   #   takes its own instruction sequence in the form of a compiled method.
2968   def create_block2
2969     <<-CODE
2970     t1 = stack_pop(); /* the method */
2971     t4 = c->active_context;
2973     t3 = Qnil;
2974     if(block_context_p(state, t4)) {
2975       t3 = blokctx_home(state, t4);
2976     } else {
2977       t3 = t4;
2978     }
2980     methctx_reference(state, t4);
2981     methctx_reference(state, t3);
2983     cmethod_set_staticscope(t1,
2984                cmethod_get_staticscope(cpu_current_method(state, c)));
2986     t2 = blokenv_s_under_context2(state, t1, t3, t4);
2987     stack_push(t2);
2988     CODE
2989   end
2991   # [Operation]
2992   #   Evaluate if +object+ is an instance of +\class+ or of an ancestor of
2993   #   +\class+.
2994   # [Format]
2995   #   \kind_of
2996   # [Stack Before]
2997   #   * object
2998   #   * class
2999   #   * ...
3000   # [Stack After]
3001   #   * result
3002   #   * ...
3003   # [Description]
3004   #   Evaluate if the object is created by +\class+, its parent, or a further
3005   #   ancestor. This differs from +instance_of+ in that the \class heirarchy
3006   #   will be evaluated rather than just the \class object given.
3007   # [See Also]
3008   #   * instance_of
3010   def kind_of
3011     <<-CODE
3012     t1 = stack_pop();
3013     t2 = stack_pop();
3014     if(ISA(t1, t2)) {
3015       stack_push(Qtrue);
3016     } else {
3017       stack_push(Qfalse);
3018     }
3019     CODE
3020   end
3022   # [Operation]
3023   #   Evaluate if +object+ is an instance of +class+
3024   # [Format]
3025   #   \instance_of
3026   # [Stack Before]
3027   #   * object
3028   #   * class
3029   #   * ...
3030   # [Stack After]
3031   #   * result
3032   #   * ...
3033   # [Description]
3034   #   If the object is an instance of +\class+ return the special value +true+,
3035   #   otherwise return +false+. This check is different than +kind_of+ in that
3036   #   it does not evaluate superclass relationships. Instance-specific
3037   #   subtyping via metaclasses are ignored in computing the parent \class.
3038   # [See Also]
3039   #   * kind_of
3041   def instance_of
3042     <<-CODE
3043     t1 = stack_pop();
3044     t2 = stack_pop();
3045     if(object_class(state, t1) == t2) {
3046       stack_push(Qtrue);
3047     } else {
3048       stack_push(Qfalse);
3049     }
3050     CODE
3051   end
3053   # [Operation]
3054   #   Pauses execution and yields to the debugger
3055   # [Format]
3056   #   \yield_debugger
3057   # [Stack Before]
3058   #   * ...
3059   # [Stack After]
3060   #   * ...
3061   # [Description]
3062   #   Pauses virtual machine execution at the \yield_debugger instruction, and
3063   #   yields control to the debugger on the debug channel. If no debugger is
3064   #   registered, an error is raised.
3065   # [Notes]
3066   #   The \yield_debugger instruction is VM plumbing that exists to support
3067   #   "full-speed" debugging. As such, it is not output by the compiler, but
3068   #   rather is used by the debugger to replace an existing instruction at a
3069   #   breakpoint. Prior to encountering a \yield_debugger instruction, the VM
3070   #   will execute normally, i.e. at full speed, and not be slowed
3071   #   significantly by the fact that a debugger is attached.
3072   #
3073   #   When the debugger is yielded to by this instruction, it can examine the
3074   #   execution context, stack, etc, or replace the \yield_debugger instruction
3075   #   with the original instruction at that point, and then step through the
3076   #   code.
3078   def yield_debugger
3079     <<-CODE
3080     cpu_yield_debugger(state, c);
3081     CODE
3082   end
3084   # [Operation]
3085   #   Return true if value is a Fixnum, otherwise false
3086   # [Format]
3087   #   \is_fixnum
3088   # [Stack Before]
3089   #   * value
3090   #   * ...
3091   # [Stack After]
3092   #   * result
3093   #   * ...
3094   # [Description]
3095   #   Consume the value on the stack, and put the special values true or false
3096   #   depending on whether the consumed value was of Fixnum type
3098   def is_fixnum
3099     <<-CODE
3100     t1 = stack_pop();
3101     stack_push(FIXNUM_P(t1) ? Qtrue : Qfalse);
3102     CODE
3103   end
3105   # [Operation]
3106   #   Return true if value is a Symbol, otherwise false
3107   # [Format]
3108   #   \is_symbol
3109   # [Stack Before]
3110   #   * value
3111   #   * ...
3112   # [Stack After]
3113   #   * result
3114   #   * ...
3115   # [Description]
3116   #   Consume the value on the stack, and put the special values true or false
3117   #   depending on whether the consumed value was of Symbol type
3119   def is_symbol
3120     <<-CODE
3121     t1 = stack_pop();
3122     stack_push(SYMBOL_P(t1) ? Qtrue : Qfalse);
3123     CODE
3124   end
3126   # [Operation]
3127   #   Return true if value is nil, otherwise false
3128   # [Format]
3129   #   \is_nil
3130   # [Stack Before]
3131   #   * value
3132   #   * ...
3133   # [Stack After]
3134   #   * result
3135   #   * ...
3136   # [Description]
3137   #   Consume the value on the stack, and put the special values true or false
3138   #   depending on whether the consumed value was the special value nil
3140   def is_nil
3141     <<-CODE
3142     t1 = stack_pop();
3143     stack_push(t1 == Qnil ? Qtrue : Qfalse);
3144     CODE
3145   end
3147   # [Operation]
3148   #   Get the \class for the specified object
3149   # [Format]
3150   #   \class
3151   # [Stack Before]
3152   #   * object
3153   #   * ...
3154   # [Stack After]
3155   #   * class
3156   #   * ...
3157   # [Description]
3158   #   Consume the object reference on the stack, and push a reference to the
3159   #   parent \class in its place.
3161   def class
3162     <<-CODE
3163     t1 = stack_pop();
3164     stack_push(object_class(state, t1));
3165     CODE
3166   end
3168   # [Operation]
3169   #   Perform a raw comparison of two object references
3170   # [Format]
3171   #   \equal
3172   # [Stack Before]
3173   #   * value1
3174   #   * value2
3175   #   * ...
3176   # [Stack After]
3177   #   * result
3178   #   * ...
3179   # [Description]
3180   #   Performs a comparison of two objects, resulting in either +true+ or
3181   #   +false+ being pushed onto the stack as a result. The comparison is done
3182   #   without any method calls.
3183   #
3184   #   For two Fixnums, two Symbols, or two literals (+true+, +false+, +nil+),
3185   #   return +true+ if the values are identical.
3186   #
3187   #   For two object references (including Bignum), return +true+ if value1
3188   #   and value2 point to the same instance.
3190   def equal
3191     <<-CODE
3192     t1 = stack_pop();
3193     t2 = stack_pop();
3194     stack_push(t1 == t2 ? Qtrue : Qfalse);
3195     CODE
3196   end
3198   # [Operation]
3199   #   Checks if the specified method serial number matches an expected value
3200   # [Format]
3201   #   \check_serial method serial
3202   # [Stack Before]
3203   #   * obj
3204   #   * ...
3205   # [Stack After]
3206   #   * true | false
3207   #   * ...
3208   # [Description]
3209   #   Pops an object off the stack, and determines whether the serial number
3210   #   of the method identified by the literal +method+ is the same as the
3211   #   expected value +serial+. The result is pushed back on the stack as the
3212   #   value +true+ or +false+.
3213   # [Notes]
3214   #   This opcode is typically used to determine at runtime whether an
3215   #   optimisation can be performed. At compile time, two code paths are
3216   #   generated: a slow, but guaranteed correct path, and a fast path that
3217   #   uses certain optimisations. The serial number check is then performed at
3218   #   runtime to determine which code path is executed.
3219   #
3220   #   For example, a method such as Fixnum#times can be optimised at compile
3221   #   time, but we can't know until runtime whether or not the Fixnum#times
3222   #   method has been overridden. The serial number check is used to determine
3223   #   each time the code is executed, whether or not the standard Fixnum#times
3224   #   has been overridden. It leverages the serial number field on a
3225   #   CompiledMethod, is initialised to either 0 (for kernel land methods) or
3226   #   1 (for user land methods).
3228   def check_serial
3229     <<-CODE
3230     t1 = stack_pop();
3231     next_literal;
3232     next_int;
3233     stack_push(cpu_check_serial(state, c, t1, _lit, _int));
3234     CODE
3235   end
3239 si = ShotgunInstructions.new
3240 si.generate_declarations(STDOUT)
3241 si.generate_switch(STDOUT)
3243 File.open("instruction_names.c","w") do |f|
3244   f.puts si.generate_names
3247 File.open("instruction_names.h","w") do |f|
3248   f.puts si.generate_names_header
3251 File.open("instruction_funcs.gen", "w") do |f|
3252   f.puts si.generate_dter
3255 File.open("instruction_dt.gen", "w") do |f|
3256   si.generate_declarations(f)
3257   si.generate_threaded(f)