}
if (hasStackDepthMarkers && stackDepthMarker.pc == currentPC) {
TypeBinding typeBinding = stackDepthMarker.typeBinding;
if (typeBinding != null) {
if (stackDepthMarker.delta > 0) {
frame.addStackItem(new VerificationTypeInfo(typeBinding));
} else {
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(typeBinding);
}
} else {
frame.numberOfStackItems--;
}
indexInStackDepthMarkers++;
if (indexInStackDepthMarkers < stackDepthMarkersLength) {
stackDepthMarker = stackDepthMarkers[indexInStackDepthMarkers];
} else {
hasStackDepthMarkers = false;
}
}
if (hasExceptionMarkers && exceptionMarker.pc == currentPC) {
frame.numberOfStackItems = 0;
frame.addStackItem(new VerificationTypeInfo(0, VerificationTypeInfo.ITEM_OBJECT, exceptionMarker.constantPoolName));
indexInExceptionMarkers++;
if (indexInExceptionMarkers < exceptionsMarkersLength) {
exceptionMarker = exceptionMarkers[indexInExceptionMarkers];
} else {
hasExceptionMarkers = false;
}
}
if (currentFramePosition < currentPC) {
do {
indexInFramePositions++;
if (indexInFramePositions < framePositionsLength) {
currentFramePosition = framePositions[indexInFramePositions];
} else {
// no more frame to generate
return;
}
} while (currentFramePosition < currentPC);
}
if (currentFramePosition == currentPC) {
// need to build a new frame and create a stack map attribute entry
StackMapFrame currentFrame = frame.duplicate();
currentFrame.pc = currentPC;
// initialize locals
initializeLocals(isClinit ? true : methodBinding.isStatic(), currentPC, currentFrame);
// insert a new frame
frames.add(currentFrame);
indexInFramePositions++;
if (indexInFramePositions < framePositionsLength) {
currentFramePosition = framePositions[indexInFramePositions];
} else {
// no more frame to generate
return;
}
}
byte opcode = (byte) u1At(bytecodes, 0, pc);
switch (opcode) {
case Opcodes.OPC_nop:
pc++;
break;
case Opcodes.OPC_aconst_null:
frame.addStackItem(TypeBinding.NULL);
pc++;
break;
case Opcodes.OPC_iconst_m1:
case Opcodes.OPC_iconst_0:
case Opcodes.OPC_iconst_1:
case Opcodes.OPC_iconst_2:
case Opcodes.OPC_iconst_3:
case Opcodes.OPC_iconst_4:
case Opcodes.OPC_iconst_5:
frame.addStackItem(TypeBinding.INT);
pc++;
break;
case Opcodes.OPC_lconst_0:
case Opcodes.OPC_lconst_1:
frame.addStackItem(TypeBinding.LONG);
pc++;
break;
case Opcodes.OPC_fconst_0:
case Opcodes.OPC_fconst_1:
case Opcodes.OPC_fconst_2:
frame.addStackItem(TypeBinding.FLOAT);
pc++;
break;
case Opcodes.OPC_dconst_0:
case Opcodes.OPC_dconst_1:
frame.addStackItem(TypeBinding.DOUBLE);
pc++;
break;
case Opcodes.OPC_bipush:
frame.addStackItem(TypeBinding.BYTE);
pc += 2;
break;
case Opcodes.OPC_sipush:
frame.addStackItem(TypeBinding.SHORT);
pc += 3;
break;
case Opcodes.OPC_ldc:
index = u1At(bytecodes, 1, pc);
switch (u1At(poolContents, 0, constantPoolOffsets[index])) {
case ClassFileConstants.StringTag:
frame
.addStackItem(new VerificationTypeInfo(
TypeIds.T_JavaLangString,
ConstantPool.JavaLangStringConstantPoolName));
break;
case ClassFileConstants.IntegerTag:
frame.addStackItem(TypeBinding.INT);
break;
case ClassFileConstants.FloatTag:
frame.addStackItem(TypeBinding.FLOAT);
break;
case ClassFileConstants.ClassTag:
frame.addStackItem(new VerificationTypeInfo(
TypeIds.T_JavaLangClass,
ConstantPool.JavaLangClassConstantPoolName));
}
pc += 2;
break;
case Opcodes.OPC_ldc_w:
index = u2At(bytecodes, 1, pc);
switch (u1At(poolContents, 0, constantPoolOffsets[index])) {
case ClassFileConstants.StringTag:
frame
.addStackItem(new VerificationTypeInfo(
TypeIds.T_JavaLangString,
ConstantPool.JavaLangStringConstantPoolName));
break;
case ClassFileConstants.IntegerTag:
frame.addStackItem(TypeBinding.INT);
break;
case ClassFileConstants.FloatTag:
frame.addStackItem(TypeBinding.FLOAT);
break;
case ClassFileConstants.ClassTag:
frame.addStackItem(new VerificationTypeInfo(
TypeIds.T_JavaLangClass,
ConstantPool.JavaLangClassConstantPoolName));
}
pc += 3;
break;
case Opcodes.OPC_ldc2_w:
index = u2At(bytecodes, 1, pc);
switch (u1At(poolContents, 0, constantPoolOffsets[index])) {
case ClassFileConstants.DoubleTag:
frame.addStackItem(TypeBinding.DOUBLE);
break;
case ClassFileConstants.LongTag:
frame.addStackItem(TypeBinding.LONG);
break;
}
pc += 3;
break;
case Opcodes.OPC_iload:
frame.addStackItem(TypeBinding.INT);
pc += 2;
break;
case Opcodes.OPC_lload:
frame.addStackItem(TypeBinding.LONG);
pc += 2;
break;
case Opcodes.OPC_fload:
frame.addStackItem(TypeBinding.FLOAT);
pc += 2;
break;
case Opcodes.OPC_dload:
frame.addStackItem(TypeBinding.DOUBLE);
pc += 2;
break;
case Opcodes.OPC_aload:
index = u1At(bytecodes, 1, pc);
VerificationTypeInfo localsN = retrieveLocal(currentPC, index);
frame.addStackItem(localsN);
pc += 2;
break;
case Opcodes.OPC_iload_0:
case Opcodes.OPC_iload_1:
case Opcodes.OPC_iload_2:
case Opcodes.OPC_iload_3:
frame.addStackItem(TypeBinding.INT);
pc++;
break;
case Opcodes.OPC_lload_0:
case Opcodes.OPC_lload_1:
case Opcodes.OPC_lload_2:
case Opcodes.OPC_lload_3:
frame.addStackItem(TypeBinding.LONG);
pc++;
break;
case Opcodes.OPC_fload_0:
case Opcodes.OPC_fload_1:
case Opcodes.OPC_fload_2:
case Opcodes.OPC_fload_3:
frame.addStackItem(TypeBinding.FLOAT);
pc++;
break;
case Opcodes.OPC_dload_0:
case Opcodes.OPC_dload_1:
case Opcodes.OPC_dload_2:
case Opcodes.OPC_dload_3:
frame.addStackItem(TypeBinding.DOUBLE);
pc++;
break;
case Opcodes.OPC_aload_0:
VerificationTypeInfo locals0 = frame.locals[0];
// special case to handle uninitialized object
if (locals0 == null) {
locals0 = retrieveLocal(currentPC, 0);
}
frame.addStackItem(locals0);
pc++;
break;
case Opcodes.OPC_aload_1:
VerificationTypeInfo locals1 = retrieveLocal(currentPC, 1);
frame.addStackItem(locals1);
pc++;
break;
case Opcodes.OPC_aload_2:
VerificationTypeInfo locals2 = retrieveLocal(currentPC, 2);
frame.addStackItem(locals2);
pc++;
break;
case Opcodes.OPC_aload_3:
VerificationTypeInfo locals3 = retrieveLocal(currentPC, 3);
frame.addStackItem(locals3);
pc++;
break;
case Opcodes.OPC_iaload:
frame.numberOfStackItems -=2;
frame.addStackItem(TypeBinding.INT);
pc++;
break;
case Opcodes.OPC_laload:
frame.numberOfStackItems -=2;
frame.addStackItem(TypeBinding.LONG);
pc++;
break;
case Opcodes.OPC_faload:
frame.numberOfStackItems -=2;
frame.addStackItem(TypeBinding.FLOAT);
pc++;
break;
case Opcodes.OPC_daload:
frame.numberOfStackItems -=2;
frame.addStackItem(TypeBinding.DOUBLE);
pc++;
break;
case Opcodes.OPC_aaload:
frame.numberOfStackItems--;
frame.replaceWithElementType();
pc++;
break;
case Opcodes.OPC_baload:
frame.numberOfStackItems -=2;
frame.addStackItem(TypeBinding.BYTE);
pc++;
break;
case Opcodes.OPC_caload:
frame.numberOfStackItems -=2;
frame.addStackItem(TypeBinding.CHAR);
pc++;
break;
case Opcodes.OPC_saload:
frame.numberOfStackItems -=2;
frame.addStackItem(TypeBinding.SHORT);
pc++;
break;
case Opcodes.OPC_istore:
case Opcodes.OPC_lstore:
case Opcodes.OPC_fstore:
case Opcodes.OPC_dstore:
frame.numberOfStackItems--;
pc += 2;
break;
case Opcodes.OPC_astore:
index = u1At(bytecodes, 1, pc);
frame.numberOfStackItems--;
pc += 2;
break;
case Opcodes.OPC_astore_0:
frame.locals[0] = frame.stackItems[frame.numberOfStackItems - 1];
frame.numberOfStackItems--;
pc++;
break;
case Opcodes.OPC_astore_1:
case Opcodes.OPC_astore_2:
case Opcodes.OPC_astore_3:
case Opcodes.OPC_istore_0:
case Opcodes.OPC_istore_1:
case Opcodes.OPC_istore_2:
case Opcodes.OPC_istore_3:
case Opcodes.OPC_lstore_0:
case Opcodes.OPC_lstore_1:
case Opcodes.OPC_lstore_2:
case Opcodes.OPC_lstore_3:
case Opcodes.OPC_fstore_0:
case Opcodes.OPC_fstore_1:
case Opcodes.OPC_fstore_2:
case Opcodes.OPC_fstore_3:
case Opcodes.OPC_dstore_0:
case Opcodes.OPC_dstore_1:
case Opcodes.OPC_dstore_2:
case Opcodes.OPC_dstore_3:
frame.numberOfStackItems--;
pc++;
break;
case Opcodes.OPC_iastore:
case Opcodes.OPC_lastore:
case Opcodes.OPC_fastore:
case Opcodes.OPC_dastore:
case Opcodes.OPC_aastore:
case Opcodes.OPC_bastore:
case Opcodes.OPC_castore:
case Opcodes.OPC_sastore:
frame.numberOfStackItems-=3;
pc++;
break;
case Opcodes.OPC_pop:
frame.numberOfStackItems--;
pc++;
break;
case Opcodes.OPC_pop2:
int numberOfStackItems = frame.numberOfStackItems;
switch(frame.stackItems[numberOfStackItems - 1].id()) {
case TypeIds.T_long :
case TypeIds.T_double :
frame.numberOfStackItems--;
break;
default:
frame.numberOfStackItems -= 2;
}
pc++;
break;
case Opcodes.OPC_dup:
frame.addStackItem(frame.stackItems[frame.numberOfStackItems - 1]);
pc++;
break;
case Opcodes.OPC_dup_x1:
VerificationTypeInfo info = frame.stackItems[frame.numberOfStackItems - 1];
frame.numberOfStackItems--;
VerificationTypeInfo info2 = frame.stackItems[frame.numberOfStackItems - 1];
frame.numberOfStackItems--;
frame.addStackItem(info);
frame.addStackItem(info2);
frame.addStackItem(info);
pc++;
break;
case Opcodes.OPC_dup_x2:
info = frame.stackItems[frame.numberOfStackItems - 1];
frame.numberOfStackItems--;
info2 = frame.stackItems[frame.numberOfStackItems - 1];
frame.numberOfStackItems--;
switch(info2.id()) {
case TypeIds.T_long :
case TypeIds.T_double :
frame.addStackItem(info);
frame.addStackItem(info2);
frame.addStackItem(info);
break;
default:
numberOfStackItems = frame.numberOfStackItems;
VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1];
frame.numberOfStackItems--;
frame.addStackItem(info);
frame.addStackItem(info3);
frame.addStackItem(info2);
frame.addStackItem(info);
}
pc++;
break;
case Opcodes.OPC_dup2:
info = frame.stackItems[frame.numberOfStackItems - 1];
frame.numberOfStackItems--;
switch(info.id()) {
case TypeIds.T_double :
case TypeIds.T_long :
frame.addStackItem(info);
frame.addStackItem(info);
break;
default:
info2 = frame.stackItems[frame.numberOfStackItems - 1];
frame.numberOfStackItems--;
frame.addStackItem(info2);
frame.addStackItem(info);
frame.addStackItem(info2);
frame.addStackItem(info);
}
pc++;
break;
case Opcodes.OPC_dup2_x1:
info = frame.stackItems[frame.numberOfStackItems - 1];
frame.numberOfStackItems--;
info2 = frame.stackItems[frame.numberOfStackItems - 1];
frame.numberOfStackItems--;
switch(info.id()) {
case TypeIds.T_double :
case TypeIds.T_long :
frame.addStackItem(info);
frame.addStackItem(info2);
frame.addStackItem(info);
break;
default:
VerificationTypeInfo info3 = frame.stackItems[frame.numberOfStackItems - 1];
frame.numberOfStackItems--;
frame.addStackItem(info2);
frame.addStackItem(info);
frame.addStackItem(info3);
frame.addStackItem(info2);
frame.addStackItem(info);
}
pc++;
break;
case Opcodes.OPC_dup2_x2:
numberOfStackItems = frame.numberOfStackItems;
info = frame.stackItems[numberOfStackItems - 1];
frame.numberOfStackItems--;
info2 = frame.stackItems[frame.numberOfStackItems - 1];
frame.numberOfStackItems--;
switch(info.id()) {
case TypeIds.T_long :
case TypeIds.T_double :
switch(info2.id()) {
case TypeIds.T_long :
case TypeIds.T_double :
// form 4
frame.addStackItem(info);
frame.addStackItem(info2);
frame.addStackItem(info);
break;
default:
// form 2
numberOfStackItems = frame.numberOfStackItems;
VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1];
frame.numberOfStackItems--;
frame.addStackItem(info);
frame.addStackItem(info3);
frame.addStackItem(info2);
frame.addStackItem(info);
}
break;
default:
numberOfStackItems = frame.numberOfStackItems;
VerificationTypeInfo info3 = frame.stackItems[numberOfStackItems - 1];
frame.numberOfStackItems--;
switch(info3.id()) {
case TypeIds.T_long :
case TypeIds.T_double :
// form 3
frame.addStackItem(info2);
frame.addStackItem(info);
frame.addStackItem(info3);
frame.addStackItem(info2);
frame.addStackItem(info);
break;
default:
// form 1
numberOfStackItems = frame.numberOfStackItems;
VerificationTypeInfo info4 = frame.stackItems[numberOfStackItems - 1];
frame.numberOfStackItems--;
frame.addStackItem(info2);
frame.addStackItem(info);
frame.addStackItem(info4);
frame.addStackItem(info3);
frame.addStackItem(info2);
frame.addStackItem(info);
}
}
pc++;
break;
case Opcodes.OPC_swap:
numberOfStackItems = frame.numberOfStackItems;
info = frame.stackItems[numberOfStackItems - 1];
info2 = frame.stackItems[numberOfStackItems - 2];
frame.stackItems[numberOfStackItems - 1] = info2;
frame.stackItems[numberOfStackItems - 2] = info;
pc++;
break;
case Opcodes.OPC_iadd:
case Opcodes.OPC_ladd:
case Opcodes.OPC_fadd:
case Opcodes.OPC_dadd:
case Opcodes.OPC_isub:
case Opcodes.OPC_lsub:
case Opcodes.OPC_fsub:
case Opcodes.OPC_dsub:
case Opcodes.OPC_imul:
case Opcodes.OPC_lmul:
case Opcodes.OPC_fmul:
case Opcodes.OPC_dmul:
case Opcodes.OPC_idiv:
case Opcodes.OPC_ldiv:
case Opcodes.OPC_fdiv:
case Opcodes.OPC_ddiv:
case Opcodes.OPC_irem:
case Opcodes.OPC_lrem:
case Opcodes.OPC_frem:
case Opcodes.OPC_drem:
case Opcodes.OPC_ishl:
case Opcodes.OPC_lshl:
case Opcodes.OPC_ishr:
case Opcodes.OPC_lshr:
case Opcodes.OPC_iushr:
case Opcodes.OPC_lushr:
case Opcodes.OPC_iand:
case Opcodes.OPC_land:
case Opcodes.OPC_ior:
case Opcodes.OPC_lor:
case Opcodes.OPC_ixor:
case Opcodes.OPC_lxor:
frame.numberOfStackItems--;
pc++;
break;
case Opcodes.OPC_ineg:
case Opcodes.OPC_lneg:
case Opcodes.OPC_fneg:
case Opcodes.OPC_dneg:
pc++;
break;
case Opcodes.OPC_iinc:
pc += 3;
break;
case Opcodes.OPC_i2l:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG);
pc++;
break;
case Opcodes.OPC_i2f:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT);
pc++;
break;
case Opcodes.OPC_i2d:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE);
pc++;
break;
case Opcodes.OPC_l2i:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
pc++;
break;
case Opcodes.OPC_l2f:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT);
pc++;
break;
case Opcodes.OPC_l2d:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE);
pc++;
break;
case Opcodes.OPC_f2i:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
pc++;
break;
case Opcodes.OPC_f2l:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG);
pc++;
break;
case Opcodes.OPC_f2d:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE);
pc++;
break;
case Opcodes.OPC_d2i:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
pc++;
break;
case Opcodes.OPC_d2l:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG);
pc++;
break;
case Opcodes.OPC_d2f:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT);
pc++;
break;
case Opcodes.OPC_i2b:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.BYTE);
pc++;
break;
case Opcodes.OPC_i2c:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.CHAR);
pc++;
break;
case Opcodes.OPC_i2s:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.SHORT);
pc++;
break;
case Opcodes.OPC_lcmp:
case Opcodes.OPC_fcmpl:
case Opcodes.OPC_fcmpg:
case Opcodes.OPC_dcmpl:
case Opcodes.OPC_dcmpg:
frame.numberOfStackItems-=2;
frame.addStackItem(TypeBinding.INT);
pc++;
break;
case Opcodes.OPC_ifeq:
case Opcodes.OPC_ifne:
case Opcodes.OPC_iflt:
case Opcodes.OPC_ifge:
case Opcodes.OPC_ifgt:
case Opcodes.OPC_ifle:
frame.numberOfStackItems--;
pc += 3;
break;
case Opcodes.OPC_if_icmpeq:
case Opcodes.OPC_if_icmpne:
case Opcodes.OPC_if_icmplt:
case Opcodes.OPC_if_icmpge:
case Opcodes.OPC_if_icmpgt:
case Opcodes.OPC_if_icmple:
case Opcodes.OPC_if_acmpeq:
case Opcodes.OPC_if_acmpne:
frame.numberOfStackItems -= 2;
pc += 3;
break;
case Opcodes.OPC_goto:
pc += 3;
break;
case Opcodes.OPC_tableswitch:
pc++;
while (((pc - codeOffset) & 0x03) != 0) {
pc++;
}
pc += 4; // default
int low = i4At(bytecodes, 0, pc);
pc += 4;
int high = i4At(bytecodes, 0, pc);
pc += 4;
int length = high - low + 1;
pc += (length * 4);
frame.numberOfStackItems--;
break;
case Opcodes.OPC_lookupswitch:
pc++;
while (((pc - codeOffset) & 0x03) != 0) {
pc++;
}
pc += 4; // default
int npairs = (int) u4At(bytecodes, 0, pc);
pc += (4 + npairs * 8);
frame.numberOfStackItems--;
break;
case Opcodes.OPC_ireturn:
case Opcodes.OPC_lreturn:
case Opcodes.OPC_freturn:
case Opcodes.OPC_dreturn:
case Opcodes.OPC_areturn:
frame.numberOfStackItems--;
pc++;
break;
case Opcodes.OPC_return:
pc++;
break;
case Opcodes.OPC_getstatic:
index = u2At(bytecodes, 1, pc);
int nameAndTypeIndex = u2At(poolContents, 3,
constantPoolOffsets[index]);
int utf8index = u2At(poolContents, 3,
constantPoolOffsets[nameAndTypeIndex]);
char[] descriptor = utf8At(poolContents,
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
if (descriptor.length == 1) {
// base type
switch(descriptor[0]) {
case 'Z':
frame.addStackItem(TypeBinding.BOOLEAN);
break;
case 'B':
frame.addStackItem(TypeBinding.BYTE);
break;
case 'C':
frame.addStackItem(TypeBinding.CHAR);
break;
case 'D':
frame.addStackItem(TypeBinding.DOUBLE);
break;
case 'F':
frame.addStackItem(TypeBinding.FLOAT);
break;
case 'I':
frame.addStackItem(TypeBinding.INT);
break;
case 'J':
frame.addStackItem(TypeBinding.LONG);
break;
case 'S':
frame.addStackItem(TypeBinding.SHORT);
break;
}
} else if (descriptor[0] == '[') {
frame.addStackItem(new VerificationTypeInfo(0, descriptor));
} else {
frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(descriptor, 1, descriptor.length - 1)));
}
pc += 3;
break;
case Opcodes.OPC_putstatic:
frame.numberOfStackItems--;
pc += 3;
break;
case Opcodes.OPC_getfield:
index = u2At(bytecodes, 1, pc);
nameAndTypeIndex = u2At(poolContents, 3,
constantPoolOffsets[index]);
utf8index = u2At(poolContents, 3,
constantPoolOffsets[nameAndTypeIndex]);
descriptor = utf8At(poolContents,
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
frame.numberOfStackItems--;
if (descriptor.length == 1) {
// base type
switch(descriptor[0]) {
case 'Z':
frame.addStackItem(TypeBinding.BOOLEAN);
break;
case 'B':
frame.addStackItem(TypeBinding.BYTE);
break;
case 'C':
frame.addStackItem(TypeBinding.CHAR);
break;
case 'D':
frame.addStackItem(TypeBinding.DOUBLE);
break;
case 'F':
frame.addStackItem(TypeBinding.FLOAT);
break;
case 'I':
frame.addStackItem(TypeBinding.INT);
break;
case 'J':
frame.addStackItem(TypeBinding.LONG);
break;
case 'S':
frame.addStackItem(TypeBinding.SHORT);
break;
}
} else if (descriptor[0] == '[') {
frame.addStackItem(new VerificationTypeInfo(0, descriptor));
} else {
frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(descriptor, 1, descriptor.length - 1)));
}
pc += 3;
break;
case Opcodes.OPC_putfield:
frame.numberOfStackItems -= 2;
pc += 3;
break;
case Opcodes.OPC_invokevirtual:
index = u2At(bytecodes, 1, pc);
nameAndTypeIndex = u2At(poolContents, 3,
constantPoolOffsets[index]);
utf8index = u2At(poolContents, 3,
constantPoolOffsets[nameAndTypeIndex]);
descriptor = utf8At(poolContents,
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
utf8index = u2At(poolContents, 1,
constantPoolOffsets[nameAndTypeIndex]);
char[] name = utf8At(poolContents,
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
frame.numberOfStackItems -= (getParametersCount(descriptor) + 1);
char[] returnType = getReturnType(descriptor);
if (returnType.length == 1) {
// base type
switch(returnType[0]) {
case 'Z':
frame.addStackItem(TypeBinding.BOOLEAN);
break;
case 'B':
frame.addStackItem(TypeBinding.BYTE);
break;
case 'C':
frame.addStackItem(TypeBinding.CHAR);
break;
case 'D':
frame.addStackItem(TypeBinding.DOUBLE);
break;
case 'F':
frame.addStackItem(TypeBinding.FLOAT);
break;
case 'I':
frame.addStackItem(TypeBinding.INT);
break;
case 'J':
frame.addStackItem(TypeBinding.LONG);
break;
case 'S':
frame.addStackItem(TypeBinding.SHORT);
break;
}
} else {
if (returnType[0] == '[') {
frame.addStackItem(new VerificationTypeInfo(0, returnType));
} else {
frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
}
}
pc += 3;
break;
case Opcodes.OPC_invokespecial:
index = u2At(bytecodes, 1, pc);
nameAndTypeIndex = u2At(poolContents, 3,
constantPoolOffsets[index]);
utf8index = u2At(poolContents, 3,
constantPoolOffsets[nameAndTypeIndex]);
descriptor = utf8At(poolContents,
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
utf8index = u2At(poolContents, 1,
constantPoolOffsets[nameAndTypeIndex]);
name = utf8At(poolContents,
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
frame.numberOfStackItems -= getParametersCount(descriptor);
if (CharOperation.equals(ConstantPool.Init, name)) {
// constructor
frame.stackItems[frame.numberOfStackItems - 1].tag = VerificationTypeInfo.ITEM_OBJECT;
}
frame.numberOfStackItems--;
returnType = getReturnType(descriptor);
if (returnType.length == 1) {
// base type
switch(returnType[0]) {
case 'Z':
frame.addStackItem(TypeBinding.BOOLEAN);
break;
case 'B':
frame.addStackItem(TypeBinding.BYTE);
break;
case 'C':
frame.addStackItem(TypeBinding.CHAR);
break;
case 'D':
frame.addStackItem(TypeBinding.DOUBLE);
break;
case 'F':
frame.addStackItem(TypeBinding.FLOAT);
break;
case 'I':
frame.addStackItem(TypeBinding.INT);
break;
case 'J':
frame.addStackItem(TypeBinding.LONG);
break;
case 'S':
frame.addStackItem(TypeBinding.SHORT);
break;
}
} else {
if (returnType[0] == '[') {
frame.addStackItem(new VerificationTypeInfo(0, returnType));
} else {
frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
}
}
pc += 3;
break;
case Opcodes.OPC_invokestatic:
index = u2At(bytecodes, 1, pc);
nameAndTypeIndex = u2At(poolContents, 3,
constantPoolOffsets[index]);
utf8index = u2At(poolContents, 3,
constantPoolOffsets[nameAndTypeIndex]);
descriptor = utf8At(poolContents,
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
utf8index = u2At(poolContents, 1,
constantPoolOffsets[nameAndTypeIndex]);
name = utf8At(poolContents,
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
frame.numberOfStackItems -= getParametersCount(descriptor);
returnType = getReturnType(descriptor);
if (returnType.length == 1) {
// base type
switch(returnType[0]) {
case 'Z':
frame.addStackItem(TypeBinding.BOOLEAN);
break;
case 'B':
frame.addStackItem(TypeBinding.BYTE);
break;
case 'C':
frame.addStackItem(TypeBinding.CHAR);
break;
case 'D':
frame.addStackItem(TypeBinding.DOUBLE);
break;
case 'F':
frame.addStackItem(TypeBinding.FLOAT);
break;
case 'I':
frame.addStackItem(TypeBinding.INT);
break;
case 'J':
frame.addStackItem(TypeBinding.LONG);
break;
case 'S':
frame.addStackItem(TypeBinding.SHORT);
break;
}
} else {
if (returnType[0] == '[') {
frame.addStackItem(new VerificationTypeInfo(0, returnType));
} else {
frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
}
}
pc += 3;
break;
case Opcodes.OPC_invokeinterface:
index = u2At(bytecodes, 1, pc);
nameAndTypeIndex = u2At(poolContents, 3,
constantPoolOffsets[index]);
utf8index = u2At(poolContents, 3,
constantPoolOffsets[nameAndTypeIndex]);
descriptor = utf8At(poolContents,
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
utf8index = u2At(poolContents, 1,
constantPoolOffsets[nameAndTypeIndex]);
name = utf8At(poolContents,
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
// we don't need count and args
// u1At(bytecodes, 3, pc); // count
// u1At(bytecodes, 4, pc); // extra args
frame.numberOfStackItems -= (getParametersCount(descriptor) + 1);
returnType = getReturnType(descriptor);
if (returnType.length == 1) {
// base type
switch(returnType[0]) {
case 'Z':
frame.addStackItem(TypeBinding.BOOLEAN);
break;
case 'B':
frame.addStackItem(TypeBinding.BYTE);
break;
case 'C':
frame.addStackItem(TypeBinding.CHAR);
break;
case 'D':
frame.addStackItem(TypeBinding.DOUBLE);
break;
case 'F':
frame.addStackItem(TypeBinding.FLOAT);
break;
case 'I':
frame.addStackItem(TypeBinding.INT);
break;
case 'J':
frame.addStackItem(TypeBinding.LONG);
break;
case 'S':
frame.addStackItem(TypeBinding.SHORT);
break;
}
} else {
if (returnType[0] == '[') {
frame.addStackItem(new VerificationTypeInfo(0, returnType));
} else {
frame.addStackItem(new VerificationTypeInfo(0, CharOperation.subarray(returnType, 1, returnType.length - 1)));
}
}
pc += 5;
break;
case Opcodes.OPC_new:
index = u2At(bytecodes, 1, pc);
utf8index = u2At(poolContents, 1,
constantPoolOffsets[index]);
char[] className = utf8At(poolContents,
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo(0, VerificationTypeInfo.ITEM_UNINITIALIZED, className);
verificationTypeInfo.offset = currentPC;
frame.addStackItem(verificationTypeInfo);
pc += 3;
break;
case Opcodes.OPC_newarray:
char[] constantPoolName = null;
switch (u1At(bytecodes, 1, pc)) {
case ClassFileConstants.INT_ARRAY :
constantPoolName = new char[] { '[', 'I' };
break;
case ClassFileConstants.BYTE_ARRAY :
constantPoolName = new char[] { '[', 'B' };
break;
case ClassFileConstants.BOOLEAN_ARRAY :
constantPoolName = new char[] { '[', 'Z' };
break;
case ClassFileConstants.SHORT_ARRAY :
constantPoolName = new char[] { '[', 'S' };
break;
case ClassFileConstants.CHAR_ARRAY :
constantPoolName = new char[] { '[', 'C' };
break;
case ClassFileConstants.LONG_ARRAY :
constantPoolName = new char[] { '[', 'J' };
break;
case ClassFileConstants.FLOAT_ARRAY :
constantPoolName = new char[] { '[', 'F' };
break;
case ClassFileConstants.DOUBLE_ARRAY :
constantPoolName = new char[] { '[', 'D' };
break;
}
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangObject, constantPoolName);
pc += 2;
break;
case Opcodes.OPC_anewarray:
index = u2At(bytecodes, 1, pc);
utf8index = u2At(poolContents, 1,
constantPoolOffsets[index]);
className = utf8At(poolContents,
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
int classNameLength = className.length;
if (className[0] != '[') {
// this is a type name (class or interface). So we add appropriate '[', 'L' and ';'.
System.arraycopy(className, 0, (constantPoolName = new char[classNameLength + 3]), 2, classNameLength);
constantPoolName[0] = '[';
constantPoolName[1] = 'L';
constantPoolName[classNameLength + 2] = ';';
} else {
// if class name is already an array, we just need to add one dimension
System.arraycopy(className, 0, (constantPoolName = new char[classNameLength + 1]), 1, classNameLength);
constantPoolName[0] = '[';
}
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(0, constantPoolName);
pc += 3;
break;
case Opcodes.OPC_arraylength:
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
pc++;
break;
case Opcodes.OPC_athrow:
frame.numberOfStackItems--;
pc++;
break;
case Opcodes.OPC_checkcast:
index = u2At(bytecodes, 1, pc);
utf8index = u2At(poolContents, 1,
constantPoolOffsets[index]);
className = utf8At(poolContents,
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(0, className);
pc += 3;
break;
case Opcodes.OPC_instanceof:
// no need to know the class index = u2At(bytecodes, 1, pc);
frame.stackItems[frame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
pc += 3;
break;
case Opcodes.OPC_monitorenter:
case Opcodes.OPC_monitorexit:
frame.numberOfStackItems--;
pc++;
break;
case Opcodes.OPC_wide:
opcode = (byte) u1At(bytecodes, 1, pc);
if (opcode == Opcodes.OPC_iinc) {
// index = u2At(bytecodes, 2, pc);
// i2At(bytecodes, 4, pc); // const
// we don't need the index and the const value
pc += 6;
} else {
index = u2At(bytecodes, 2, pc);
// need to handle iload, fload, aload, lload, dload, istore, fstore, astore, lstore or dstore
switch(opcode) {
case Opcodes.OPC_iload :
frame.addStackItem(TypeBinding.INT);
break;
case Opcodes.OPC_fload :
frame.addStackItem(TypeBinding.FLOAT);
break;
case Opcodes.OPC_aload :
localsN = frame.locals[index];
if (localsN == null) {
localsN = retrieveLocal(currentPC, index);
}
frame.addStackItem(localsN);
break;
case Opcodes.OPC_lload :
frame.addStackItem(TypeBinding.LONG);
break;
case Opcodes.OPC_dload :
frame.addStackItem(TypeBinding.DOUBLE);
break;
case Opcodes.OPC_istore :
frame.numberOfStackItems--;
break;
case Opcodes.OPC_fstore :
frame.numberOfStackItems--;
break;
case Opcodes.OPC_astore :
frame.locals[index] = frame.stackItems[frame.numberOfStackItems - 1];
frame.numberOfStackItems--;
break;
case Opcodes.OPC_lstore :
frame.numberOfStackItems--;
break;
case Opcodes.OPC_dstore :
frame.numberOfStackItems--;
break;
}
pc += 4;
}
break;
case Opcodes.OPC_multianewarray:
index = u2At(bytecodes, 1, pc);
utf8index = u2At(poolContents, 1,
constantPoolOffsets[index]);
className = utf8At(poolContents,
constantPoolOffsets[utf8index] + 3, u2At(
poolContents, 1,
constantPoolOffsets[utf8index]));
int dimensions = u1At(bytecodes, 3, pc); // dimensions
frame.numberOfStackItems -= dimensions;
classNameLength = className.length;
constantPoolName = new char[classNameLength + dimensions];
for (int i = 0; i < dimensions; i++) {
constantPoolName[i] = '[';
}
System.arraycopy(className, 0, constantPoolName, dimensions, classNameLength);
frame.addStackItem(new VerificationTypeInfo(0, constantPoolName));
pc += 4;
break;
case Opcodes.OPC_ifnull:
case Opcodes.OPC_ifnonnull:
frame.numberOfStackItems--;