001: /*
002: * Copyright 2004 Brian S O'Neill
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.cojen.classfile;
018:
019: import java.lang.reflect.Constructor;
020: import java.lang.reflect.Method;
021: import java.util.MissingResourceException;
022:
023: /**
024: * CodeAssembler is a high-level interface for assembling Java Virtual Machine
025: * byte code. It can also be used as a visitor to a disassembler.
026: *
027: * @author Brian S O'Neill
028: */
029: public interface CodeAssembler {
030: /** Convert floating point values as normal */
031: public final static int CONVERT_FP_NORMAL = 0;
032: /** Convert floating point values as bits (NaN is canonicalized) */
033: public final static int CONVERT_FP_BITS = 1;
034: /** Convert floating point values as raw bits */
035: public final static int CONVERT_FP_RAW_BITS = 2;
036:
037: /**
038: * Returns the amount of parameters that are accepted by the method being
039: * built, not including any "this" reference.
040: */
041: int getParameterCount();
042:
043: /**
044: * Returns a specific parameter, whose index lies within 0 to
045: * getParameterCount() - 1. The names of the LocalVariables returned by
046: * this method are initially set to null. It is encouraged that a name be
047: * provided.
048: */
049: LocalVariable getParameter(int index)
050: throws IndexOutOfBoundsException;
051:
052: /**
053: * Creates a LocalVariable reference from a name and type. Although name
054: * is optional, it is encouraged that a name be provided. Names do not
055: * need to be unique.
056: *
057: * @param name Optional name for the LocalVariable.
058: * @param type The type of data that the requested LocalVariable can
059: * store.
060: */
061: LocalVariable createLocalVariable(String name, TypeDesc type);
062:
063: /**
064: * Creates a label, whose location must be set. To create a label and
065: * locate it here, the following example demonstrates how the call to
066: * setLocation can be chained:
067: *
068: * <pre>
069: * CodeBuilder builder;
070: * ...
071: * Label label = builder.createLabel().setLocation();
072: * </pre>
073: *
074: * @see Label#setLocation
075: */
076: Label createLabel();
077:
078: /**
079: * Sets up an exception handler located here, the location of the next
080: * code to be generated.
081: *
082: * @param startLocation Location at the start of the section of
083: * code to be wrapped by an exception handler.
084: * @param endLocation Location directly after the end of the
085: * section of code.
086: * @param catchClassName The class name of exception to be caught;
087: * if null, then catch every object.
088: */
089: void exceptionHandler(Location startLocation, Location endLocation,
090: String catchClassName);
091:
092: /**
093: * Map the location of the next code to be generated to a line number
094: * in source code. This enables line numbers in a stack trace from the
095: * generated code.
096: */
097: void mapLineNumber(int lineNumber);
098:
099: /**
100: * Allows code to disassembled and copied straight in. The code object
101: * passed in must have a single method named "define" whose arguments match
102: * the type and order of values expected on the operand stack. If a return
103: * value is provided, it will pushed onto the stack. The define method can
104: * have any access modifier.
105: *
106: * @throws IllegalArgumentException if define method not found, or if
107: * multiple are found
108: * @throws MissingResourceException if define code not found
109: */
110: void inline(Object code) throws IllegalArgumentException,
111: MissingResourceException;
112:
113: // load-constant-to-stack style instructions
114:
115: /**
116: * Generates code that loads a null reference onto the stack.
117: */
118: void loadNull();
119:
120: /**
121: * Generates code that loads a constant string value onto the stack. If
122: * value is null, the generated code loads a null onto the stack. Strings
123: * that exceed 65535 UTF encoded bytes in length are loaded by creating a
124: * StringBuffer (or a StringBuilder), appending substrings, and then
125: * converting it to a String.
126: */
127: void loadConstant(String value);
128:
129: /**
130: * Generates code that loads a constant class value onto the stack.
131: * If value is null, the generated code loads a null onto the stack.
132: *
133: * @param type any object or primitive type
134: * @throws IllegalStateException if class file target version does not
135: * support this feature
136: */
137: void loadConstant(TypeDesc type) throws IllegalStateException;
138:
139: /**
140: * Generates code that loads a constant boolean value onto the stack.
141: */
142: void loadConstant(boolean value);
143:
144: /**
145: * Generates code that loads a constant int, char, short or byte value
146: * onto the stack.
147: */
148: void loadConstant(int value);
149:
150: /**
151: * Generates code that loads a constant long value onto the stack.
152: */
153: void loadConstant(long value);
154:
155: /**
156: * Generates code that loads a constant float value onto the stack.
157: */
158: void loadConstant(float value);
159:
160: /**
161: * Generates code that loads a constant double value onto the stack.
162: */
163: void loadConstant(double value);
164:
165: // load-local-to-stack style instructions
166:
167: /**
168: * Generates code that loads a local variable onto the stack. Parameters
169: * passed to a method and the "this" reference are all considered local
170: * variables, as well as any that were created.
171: *
172: * @param local The local variable reference
173: */
174: void loadLocal(LocalVariable local);
175:
176: /**
177: * Loads a reference to "this" onto the stack. Static methods have no
178: * "this" reference, and an exception is thrown when attempting to
179: * generate "this" in a static method.
180: */
181: void loadThis();
182:
183: // store-from-stack-to-local style instructions
184:
185: /**
186: * Generates code that pops a value off of the stack into a local variable.
187: * Parameters passed to a method and the "this" reference are all
188: * considered local variables, as well as any that were created.
189: *
190: * @param local The local variable reference
191: * @see #getParameter
192: * @see #createLocalVariable
193: */
194: void storeLocal(LocalVariable local);
195:
196: // load-to-stack-from-array style instructions
197:
198: /**
199: * Generates code that loads a value from an array. An array
200: * reference followed by an index must be on the stack. The array
201: * reference and index are replaced by the value retrieved from the array
202: * after the generated instruction has executed.
203: * <p>
204: * The type doesn't need to be an exact match for objects.
205: * TypeDesc.OBJECT works fine for all objects. For primitive types, use
206: * the appropriate TypeDesc. For an int, the type is TypeDesc.INT.
207: *
208: * @param type The type of data stored in the array.
209: */
210: void loadFromArray(TypeDesc type);
211:
212: // store-to-array-from-stack style instructions
213:
214: /**
215: * Generates code that stores a value to an array. An array
216: * reference followed by an index, followed by a value (or two if a long
217: * or double) must be on the stack. All items on the stack are gone
218: * after the generated instruction has executed.
219: * <p>
220: * The type doesn't need to be an exact match for objects.
221: * TypeDesc.OBJECT works fine for all objects. For primitive types, use
222: * the appropriate TypeDesc. For an int, the type is TypeDesc.INT.
223: *
224: * @param type The type of data stored in the array.
225: */
226: void storeToArray(TypeDesc type);
227:
228: // load-field-to-stack style instructions
229:
230: /**
231: * Generates code that loads a value from a field from this class.
232: * An object reference must be on the stack. After the generated code
233: * has executed, the object reference is replaced by the value retrieved
234: * from the field.
235: */
236: void loadField(String fieldName, TypeDesc type);
237:
238: /**
239: * Generates code that loads a value from a field from any class.
240: * An object reference must be on the stack. After the generated code
241: * has executed, the object reference is replaced by the value retrieved
242: * from the field.
243: */
244: void loadField(String className, String fieldName, TypeDesc type);
245:
246: /**
247: * Generates code that loads a value from a field from any class.
248: * An object reference must be on the stack. After the generated code
249: * has executed, the object reference is replaced by the value retrieved
250: * from the field.
251: *
252: * @throws IllegalArgumentException if classDesc refers to an array or
253: * primitive type
254: */
255: void loadField(TypeDesc classDesc, String fieldName, TypeDesc type);
256:
257: /**
258: * Generates code that loads a value from a static field from this class.
259: * After the generated code has executed, the value retrieved is placed
260: * on the stack.
261: */
262: void loadStaticField(String fieldName, TypeDesc type);
263:
264: /**
265: * Generates code that loads a value from a static field from any class.
266: * After the generated code has executed, the value retrieved is placed
267: * on the stack.
268: */
269: void loadStaticField(String className, String fieldName,
270: TypeDesc type);
271:
272: /**
273: * Generates code that loads a value from a static field from any class.
274: * After the generated code has executed, the value retrieved is placed
275: * on the stack.
276: *
277: * @throws IllegalArgumentException if classDesc refers to an array or
278: * primitive type
279: */
280: void loadStaticField(TypeDesc classDesc, String fieldName,
281: TypeDesc type);
282:
283: // store-to-field-from-stack style instructions
284:
285: /**
286: * Generates code that stores a value into a field from this class.
287: * An object reference and value must be on the stack. After the generated
288: * code has executed, the object reference and value are gone from
289: * the stack.
290: */
291: void storeField(String fieldName, TypeDesc type);
292:
293: /**
294: * Generates code that stores a value into a field from any class.
295: * An object reference and value must be on the stack. After the generated
296: * code has executed, the object reference and value are gone from
297: * the stack.
298: */
299: void storeField(String className, String fieldName, TypeDesc type);
300:
301: /**
302: * Generates code that stores a value into a field from any class.
303: * An object reference and value must be on the stack. After the generated
304: * code has executed, the object reference and value are gone from
305: * the stack.
306: *
307: * @throws IllegalArgumentException if classDesc refers to an array or
308: * primitive type
309: */
310: void storeField(TypeDesc classDesc, String fieldName, TypeDesc type);
311:
312: /**
313: * Generates code that stores a value into a field from this class.
314: * A value must be on the stack. After the generated
315: * code has executed, the value is gone from the stack.
316: */
317: void storeStaticField(String fieldName, TypeDesc type);
318:
319: /**
320: * Generates code that stores a value into a field from any class.
321: * A value must be on the stack. After the generated
322: * code has executed, the value is gone from the stack.
323: */
324: void storeStaticField(String className, String fieldName,
325: TypeDesc type);
326:
327: /**
328: * Generates code that stores a value into a field from any class.
329: * A value must be on the stack. After the generated
330: * code has executed, the value is gone from the stack.
331: *
332: * @throws IllegalArgumentException if classDesc refers to an array or
333: * primitive type
334: */
335: void storeStaticField(TypeDesc classDesc, String fieldName,
336: TypeDesc type);
337:
338: // return style instructions
339:
340: /**
341: * Generates code that returns void.
342: */
343: void returnVoid();
344:
345: /**
346: * Generates code that returns an object or primitive type. The value to
347: * return must be on the stack.
348: * <p>
349: * The type doesn't need to be an exact match for objects.
350: * TypeDesc.OBJECT works fine for all objects. For primitive types, use
351: * the appropriate TypeDesc. For an int, the type is TypeDesc.INT.
352: */
353: void returnValue(TypeDesc type);
354:
355: // numerical conversion style instructions
356:
357: /**
358: * Generates code that converts the value of a primitive type already
359: * on the stack. Conversions between all primitive types are supported as
360: * well as boxing and unboxing conversions. Some example conversions:
361: *
362: * <pre>
363: * int to char
364: * byte to double
365: * Double to double
366: * Float to boolean
367: * long to Long
368: * Double to Short
369: * </pre>
370: *
371: * In all, 240 conversions are supported.
372: *
373: * @throws IllegalArgumentException if conversion not supported
374: */
375: void convert(TypeDesc fromType, TypeDesc toType);
376:
377: /**
378: * Generates code that converts the value of a primitive type already
379: * on the stack. Conversions between all primitive types are supported as
380: * well as boxing and unboxing conversions. Some example conversions:
381: *
382: * <pre>
383: * int to char
384: * byte to double
385: * Double to double
386: * Float to boolean
387: * long to Long
388: * Double to Short
389: * </pre>
390: *
391: * In all, 240 conversions are supported.
392: *
393: * @param fpConvertMode controls floating point conversion if converting
394: * float <--> int or double <--> long
395: * @throws IllegalArgumentException if conversion not supported
396: */
397: void convert(TypeDesc fromType, TypeDesc toType, int fpConvertMode);
398:
399: // invocation style instructions
400:
401: /**
402: * Generates code to invoke a method. If the method is static, the method's
403: * argument(s) must be on the stack. If the method is non-static, then the
404: * object reference must also be on the stack, prior to the arguments.
405: */
406: void invoke(Method method);
407:
408: /**
409: * Generates code to invoke a virtual method in this class. The object
410: * reference and the method's argument(s) must be on the stack.
411: *
412: * @param ret May be null if method returns void.
413: * @param params May be null if method takes no parameters.
414: */
415: void invokeVirtual(String methodName, TypeDesc ret,
416: TypeDesc[] params);
417:
418: /**
419: * Generates code to invoke a virtual method in any class. The object
420: * reference and the method's argument(s) must be on the stack.
421: *
422: * @param ret May be null if method returns void.
423: * @param params May be null if method takes no parameters.
424: */
425: void invokeVirtual(String className, String methodName,
426: TypeDesc ret, TypeDesc[] params);
427:
428: /**
429: * Generates code to invoke a virtual method in any class. The object
430: * reference and the method's argument(s) must be on the stack.
431: *
432: * @param ret May be null if method returns void.
433: * @param params May be null if method takes no parameters.
434: * @throws IllegalArgumentException if classDesc refers to an array or
435: * primitive type
436: */
437: void invokeVirtual(TypeDesc classDesc, String methodName,
438: TypeDesc ret, TypeDesc[] params);
439:
440: /**
441: * Generates code to invoke a static method in this class. The method's
442: * argument(s) must be on the stack.
443: *
444: * @param ret May be null if method returns void.
445: * @param params May be null if method takes no parameters.
446: */
447: void invokeStatic(String methodName, TypeDesc ret, TypeDesc[] params);
448:
449: /**
450: * Generates code to invoke a static method in any class. The method's
451: * argument(s) must be on the stack.
452: *
453: * @param ret May be null if method returns void.
454: * @param params May be null if method takes no parameters.
455: */
456: void invokeStatic(String className, String methodName,
457: TypeDesc ret, TypeDesc[] params);
458:
459: /**
460: * Generates code to invoke a static method in any class. The method's
461: * argument(s) must be on the stack.
462: *
463: * @param ret May be null if method returns void.
464: * @param params May be null if method takes no parameters.
465: * @throws IllegalArgumentException if classDesc refers to an array or
466: * primitive type
467: */
468: void invokeStatic(TypeDesc classDesc, String methodName,
469: TypeDesc ret, TypeDesc[] params);
470:
471: /**
472: * Generates code to invoke an interface method in any class. The object
473: * reference and the method's argument(s) must be on the stack.
474: *
475: * @param ret May be null if method returns void.
476: * @param params May be null if method takes no parameters.
477: */
478: void invokeInterface(String className, String methodName,
479: TypeDesc ret, TypeDesc[] params);
480:
481: /**
482: * Generates code to invoke an interface method in any class. The object
483: * reference and the method's argument(s) must be on the stack.
484: *
485: * @param ret May be null if method returns void.
486: * @param params May be null if method takes no parameters.
487: * @throws IllegalArgumentException if classDesc refers to an array or
488: * primitive type
489: */
490: void invokeInterface(TypeDesc classDesc, String methodName,
491: TypeDesc ret, TypeDesc[] params);
492:
493: /**
494: * Generates code to invoke a private method in this class.
495: * The object reference and the method's argument(s) must be on the stack.
496: *
497: * @param ret May be null if method returns void.
498: * @param params May be null if method takes no parameters.
499: */
500: void invokePrivate(String methodName, TypeDesc ret,
501: TypeDesc[] params);
502:
503: /**
504: * Generates code to invoke a method in the super class.
505: * The object reference and the method's argument(s) must be on the stack.
506: */
507: void invokeSuper(Method method);
508:
509: /**
510: * Generates code to invoke a method in the super class.
511: * The object reference and the method's argument(s) must be on the stack.
512: *
513: * @param ret May be null if method returns void.
514: * @param params May be null if method takes no parameters.
515: */
516: void invokeSuper(String super ClassName, String methodName,
517: TypeDesc ret, TypeDesc[] params);
518:
519: /**
520: * Generates code to invoke a method in the super class.
521: * The object reference and the method's argument(s) must be on the stack.
522: *
523: * @param ret May be null if method returns void.
524: * @param params May be null if method takes no parameters.
525: * @throws IllegalArgumentException if superClassDesc refers to an array or
526: * primitive type
527: */
528: void invokeSuper(TypeDesc super ClassDesc, String methodName,
529: TypeDesc ret, TypeDesc[] params);
530:
531: /**
532: * Generates code to invoke a class constructor in any class. The object
533: * reference and the constructor's argument(s) must be on the stack.
534: */
535: void invoke(Constructor constructor);
536:
537: /**
538: * Generates code to invoke a class constructor in this class. The object
539: * reference and the constructor's argument(s) must be on the stack.
540: *
541: * @param params May be null if constructor takes no parameters.
542: */
543: void invokeConstructor(TypeDesc[] params);
544:
545: /**
546: * Generates code to invoke a class constructor in any class. The object
547: * reference and the constructor's argument(s) must be on the stack.
548: *
549: * @param params May be null if constructor takes no parameters.
550: */
551: void invokeConstructor(String className, TypeDesc[] params);
552:
553: /**
554: * Generates code to invoke a class constructor in any class. The object
555: * reference and the constructor's argument(s) must be on the stack.
556: *
557: * @param params May be null if constructor takes no parameters.
558: * @throws IllegalArgumentException if classDesc refers to an array or
559: * primitive type
560: */
561: void invokeConstructor(TypeDesc classDesc, TypeDesc[] params);
562:
563: /**
564: * Generates code to invoke a super class constructor. The object
565: * reference and the constructor's argument(s) must be on the stack.
566: *
567: * @param params May be null if constructor takes no parameters.
568: */
569: void invokeSuperConstructor(TypeDesc[] params);
570:
571: // creation style instructions
572:
573: /**
574: * Generates code to create a new object. Unless the new object is an
575: * array, it is invalid until a constructor method is invoked on it.
576: * <p>
577: * If the specified type is an array, this call is equivalent to
578: * newObject(type, 1). The size of the dimension must be on the operand
579: * stack. To create multi-dimensional arrays, call
580: * newObject(type, dimensions).
581: *
582: * @see #invokeConstructor
583: */
584: void newObject(TypeDesc type);
585:
586: /**
587: * Generates code to create a new array. The type descriptor specifies
588: * the type of array to create. The dimensions parameter specifies the
589: * amount of dimensions that will initialized, which may not be larger than
590: * the amount of dimensions specified in the type.
591: * <p>
592: * For each dimension, its size must be on the operand stack. If the
593: * specified dimensions is 0 and the type is not an array, then this call
594: * is equivalent to newObject(type).
595: */
596: void newObject(TypeDesc type, int dimensions);
597:
598: // stack operation style instructions
599:
600: /**
601: * Generates code for the dup instruction.
602: */
603: void dup();
604:
605: /**
606: * Generates code for the dup_x1 instruction.
607: */
608: void dupX1();
609:
610: /**
611: * Generates code for the dup_x2 instruction.
612: */
613: void dupX2();
614:
615: /**
616: * Generates code for the dup2 instruction.
617: */
618: void dup2();
619:
620: /**
621: * Generates code for the dup2_x1 instruction.
622: */
623: void dup2X1();
624:
625: /**
626: * Generates code for the dup2_x2 instruction.
627: */
628: void dup2X2();
629:
630: /**
631: * Generates code for the pop instruction.
632: */
633: void pop();
634:
635: /**
636: * Generates code for the pop2 instruction.
637: */
638: void pop2();
639:
640: /**
641: * Generates code for the swap instruction.
642: */
643: void swap();
644:
645: /**
646: * Generates code for a swap2 instruction.
647: */
648: void swap2();
649:
650: // flow control instructions
651:
652: /**
653: * Generates code that performs an unconditional branch to the specified
654: * location.
655: *
656: * @param location The location to branch to
657: */
658: void branch(Location location);
659:
660: /**
661: * Generates code that performs a conditional branch based on the
662: * value of an object on the stack. A branch is performed based on whether
663: * the object reference on the stack is null or not.
664: *
665: * <p>The generated instruction consumes the value on the stack.
666: *
667: * @param location The location to branch to
668: * @param choice If true, do branch when null, else branch when not null
669: */
670: void ifNullBranch(Location location, boolean choice);
671:
672: /**
673: * Generates code that performs a conditional branch based on the value of
674: * two object references on the stack. A branch is performed based on
675: * whether the two objects are exactly the same.
676: *
677: * <p>The generated instruction consumes the two values on the stack.
678: *
679: * @param location The location to branch to
680: * @param choice If true, branch when equal, else branch when not equal
681: */
682: void ifEqualBranch(Location location, boolean choice);
683:
684: /**
685: * Generates code the performs a conditional branch based on a comparison
686: * between an int value on the stack and zero. The int value on the
687: * stack is on the left side of the comparison expression.
688: *
689: * <p>The generated instruction consumes the value on the stack.
690: *
691: * @param location The location to branch to
692: * @param choice One of "==", "!=", "<", ">=", ">" or "<="
693: * @throws IllegalArgumentException When the choice is not valid
694: */
695: void ifZeroComparisonBranch(Location location, String choice)
696: throws IllegalArgumentException;
697:
698: /**
699: * Generates code the performs a conditional branch based on a comparison
700: * between two int values on the stack. The first int value on the stack
701: * is on the left side of the comparison expression.
702: *
703: * <p>The generated instruction consumes the two values on the stack.
704: *
705: * @param location The location to branch to
706: * @param choice One of "==", "!=", "<", ">=", ">" or "<="
707: * @throws IllegalArgumentException When the choice is not valid
708: */
709: void ifComparisonBranch(Location location, String choice)
710: throws IllegalArgumentException;
711:
712: /**
713: * Generates code the performs a conditional branch based on a comparison
714: * between two values of the given type on the stack. The first int value
715: * on the stack is on the left side of the comparison expression. When
716: * comparing objects, only an identity comparison is performed.
717: *
718: * <p>When comparing floating point values, treatment of NaN requires
719: * special attention. Ordinarily, it is assumed that the branch location
720: * represents the target of a comparison failure, and that the code to
721: * handle the "true" condition immediately follows the comparison. If this
722: * is not the case, append a 't' suffix to the choice to indicate that the
723: * target location is reached for a "true" condition. This suffix is
724: * ignored if the type is not a float or double.
725: *
726: * <p>The generated instruction(s) consumes the two values on the stack.
727: *
728: * @param location The location to branch to
729:
730: * @param choice One of "==", "!=", "<", ">=", ">", "<=", "==t", "!=t",
731: * "<t", ">=t", ">t", or "<=t". Object types can only be compared for
732: * equality.
733: * @param type Type to expect on the stack
734: * @throws IllegalArgumentException When the choice is not valid
735: */
736: void ifComparisonBranch(Location location, String choice,
737: TypeDesc type) throws IllegalArgumentException;
738:
739: /**
740: * Generates code for a switch statement. The generated code is either a
741: * lookupswitch or tableswitch. The choice of which switch type to generate
742: * is made based on the amount of bytes to be generated. A tableswitch
743: * is usually smaller, unless the cases are sparse.
744: *
745: * <p>The key value to switch on must already be on the stack when this
746: * instruction executes. It is consumed by the instruction.
747: *
748: * @param cases The values to match on. The array length must be the same
749: * as for locations.
750: * @param locations The locations to branch to for each case.
751: * The array length must be the same as for cases.
752: * @param defaultLocation The location to branch to if the key on
753: * the stack was not matched.
754: */
755: void switchBranch(int[] cases, Location[] locations,
756: Location defaultLocation);
757:
758: /**
759: * Generates code that performs a subroutine branch to the specified
760: * location. The instruction generated is either jsr or jsr_w. It is most
761: * often used for implementing a finally block.
762: *
763: * @param location The location to branch to
764: */
765: void jsr(Location location);
766:
767: /**
768: * Generates code that returns from a subroutine invoked by jsr.
769: *
770: * @param local The local variable reference that contains the return
771: * address. The local variable must be of an object type.
772: */
773: void ret(LocalVariable local);
774:
775: // math instructions
776:
777: /**
778: * Generates code for either a unary or binary math operation on one
779: * or two values pushed on the stack.
780: * <p>
781: * Pass in an opcode from the the Opcode class. The only valid math
782: * opcodes are:
783: *
784: * <pre>
785: * IADD, ISUB, IMUL, IDIV, IREM, INEG, IAND, IOR, IXOR, ISHL, ISHR, IUSHR
786: * LADD, LSUB, LMUL, LDIV, LREM, LNEG, LAND, LOR, LXOR, LSHL, LSHR, LUSHR
787: * FADD, FSUB, FMUL, FDIV, FREM, FNEG
788: * DADD, DSUB, DMUL, DDIV, DREM, DNEG
789: *
790: * LCMP
791: * FCMPG, FCMPL
792: * DCMPG, DCMPL
793: * </pre>
794: *
795: * A not operation (~) is performed by doing a loadConstant with either
796: * -1 or -1L followed by math(Opcode.IXOR) or math(Opcode.LXOR).
797: *
798: * @param opcode An opcode from the Opcode class.
799: * @throws IllegalArgumentException When the opcode selected is not
800: * a math operation.
801: * @see Opcode
802: */
803: void math(byte opcode);
804:
805: // miscellaneous instructions
806:
807: /**
808: * Generates code for an arraylength instruction. The object to get the
809: * length from must already be on the stack.
810: */
811: void arrayLength();
812:
813: /**
814: * Generates code that throws an exception. The object to throw must
815: * already be on the stack.
816: */
817: void throwObject();
818:
819: /**
820: * Generates code that performs an object cast operation. The object
821: * to check must already be on the stack.
822: */
823: void checkCast(TypeDesc type);
824:
825: /**
826: * Generates code that performs an instanceof operation. The object to
827: * check must already be on the stack.
828: */
829: void instanceOf(TypeDesc type);
830:
831: /**
832: * Generates code that increments a local integer variable by a signed
833: * constant amount.
834: */
835: void integerIncrement(LocalVariable local, int amount);
836:
837: /**
838: * Generates code to enter the monitor on an object loaded on the stack.
839: */
840: void monitorEnter();
841:
842: /**
843: * Generates code to exit the monitor on an object loaded on the stack.
844: */
845: void monitorExit();
846:
847: /**
848: * Generates an instruction that does nothing. (No-OPeration)
849: */
850: void nop();
851:
852: /**
853: * Generates a breakpoint instruction for use in a debugging environment.
854: */
855: void breakpoint();
856: }
|