Source code: com/techtrader/modules/tools/bytecode/Code.java
1 package com.techtrader.modules.tools.bytecode;
2
3
4 import java.util.List;
5 import java.util.LinkedList;
6 import java.util.ListIterator;
7 import java.util.Iterator;
8 import java.io.IOException;
9 import java.io.DataInput;
10 import java.io.DataOutput;
11 import java.io.DataInputStream;
12 import java.io.DataOutputStream;
13 import java.io.ByteArrayInputStream;
14 import java.io.ByteArrayOutputStream;
15
16 import com.techtrader.modules.tools.bytecode.visitor.BCVisitor;
17
18
19 /**
20 * Representation of a code block of a class.
21 * The methods of this class mimic those of
22 * the same name in the {@link java.util.ListIterator} class. Note that
23 * the size and index information of the Code block will change as opcodes
24 * are added.
25 * <p>
26 * Code blocks are usually obtained from a BCMethod, but can also be
27 * constructed via the default Constructor. Blocks created this way can
28 * be used to provide template instructions to the various search/replace
29 * methods in this class.
30 * <p>
31 * The Code class contains methods named after each JVM instruction, each
32 * of which adds the matching opcode to the code block at the
33 * current iterator position. There are also many pseudo-instruction
34 * methods that do not have a corresponding JVM opcode, but are provided
35 * for convenience when the exact opcode is difficult to determine at
36 * compile time. Unlike the other opcode methods, these convenience
37 * methods have javadoc comments so that they are easy to pick out;
38 * they should be skimmed to get an idea of the functionality that each
39 * provides. Also note that many Instructions are able to 'morph' their
40 * opcode on the fly as the arguments to the instruction change. Thus
41 * the developer can initially call, for example, the aload_1 opcode, but
42 * later change the type to load to 'int', and the opcode will automatically
43 * morph to iload_1.
44 *
45 * @author Abe White
46 */
47 public class Code
48 extends Attribute
49 implements Constants
50 {
51 private int _maxStack = 0;
52 private int _maxLocals = 0;
53 private List _opcodes = new LinkedList ();
54 private List _handlers = new LinkedList ();
55 private ListIterator _li = _opcodes.listIterator ();
56
57
58 protected Code (int nameIndex, BCEntity owner)
59 {
60 super (nameIndex, owner);
61 }
62
63
64 /**
65 * The public constructor is for creating template code modules
66 * that can be used to produce Instructions to be used in
67 * matching for various search() and replace() methods.
68 */
69 public Code ()
70 {
71 // create a new empty anon class so we can use its
72 // constant pool to track the code we create
73 super (0, new BCClass ().addMethod ());
74 _nameIndex = getPool ().setUTF (0, ATTR_CODE);
75 }
76
77
78 /**
79 * Get the maximum stack depth for this code block.
80 */
81 public int getMaxStack ()
82 {
83 return _maxStack;
84 }
85
86
87 /**
88 * Set the maximum stack depth for this code block.
89 */
90 public void setMaxStack (int max)
91 {
92 _maxStack = max;
93 }
94
95
96 /**
97 * Get the maximum number of local variables (including params)
98 * in this method.
99 */
100 public int getMaxLocals ()
101 {
102 return _maxLocals;
103 }
104
105
106 /**
107 * Set the maximum number of local variables (including params) in
108 * this method.
109 */
110 public void setMaxLocals (int max)
111 {
112 _maxLocals = max;
113 }
114
115
116 /**
117 * Get the local variable index for the paramIndex'th parameter to
118 * the method. These numbers are different because
119 * a) non-static methods use the 0th local variable for the 'this' ptr, and
120 * b) double and long values occupy two spots in the local
121 * variable array.
122 */
123 public int getLocalsIndex (int paramIndex)
124 {
125 if (paramIndex < 0)
126 return -1;
127
128 int pos = 0;
129 if (!((BCMethod) _owner).isStatic ())
130 pos = 1;
131
132 String[] params = ((BCMethod) _owner).getParamTypeNames ();
133 for (int i = 0; i < paramIndex; i++, pos++)
134 if (params[i].equals ("long") || params[i].equals ("double"))
135 pos++;
136
137 return pos;
138 }
139
140
141 /**
142 * Get the next next available local variable index.
143 */
144 public int getNextLocalsIndex ()
145 {
146 calculateMaxLocals ();
147 return getMaxLocals ();
148 }
149
150
151 /**
152 * Ask the code to figure out the number of locals it needs based on
153 * the instructions used and the parameters of the method this code
154 * block is a part of.
155 */
156 public void calculateMaxLocals ()
157 {
158 // start off assuming the max number needed is the
159 // number for all the params
160 String[] params = ((BCMethod) _owner).getParamTypeNames ();
161 int max = 0;
162 if (params.length == 0 && !((BCMethod) _owner).isStatic ())
163 max = 1;
164 else if (params.length > 0)
165 {
166 max = getLocalsIndex (params.length - 1) + 1;
167 if (params[params.length-1].equals ("long")
168 || params[params.length-1].equals ("double"))
169 max++;
170 }
171
172 // check to see if there are any store instructions that
173 // try to reference beyond that point
174 Instruction ins;
175 StoreInstruction store;
176 int current;
177 for (Iterator i = _opcodes.iterator (); i.hasNext ();)
178 {
179 current = 0;
180 ins = (Instruction) i.next ();
181
182 if (ins instanceof StoreInstruction)
183 {
184 store = (StoreInstruction) ins;
185 current = store.getIndex () + 1;
186 if (store.getType ().equals (long.class)
187 || store.getType ().equals (double.class))
188 current++;
189
190 if (current > max)
191 max = current;
192 }
193 }
194
195 setMaxLocals (max);
196 }
197
198
199 /**
200 * Ask the code to figure out the maximum stack depth it needs
201 * the instructions used.
202 */
203 public void calculateMaxStack ()
204 {
205 int stack = 0;
206 int max = 0;
207
208 ExceptionHandler[] handlers = getExceptionHandlers ();
209 Instruction ins;
210 for (Iterator i = _opcodes.iterator (); i.hasNext ();)
211 {
212 ins = (Instruction) i.next ();
213 stack += ins.getStackChange ();
214
215 // if this is the start of a try, the exception will be placed
216 // on the stack
217 for (int j = 0; j < handlers.length; j++)
218 if (handlers[j].getTryStart () == ins)
219 stack++;
220
221 if (stack > max)
222 max = stack;
223 }
224
225 setMaxStack (max);
226 }
227
228
229 /**
230 * Get the exception handlers active in this code block, or an
231 * empty array if none.
232 */
233 public ExceptionHandler[] getExceptionHandlers ()
234 {
235 return (ExceptionHandler[]) _handlers.toArray
236 (new ExceptionHandler[_handlers.size ()]);
237 }
238
239
240 /**
241 * Get the exception handler that catches the given exception type;
242 * if multiple handlers catch the given type, which is returned is
243 * undefined.
244 */
245 public ExceptionHandler getExceptionHandler (Class catchType)
246 {
247 return getExceptionHandler (catchType.getName ());
248 }
249
250
251 /**
252 * Get the exception handler that catches the given exception type;
253 * if multiple handlers catch the given type, which is returned is
254 * undefined.
255 */
256 public ExceptionHandler getExceptionHandler (String catchType)
257 {
258 ExceptionHandler next;
259 for (Iterator i = _handlers.iterator (); i.hasNext ();)
260 {
261 next = (ExceptionHandler) i.next ();
262 if (next.getCatchTypeName ().equals (catchType))
263 return next;
264 }
265
266 return null;
267 }
268
269
270 /**
271 * Get all exception handlers that catch the given exception type.
272 */
273 public ExceptionHandler[] getExceptionHandlers (Class catchType)
274 {
275 return getExceptionHandlers (catchType.getName ());
276 }
277
278
279 /**
280 * Get all exception handlers that catch the given exception type.
281 */
282 public ExceptionHandler[] getExceptionHandlers (String catchType)
283 {
284 List matches = new LinkedList ();
285
286 ExceptionHandler next;
287 for (Iterator i = _handlers.iterator (); i.hasNext ();)
288 {
289 next = (ExceptionHandler) i.next ();
290 if (next.getCatchTypeName ().equals (catchType))
291 matches.add (next);
292 }
293
294 return (ExceptionHandler[]) matches.toArray
295 (new ExceptionHandler[matches.size ()]);
296 }
297
298
299 /**
300 * Add an exception handler to this code block.
301 */
302 public ExceptionHandler addExceptionHandler ()
303 {
304 ExceptionHandler handler = new ExceptionHandler (this);
305 _handlers.add (handler);
306
307 return handler;
308 }
309
310
311 /**
312 * Add an exception handler to this code block.
313 *
314 * @param tryStart the first instruction of the try {} block
315 * @param tryEnd the last instruction of the try {} block
316 * @param handlerStart the first instruction of the catch {} block
317 * @param catchType the type of Exception being caught
318 */
319 public ExceptionHandler addExceptionHandler (Instruction tryStart,
320 Instruction tryEnd, Instruction handlerStart, Class catchType)
321 {
322 String catchName = null;
323 if (catchType != null)
324 catchName = catchType.getName ();
325
326 return addExceptionHandler (tryStart, tryEnd, handlerStart, catchName);
327 }
328
329
330 /**
331 * Add an exception handler to this code block.
332 *
333 * @param tryStart the first instruction of the try {} block
334 * @param tryEnd the last instruction of the try {} block
335 * @param handlerStart the first instruction of the catch {} block
336 * @param catchType the type of Exception being caught
337 */
338 public ExceptionHandler addExceptionHandler (Instruction tryStart,
339 Instruction tryEnd, Instruction handlerStart, String catchType)
340 {
341 ExceptionHandler handler = addExceptionHandler ();
342 handler.setTryStart (tryStart);
343 handler.setTryEnd (tryEnd);
344 handler.setHandlerStart (handlerStart);
345 handler.setCatchTypeName (catchType);
346
347 return handler;
348 }
349
350
351 /**
352 * Clear all exception handlers.
353 */
354 public void clearExceptionHandlers ()
355 {
356 _handlers.clear ();
357 }
358
359
360 /**
361 * Remove all exception handlers that catch the given type.
362 */
363 public boolean removeExceptionHandler (Class catchType)
364 {
365 ExceptionHandler[] matches = getExceptionHandlers (catchType);
366 for (int i = 0; i < matches.length; i++)
367 removeExceptionHandler (matches[i]);
368
369 return (matches.length > 0);
370 }
371
372
373 /**
374 * Remove all exception handlers that catch the given type.
375 */
376 public boolean removeExceptionHandler (String catchType)
377 {
378 ExceptionHandler[] matches = getExceptionHandlers (catchType);
379 for (int i = 0; i < matches.length; i++)
380 removeExceptionHandler (matches[i]);
381
382 return (matches.length > 0);
383 }
384
385
386 /**
387 * Remove an exception handler from this code block.
388 */
389 public boolean removeExceptionHandler (ExceptionHandler handler)
390 {
391 if (handler == null || !_handlers.remove (handler))
392 return false;
393
394 handler.invalidate ();
395 return true;
396 }
397
398
399 /**
400 * Return the number of instructions in the method.
401 */
402 public int size ()
403 {
404 return _opcodes.size ();
405 }
406
407
408 /**
409 * Reset the position of the instruction iterator to the first opcode.
410 */
411 public void beforeFirst ()
412 {
413 _li = _opcodes.listIterator ();
414 }
415
416
417 /**
418 * Set the position of the instruction iterator to after the last opcode.
419 */
420 public void afterLast ()
421 {
422 _li = _opcodes.listIterator (_opcodes.size ());
423 }
424
425
426 /**
427 * Position the iterator just before the given instruction. The
428 * instruction must belong to this method.
429 */
430 public void before (Instruction ins)
431 {
432 Iterator instructions = _opcodes.iterator ();
433 int pos = 0;
434 for (; instructions.hasNext (); pos++)
435 if (instructions.next () == ins)
436 break;
437
438 _li = _opcodes.listIterator (pos);
439 }
440
441
442 /**
443 * Position the iterator just after the given instruction. The
444 * instruction must belong to this method.
445 */
446 public void after (Instruction ins)
447 {
448 before (ins);
449 next ();
450 }
451
452
453 /**
454 * Return true if a subsequent call to next() will return an instruction.
455 */
456 public boolean hasNext ()
457 {
458 return _li.hasNext ();
459 }
460
461
462 /**
463 * Return true if a subsequent call to previous() will return an
464 * instruction.
465 */
466 public boolean hasPrevious ()
467 {
468 return _li.hasPrevious ();
469 }
470
471
472 /**
473 * Return the next instruction.
474 */
475 public Instruction next ()
476 {
477 return (Instruction) _li.next ();
478 }
479
480
481 /**
482 * Return the index of the next instruction, or size() if at end.
483 */
484 public int nextIndex ()
485 {
486 return _li.nextIndex ();
487 }
488
489
490 /**
491 * Return the previous instruction.
492 */
493 public Instruction previous ()
494 {
495 return (Instruction) _li.previous ();
496 }
497
498
499 /**
500 * Return the index of the previous instruction, or -1 if at beginning.
501 */
502 public int previousIndex ()
503 {
504 return _li.previousIndex ();
505 }
506
507
508 /**
509 * Place the iterator before the given list index.
510 */
511 public void before (int index)
512 {
513 _li = _opcodes.listIterator (index);
514 }
515
516
517 /**
518 * Place the iterator after the given list index.
519 */
520 public void after (int index)
521 {
522 before (index);
523 next ();
524 }
525
526
527 /**
528 * Find the next Instruction from the current iterator position that
529 * matches the given one, according to the equals() methods of the
530 * Instruction types. This allows for matching based on template
531 * instructions, as the equals() methods of most Instructions return
532 * true if the information for the given Instruction has not been filled
533 * in. If a match is found, the iterator is placed after the matching
534 * Instruction. If no match is found, moves the iterator to afterLast().
535 *
536 * @return true if match found
537 */
538 public boolean searchForward (Instruction template)
539 {
540 Instruction next;
541 while (hasNext ())
542 {
543 next = next ();
544 if (next.equals (template))
545 return true;
546 }
547 return false;
548 }
549
550
551 /**
552 * Find the closest previous Instruction from the current iterator
553 * position that matches the given one, according to the equals()
554 * methods of the Instruction types. This allows for matching based on
555 * template instructions, as the equals() methods of most Instructions
556 * returns true if the information for the given Instruction has not been
557 * filled in. If a match is found, the iterator is placed before the
558 * matching Instruction. If no match is found, moves the iterator to
559 * beforeFirst().
560 *
561 * @return true if match found
562 */
563 public boolean searchBackward (Instruction template)
564 {
565 Instruction prev;
566 while (hasPrevious ())
567 {
568 prev = previous ();
569 if (prev.equals (template))
570 return true;
571 }
572 return false;
573 }
574
575
576 /**
577 * Replaces the next Instruction with the given one. It is an error to
578 * call this method if the iterator is afterLast(). After this
579 * method, the iterator will be after the newly added Instruction.
580 * This method will also make sure that all jump points
581 * that referenced the old opcode are updated correctly.
582 *
583 * @return the newly added Instruction
584 */
585 public Instruction replaceNext (Instruction with)
586 {
587 Instruction orig = (Instruction) _li.next ();
588 Instruction ins = null;
589
590 _li.remove ();
591 if (with != null)
592 {
593 // create the new Instruction and copy import the given info
594 ins = getInstruction (with.getOpCode ());
595 ins.copy (with);
596
597 // update all jump points
598 updateJumpPoints (orig, ins);
599 }
600
601 return ins;
602 }
603
604
605 /**
606 * Replaces the previous Instruction with the given one. It is an
607 * error to call this method if the iterator is beforeFirst().
608 * After this method, the iterator will be before the newly added
609 * Instruction. This method will also make sure that all jump points
610 * that referenced the old opcode are updated correctly.
611 *
612 * @return the newly added Instruction
613 */
614 public Instruction replacePrevious (Instruction with)
615 {
616 Instruction orig = (Instruction) _li.previous ();
617 Instruction ins = null;
618
619 _li.remove ();
620 if (with != null)
621 {
622 // create the new Instruction and copy import the given info
623 ins = getInstruction (with.getOpCode ());
624 ins.copy (with);
625
626 // update all jump points
627 updateJumpPoints (orig, ins);
628 }
629
630 return ins;
631 }
632
633
634 /**
635 * Replaces all the Instructions in this code block that match the
636 * given template with the given Instruction. After this method,
637 * the iterator will be in its original position.
638 *
639 * @return the number of substitutions made
640 */
641 public int replaceAll (Instruction template, Instruction with)
642 {
643 // remember the iterator position
644 int pos = nextIndex ();
645
646 beforeFirst ();
647 int count;
648 for (count = 0; searchForward (template); count++)
649 replacePrevious (with);
650
651 before (pos);
652 return count;
653 }
654
655
656 /**
657 * Equivalent to looping over each given template/replacement
658 * pair and calling replaceAll(Instruction, Instruction) for each.
659 */
660 public int replaceAll (Instruction[] templates, Instruction[] with)
661 {
662 if (templates == null && with == null)
663 return 0;
664
665 int count = 0;
666 for (int i = 0; i < templates.length; i++)
667 {
668 if (with == null)
669 count += replaceAll (templates[i], null);
670 else
671 count += replaceAll (templates[i], with[i]);
672 }
673
674 return count;
675 }
676
677
678 /**
679 * Update all jump points that reference the original opcode
680 * to reference the new one.
681 */
682 private void updateJumpPoints (Instruction orig, Instruction ins)
683 {
684 ListIterator li = _opcodes.listIterator ();
685
686 for (Instruction next; li.hasNext ();)
687 {
688 next = (Instruction) li.next ();
689 if (next instanceof JumpInstruction)
690 {
691 if (orig.equals (((JumpInstruction) next).getTarget ()))
692 ((JumpInstruction) next).setTarget (ins);
693
694 if (next.getOpCode () == TABLESWITCH)
695 updateJumpPoints (orig, ins, (TableSwitchInstruction) next);
696 else if (next.getOpCode () == LOOKUPSWITCH)
697 updateJumpPoints (orig, ins, (LookupSwitchInstruction)next);
698 }
699 }
700 }
701
702
703 private void updateJumpPoints (Instruction orig, Instruction ins,
704 TableSwitchInstruction update)
705 {
706 Instruction[] jumps = update.getTargets ();
707
708 for (int i = 0; i < jumps.length; i++)
709 if (orig == jumps[i])
710 jumps[i] = ins;
711
712 update.setTargets (jumps);
713 }
714
715
716 private void updateJumpPoints (Instruction orig, Instruction ins,
717 LookupSwitchInstruction update)
718 {
719 Instruction[] jumps = update.getTargets ();
720
721 for (int i = 0; i < jumps.length; i++)
722 if (orig == jumps[i])
723 jumps[i] = ins;
724
725 update.setCases (update.getMatches (), jumps);
726 }
727
728
729 /**
730 * Remove the current instruction.
731 */
732 public void remove ()
733 {
734 _li.remove ();
735 }
736
737
738 public Instruction nop ()
739 {
740 return addInstruction (NOP);
741 }
742
743
744 /**
745 * Load some constant onto the stack. The ConstantInstruction type
746 * takes any constant and correctly translates it into the proper
747 * opcode, depending on the constant type and value. For example,
748 * if the constant value is set to 0L, the opcode will be set to
749 * lconst_0.
750 */
751 public ConstantInstruction constant ()
752 {
753 return (ConstantInstruction) addInstruction
754 (new ConstantInstruction (this));
755 }
756
757
758 /**
759 * Loads a Class constant onto the stack.
760 * For primitive types, this translates into a
761 * getstatic() for the TYPE field of the primitive's wrapper type.
762 * For non-primitives, things get much more complex. Suffice it to
763 * say that the operation involves adding synthetic static fields
764 * and even methods to the class. Note that this instruction requires
765 * up to 3 stack positions to execute.
766 */
767 public ClassConstantInstruction classconstant ()
768 {
769 return new ClassConstantInstruction
770 (((BCMethod) _owner).getOwner (), this, nop ());
771 }
772
773
774 public ConstantInstruction aconst_null ()
775 {
776 return (ConstantInstruction) addInstruction (new ConstantInstruction
777 (this, ACONST_NULL, null));
778 }
779
780
781 public ConstantInstruction iconst_m1 ()
782 {
783 return (ConstantInstruction) addInstruction (new ConstantInstruction
784 (this, ICONST_M1, new Integer (-1)));
785 }
786
787
788 public ConstantInstruction iconst_0 ()
789 {
790 return (ConstantInstruction) addInstruction (new ConstantInstruction
791 (this, ICONST_0, new Integer (0)));
792 }
793
794
795 public ConstantInstruction iconst_1 ()
796 {
797 return (ConstantInstruction) addInstruction (new ConstantInstruction
798 (this, ICONST_1, new Integer (1)));
799 }
800
801
802 public ConstantInstruction iconst_2 ()
803 {
804 return (ConstantInstruction) addInstruction (new ConstantInstruction
805 (this, ICONST_2, new Integer (2)));
806 }
807
808
809 public ConstantInstruction iconst_3 ()
810 {
811 return (ConstantInstruction) addInstruction (new ConstantInstruction
812 (this, ICONST_3, new Integer (3)));
813 }
814
815
816 public ConstantInstruction iconst_4 ()
817 {
818 return (ConstantInstruction) addInstruction (new ConstantInstruction
819 (this, ICONST_4, new Integer (4)));
820 }
821
822
823 public ConstantInstruction iconst_5 ()
824 {
825 return (ConstantInstruction) addInstruction (new ConstantInstruction
826 (this, ICONST_5, new Integer (5)));
827 }
828
829
830 public ConstantInstruction lconst_0 ()
831 {
832 return (ConstantInstruction) addInstruction (new ConstantInstruction
833 (this, LCONST_0, new Long (0)));
834 }
835
836
837 public ConstantInstruction lconst_1 ()
838 {
839 return (ConstantInstruction) addInstruction (new ConstantInstruction
840 (this, LCONST_1, new Long (1)));
841 }
842
843
844 public ConstantInstruction fconst_0 ()
845 {
846 return (ConstantInstruction) addInstruction (new ConstantInstruction
847 (this, FCONST_0, new Float (0)));
848 }
849
850
851 public ConstantInstruction fconst_1 ()
852 {
853 return (ConstantInstruction) addInstruction (new ConstantInstruction
854 (this, FCONST_1, new Float (1)));
855 }
856
857
858 public ConstantInstruction fconst_2 ()
859 {
860 return (ConstantInstruction) addInstruction (new ConstantInstruction
861 (this, FCONST_2, new Float (2)));
862 }
863
864
865 public ConstantInstruction dconst_0 ()
866 {
867 return (ConstantInstruction) addInstruction (new ConstantInstruction
868 (this, DCONST_0, new Double (0)));
869 }
870
871
872 public ConstantInstruction dconst_1 ()
873 {
874 return (ConstantInstruction) addInstruction (new ConstantInstruction
875 (this, DCONST_1, new Double (1)));
876 }
877
878
879 public ConstantInstruction bipush ()
880 {
881 return (ConstantInstruction) addInstruction (new ConstantInstruction
882 (this, BIPUSH, null));
883 }
884
885
886 public ConstantInstruction sipush ()
887 {
888 return (ConstantInstruction) addInstruction (new ConstantInstruction
889 (this, SIPUSH, null));
890 }
891
892
893 public ConstantInstruction ldc ()
894 {
895 return (ConstantInstruction) addInstruction (new ConstantInstruction
896 (this, LDC, null));
897 }
898
899
900 public ConstantInstruction ldc_w ()
901 {
902 return (ConstantInstruction) addInstruction (new ConstantInstruction
903 (this, LDC_W, null));
904 }
905
906
907 public ConstantInstruction ldc2_w ()
908 {
909 return (ConstantInstruction) addInstruction (new ConstantInstruction
910 (this, LDC2_W, null));
911 }
912
913
914 /**
915 * This is a convenience method to load a local variable onto the stack,
916 * if the type and index to load is not known at compile time.
917 */
918 public LoadInstruction load ()
919 {
920 return (LoadInstruction) addInstruction (new LoadInstruction (this));
921 }
922
923
924 public LoadInstruction iload ()
925 {
926 return (LoadInstruction) addInstruction (new LoadInstruction
927 (this, ILOAD, int.class, -1));
928 }
929
930
931 public LoadInstruction iload_0 ()
932 {
933 return (LoadInstruction) addInstruction (new LoadInstruction
934 (this, ILOAD_0, int.class, 0));
935 }
936
937
938 public LoadInstruction iload_1 ()
939 {
940 return (LoadInstruction) addInstruction (new LoadInstruction
941 (this, ILOAD_1, int.class, 1));
942 }
943
944
945 public LoadInstruction iload_2 ()
946 {
947 return (LoadInstruction) addInstruction (new LoadInstruction
948 (this, ILOAD_2, int.class, 2));
949 }
950
951
952 public LoadInstruction iload_3 ()
953 {
954 return (LoadInstruction) addInstruction (new LoadInstruction
955 (this, ILOAD_3, int.class, 3));
956 }
957
958
959 public LoadInstruction lload ()
960 {
961 return (LoadInstruction) addInstruction (new LoadInstruction
962 (this, LLOAD, long.class, -1));
963 }
964
965
966 public LoadInstruction lload_0 ()
967 {
968 return (LoadInstruction) addInstruction (new LoadInstruction
969 (this, LLOAD_0, long.class, 0));
970 }
971
972
973 public LoadInstruction lload_1 ()
974 {
975 return (LoadInstruction) addInstruction (new LoadInstruction
976 (this, LLOAD_1, long.class, 1));
977 }
978
979
980 public LoadInstruction lload_2 ()
981 {
982 return (LoadInstruction) addInstruction (new LoadInstruction
983 (this, LLOAD_2, long.class, 2));
984 }
985
986
987 public LoadInstruction lload_3 ()
988 {
989 return (LoadInstruction) addInstruction (new LoadInstruction
990 (this, LLOAD_3, long.class, 3));
991 }
992
993
994 public LoadInstruction fload ()
995 {
996 return (LoadInstruction) addInstruction (new LoadInstruction
997 (this, FLOAD, float.class, -1));
998 }
999
1000
1001 public LoadInstruction fload_0 ()
1002 {
1003 return (LoadInstruction) addInstruction (new LoadInstruction
1004 (this, FLOAD_0, float.class, 0));
1005 }
1006
1007
1008 public LoadInstruction fload_1 ()
1009 {
1010 return (LoadInstruction) addInstruction (new LoadInstruction
1011 (this, FLOAD_1, float.class, 1));
1012 }
1013
1014
1015 public LoadInstruction fload_2 ()
1016 {
1017 return (LoadInstruction) addInstruction (new LoadInstruction
1018 (this, FLOAD_2, float.class, 2));
1019 }
1020
1021
1022 public LoadInstruction fload_3 ()
1023 {
1024 return (LoadInstruction) addInstruction (new LoadInstruction
1025 (this, FLOAD_3, float.class, 3));
1026 }
1027
1028
1029 public LoadInstruction dload ()
1030 {
1031 return (LoadInstruction) addInstruction (new LoadInstruction
1032 (this, DLOAD, double.class, -1));
1033 }
1034
1035
1036 public LoadInstruction dload_0 ()
1037 {
1038 return (LoadInstruction) addInstruction (new LoadInstruction
1039 (this, DLOAD_0, double.class, 0));
1040 }
1041
1042
1043 public LoadInstruction dload_1 ()
1044 {
1045 return (LoadInstruction) addInstruction (new LoadInstruction
1046 (this, DLOAD_1, double.class, 1));
1047 }
1048
1049
1050 public LoadInstruction dload_2 ()
1051 {
1052 return (LoadInstruction) addInstruction (new LoadInstruction
1053 (this, DLOAD_2, double.class, 2));
1054 }
1055
1056
1057 public LoadInstruction dload_3 ()
1058 {
1059 return (LoadInstruction) addInstruction (new LoadInstruction
1060 (this, DLOAD_3, double.class, 3));
1061 }
1062
1063
1064 public LoadInstruction aload ()
1065 {
1066 return (LoadInstruction) addInstruction (new LoadInstruction
1067 (this, ALOAD, Object.class, -1));
1068 }
1069
1070
1071 public LoadInstruction aload_0 ()
1072 {
1073 return (LoadInstruction) addInstruction (new LoadInstruction
1074 (this, ALOAD_0, Object.class, 0));
1075 }
1076
1077
1078 public LoadInstruction aload_1 ()
1079 {
1080 return (LoadInstruction) addInstruction (new LoadInstruction
1081 (this, ALOAD_1, Object.class, 1));
1082 }
1083
1084
1085 public LoadInstruction aload_2 ()
1086 {
1087 return (LoadInstruction) addInstruction (new LoadInstruction
1088 (this, ALOAD_2, Object.class, 2));
1089 }
1090
1091
1092 public LoadInstruction aload_3 ()
1093 {
1094 return (LoadInstruction) addInstruction (new LoadInstruction
1095 (this, ALOAD_3, Object.class, 3));
1096 }
1097
1098
1099 /**
1100 * This is a convenience method to store a stack value into a local
1101 * variable if the type and index to store is not known at compile time.
1102 */
1103 public StoreInstruction store ()
1104 {
1105 return (StoreInstruction) addInstruction (new StoreInstruction (this));
1106 }
1107
1108
1109 public StoreInstruction istore ()
1110 {
1111 return (StoreInstruction) addInstruction (new StoreInstruction
1112 (this, ISTORE, int.class, -1));
1113 }
1114
1115
1116 public StoreInstruction istore_0 ()
1117 {
1118 return (StoreInstruction) addInstruction (new StoreInstruction
1119 (this, ISTORE_0, int.class, 0));
1120 }
1121
1122
1123 public StoreInstruction istore_1 ()
1124 {
1125 return (StoreInstruction) addInstruction (new StoreInstruction
1126 (this, ISTORE_1, int.class, 1));
1127 }
1128
1129
1130 public StoreInstruction istore_2 ()
1131 {
1132 return (StoreInstruction) addInstruction (new StoreInstruction
1133 (this, ISTORE_2, int.class, 2));
1134 }
1135
1136
1137 public StoreInstruction istore_3 ()
1138 {
1139 return (StoreInstruction) addInstruction (new StoreInstruction
1140 (this, ISTORE_3, int.class, 3));
1141 }
1142
1143
1144 public StoreInstruction lstore ()
1145 {
1146 return (StoreInstruction) addInstruction (new StoreInstruction
1147 (this, LSTORE, long.class, -1));
1148 }
1149
1150
1151 public StoreInstruction lstore_0 ()
1152 {
1153 return (StoreInstruction) addInstruction (new StoreInstruction
1154 (this, LSTORE_0, long.class, 0));
1155 }
1156
1157
1158 public StoreInstruction lstore_1 ()
1159 {
1160 return (StoreInstruction) addInstruction (new StoreInstruction
1161 (this, LSTORE_1, long.class, 1));
1162 }
1163
1164
1165 public StoreInstruction lstore_2 ()
1166 {
1167 return (StoreInstruction) addInstruction (new StoreInstruction
1168 (this, LSTORE_2, long.class, 2));
1169 }
1170
1171
1172 public StoreInstruction lstore_3 ()
1173 {
1174 return (StoreInstruction) addInstruction (new StoreInstruction
1175 (this, LSTORE_3, long.class, 3));
1176 }
1177
1178
1179 public StoreInstruction fstore ()
1180 {
1181 return (StoreInstruction) addInstruction (new StoreInstruction
1182 (this, FSTORE, float.class, -1));
1183 }
1184
1185
1186 public StoreInstruction fstore_0 ()
1187 {
1188 return (StoreInstruction) addInstruction (new StoreInstruction
1189 (this, FSTORE_0, float.class, 0));
1190 }
1191
1192
1193 public StoreInstruction fstore_1 ()
1194 {
1195 return (StoreInstruction) addInstruction (new StoreInstruction
1196 (this, FSTORE_1, float.class, 1));
1197 }
1198
1199
1200 public StoreInstruction fstore_2 ()
1201 {
1202 return (StoreInstruction) addInstruction (new StoreInstruction
1203 (this, FSTORE_2, float.class, 2));
1204 }
1205
1206
1207 public StoreInstruction fstore_3 ()
1208 {
1209 return (StoreInstruction) addInstruction (new StoreInstruction
1210 (this, FSTORE_3, float.class, 3));
1211 }
1212
1213
1214 public StoreInstruction dstore ()
1215 {
1216 return (StoreInstruction) addInstruction (new StoreInstruction
1217 (this, DSTORE, double.class, -1));
1218 }
1219
1220
1221 public StoreInstruction dstore_0 ()
1222 {
1223 return (StoreInstruction) addInstruction (new StoreInstruction
1224 (this, DSTORE_0, double.class, 0));
1225 }
1226
1227
1228 public StoreInstruction dstore_1 ()
1229 {
1230 return (StoreInstruction) addInstruction (new StoreInstruction
1231 (this, DSTORE_1, double.class, 1));
1232 }
1233
1234
1235 public StoreInstruction dstore_2 ()
1236 {
1237 return (StoreInstruction) addInstruction (new StoreInstruction
1238 (this, DSTORE_2, double.class, 2));
1239 }
1240
1241
1242 public StoreInstruction dstore_3 ()
1243 {
1244 return (StoreInstruction) addInstruction (new StoreInstruction
1245 (this, DSTORE_3, double.class, 3));
1246 }
1247
1248
1249 public StoreInstruction astore ()
1250 {
1251 return (StoreInstruction) addInstruction (new StoreInstruction
1252 (this, ASTORE, Object.class, -1));
1253 }
1254
1255
1256 public StoreInstruction astore_0 ()
1257 {
1258 return (StoreInstruction) addInstruction (new StoreInstruction
1259 (this, ASTORE_0, Object.class, 0));
1260 }
1261
1262
1263 public StoreInstruction astore_1 ()
1264 {
1265 return (StoreInstruction) addInstruction (new StoreInstruction
1266 (this, ASTORE_1, Object.class, 1));
1267 }
1268
1269
1270 public StoreInstruction astore_2 ()
1271 {
1272 return (StoreInstruction) addInstruction (new StoreInstruction
1273 (this, ASTORE_2, Object.class, 2));
1274 }
1275
1276
1277 public StoreInstruction astore_3 ()
1278 {
1279 return (StoreInstruction) addInstruction (new StoreInstruction
1280 (this, ASTORE_3, Object.class, 3));
1281 }
1282
1283
1284 public RetInstruction ret ()
1285 {
1286 return (RetInstruction) addInstruction (new RetInstruction (this));
1287 }
1288
1289
1290 public IIncInstruction iinc ()
1291 {
1292 return (IIncInstruction) addInstruction (new IIncInstruction (this));
1293 }
1294
1295
1296 public WideInstruction wide ()
1297 {
1298 return (WideInstruction) addInstruction (new WideInstruction (this));
1299 }
1300
1301
1302 /**
1303 * This is a convenience method to invoke the proper array load instruction
1304 * if the type is not known at compile time.
1305 */
1306 public ArrayLoadInstruction arrayload ()
1307 {
1308 return (ArrayLoadInstruction) addInstruction
1309 (new ArrayLoadInstruction (this));
1310 }
1311
1312
1313 public ArrayLoadInstruction iaload ()
1314 {
1315 return (ArrayLoadInstruction) addInstruction
1316 (new ArrayLoadInstruction (this, IALOAD, int.class));
1317 }
1318
1319
1320 public ArrayLoadInstruction laload ()
1321 {
1322 return (ArrayLoadInstruction) addInstruction
1323 (new ArrayLoadInstruction (this, LALOAD, long.class));
1324 }
1325
1326
1327 public ArrayLoadInstruction faload ()
1328 {
1329 return (ArrayLoadInstruction) addInstruction
1330 (new ArrayLoadInstruction (this, FALOAD, float.class));
1331 }
1332
1333
1334 public ArrayLoadInstruction daload ()
1335 {
1336 return (ArrayLoadInstruction) addInstruction
1337 (new ArrayLoadInstruction (this, DALOAD, double.class));
1338 }
1339
1340
1341 public ArrayLoadInstruction aaload ()
1342 {
1343 return (ArrayLoadInstruction) addInstruction
1344 (new ArrayLoadInstruction (this, AALOAD, Object.class));
1345 }
1346
1347
1348 public ArrayLoadInstruction baload ()
1349 {
1350 return (ArrayLoadInstruction) addInstruction
1351 (new ArrayLoadInstruction (this, BALOAD, byte.class));
1352 }
1353
1354
1355 public ArrayLoadInstruction caload ()
1356 {
1357 return (ArrayLoadInstruction) addInstruction
1358 (new