0001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
0002:
0003: This file is part of the db4o open source object database.
0004:
0005: db4o is free software; you can redistribute it and/or modify it under
0006: the terms of version 2 of the GNU General Public License as published
0007: by the Free Software Foundation and as clarified by db4objects' GPL
0008: interpretation policy, available at
0009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
0010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
0011: Suite 350, San Mateo, CA 94403, USA.
0012:
0013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
0014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
0015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0016: for more details.
0017:
0018: You should have received a copy of the GNU General Public License along
0019: with this program; if not, write to the Free Software Foundation, Inc.,
0020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
0021: package EDU.purdue.cs.bloat.editor;
0022:
0023: import EDU.purdue.cs.bloat.util.*;
0024:
0025: /**
0026: * <tt>Instruction</tt> represents a single instruction in the JVM. All
0027: * <tt>Instruction</tt>s known their opcode. Some instructions have an
0028: * operand. Operands are integers, floats, or one of the special classes that
0029: * represent multiple operands such as <tt>IncOperand</tt> and <tt>Switch</tt>.
0030: *
0031: * @see IncOperand
0032: * @see Switch
0033: * @see MultiArrayOperand
0034: *
0035: * @author Nate Nystrom (<a
0036: * href="mailto:nystrom@cs.purdue.edu">nystrom@cs.purdue.edu</a>)
0037: */
0038: public class Instruction implements Opcode {
0039: private Object operand;
0040:
0041: private int opcode; // Mapped opcode
0042:
0043: private int origOpcode; // Original (non-mapped) opcode
0044:
0045: private boolean useSlow = false;
0046:
0047: // Do we use a slow version when generating code?
0048:
0049: /**
0050: * Constructor.
0051: *
0052: * @param opcode
0053: * The opcode class of the instruction.
0054: */
0055: public Instruction(final int opcode) {
0056: this (opcode, null);
0057: }
0058:
0059: /**
0060: * Constructor.
0061: *
0062: * @param opcode
0063: * The opcode class of the instruction.
0064: * @param operand
0065: * The operand of the instruction, or null.
0066: */
0067: public Instruction(final int opcode, final Object operand) {
0068: this .opcode = opcode;
0069: this .origOpcode = opcode;
0070: this .operand = operand;
0071: Assert.isTrue(opcode == Opcode.opcXMap[opcode],
0072: "Illegal instruction: " + this );
0073: }
0074:
0075: /**
0076: * Constructor.
0077: *
0078: * @param code
0079: * The raw byte code array of the method.
0080: * @param index
0081: * This index into the byte array of the instruction.
0082: * @param targets
0083: * Indices of the branch targets of the instruction.
0084: * @param lookups
0085: * Values of the switch lookups of the instruction.
0086: * @param locals
0087: * The local variables defined at this index.
0088: * @param constants
0089: * The constant pool for the class.
0090: */
0091: public Instruction(final byte[] code, final int index,
0092: final int[] targets, final int[] lookups,
0093: final LocalVariable[] locals, final ConstantPool constants) {
0094: int i, j;
0095: int incr;
0096: int dim;
0097: int atype;
0098: Label[] t;
0099: int[] v;
0100:
0101: int opc = Instruction.toUByte(code[index]);
0102:
0103: switch (opc) {
0104: case opc_aconst_null:
0105: operand = null;
0106: break;
0107: case opc_iconst_m1:
0108: operand = new Integer(-1);
0109: break;
0110: case opc_iconst_0:
0111: operand = new Integer(0);
0112: break;
0113: case opc_iconst_1:
0114: operand = new Integer(1);
0115: break;
0116: case opc_iconst_2:
0117: operand = new Integer(2);
0118: break;
0119: case opc_iconst_3:
0120: operand = new Integer(3);
0121: break;
0122: case opc_iconst_4:
0123: operand = new Integer(4);
0124: break;
0125: case opc_iconst_5:
0126: operand = new Integer(5);
0127: break;
0128: case opc_lconst_0:
0129: operand = new Long(0);
0130: break;
0131: case opc_lconst_1:
0132: operand = new Long(1);
0133: break;
0134: case opc_fconst_0:
0135: operand = new Float(0.0F);
0136: break;
0137: case opc_fconst_1:
0138: operand = new Float(1.0F);
0139: break;
0140: case opc_fconst_2:
0141: operand = new Float(2.0F);
0142: break;
0143: case opc_dconst_0:
0144: operand = new Double(0.0);
0145: break;
0146: case opc_dconst_1:
0147: operand = new Double(1.0);
0148: break;
0149: case opc_bipush:
0150: operand = new Integer(code[index + 1]);
0151: break;
0152: case opc_sipush:
0153: operand = new Integer(Instruction.toShort(code[index + 1],
0154: code[index + 2]));
0155: break;
0156: case opc_ldc:
0157: i = Instruction.toUByte(code[index + 1]);
0158: operand = constants.constantAt(i);
0159: break;
0160: case opc_ldc_w:
0161: case opc_ldc2_w:
0162: i = Instruction.toUShort(code[index + 1], code[index + 2]);
0163: operand = constants.constantAt(i);
0164: break;
0165: case opc_iload:
0166: case opc_lload:
0167: case opc_fload:
0168: case opc_dload:
0169: case opc_aload:
0170: i = Instruction.toUByte(code[index + 1]);
0171: operand = (i < locals.length) && (locals[i] != null) ? locals[i]
0172: : new LocalVariable(i);
0173: break;
0174: case opc_iload_0:
0175: case opc_lload_0:
0176: case opc_fload_0:
0177: case opc_dload_0:
0178: case opc_aload_0:
0179: operand = (0 < locals.length) && (locals[0] != null) ? locals[0]
0180: : new LocalVariable(0);
0181: break;
0182: case opc_iload_1:
0183: case opc_lload_1:
0184: case opc_fload_1:
0185: case opc_dload_1:
0186: case opc_aload_1:
0187: operand = (1 < locals.length) && (locals[1] != null) ? locals[1]
0188: : new LocalVariable(1);
0189: break;
0190: case opc_iload_2:
0191: case opc_lload_2:
0192: case opc_fload_2:
0193: case opc_dload_2:
0194: case opc_aload_2:
0195: operand = (2 < locals.length) && (locals[2] != null) ? locals[2]
0196: : new LocalVariable(2);
0197: break;
0198: case opc_iload_3:
0199: case opc_lload_3:
0200: case opc_fload_3:
0201: case opc_dload_3:
0202: case opc_aload_3:
0203: operand = (3 < locals.length) && (locals[3] != null) ? locals[3]
0204: : new LocalVariable(3);
0205: break;
0206: case opc_istore:
0207: case opc_lstore:
0208: case opc_fstore:
0209: case opc_dstore:
0210: case opc_astore:
0211: i = Instruction.toUByte(code[index + 1]);
0212: operand = (i < locals.length) && (locals[i] != null) ? locals[i]
0213: : new LocalVariable(i);
0214: break;
0215: case opc_istore_0:
0216: case opc_lstore_0:
0217: case opc_fstore_0:
0218: case opc_dstore_0:
0219: case opc_astore_0:
0220: operand = (0 < locals.length) && (locals[0] != null) ? locals[0]
0221: : new LocalVariable(0);
0222: break;
0223: case opc_istore_1:
0224: case opc_lstore_1:
0225: case opc_fstore_1:
0226: case opc_dstore_1:
0227: case opc_astore_1:
0228: operand = (1 < locals.length) && (locals[1] != null) ? locals[1]
0229: : new LocalVariable(1);
0230: break;
0231: case opc_istore_2:
0232: case opc_lstore_2:
0233: case opc_fstore_2:
0234: case opc_dstore_2:
0235: case opc_astore_2:
0236: operand = (2 < locals.length) && (locals[2] != null) ? locals[2]
0237: : new LocalVariable(2);
0238: break;
0239: case opc_istore_3:
0240: case opc_lstore_3:
0241: case opc_fstore_3:
0242: case opc_dstore_3:
0243: case opc_astore_3:
0244: operand = (3 < locals.length) && (locals[3] != null) ? locals[3]
0245: : new LocalVariable(3);
0246: break;
0247: case opc_iinc:
0248: i = Instruction.toUByte(code[index + 1]);
0249: incr = code[index + 2];
0250: operand = new IncOperand((i < locals.length)
0251: && (locals[i] != null) ? locals[i]
0252: : new LocalVariable(i), incr);
0253: break;
0254: case opc_ifeq:
0255: case opc_ifne:
0256: case opc_iflt:
0257: case opc_ifge:
0258: case opc_ifgt:
0259: case opc_ifle:
0260: case opc_if_icmpeq:
0261: case opc_if_icmpne:
0262: case opc_if_icmplt:
0263: case opc_if_icmpge:
0264: case opc_if_icmpgt:
0265: case opc_if_icmple:
0266: case opc_if_acmpeq:
0267: case opc_if_acmpne:
0268: Assert.isTrue(targets.length == 1, "Illegal instruction: "
0269: + Opcode.opcNames[opc]);
0270: operand = new Label(targets[0]);
0271: break;
0272: case opc_goto:
0273: case opc_jsr:
0274: case opc_ifnull:
0275: case opc_ifnonnull:
0276: case opc_goto_w:
0277: case opc_jsr_w:
0278: Assert.isTrue(targets.length == 1, "Illegal instruction: "
0279: + Opcode.opcNames[opc]);
0280: operand = new Label(targets[0]);
0281: break;
0282: case opc_ret:
0283: i = Instruction.toUByte(code[index + 1]);
0284: operand = (i < locals.length) && (locals[i] != null) ? locals[i]
0285: : new LocalVariable(i);
0286: break;
0287: case opc_tableswitch:
0288: // The first target is the default.
0289: t = new Label[targets.length - 1];
0290: v = new int[targets.length - 1];
0291: for (i = 1, j = lookups[0]; i < targets.length; i++, j++) {
0292: t[i - 1] = new Label(targets[i]);
0293: v[i - 1] = j;
0294: }
0295: operand = new Switch(new Label(targets[0]), t, v);
0296: break;
0297: case opc_lookupswitch:
0298: // The first target is the default.
0299: t = new Label[targets.length - 1];
0300: v = new int[targets.length - 1];
0301: for (i = 1; i < targets.length; i++) {
0302: t[i - 1] = new Label(targets[i]);
0303: v[i - 1] = lookups[i - 1];
0304: }
0305: operand = new Switch(new Label(targets[0]), t, v);
0306: break;
0307: case opc_getstatic:
0308: case opc_putstatic:
0309: case opc_putstatic_nowb:
0310: case opc_getfield:
0311: case opc_putfield:
0312: case opc_putfield_nowb:
0313: case opc_invokevirtual:
0314: case opc_invokespecial:
0315: case opc_invokestatic:
0316: case opc_invokeinterface:
0317: case opc_new:
0318: case opc_anewarray:
0319: case opc_checkcast:
0320: case opc_instanceof :
0321: i = Instruction.toUShort(code[index + 1], code[index + 2]);
0322: operand = constants.constantAt(i);
0323: break;
0324: case opc_newarray:
0325: atype = code[index + 1];
0326: operand = Type.getType(atype);
0327: break;
0328: case opc_wide:
0329: opc = Instruction.toUByte(code[index + 1]);
0330: switch (opc) {
0331: case opc_iload:
0332: case opc_fload:
0333: case opc_aload:
0334: case opc_lload:
0335: case opc_dload:
0336: case opc_istore:
0337: case opc_fstore:
0338: case opc_astore:
0339: case opc_lstore:
0340: case opc_dstore:
0341: case opc_ret:
0342: i = Instruction.toUShort(code[index + 2],
0343: code[index + 3]);
0344: operand = (i < locals.length) && (locals[i] != null) ? locals[i]
0345: : new LocalVariable(i);
0346: break;
0347: case opc_iinc:
0348: i = Instruction.toUShort(code[index + 2],
0349: code[index + 3]);
0350: incr = Instruction.toShort(code[index + 4],
0351: code[index + 5]);
0352: operand = new IncOperand((i < locals.length)
0353: && (locals[i] != null) ? locals[i]
0354: : new LocalVariable(i), incr);
0355: break;
0356: }
0357: break;
0358: case opc_multianewarray:
0359: i = Instruction.toUShort(code[index + 1], code[index + 2]);
0360: dim = Instruction.toUByte(code[index + 3]);
0361: operand = new MultiArrayOperand((Type) constants
0362: .constantAt(i), dim);
0363: break;
0364: case opc_rc:
0365: i = Instruction.toUByte(code[index + 1]);
0366: operand = new Integer(i);
0367: break;
0368: case opc_aupdate:
0369: i = Instruction.toUByte(code[index + 1]);
0370: operand = new Integer(i);
0371: break;
0372: case opc_supdate:
0373: i = Instruction.toUByte(code[index + 1]);
0374: operand = new Integer(i);
0375: break;
0376: default:
0377: break;
0378: }
0379:
0380: origOpcode = opc;
0381: opcode = Opcode.opcXMap[opc];
0382: }
0383:
0384: /**
0385: * Returns the original (non-mapped) opcode used to create this Instruction.
0386: */
0387: public int origOpcode() {
0388: return (this .origOpcode);
0389: }
0390:
0391: /**
0392: * Sets a flag that determines whether or not the "slow" version of the
0393: * instruction should be generated. For example, if useSlow is true, "iload
0394: * 2" is generated instead of "iload_2".
0395: */
0396: public void setUseSlow(final boolean useSlow) {
0397: this .useSlow = useSlow;
0398: }
0399:
0400: /**
0401: * Returns whether or not the "slow" version of this instruction is
0402: * generated.
0403: */
0404: public boolean useSlow() {
0405: return (this .useSlow);
0406: }
0407:
0408: /**
0409: * Check if the instruction is a load.
0410: *
0411: * @return true if the instruction is a load, false if not.
0412: */
0413: public boolean isLoad() {
0414: switch (opcode) {
0415: case opc_iload:
0416: case opc_lload:
0417: case opc_fload:
0418: case opc_dload:
0419: case opc_aload:
0420: case opc_iload_0:
0421: case opc_lload_0:
0422: case opc_fload_0:
0423: case opc_dload_0:
0424: case opc_aload_0:
0425: case opc_iload_1:
0426: case opc_lload_1:
0427: case opc_fload_1:
0428: case opc_dload_1:
0429: case opc_aload_1:
0430: case opc_iload_2:
0431: case opc_lload_2:
0432: case opc_fload_2:
0433: case opc_dload_2:
0434: case opc_aload_2:
0435: case opc_iload_3:
0436: case opc_lload_3:
0437: case opc_fload_3:
0438: case opc_dload_3:
0439: case opc_aload_3:
0440: return true;
0441: default:
0442: return false;
0443: }
0444: }
0445:
0446: /**
0447: * Check if the instruction is a store.
0448: *
0449: * @return true if the instruction is a store, false if not.
0450: */
0451: public boolean isStore() {
0452: switch (opcode) {
0453: case opc_istore:
0454: case opc_lstore:
0455: case opc_fstore:
0456: case opc_dstore:
0457: case opc_astore:
0458: case opc_istore_0:
0459: case opc_lstore_0:
0460: case opc_fstore_0:
0461: case opc_dstore_0:
0462: case opc_astore_0:
0463: case opc_istore_1:
0464: case opc_lstore_1:
0465: case opc_fstore_1:
0466: case opc_dstore_1:
0467: case opc_astore_1:
0468: case opc_istore_2:
0469: case opc_lstore_2:
0470: case opc_fstore_2:
0471: case opc_dstore_2:
0472: case opc_astore_2:
0473: case opc_istore_3:
0474: case opc_lstore_3:
0475: case opc_fstore_3:
0476: case opc_dstore_3:
0477: case opc_astore_3:
0478: return true;
0479: default:
0480: return false;
0481: }
0482: }
0483:
0484: /**
0485: * Check if the instruction is an increment.
0486: *
0487: * @return true if the instruction is an increment, false if not.
0488: */
0489: public boolean isInc() {
0490: return opcode == Opcode.opc_iinc;
0491: }
0492:
0493: /**
0494: * Check if the instruction is an exception throw instruction.
0495: *
0496: * @return true if the instruction is a throw, false if not.
0497: */
0498: public boolean isThrow() {
0499: return opcode == Opcode.opc_athrow;
0500: }
0501:
0502: /**
0503: * Returns <tt>true</tt> if this instruction invokes a method.
0504: */
0505: public boolean isInvoke() {
0506: switch (opcode) {
0507: case opc_invokevirtual:
0508: case opc_invokespecial:
0509: case opc_invokestatic:
0510: case opc_invokeinterface:
0511: return (true);
0512: default:
0513: return (false);
0514: }
0515: }
0516:
0517: /**
0518: * Check if the instruction is a subroutine return instruction.
0519: *
0520: * @return true if the instruction is a ret, false if not.
0521: */
0522: public boolean isRet() {
0523: return opcode == Opcode.opc_ret;
0524: }
0525:
0526: /**
0527: * Returns <tt>true</tt> if the instruction returns from a method.
0528: */
0529: public boolean isReturn() {
0530: switch (opcode) {
0531: case opc_areturn:
0532: case opc_ireturn:
0533: case opc_lreturn:
0534: case opc_freturn:
0535: case opc_dreturn:
0536: case opc_return:
0537: return true;
0538: default:
0539: return false;
0540: }
0541: }
0542:
0543: /**
0544: * Check if the instruction is a switch.
0545: *
0546: * @return true if the instruction is a switch, false if not.
0547: */
0548: public boolean isSwitch() {
0549: return opcodeClass() == Opcode.opcx_switch;
0550: }
0551:
0552: /**
0553: * Check if the instruction is a jump.
0554: *
0555: * @return true if the instruction is a jump, false if not.
0556: */
0557: public boolean isJump() {
0558: return isConditionalJump() || isGoto();
0559: }
0560:
0561: /**
0562: * Check if the instruction is a jsr.
0563: *
0564: * @return true if the instruction is a jsr, false if not.
0565: */
0566: public boolean isJsr() {
0567: return opcodeClass() == Opcode.opcx_jsr;
0568: }
0569:
0570: /**
0571: * Check if the instruction is a goto.
0572: *
0573: * @return true if the instruction is a goto, false if not.
0574: */
0575: public boolean isGoto() {
0576: return opcodeClass() == Opcode.opcx_goto;
0577: }
0578:
0579: /**
0580: * Check if the instruction is a conditional jump.
0581: *
0582: * @return true if the instruction is a conditional jump, false if not.
0583: */
0584: public boolean isConditionalJump() {
0585: switch (opcode) {
0586: case opc_if_icmpeq:
0587: case opc_if_icmpne:
0588: case opc_if_icmplt:
0589: case opc_if_icmpge:
0590: case opc_if_icmpgt:
0591: case opc_if_icmple:
0592: case opc_if_acmpeq:
0593: case opc_if_acmpne:
0594: case opc_ifeq:
0595: case opc_ifne:
0596: case opc_iflt:
0597: case opc_ifge:
0598: case opc_ifgt:
0599: case opc_ifle:
0600: case opc_ifnull:
0601: case opc_ifnonnull:
0602: return true;
0603: default:
0604: return false;
0605: }
0606: }
0607:
0608: /**
0609: * Get the opcode class of the instruction.
0610: *
0611: * @return The opcode class of the instruction.
0612: */
0613: public int opcodeClass() {
0614: return opcode;
0615: }
0616:
0617: /**
0618: * Set the opcode class of the instruction.
0619: *
0620: * @param opcode
0621: * The opcode class of the instruction.
0622: */
0623: public void setOpcodeClass(final int opcode) {
0624: this .opcode = opcode;
0625: }
0626:
0627: /**
0628: * Set the operand of the instruction.
0629: *
0630: * @param operand
0631: * The operand of the instruction.
0632: */
0633: public void setOperand(final Object operand) {
0634: this .operand = operand;
0635: }
0636:
0637: /**
0638: * Get the operand of the instruction.
0639: *
0640: * @return The operand of the instruction.
0641: */
0642: public Object operand() {
0643: return operand;
0644: }
0645:
0646: /**
0647: * Convert the instruction to a string.
0648: *
0649: * @return A string representation of the instruction.
0650: */
0651: public String toString() {
0652: if ((operand == null) && (opcodeClass() != Opcode.opcx_ldc)) {
0653: return Opcode.opcNames[opcode];
0654: } else if (operand instanceof Float) {
0655: return Opcode.opcNames[opcode] + " " + operand + "F";
0656: } else if (operand instanceof Long) {
0657: return Opcode.opcNames[opcode] + " " + operand + "L";
0658: } else if (operand instanceof String) {
0659: final StringBuffer sb = new StringBuffer();
0660:
0661: final String s = (String) operand;
0662:
0663: for (int i = 0; i < s.length(); i++) {
0664: final char c = s.charAt(i);
0665: if (Character.isWhitespace(c)
0666: || ((0x20 <= c) && (c <= 0x7e))) {
0667: sb.append(c);
0668: } else {
0669: sb.append("\\u");
0670: sb.append(Integer.toHexString(c));
0671: }
0672:
0673: if (sb.length() > 50) {
0674: sb.append("...");
0675: break;
0676: }
0677: }
0678:
0679: return Opcode.opcNames[opcode] + " \"" + sb.toString()
0680: + "\"";
0681:
0682: } else {
0683:
0684: return Opcode.opcNames[opcode] + " " + operand;
0685: }
0686: }
0687:
0688: /**
0689: * Utility function to join 2 bytes into an unsigned short.
0690: *
0691: * @param b1
0692: * The upper byte.
0693: * @param b2
0694: * The lower byte.
0695: * @return The unsigned short.
0696: */
0697: protected static int toUShort(final byte b1, final byte b2) {
0698: int x = (short) (Instruction.toUByte(b1) << 8)
0699: | Instruction.toUByte(b2);
0700: if (x < 0) {
0701: x += 0x10000;
0702: }
0703: return x;
0704: }
0705:
0706: /**
0707: * Utility function to join 2 bytes into an signed short.
0708: *
0709: * @param b1
0710: * The upper byte.
0711: * @param b2
0712: * The lower byte.
0713: * @return The signed short.
0714: */
0715: protected static short toShort(final byte b1, final byte b2) {
0716: return (short) ((Instruction.toUByte(b1) << 8) | Instruction
0717: .toUByte(b2));
0718: }
0719:
0720: /**
0721: * Utility function to join 4 bytes into an signed int.
0722: *
0723: * @param b1
0724: * The upper byte.
0725: * @param b2
0726: * The next-to-upper byte.
0727: * @param b3
0728: * The next-to-lower byte.
0729: * @param b4
0730: * The lower byte.
0731: * @return The signed int.
0732: */
0733: protected static int toInt(final byte b1, final byte b2,
0734: final byte b3, final byte b4) {
0735: return (Instruction.toUByte(b1) << 24)
0736: | (Instruction.toUByte(b2) << 16)
0737: | (Instruction.toUByte(b3) << 8)
0738: | Instruction.toUByte(b4);
0739: }
0740:
0741: /**
0742: * Utility function to convert a byte into an unsigned byte.
0743: *
0744: * @param b
0745: * The byte.
0746: * @return The unsigned byte.
0747: */
0748: protected static int toUByte(final byte b) {
0749: return b < 0 ? b + 0x100 : b;
0750: }
0751:
0752: /**
0753: * Returns the category of this instruction. An instruction's category is
0754: * basically the width of the value the instruction places on the stack.
0755: * Types <tt>long</tt> and <tt>double</tt> are Category 2. All other
0756: * types are Category 1.
0757: */
0758: public int category() {
0759: switch (this .opcode) {
0760: case opcx_lload:
0761: case opcx_dload:
0762: case opcx_lstore:
0763: case opcx_dstore:
0764: case opcx_laload:
0765: case opcx_daload:
0766: case opcx_lastore:
0767: case opcx_dastore:
0768: case opcx_ladd:
0769: case opcx_dadd:
0770: case opcx_lsub:
0771: case opcx_dsub:
0772: case opcx_lmul:
0773: case opcx_dmul:
0774: case opcx_ldiv:
0775: case opcx_ddiv:
0776: case opcx_lrem:
0777: case opcx_drem:
0778: case opcx_lneg:
0779: case opcx_dneg:
0780: case opcx_i2l:
0781: case opcx_i2d:
0782: case opcx_l2d:
0783: case opcx_f2l:
0784: case opcx_f2d:
0785: case opcx_d2l:
0786: case opcx_land:
0787: case opcx_lor:
0788: case opcx_lxor:
0789: case opcx_lshl:
0790: case opcx_lshr:
0791: case opcx_lushr:
0792: return (2);
0793:
0794: case opcx_ldc:
0795: // If we're loading a Long or Double, the category is 2.
0796: if ((this .operand instanceof Long)
0797: || (this .operand instanceof Double)) {
0798: return (2);
0799:
0800: } else {
0801: return (1);
0802: }
0803:
0804: case opcx_invokevirtual:
0805: case opcx_invokespecial:
0806: case opcx_invokeinterface:
0807: case opcx_invokestatic:
0808: // If the return type is wide, then the category is 2.
0809: final MemberRef callee = (MemberRef) this .operand;
0810: if (callee.nameAndType().type().returnType().isWide()) {
0811: return (2);
0812:
0813: } else {
0814: return (1);
0815: }
0816:
0817: default:
0818: return (1);
0819: }
0820: }
0821:
0822: /**
0823: * Big switch statement to call the appropriate method of an instruction
0824: * visitor.
0825: *
0826: * @param visitor
0827: * The instruction visitor.
0828: */
0829: public void visit(final InstructionVisitor visitor) {
0830: switch (opcodeClass()) {
0831: case opcx_nop:
0832: visitor.visit_nop(this);
0833: break;
0834: case opcx_ldc:
0835: visitor.visit_ldc(this);
0836: break;
0837: case opcx_iload:
0838: visitor.visit_iload(this);
0839: break;
0840: case opcx_lload:
0841: visitor.visit_lload(this);
0842: break;
0843: case opcx_fload:
0844: visitor.visit_fload(this);
0845: break;
0846: case opcx_dload:
0847: visitor.visit_dload(this);
0848: break;
0849: case opcx_aload:
0850: visitor.visit_aload(this);
0851: break;
0852: case opcx_iaload:
0853: visitor.visit_iaload(this);
0854: break;
0855: case opcx_laload:
0856: visitor.visit_laload(this);
0857: break;
0858: case opcx_faload:
0859: visitor.visit_faload(this);
0860: break;
0861: case opcx_daload:
0862: visitor.visit_daload(this);
0863: break;
0864: case opcx_aaload:
0865: visitor.visit_aaload(this);
0866: break;
0867: case opcx_baload:
0868: visitor.visit_baload(this);
0869: break;
0870: case opcx_caload:
0871: visitor.visit_caload(this);
0872: break;
0873: case opcx_saload:
0874: visitor.visit_saload(this);
0875: break;
0876: case opcx_istore:
0877: visitor.visit_istore(this);
0878: break;
0879: case opcx_lstore:
0880: visitor.visit_lstore(this);
0881: break;
0882: case opcx_fstore:
0883: visitor.visit_fstore(this);
0884: break;
0885: case opcx_dstore:
0886: visitor.visit_dstore(this);
0887: break;
0888: case opcx_astore:
0889: visitor.visit_astore(this);
0890: break;
0891: case opcx_iastore:
0892: visitor.visit_iastore(this);
0893: break;
0894: case opcx_lastore:
0895: visitor.visit_lastore(this);
0896: break;
0897: case opcx_fastore:
0898: visitor.visit_fastore(this);
0899: break;
0900: case opcx_dastore:
0901: visitor.visit_dastore(this);
0902: break;
0903: case opcx_aastore:
0904: visitor.visit_aastore(this);
0905: break;
0906: case opcx_bastore:
0907: visitor.visit_bastore(this);
0908: break;
0909: case opcx_castore:
0910: visitor.visit_castore(this);
0911: break;
0912: case opcx_sastore:
0913: visitor.visit_sastore(this);
0914: break;
0915: case opcx_pop:
0916: visitor.visit_pop(this);
0917: break;
0918: case opcx_pop2:
0919: visitor.visit_pop2(this);
0920: break;
0921: case opcx_dup:
0922: visitor.visit_dup(this);
0923: break;
0924: case opcx_dup_x1:
0925: visitor.visit_dup_x1(this);
0926: break;
0927: case opcx_dup_x2:
0928: visitor.visit_dup_x2(this);
0929: break;
0930: case opcx_dup2:
0931: visitor.visit_dup2(this);
0932: break;
0933: case opcx_dup2_x1:
0934: visitor.visit_dup2_x1(this);
0935: break;
0936: case opcx_dup2_x2:
0937: visitor.visit_dup2_x2(this);
0938: break;
0939: case opcx_swap:
0940: visitor.visit_swap(this);
0941: break;
0942: case opcx_iadd:
0943: visitor.visit_iadd(this);
0944: break;
0945: case opcx_ladd:
0946: visitor.visit_ladd(this);
0947: break;
0948: case opcx_fadd:
0949: visitor.visit_fadd(this);
0950: break;
0951: case opcx_dadd:
0952: visitor.visit_dadd(this);
0953: break;
0954: case opcx_isub:
0955: visitor.visit_isub(this);
0956: break;
0957: case opcx_lsub:
0958: visitor.visit_lsub(this);
0959: break;
0960: case opcx_fsub:
0961: visitor.visit_fsub(this);
0962: break;
0963: case opcx_dsub:
0964: visitor.visit_dsub(this);
0965: break;
0966: case opcx_imul:
0967: visitor.visit_imul(this);
0968: break;
0969: case opcx_lmul:
0970: visitor.visit_lmul(this);
0971: break;
0972: case opcx_fmul:
0973: visitor.visit_fmul(this);
0974: break;
0975: case opcx_dmul:
0976: visitor.visit_dmul(this);
0977: break;
0978: case opcx_idiv:
0979: visitor.visit_idiv(this);
0980: break;
0981: case opcx_ldiv:
0982: visitor.visit_ldiv(this);
0983: break;
0984: case opcx_fdiv:
0985: visitor.visit_fdiv(this);
0986: break;
0987: case opcx_ddiv:
0988: visitor.visit_ddiv(this);
0989: break;
0990: case opcx_irem:
0991: visitor.visit_irem(this);
0992: break;
0993: case opcx_lrem:
0994: visitor.visit_lrem(this);
0995: break;
0996: case opcx_frem:
0997: visitor.visit_frem(this);
0998: break;
0999: case opcx_drem:
1000: visitor.visit_drem(this);
1001: break;
1002: case opcx_ineg:
1003: visitor.visit_ineg(this);
1004: break;
1005: case opcx_lneg:
1006: visitor.visit_lneg(this);
1007: break;
1008: case opcx_fneg:
1009: visitor.visit_fneg(this);
1010: break;
1011: case opcx_dneg:
1012: visitor.visit_dneg(this);
1013: break;
1014: case opcx_ishl:
1015: visitor.visit_ishl(this);
1016: break;
1017: case opcx_lshl:
1018: visitor.visit_lshl(this);
1019: break;
1020: case opcx_ishr:
1021: visitor.visit_ishr(this);
1022: break;
1023: case opcx_lshr:
1024: visitor.visit_lshr(this);
1025: break;
1026: case opcx_iushr:
1027: visitor.visit_iushr(this);
1028: break;
1029: case opcx_lushr:
1030: visitor.visit_lushr(this);
1031: break;
1032: case opcx_iand:
1033: visitor.visit_iand(this);
1034: break;
1035: case opcx_land:
1036: visitor.visit_land(this);
1037: break;
1038: case opcx_ior:
1039: visitor.visit_ior(this);
1040: break;
1041: case opcx_lor:
1042: visitor.visit_lor(this);
1043: break;
1044: case opcx_ixor:
1045: visitor.visit_ixor(this);
1046: break;
1047: case opcx_lxor:
1048: visitor.visit_lxor(this);
1049: break;
1050: case opcx_iinc:
1051: visitor.visit_iinc(this);
1052: break;
1053: case opcx_i2l:
1054: visitor.visit_i2l(this);
1055: break;
1056: case opcx_i2f:
1057: visitor.visit_i2f(this);
1058: break;
1059: case opcx_i2d:
1060: visitor.visit_i2d(this);
1061: break;
1062: case opcx_l2i:
1063: visitor.visit_l2i(this);
1064: break;
1065: case opcx_l2f:
1066: visitor.visit_l2f(this);
1067: break;
1068: case opcx_l2d:
1069: visitor.visit_l2d(this);
1070: break;
1071: case opcx_f2i:
1072: visitor.visit_f2i(this);
1073: break;
1074: case opcx_f2l:
1075: visitor.visit_f2l(this);
1076: break;
1077: case opcx_f2d:
1078: visitor.visit_f2d(this);
1079: break;
1080: case opcx_d2i:
1081: visitor.visit_d2i(this);
1082: break;
1083: case opcx_d2l:
1084: visitor.visit_d2l(this);
1085: break;
1086: case opcx_d2f:
1087: visitor.visit_d2f(this);
1088: break;
1089: case opcx_i2b:
1090: visitor.visit_i2b(this);
1091: break;
1092: case opcx_i2c:
1093: visitor.visit_i2c(this);
1094: break;
1095: case opcx_i2s:
1096: visitor.visit_i2s(this);
1097: break;
1098: case opcx_lcmp:
1099: visitor.visit_lcmp(this);
1100: break;
1101: case opcx_fcmpl:
1102: visitor.visit_fcmpl(this);
1103: break;
1104: case opcx_fcmpg:
1105: visitor.visit_fcmpg(this);
1106: break;
1107: case opcx_dcmpl:
1108: visitor.visit_dcmpl(this);
1109: break;
1110: case opcx_dcmpg:
1111: visitor.visit_dcmpg(this);
1112: break;
1113: case opcx_ifeq:
1114: visitor.visit_ifeq(this);
1115: break;
1116: case opcx_ifne:
1117: visitor.visit_ifne(this);
1118: break;
1119: case opcx_iflt:
1120: visitor.visit_iflt(this);
1121: break;
1122: case opcx_ifge:
1123: visitor.visit_ifge(this);
1124: break;
1125: case opcx_ifgt:
1126: visitor.visit_ifgt(this);
1127: break;
1128: case opcx_ifle:
1129: visitor.visit_ifle(this);
1130: break;
1131: case opcx_if_icmpeq:
1132: visitor.visit_if_icmpeq(this);
1133: break;
1134: case opcx_if_icmpne:
1135: visitor.visit_if_icmpne(this);
1136: break;
1137: case opcx_if_icmplt:
1138: visitor.visit_if_icmplt(this);
1139: break;
1140: case opcx_if_icmpge:
1141: visitor.visit_if_icmpge(this);
1142: break;
1143: case opcx_if_icmpgt:
1144: visitor.visit_if_icmpgt(this);
1145: break;
1146: case opcx_if_icmple:
1147: visitor.visit_if_icmple(this);
1148: break;
1149: case opcx_if_acmpeq:
1150: visitor.visit_if_acmpeq(this);
1151: break;
1152: case opcx_if_acmpne:
1153: visitor.visit_if_acmpne(this);
1154: break;
1155: case opcx_goto:
1156: visitor.visit_goto(this);
1157: break;
1158: case opcx_jsr:
1159: visitor.visit_jsr(this);
1160: break;
1161: case opcx_ret:
1162: visitor.visit_ret(this);
1163: break;
1164: case opcx_switch:
1165: visitor.visit_switch(this);
1166: break;
1167: case opcx_ireturn:
1168: visitor.visit_ireturn(this);
1169: break;
1170: case opcx_lreturn:
1171: visitor.visit_lreturn(this);
1172: break;
1173: case opcx_freturn:
1174: visitor.visit_freturn(this);
1175: break;
1176: case opcx_dreturn:
1177: visitor.visit_dreturn(this);
1178: break;
1179: case opcx_areturn:
1180: visitor.visit_areturn(this);
1181: break;
1182: case opcx_return:
1183: visitor.visit_return(this);
1184: break;
1185: case opcx_getstatic:
1186: visitor.visit_getstatic(this);
1187: break;
1188: case opcx_putstatic:
1189: visitor.visit_putstatic(this);
1190: break;
1191: case opcx_putstatic_nowb:
1192: visitor.visit_putstatic_nowb(this);
1193: break;
1194: case opcx_getfield:
1195: visitor.visit_getfield(this);
1196: break;
1197: case opcx_putfield:
1198: visitor.visit_putfield(this);
1199: break;
1200: case opcx_putfield_nowb:
1201: visitor.visit_putfield_nowb(this);
1202: break;
1203: case opcx_invokevirtual:
1204: visitor.visit_invokevirtual(this);
1205: break;
1206: case opcx_invokespecial:
1207: visitor.visit_invokespecial(this);
1208: break;
1209: case opcx_invokestatic:
1210: visitor.visit_invokestatic(this);
1211: break;
1212: case opcx_invokeinterface:
1213: visitor.visit_invokeinterface(this);
1214: break;
1215: case opcx_new:
1216: visitor.visit_new(this);
1217: break;
1218: case opcx_newarray:
1219: visitor.visit_newarray(this);
1220: break;
1221: case opcx_arraylength:
1222: visitor.visit_arraylength(this);
1223: break;
1224: case opcx_athrow:
1225: visitor.visit_athrow(this);
1226: break;
1227: case opcx_checkcast:
1228: visitor.visit_checkcast(this);
1229: break;
1230: case opcx_instanceof:
1231: visitor.visit_instanceof(this);
1232: break;
1233: case opcx_monitorenter:
1234: visitor.visit_monitorenter(this);
1235: break;
1236: case opcx_monitorexit:
1237: visitor.visit_monitorexit(this);
1238: break;
1239: case opcx_multianewarray:
1240: visitor.visit_multianewarray(this);
1241: break;
1242: case opcx_ifnull:
1243: visitor.visit_ifnull(this);
1244: break;
1245: case opcx_ifnonnull:
1246: visitor.visit_ifnonnull(this);
1247: break;
1248: case opcx_rc:
1249: visitor.visit_rc(this);
1250: break;
1251: case opcx_aupdate:
1252: visitor.visit_aupdate(this);
1253: break;
1254: case opcx_supdate:
1255: visitor.visit_supdate(this);
1256: break;
1257: case opcx_aswizzle:
1258: visitor.visit_aswizzle(this);
1259: break;
1260: case opcx_aswrange:
1261: visitor.visit_aswrange(this);
1262: break;
1263: }
1264: }
1265: }
|