blob: 82ba955ae80eb19dea7fae714ba003fd45c30c5d [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.core.util;
import org.eclipse.jdt.core.util.ClassFormatException;
import org.eclipse.jdt.core.util.IAttributeNamesConstants;
import org.eclipse.jdt.core.util.IBytecodeVisitor;
import org.eclipse.jdt.core.util.IClassFileAttribute;
import org.eclipse.jdt.core.util.ICodeAttribute;
import org.eclipse.jdt.core.util.IConstantPool;
import org.eclipse.jdt.core.util.IConstantPoolConstant;
import org.eclipse.jdt.core.util.IConstantPoolEntry;
import org.eclipse.jdt.core.util.IExceptionTableEntry;
import org.eclipse.jdt.core.util.ILineNumberAttribute;
import org.eclipse.jdt.core.util.ILocalVariableAttribute;
import org.eclipse.jdt.core.util.IOpcodeMnemonics;
/**
* Default implementation of ICodeAttribute.
*/
public class CodeAttribute extends ClassFileAttribute implements ICodeAttribute {
private static final IExceptionTableEntry[] NO_EXCEPTION_TABLE = new IExceptionTableEntry[0];
private IClassFileAttribute[] attributes;
private int attributesCount;
private byte[] bytecodes;
private byte[] classFileBytes;
private long codeLength;
private int codeOffset;
private IConstantPool constantPool;
private IExceptionTableEntry[] exceptionTableEntries;
private int exceptionTableLength;
private ILineNumberAttribute lineNumberAttribute;
private ILocalVariableAttribute localVariableAttribute;
private int maxLocals;
private int maxStack;
CodeAttribute(byte[] classFileBytes, IConstantPool constantPool, int offset) throws ClassFormatException {
super(classFileBytes, constantPool, offset);
this.classFileBytes = classFileBytes;
this.constantPool = constantPool;
this.maxStack = u2At(classFileBytes, 6, offset);
this.maxLocals = u2At(classFileBytes, 8, offset);
this.codeLength = u4At(classFileBytes, 10, offset);
this.codeOffset = offset + 14;
int readOffset = (int) (14 + this.codeLength);
this.exceptionTableLength = u2At(classFileBytes, readOffset, offset);
readOffset += 2;
this.exceptionTableEntries = NO_EXCEPTION_TABLE;
if (this.exceptionTableLength != 0) {
this.exceptionTableEntries = new ExceptionTableEntry[this.exceptionTableLength];
for (int i = 0; i < this.exceptionTableLength; i++) {
this.exceptionTableEntries [i] = new ExceptionTableEntry(classFileBytes, constantPool, offset + readOffset);
readOffset += 8;
}
}
this.attributesCount = u2At(classFileBytes, readOffset, offset);
this.attributes = ClassFileAttribute.NO_ATTRIBUTES;
if (this.attributesCount != 0) {
this.attributes = new IClassFileAttribute[this.attributesCount];
}
int attributesIndex = 0;
readOffset += 2;
for (int i = 0; i < this.attributesCount; i++) {
IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(u2At(classFileBytes, readOffset, offset));
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
char[] attributeName = constantPoolEntry.getUtf8Value();
if (equals(attributeName, IAttributeNamesConstants.LINE_NUMBER)) {
this.lineNumberAttribute = new LineNumberAttribute(classFileBytes, constantPool, offset + readOffset);
this.attributes[attributesIndex++] = this.lineNumberAttribute;
} else if (equals(attributeName, IAttributeNamesConstants.LOCAL_VARIABLE)) {
this.localVariableAttribute = new LocalVariableAttribute(classFileBytes, constantPool, offset + readOffset);
this.attributes[attributesIndex++] = this.localVariableAttribute;
} else if (equals(attributeName, IAttributeNamesConstants.LOCAL_VARIABLE_TYPE_TABLE)) {
this.attributes[attributesIndex++] = new LocalVariableTypeAttribute(classFileBytes, constantPool, offset + readOffset);
} else if (equals(attributeName, IAttributeNamesConstants.STACK_MAP_TABLE)) {
this.attributes[attributesIndex++] = new StackMapTableAttribute(classFileBytes, constantPool, offset + readOffset);
} else if (equals(attributeName, IAttributeNamesConstants.STACK_MAP)) {
this.attributes[attributesIndex++] = new StackMapAttribute(classFileBytes, constantPool, offset + readOffset);
} else {
this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, constantPool, offset + readOffset);
}
readOffset += (6 + u4At(classFileBytes, readOffset + 2, offset));
}
}
/**
* @see ICodeAttribute#getAttributes()
*/
public IClassFileAttribute[] getAttributes() {
return this.attributes;
}
/**
* @see ICodeAttribute#getAttributesCount()
*/
public int getAttributesCount() {
return this.attributesCount;
}
/**
* @see ICodeAttribute#getBytecodes()
*/
public byte[] getBytecodes() {
if (this.bytecodes == null) {
System.arraycopy(this.classFileBytes, this.codeOffset, (this.bytecodes = new byte[(int) this.codeLength]), 0, (int) this.codeLength);
}
return this.bytecodes;
}
/**
* @see ICodeAttribute#getCodeLength()
*/
public long getCodeLength() {
return this.codeLength;
}
/**
* @see ICodeAttribute#getExceptionTable()
*/
public IExceptionTableEntry[] getExceptionTable() {
return this.exceptionTableEntries;
}
/**
* @see ICodeAttribute#getExceptionTableLength()
*/
public int getExceptionTableLength() {
return this.exceptionTableLength;
}
/**
* @see ICodeAttribute#getLineNumberAttribute()
*/
public ILineNumberAttribute getLineNumberAttribute() {
return this.lineNumberAttribute;
}
/**
* @see ICodeAttribute#getLocalVariableAttribute()
*/
public ILocalVariableAttribute getLocalVariableAttribute() {
return this.localVariableAttribute;
}
/**
* @see ICodeAttribute#getMaxLocals()
*/
public int getMaxLocals() {
return this.maxLocals;
}
/**
* @see ICodeAttribute#getMaxStack()
*/
public int getMaxStack() {
return this.maxStack;
}
/**
* @see ICodeAttribute#traverse(IBytecodeVisitor visitor)
*/
public void traverse(IBytecodeVisitor visitor) throws ClassFormatException {
int pc = this.codeOffset;
int opcode, index, _const, branchOffset;
IConstantPoolEntry constantPoolEntry;
while (true) {
opcode = u1At(this.classFileBytes, 0, pc);
switch(opcode) {
case IOpcodeMnemonics.NOP :
visitor._nop(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ACONST_NULL :
visitor._aconst_null(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ICONST_M1 :
visitor._iconst_m1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ICONST_0 :
visitor._iconst_0(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ICONST_1 :
visitor._iconst_1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ICONST_2 :
visitor._iconst_2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ICONST_3 :
visitor._iconst_3(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ICONST_4 :
visitor._iconst_4(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ICONST_5 :
visitor._iconst_5(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LCONST_0 :
visitor._lconst_0(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LCONST_1 :
visitor._lconst_1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FCONST_0 :
visitor._fconst_0(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FCONST_1 :
visitor._fconst_1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FCONST_2 :
visitor._fconst_2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DCONST_0 :
visitor._dconst_0(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DCONST_1 :
visitor._dconst_1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.BIPUSH :
visitor._bipush(pc - this.codeOffset, (byte) i1At(this.classFileBytes, 1, pc));
pc+=2;
break;
case IOpcodeMnemonics.SIPUSH :
visitor._sipush(pc - this.codeOffset, (short) i2At(this.classFileBytes, 1, pc));
pc+=3;
break;
case IOpcodeMnemonics.LDC :
index = u1At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Float
&& constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Integer
&& constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_String
&& constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
visitor._ldc(pc - this.codeOffset, index, constantPoolEntry);
pc+=2;
break;
case IOpcodeMnemonics.LDC_W :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Float
&& constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Integer
&& constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_String
&& constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
visitor._ldc_w(pc - this.codeOffset, index, constantPoolEntry);
pc+=3;
break;
case IOpcodeMnemonics.LDC2_W :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Double
&& constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Long) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
visitor._ldc2_w(pc - this.codeOffset, index, constantPoolEntry);
pc+=3;
break;
case IOpcodeMnemonics.ILOAD :
index = u1At(this.classFileBytes, 1, pc);
visitor._iload(pc - this.codeOffset, index);
pc+=2;
break;
case IOpcodeMnemonics.LLOAD :
index = u1At(this.classFileBytes, 1, pc);
visitor._lload(pc - this.codeOffset, index);
pc+=2;
break;
case IOpcodeMnemonics.FLOAD :
index = u1At(this.classFileBytes, 1, pc);
visitor._fload(pc - this.codeOffset, index);
pc+=2;
break;
case IOpcodeMnemonics.DLOAD :
index = u1At(this.classFileBytes, 1, pc);
visitor._dload(pc - this.codeOffset, index);
pc+=2;
break;
case IOpcodeMnemonics.ALOAD :
index = u1At(this.classFileBytes, 1, pc);
visitor._aload(pc - this.codeOffset, index);
pc+=2;
break;
case IOpcodeMnemonics.ILOAD_0 :
visitor._iload_0(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ILOAD_1 :
visitor._iload_1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ILOAD_2 :
visitor._iload_2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ILOAD_3 :
visitor._iload_3(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LLOAD_0 :
visitor._lload_0(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LLOAD_1 :
visitor._lload_1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LLOAD_2 :
visitor._lload_2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LLOAD_3 :
visitor._lload_3(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FLOAD_0 :
visitor._fload_0(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FLOAD_1 :
visitor._fload_1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FLOAD_2 :
visitor._fload_2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FLOAD_3 :
visitor._fload_3(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DLOAD_0 :
visitor._dload_0(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DLOAD_1 :
visitor._dload_1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DLOAD_2 :
visitor._dload_2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DLOAD_3 :
visitor._dload_3(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ALOAD_0 :
visitor._aload_0(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ALOAD_1 :
visitor._aload_1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ALOAD_2 :
visitor._aload_2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ALOAD_3 :
visitor._aload_3(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.IALOAD :
visitor._iaload(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LALOAD :
visitor._laload(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FALOAD :
visitor._faload(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DALOAD :
visitor._daload(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.AALOAD :
visitor._aaload(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.BALOAD :
visitor._baload(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.CALOAD :
visitor._caload(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.SALOAD :
visitor._saload(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ISTORE :
index = u1At(this.classFileBytes, 1, pc);
visitor._istore(pc - this.codeOffset, index);
pc+=2;
break;
case IOpcodeMnemonics.LSTORE :
index = u1At(this.classFileBytes, 1, pc);
visitor._lstore(pc - this.codeOffset, index);
pc+=2;
break;
case IOpcodeMnemonics.FSTORE :
index = u1At(this.classFileBytes, 1, pc);
visitor._fstore(pc - this.codeOffset, index);
pc+=2;
break;
case IOpcodeMnemonics.DSTORE :
index = u1At(this.classFileBytes, 1, pc);
visitor._dstore(pc - this.codeOffset, index);
pc+=2;
break;
case IOpcodeMnemonics.ASTORE :
index = u1At(this.classFileBytes, 1, pc);
visitor._astore(pc - this.codeOffset, index);
pc+=2;
break;
case IOpcodeMnemonics.ISTORE_0 :
visitor._istore_0(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ISTORE_1 :
visitor._istore_1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ISTORE_2 :
visitor._istore_2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ISTORE_3 :
visitor._istore_3(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LSTORE_0 :
visitor._lstore_0(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LSTORE_1 :
visitor._lstore_1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LSTORE_2 :
visitor._lstore_2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LSTORE_3 :
visitor._lstore_3(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FSTORE_0 :
visitor._fstore_0(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FSTORE_1 :
visitor._fstore_1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FSTORE_2 :
visitor._fstore_2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FSTORE_3 :
visitor._fstore_3(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DSTORE_0 :
visitor._dstore_0(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DSTORE_1 :
visitor._dstore_1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DSTORE_2 :
visitor._dstore_2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DSTORE_3 :
visitor._dstore_3(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ASTORE_0 :
visitor._astore_0(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ASTORE_1 :
visitor._astore_1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ASTORE_2 :
visitor._astore_2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ASTORE_3 :
visitor._astore_3(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.IASTORE :
visitor._iastore(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LASTORE :
visitor._lastore(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FASTORE :
visitor._fastore(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DASTORE :
visitor._dastore(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.AASTORE :
visitor._aastore(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.BASTORE :
visitor._bastore(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.CASTORE :
visitor._castore(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.SASTORE :
visitor._sastore(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.POP :
visitor._pop(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.POP2 :
visitor._pop2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DUP :
visitor._dup(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DUP_X1 :
visitor._dup_x1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DUP_X2 :
visitor._dup_x2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DUP2 :
visitor._dup2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DUP2_X1 :
visitor._dup2_x1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DUP2_X2 :
visitor._dup2_x2(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.SWAP :
visitor._swap(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.IADD :
visitor._iadd(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LADD :
visitor._ladd(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FADD :
visitor._fadd(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DADD :
visitor._dadd(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ISUB :
visitor._isub(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LSUB :
visitor._lsub(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FSUB :
visitor._fsub(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DSUB :
visitor._dsub(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.IMUL :
visitor._imul(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LMUL :
visitor._lmul(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FMUL :
visitor._fmul(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DMUL :
visitor._dmul(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.IDIV :
visitor._idiv(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LDIV :
visitor._ldiv(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FDIV :
visitor._fdiv(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DDIV :
visitor._ddiv(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.IREM :
visitor._irem(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LREM :
visitor._lrem(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FREM :
visitor._frem(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DREM :
visitor._drem(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.INEG :
visitor._ineg(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LNEG :
visitor._lneg(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FNEG :
visitor._fneg(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DNEG :
visitor._dneg(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ISHL :
visitor._ishl(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LSHL :
visitor._lshl(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ISHR :
visitor._ishr(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LSHR :
visitor._lshr(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.IUSHR :
visitor._iushr(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LUSHR :
visitor._lushr(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.IAND :
visitor._iand(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LAND :
visitor._land(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.IOR :
visitor._ior(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LOR :
visitor._lor(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.IXOR :
visitor._ixor(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LXOR :
visitor._lxor(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.IINC :
index = u1At(this.classFileBytes, 1, pc);
_const = i1At(this.classFileBytes, 2, pc);
visitor._iinc(pc - this.codeOffset, index, _const);
pc+=3;
break;
case IOpcodeMnemonics.I2L :
visitor._i2l(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.I2F :
visitor._i2f(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.I2D :
visitor._i2d(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.L2I :
visitor._l2i(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.L2F :
visitor._l2f(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.L2D :
visitor._l2d(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.F2I :
visitor._f2i(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.F2L :
visitor._f2l(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.F2D :
visitor._f2d(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.D2I :
visitor._d2i(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.D2L :
visitor._d2l(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.D2F :
visitor._d2f(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.I2B :
visitor._i2b(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.I2C :
visitor._i2c(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.I2S :
visitor._i2s(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LCMP :
visitor._lcmp(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FCMPL :
visitor._fcmpl(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FCMPG :
visitor._fcmpg(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DCMPL :
visitor._dcmpl(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DCMPG :
visitor._dcmpg(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.IFEQ :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._ifeq(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.IFNE :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._ifne(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.IFLT :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._iflt(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.IFGE :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._ifge(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.IFGT :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._ifgt(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.IFLE :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._ifle(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.IF_ICMPEQ :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._if_icmpeq(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.IF_ICMPNE :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._if_icmpne(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.IF_ICMPLT :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._if_icmplt(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.IF_ICMPGE :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._if_icmpge(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.IF_ICMPGT :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._if_icmpgt(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.IF_ICMPLE :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._if_icmple(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.IF_ACMPEQ :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._if_acmpeq(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.IF_ACMPNE :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._if_acmpne(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.GOTO :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._goto(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.JSR :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._jsr(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.RET :
index = u1At(this.classFileBytes, 1, pc);
visitor._ret(pc - this.codeOffset, index);
pc+=2;
break;
case IOpcodeMnemonics.TABLESWITCH :
int startpc = pc;
pc++;
while (((pc - this.codeOffset) & 0x03) != 0) { // faster than % 4
pc++;
}
int defaultOffset = i4At(this.classFileBytes, 0, pc);
pc += 4;
int low = i4At(this.classFileBytes, 0, pc);
pc += 4;
int high = i4At(this.classFileBytes, 0, pc);
pc += 4;
int length = high - low + 1;
int[] jumpOffsets = new int[length];
for (int i = 0; i < length; i++) {
jumpOffsets[i] = i4At(this.classFileBytes, 0, pc);
pc += 4;
}
visitor._tableswitch(startpc - this.codeOffset, defaultOffset, low, high, jumpOffsets);
break;
case IOpcodeMnemonics.LOOKUPSWITCH :
startpc = pc;
pc++;
while (((pc - this.codeOffset) & 0x03) != 0) {
pc++;
}
defaultOffset = i4At(this.classFileBytes, 0, pc);
pc += 4;
int npairs = (int) u4At(this.classFileBytes, 0, pc);
int[][] offset_pairs = new int[npairs][2];
pc += 4;
for (int i = 0; i < npairs; i++) {
offset_pairs[i][0] = i4At(this.classFileBytes, 0, pc);
pc += 4;
offset_pairs[i][1] = i4At(this.classFileBytes, 0, pc);
pc += 4;
}
visitor._lookupswitch(startpc - this.codeOffset, defaultOffset, npairs, offset_pairs);
break;
case IOpcodeMnemonics.IRETURN :
visitor._ireturn(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.LRETURN :
visitor._lreturn(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.FRETURN :
visitor._freturn(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.DRETURN :
visitor._dreturn(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ARETURN :
visitor._areturn(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.RETURN :
visitor._return(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.GETSTATIC :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Fieldref) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
visitor._getstatic(pc - this.codeOffset, index, constantPoolEntry);
pc+=3;
break;
case IOpcodeMnemonics.PUTSTATIC :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Fieldref) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
visitor._putstatic(pc - this.codeOffset, index, constantPoolEntry);
pc+=3;
break;
case IOpcodeMnemonics.GETFIELD :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Fieldref) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
visitor._getfield(pc - this.codeOffset, index, constantPoolEntry);
pc+=3;
break;
case IOpcodeMnemonics.PUTFIELD :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Fieldref) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
visitor._putfield(pc - this.codeOffset, index, constantPoolEntry);
pc+=3;
break;
case IOpcodeMnemonics.INVOKEVIRTUAL :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Methodref) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
visitor._invokevirtual(pc - this.codeOffset, index, constantPoolEntry);
pc+=3;
break;
case IOpcodeMnemonics.INVOKESPECIAL :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Methodref) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
visitor._invokespecial(pc - this.codeOffset, index, constantPoolEntry);
pc+=3;
break;
case IOpcodeMnemonics.INVOKESTATIC :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Methodref) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
visitor._invokestatic(pc - this.codeOffset, index, constantPoolEntry);
pc+=3;
break;
case IOpcodeMnemonics.INVOKEINTERFACE :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_InterfaceMethodref) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
byte count = (byte) u1At(this.classFileBytes, 3, pc);
int extraArgs = u1At(this.classFileBytes, 4, pc);
if (extraArgs != 0) {
throw new ClassFormatException(ClassFormatException.INVALID_ARGUMENTS_FOR_INVOKEINTERFACE);
}
visitor._invokeinterface(pc - this.codeOffset, index, count, constantPoolEntry);
pc += 5;
break;
case IOpcodeMnemonics.INVOKEDYNAMIC :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_NameAndType) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
visitor._invokedynamic(
pc - this.codeOffset,
index,
this.constantPool.decodeEntry(constantPoolEntry.getNameAndTypeInfoNameIndex()),
this.constantPool.decodeEntry(constantPoolEntry.getNameAndTypeInfoDescriptorIndex()));
pc += 5;
break;
case IOpcodeMnemonics.NEW :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
visitor._new(pc - this.codeOffset, index, constantPoolEntry);
pc+=3;
break;
case IOpcodeMnemonics.NEWARRAY :
int atype = u1At(this.classFileBytes, 1, pc);
visitor._newarray(pc - this.codeOffset, atype);
pc+=2;
break;
case IOpcodeMnemonics.ANEWARRAY :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
visitor._anewarray(pc - this.codeOffset, index, constantPoolEntry);
pc+=3;
break;
case IOpcodeMnemonics.ARRAYLENGTH :
visitor._arraylength(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.ATHROW :
visitor._athrow(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.CHECKCAST :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
visitor._checkcast(pc - this.codeOffset, index, constantPoolEntry);
pc+=3;
break;
case IOpcodeMnemonics.INSTANCEOF :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
visitor._instanceof(pc - this.codeOffset, index, constantPoolEntry);
pc+=3;
break;
case IOpcodeMnemonics.MONITORENTER :
visitor._monitorenter(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.MONITOREXIT :
visitor._monitorexit(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.WIDE :
opcode = u1At(this.classFileBytes, 1, pc);
if (opcode == IOpcodeMnemonics.IINC) {
index = u2At(this.classFileBytes, 2, pc);
_const = i2At(this.classFileBytes, 4, pc);
visitor._wide(pc - this.codeOffset, opcode, index, _const);
pc += 6;
} else {
index = u2At(this.classFileBytes, 2, pc);
visitor._wide(pc - this.codeOffset , opcode, index);
pc += 4;
}
break;
case IOpcodeMnemonics.MULTIANEWARRAY :
index = u2At(this.classFileBytes, 1, pc);
constantPoolEntry = this.constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
int dimensions = u1At(this.classFileBytes, 3, pc);
visitor._multianewarray(pc - this.codeOffset, index, dimensions, constantPoolEntry);
pc+=4;
break;
case IOpcodeMnemonics.IFNULL :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._ifnull(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.IFNONNULL :
branchOffset = i2At(this.classFileBytes, 1, pc);
visitor._ifnonnull(pc - this.codeOffset , branchOffset);
pc+=3;
break;
case IOpcodeMnemonics.GOTO_W :
branchOffset = i4At(this.classFileBytes, 1, pc);
visitor._goto_w(pc - this.codeOffset, branchOffset);
pc+=5;
break;
case IOpcodeMnemonics.JSR_W :
branchOffset = i4At(this.classFileBytes, 1, pc);
visitor._jsr_w(pc - this.codeOffset, branchOffset);
pc+=5;
break;
case IOpcodeMnemonics.BREAKPOINT :
visitor._breakpoint(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.IMPDEP1 :
visitor._impdep1(pc - this.codeOffset);
pc++;
break;
case IOpcodeMnemonics.IMPDEP2 :
visitor._impdep2(pc - this.codeOffset);
pc++;
break;
default:
throw new ClassFormatException(ClassFormatException.INVALID_BYTECODE);
}
if (pc >= (this.codeLength + this.codeOffset)) {
break;
}
}
}
}