in rhino/src/main/java/org/mozilla/classfile/ClassFileWriter.java [1837:2277]
private int execute(int bci) {
int bc = itsCodeBuffer[bci] & 0xFF;
int type, type2, index;
int length = 0;
long lType, lType2;
String className;
switch (bc) {
case ByteCode.NOP:
case ByteCode.IINC:
case ByteCode.GOTO:
case ByteCode.GOTO_W:
// No change
break;
case ByteCode.CHECKCAST:
pop();
push(TypeInfo.OBJECT(getOperand(bci + 1, 2)));
break;
case ByteCode.IASTORE: // pop; pop; pop
case ByteCode.LASTORE:
case ByteCode.FASTORE:
case ByteCode.DASTORE:
case ByteCode.AASTORE:
case ByteCode.BASTORE:
case ByteCode.CASTORE:
case ByteCode.SASTORE:
pop();
// fall through
case ByteCode.PUTFIELD: // pop; pop
case ByteCode.IF_ICMPEQ:
case ByteCode.IF_ICMPNE:
case ByteCode.IF_ICMPLT:
case ByteCode.IF_ICMPGE:
case ByteCode.IF_ICMPGT:
case ByteCode.IF_ICMPLE:
case ByteCode.IF_ACMPEQ:
case ByteCode.IF_ACMPNE:
pop();
// fall through
case ByteCode.IFEQ: // pop
case ByteCode.IFNE:
case ByteCode.IFLT:
case ByteCode.IFGE:
case ByteCode.IFGT:
case ByteCode.IFLE:
case ByteCode.IFNULL:
case ByteCode.IFNONNULL:
case ByteCode.POP:
case ByteCode.MONITORENTER:
case ByteCode.MONITOREXIT:
case ByteCode.PUTSTATIC:
pop();
break;
case ByteCode.POP2:
pop2();
break;
case ByteCode.ACONST_NULL:
push(TypeInfo.NULL);
break;
case ByteCode.IALOAD: // pop; pop; push(INTEGER)
case ByteCode.BALOAD:
case ByteCode.CALOAD:
case ByteCode.SALOAD:
case ByteCode.IADD:
case ByteCode.ISUB:
case ByteCode.IMUL:
case ByteCode.IDIV:
case ByteCode.IREM:
case ByteCode.ISHL:
case ByteCode.ISHR:
case ByteCode.IUSHR:
case ByteCode.IAND:
case ByteCode.IOR:
case ByteCode.IXOR:
case ByteCode.LCMP:
case ByteCode.FCMPL:
case ByteCode.FCMPG:
case ByteCode.DCMPL:
case ByteCode.DCMPG:
pop();
// fall through
case ByteCode.INEG: // pop; push(INTEGER)
case ByteCode.L2I:
case ByteCode.F2I:
case ByteCode.D2I:
case ByteCode.I2B:
case ByteCode.I2C:
case ByteCode.I2S:
case ByteCode.ARRAYLENGTH:
case ByteCode.INSTANCEOF:
pop();
// fall through
case ByteCode.ICONST_M1: // push(INTEGER)
case ByteCode.ICONST_0:
case ByteCode.ICONST_1:
case ByteCode.ICONST_2:
case ByteCode.ICONST_3:
case ByteCode.ICONST_4:
case ByteCode.ICONST_5:
case ByteCode.ILOAD:
case ByteCode.ILOAD_0:
case ByteCode.ILOAD_1:
case ByteCode.ILOAD_2:
case ByteCode.ILOAD_3:
case ByteCode.BIPUSH:
case ByteCode.SIPUSH:
push(TypeInfo.INTEGER);
break;
case ByteCode.LALOAD: // pop; pop; push(LONG)
case ByteCode.LADD:
case ByteCode.LSUB:
case ByteCode.LMUL:
case ByteCode.LDIV:
case ByteCode.LREM:
case ByteCode.LSHL:
case ByteCode.LSHR:
case ByteCode.LUSHR:
case ByteCode.LAND:
case ByteCode.LOR:
case ByteCode.LXOR:
pop();
// fall through
case ByteCode.LNEG: // pop; push(LONG)
case ByteCode.I2L:
case ByteCode.F2L:
case ByteCode.D2L:
pop();
// fall through
case ByteCode.LCONST_0: // push(LONG)
case ByteCode.LCONST_1:
case ByteCode.LLOAD:
case ByteCode.LLOAD_0:
case ByteCode.LLOAD_1:
case ByteCode.LLOAD_2:
case ByteCode.LLOAD_3:
push(TypeInfo.LONG);
break;
case ByteCode.FALOAD: // pop; pop; push(FLOAT)
case ByteCode.FADD:
case ByteCode.FSUB:
case ByteCode.FMUL:
case ByteCode.FDIV:
case ByteCode.FREM:
pop();
// fall through
case ByteCode.FNEG: // pop; push(FLOAT)
case ByteCode.I2F:
case ByteCode.L2F:
case ByteCode.D2F:
pop();
// fall through
case ByteCode.FCONST_0: // push(FLOAT)
case ByteCode.FCONST_1:
case ByteCode.FCONST_2:
case ByteCode.FLOAD:
case ByteCode.FLOAD_0:
case ByteCode.FLOAD_1:
case ByteCode.FLOAD_2:
case ByteCode.FLOAD_3:
push(TypeInfo.FLOAT);
break;
case ByteCode.DALOAD: // pop; pop; push(DOUBLE)
case ByteCode.DADD:
case ByteCode.DSUB:
case ByteCode.DMUL:
case ByteCode.DDIV:
case ByteCode.DREM:
pop();
// fall through
case ByteCode.DNEG: // pop; push(DOUBLE)
case ByteCode.I2D:
case ByteCode.L2D:
case ByteCode.F2D:
pop();
// fall through
case ByteCode.DCONST_0: // push(DOUBLE)
case ByteCode.DCONST_1:
case ByteCode.DLOAD:
case ByteCode.DLOAD_0:
case ByteCode.DLOAD_1:
case ByteCode.DLOAD_2:
case ByteCode.DLOAD_3:
push(TypeInfo.DOUBLE);
break;
case ByteCode.ISTORE:
executeStore(getOperand(bci + 1, wide ? 2 : 1), TypeInfo.INTEGER);
break;
case ByteCode.ISTORE_0:
case ByteCode.ISTORE_1:
case ByteCode.ISTORE_2:
case ByteCode.ISTORE_3:
executeStore(bc - ByteCode.ISTORE_0, TypeInfo.INTEGER);
break;
case ByteCode.LSTORE:
executeStore(getOperand(bci + 1, wide ? 2 : 1), TypeInfo.LONG);
break;
case ByteCode.LSTORE_0:
case ByteCode.LSTORE_1:
case ByteCode.LSTORE_2:
case ByteCode.LSTORE_3:
executeStore(bc - ByteCode.LSTORE_0, TypeInfo.LONG);
break;
case ByteCode.FSTORE:
executeStore(getOperand(bci + 1, wide ? 2 : 1), TypeInfo.FLOAT);
break;
case ByteCode.FSTORE_0:
case ByteCode.FSTORE_1:
case ByteCode.FSTORE_2:
case ByteCode.FSTORE_3:
executeStore(bc - ByteCode.FSTORE_0, TypeInfo.FLOAT);
break;
case ByteCode.DSTORE:
executeStore(getOperand(bci + 1, wide ? 2 : 1), TypeInfo.DOUBLE);
break;
case ByteCode.DSTORE_0:
case ByteCode.DSTORE_1:
case ByteCode.DSTORE_2:
case ByteCode.DSTORE_3:
executeStore(bc - ByteCode.DSTORE_0, TypeInfo.DOUBLE);
break;
case ByteCode.ALOAD:
executeALoad(getOperand(bci + 1, wide ? 2 : 1));
break;
case ByteCode.ALOAD_0:
case ByteCode.ALOAD_1:
case ByteCode.ALOAD_2:
case ByteCode.ALOAD_3:
executeALoad(bc - ByteCode.ALOAD_0);
break;
case ByteCode.ASTORE:
executeAStore(getOperand(bci + 1, wide ? 2 : 1));
break;
case ByteCode.ASTORE_0:
case ByteCode.ASTORE_1:
case ByteCode.ASTORE_2:
case ByteCode.ASTORE_3:
executeAStore(bc - ByteCode.ASTORE_0);
break;
case ByteCode.IRETURN:
case ByteCode.LRETURN:
case ByteCode.FRETURN:
case ByteCode.DRETURN:
case ByteCode.ARETURN:
case ByteCode.RETURN:
clearStack();
break;
case ByteCode.ATHROW:
type = pop();
clearStack();
push(type);
break;
case ByteCode.SWAP:
type = pop();
type2 = pop();
push(type);
push(type2);
break;
case ByteCode.LDC:
case ByteCode.LDC_W:
case ByteCode.LDC2_W:
if (bc == ByteCode.LDC) {
index = getOperand(bci + 1);
} else {
index = getOperand(bci + 1, 2);
}
byte constType = itsConstantPool.getConstantType(index);
switch (constType) {
case ConstantPool.CONSTANT_Double:
push(TypeInfo.DOUBLE);
break;
case ConstantPool.CONSTANT_Float:
push(TypeInfo.FLOAT);
break;
case ConstantPool.CONSTANT_Long:
push(TypeInfo.LONG);
break;
case ConstantPool.CONSTANT_Integer:
push(TypeInfo.INTEGER);
break;
case ConstantPool.CONSTANT_String:
push(TypeInfo.OBJECT("java/lang/String", itsConstantPool));
break;
default:
throw new IllegalArgumentException("bad const type " + constType);
}
break;
case ByteCode.NEW:
push(TypeInfo.UNINITIALIZED_VARIABLE(bci));
break;
case ByteCode.NEWARRAY:
pop();
char componentType = arrayTypeToName(itsCodeBuffer[bci + 1]);
index = itsConstantPool.addClass("[" + componentType);
push(TypeInfo.OBJECT((short) index));
break;
case ByteCode.ANEWARRAY:
index = getOperand(bci + 1, 2);
className = (String) itsConstantPool.getConstantData(index);
pop();
push(TypeInfo.OBJECT("[L" + className + ';', itsConstantPool));
break;
case ByteCode.INVOKEVIRTUAL:
case ByteCode.INVOKESPECIAL:
case ByteCode.INVOKESTATIC:
case ByteCode.INVOKEINTERFACE:
index = getOperand(bci + 1, 2);
FieldOrMethodRef m = (FieldOrMethodRef) itsConstantPool.getConstantData(index);
String methodType = m.getType();
String methodName = m.getName();
int parameterCount = sizeOfParameters(methodType) >>> 16;
for (int i = 0; i < parameterCount; i++) {
pop();
}
if (bc != ByteCode.INVOKESTATIC) {
int instType = pop();
int tag = TypeInfo.getTag(instType);
if (tag == TypeInfo.UNINITIALIZED_VARIABLE(0)
|| tag == TypeInfo.UNINITIALIZED_THIS) {
if ("<init>".equals(methodName)) {
int newType;
if (tag == TypeInfo.UNINITIALIZED_VARIABLE(0)) {
newType = TypeInfo.OBJECT(m.getClassName(), itsConstantPool);
} else {
newType = TypeInfo.OBJECT(itsThisClassIndex);
}
initializeTypeInfo(instType, newType);
} else {
throw new IllegalStateException("bad instance");
}
}
}
int rParen = methodType.indexOf(')');
String returnType = methodType.substring(rParen + 1);
returnType = descriptorToInternalName(returnType);
if (!returnType.equals("V")) {
push(TypeInfo.fromType(returnType, itsConstantPool));
}
break;
case ByteCode.INVOKEDYNAMIC:
index = getOperand(bci + 1, 2);
methodType = (String) itsConstantPool.getConstantData(index);
parameterCount = sizeOfParameters(methodType) >>> 16;
for (int i = 0; i < parameterCount; i++) {
pop();
}
rParen = methodType.indexOf(')');
returnType = methodType.substring(rParen + 1);
returnType = descriptorToInternalName(returnType);
if (!returnType.equals("V")) {
push(TypeInfo.fromType(returnType, itsConstantPool));
}
break;
case ByteCode.GETFIELD:
pop();
// fall through
case ByteCode.GETSTATIC:
index = getOperand(bci + 1, 2);
FieldOrMethodRef f = (FieldOrMethodRef) itsConstantPool.getConstantData(index);
String fieldType = descriptorToInternalName(f.getType());
push(TypeInfo.fromType(fieldType, itsConstantPool));
break;
case ByteCode.DUP:
type = pop();
push(type);
push(type);
break;
case ByteCode.DUP_X1:
type = pop();
type2 = pop();
push(type);
push(type2);
push(type);
break;
case ByteCode.DUP_X2:
type = pop();
lType = pop2();
push(type);
push2(lType);
push(type);
break;
case ByteCode.DUP2:
lType = pop2();
push2(lType);
push2(lType);
break;
case ByteCode.DUP2_X1:
lType = pop2();
type = pop();
push2(lType);
push(type);
push2(lType);
break;
case ByteCode.DUP2_X2:
lType = pop2();
lType2 = pop2();
push2(lType);
push2(lType2);
push2(lType);
break;
case ByteCode.TABLESWITCH:
int switchStart = bci + 1 + (3 & ~bci);
int low = getOperand(switchStart + 4, 4);
int high = getOperand(switchStart + 8, 4);
length = 4 * (high - low + 4) + switchStart - bci;
pop();
break;
case ByteCode.AALOAD:
pop();
int typeIndex = pop() >>> 8;
className = (String) itsConstantPool.getConstantData(typeIndex);
String arrayType = className;
if (arrayType.charAt(0) != '[') {
throw new IllegalStateException("bad array type");
}
String elementDesc = arrayType.substring(1);
String elementType = descriptorToInternalName(elementDesc);
typeIndex = itsConstantPool.addClass(elementType);
push(TypeInfo.OBJECT(typeIndex));
break;
case ByteCode.WIDE:
// Alters behaviour of next instruction
wide = true;
break;
case ByteCode.MULTIANEWARRAY:
case ByteCode.LOOKUPSWITCH:
// Currently not used in any part of Rhino, so ignore it
case ByteCode.JSR: // TODO: JSR is deprecated
case ByteCode.RET:
case ByteCode.JSR_W:
default:
throw new IllegalArgumentException("bad opcode: " + bc);
}
if (length == 0) {
length = opcodeLength(bc, wide);
}
if (wide && bc != ByteCode.WIDE) {
wide = false;
}
return length;
}