/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* A parsed bytecode instruction.
* Provides accessors to various relevant bits.
* @author John Rose
*/
class Instruction {
protected int w; // 0 if normal, 1 if a _wide prefix at pc
protected boolean special;
}
this.w = w;
}
public int getBC() {
return bc;
}
public boolean isWide() {
return w != 0;
}
public byte[] getBytes() {
return bytes;
}
public int getPC() {
return pc;
}
public int getLength() {
return length;
}
public int getNextPC() {
}
return null;
else
}
public boolean isNonstandard() {
return isNonstandard(bc);
}
assert(isNonstandard());
}
/** A fake instruction at this pc whose next() will be at nextpc. */
}
}
int prefix = -1;
int w = 0;
if (length == 0) {
// Hard cases:
switch (bc) {
case _wide:
w = 1;
if (length == 0) {
// unknown instruction; treat as one byte
length = 1;
}
break;
case _tableswitch:
case _lookupswitch:
default:
// unknown instruction; treat as one byte
length = 1;
break;
}
}
assert(length > 0);
// Speed hack: Instruction.next reuses self if possible.
return reuse;
}
}
// Return the constant pool reference type, or 0 if none.
public byte getCPTag() {
}
// Return the constant pool index, or -1 if none.
public int getCPIndex() {
assert(w == 0);
if (length == 2)
else
}
assert(indexLoc != 0);
if (length == 2)
else
assert(getCPIndex() == cpi);
}
int index = getCPIndex();
}
// Return the slot of the affected local, or -1 if none.
public int getLocalSlot() {
if (w == 0)
else
}
// Return the target of the branch, or -1 if none.
public int getBranchLabel() {
assert(w == 0);
int offset;
if (length == 3)
else
}
assert(branchLoc != 0);
if (length == 3)
else
assert(targetPC == getBranchLabel());
}
// Return the trailing constant in the instruction (as a signed value).
// Return 0 if there is none.
public int getConstant() {
}
assert(false);
return 0;
}
assert(conLoc != 0);
}
assert(con == getConstant());
}
// Each case is a (value, label) pair, indexed 0 <= n < caseCount
public abstract int getCaseCount();
public abstract int getCaseValue(int n);
public abstract int getCaseLabel(int n);
this.special = true;
}
int caseCount = getCaseCount();
for (int i = 0; i < caseCount; i++) {
}
return s;
}
return apc;
}
}
// apc: (df, lo, hi, (hi-lo+1)*(label))
}
if (n != 0) throw new UnsupportedOperationException();
int caseCount = getCaseCount();
}
}
}
}
// apc: (df, nc, nc*(case, label))
}
}
}
}
/** Two instructions are equal if they have the same bytes. */
&& equals((Instruction) o);
}
public int hashCode() {
int hash = 3;
return hash;
}
if (this.w != that.w) return false;
for (int i = 1; i < length; i++) {
return false;
}
return true;
}
return pc+"";
}
}
if (bc >= _bytecode_limit) {
return s;
}
if (w == 1) s += "wide ";
return s+"opcode#"+bc;
}
s += bcname;
int idx = getCPIndex();
int slt = getLocalSlot();
int lab = getBranchLabel();
int con = getConstant();
return s;
}
//public static byte constantPoolTagFor(int bc) { return BC_TAG[0][bc]; }
/// Fetching values from byte arrays:
}
}
}
}
}
}
}
}
}
// some bytecode classifiers
}
assert(l > 0);
return l;
}
assert(l > 0);
return l;
}
}
}
return false;
}
return CONSTANT_None;
}
}
}
}
/// Format definitions.
static {
for (int i = 0; i < _bytecode_limit; i++) {
}
for (int i = 0; i < _bytecode_limit; i++) {
//System.out.println(i+": l="+BC_LENGTH[0][i]+" i="+BC_INDEX[0][i]);
//assert(BC_LENGTH[0][i] != -1);
assert(i == _xxxunusedxxx);
continue; // unknown opcode
}
// Have a complete mapping, to support spurious _wide prefixes.
}
"nop aconst_null iconst_m1 iconst_0 iconst_1 iconst_2 iconst_3 iconst_4 "+
"iconst_5 lconst_0 lconst_1 fconst_0 fconst_1 fconst_2 dconst_0 dconst_1 "+
"bipush sipush ldc ldc_w ldc2_w iload lload fload dload aload iload_0 "+
"iload_1 iload_2 iload_3 lload_0 lload_1 lload_2 lload_3 fload_0 fload_1 "+
"fload_2 fload_3 dload_0 dload_1 dload_2 dload_3 aload_0 aload_1 aload_2 "+
"aload_3 iaload laload faload daload aaload baload caload saload istore "+
"lstore fstore dstore astore istore_0 istore_1 istore_2 istore_3 lstore_0 "+
"lstore_1 lstore_2 lstore_3 fstore_0 fstore_1 fstore_2 fstore_3 dstore_0 "+
"dstore_1 dstore_2 dstore_3 astore_0 astore_1 astore_2 astore_3 iastore "+
"lastore fastore dastore aastore bastore castore sastore pop pop2 dup "+
"dup_x1 dup_x2 dup2 dup2_x1 dup2_x2 swap iadd ladd fadd dadd isub lsub "+
"fsub dsub imul lmul fmul dmul idiv ldiv fdiv ddiv irem lrem frem drem "+
"ineg lneg fneg dneg ishl lshl ishr lshr iushr lushr iand land ior lor "+
"ixor lxor iinc i2l i2f i2d l2i l2f l2d f2i f2l f2d d2i d2l d2f i2b i2c "+
"i2s lcmp fcmpl fcmpg dcmpl dcmpg ifeq ifne iflt ifge ifgt ifle if_icmpeq "+
"if_icmpne if_icmplt if_icmpge if_icmpgt if_icmple if_acmpeq if_acmpne "+
"goto jsr ret tableswitch lookupswitch ireturn lreturn freturn dreturn "+
"areturn return getstatic putstatic getfield putfield invokevirtual "+
"invokespecial invokestatic invokeinterface xxxunusedxxx new newarray "+
"anewarray arraylength athrow checkcast instanceof monitorenter "+
"monitorexit wide multianewarray ifnull ifnonnull goto_w jsr_w ";
}
}
} else if (isSelfLinkerOp(bc)) {
} else if (isInvokeInitOp(bc)) {
switch (idx) {
case _invokeinit_self_option:
iname = "*invokespecial_init_this"; break;
case _invokeinit_super_option:
iname = "*invokespecial_init_super"; break;
default:
assert(idx == _invokeinit_new_option);
iname = "*invokespecial_init_new"; break;
}
} else {
switch (bc) {
}
}
return iname;
}
}
}
for (int w = 0; w <= 1; w++) {
int tag = CONSTANT_None;
}
assert(tag != CONSTANT_None);
}
}
}
}
while (i != null) {
throw new FormatException(message);
}
i = i.next();
}
}
super(message);
}
}
}