Search in sources :

Example 11 with PoolConstant

use of com.oracle.truffle.espresso.classfile.constantpool.PoolConstant in project graal by oracle.

the class MethodVerifier method verify.

/**
 * Core of the verifier. Performs verification for a single bci, according (mostly) to the JVM
 * specs
 *
 * @param bci The bci of the opcode being verified
 * @param stack The current state of the stack at the point of verification
 * @param locals The current state of the local variables at the point of verification
 * @return The index of the next opcode to verify, or bci if there is no next opcode to verify
 *         (in case of a return bytecode, for example).
 */
private int verify(int bci, OperandStack stack, Locals locals) {
    verifyGuarantee(bciStates[bci] != UNREACHABLE, "Jump to the middle of an instruction: " + bci);
    bciStates[bci] = setStatus(bciStates[bci], DONE);
    int curOpcode;
    curOpcode = code.opcode(bci);
    verifyGuarantee(curOpcode < SLIM_QUICK, "invalid bytecode: " + code.readUByte(bci));
    // widened instruction.
    wideEscape: while (true) {
        switch(curOpcode) {
            case NOP:
                break;
            case ACONST_NULL:
                stack.push(Null);
                break;
            case ICONST_M1:
            case ICONST_0:
            case ICONST_1:
            case ICONST_2:
            case ICONST_3:
            case ICONST_4:
            case ICONST_5:
                stack.pushInt();
                break;
            case LCONST_0:
            case LCONST_1:
                stack.pushLong();
                break;
            case FCONST_0:
            case FCONST_1:
            case FCONST_2:
                stack.pushFloat();
                break;
            case DCONST_0:
            case DCONST_1:
                stack.pushDouble();
                break;
            case BIPUSH:
                stack.pushInt();
                break;
            case SIPUSH:
                stack.pushInt();
                break;
            case LDC:
            case LDC_W:
                {
                    PoolConstant pc = poolAt(code.readCPI(bci));
                    pc.validate(pool);
                    Operand op = ldcFromTag(pc);
                    verifyGuarantee(!isType2(op), "Loading Long or Double with LDC or LDC_W, please use LDC2_W.");
                    if (earlierThan49()) {
                        verifyGuarantee(op == Int || op == Float || op.getType() == jlString.getType(), "Loading non Int, Float or String with LDC in classfile version < 49.0");
                    }
                    stack.push(op);
                    break;
                }
            case LDC2_W:
                {
                    PoolConstant pc = poolAt(code.readCPI(bci));
                    pc.validate(pool);
                    Operand op = ldcFromTag(pc);
                    verifyGuarantee(isType2(op), "Loading non-Long or Double with LDC2_W, please use LDC or LDC_W.");
                    stack.push(op);
                    break;
                }
            case ILOAD:
                locals.load(code.readLocalIndex(bci), Int);
                stack.pushInt();
                break;
            case LLOAD:
                locals.load(code.readLocalIndex(bci), Long);
                stack.pushLong();
                break;
            case FLOAD:
                locals.load(code.readLocalIndex(bci), Float);
                stack.pushFloat();
                break;
            case DLOAD:
                locals.load(code.readLocalIndex(bci), Double);
                stack.pushDouble();
                break;
            case ALOAD:
                stack.push(locals.loadRef(code.readLocalIndex(bci)));
                break;
            case ILOAD_0:
            case ILOAD_1:
            case ILOAD_2:
            case ILOAD_3:
                locals.load(curOpcode - ILOAD_0, Int);
                stack.pushInt();
                break;
            case LLOAD_0:
            case LLOAD_1:
            case LLOAD_2:
            case LLOAD_3:
                locals.load(curOpcode - LLOAD_0, Long);
                stack.pushLong();
                break;
            case FLOAD_0:
            case FLOAD_1:
            case FLOAD_2:
            case FLOAD_3:
                locals.load(curOpcode - FLOAD_0, Float);
                stack.pushFloat();
                break;
            case DLOAD_0:
            case DLOAD_1:
            case DLOAD_2:
            case DLOAD_3:
                locals.load(curOpcode - DLOAD_0, Double);
                stack.pushDouble();
                break;
            case ALOAD_0:
            case ALOAD_1:
            case ALOAD_2:
            case ALOAD_3:
                stack.push(locals.loadRef(curOpcode - ALOAD_0));
                break;
            case IALOAD:
                xaload(stack, Int);
                break;
            case LALOAD:
                xaload(stack, Long);
                break;
            case FALOAD:
                xaload(stack, Float);
                break;
            case DALOAD:
                xaload(stack, Double);
                break;
            case AALOAD:
                {
                    stack.popInt();
                    Operand op = stack.popArray();
                    verifyGuarantee(op == Null || op.getComponent().isReference(), "Loading reference from " + op + " array.");
                    stack.push(op.getComponent());
                    break;
                }
            case BALOAD:
                xaload(stack, ByteOrBoolean);
                break;
            case CALOAD:
                xaload(stack, Char);
                break;
            case SALOAD:
                xaload(stack, Short);
                break;
            case ISTORE:
                stack.popInt();
                locals.store(code.readLocalIndex(bci), Int);
                break;
            case LSTORE:
                stack.popLong();
                locals.store(code.readLocalIndex(bci), Long);
                break;
            case FSTORE:
                stack.popFloat();
                locals.store(code.readLocalIndex(bci), Float);
                break;
            case DSTORE:
                stack.popDouble();
                locals.store(code.readLocalIndex(bci), Double);
                break;
            case ASTORE:
                locals.store(code.readLocalIndex(bci), stack.popObjOrRA());
                break;
            case ISTORE_0:
            case ISTORE_1:
            case ISTORE_2:
            case ISTORE_3:
                stack.popInt();
                locals.store(curOpcode - ISTORE_0, Int);
                break;
            case LSTORE_0:
            case LSTORE_1:
            case LSTORE_2:
            case LSTORE_3:
                stack.popLong();
                locals.store(curOpcode - LSTORE_0, Long);
                break;
            case FSTORE_0:
            case FSTORE_1:
            case FSTORE_2:
            case FSTORE_3:
                stack.popFloat();
                locals.store(curOpcode - FSTORE_0, Float);
                break;
            case DSTORE_0:
            case DSTORE_1:
            case DSTORE_2:
            case DSTORE_3:
                stack.popDouble();
                locals.store(curOpcode - DSTORE_0, Double);
                break;
            case ASTORE_0:
            case ASTORE_1:
            case ASTORE_2:
            case ASTORE_3:
                locals.store(curOpcode - ASTORE_0, stack.popObjOrRA());
                break;
            case IASTORE:
                xastore(stack, Int);
                break;
            case LASTORE:
                xastore(stack, Long);
                break;
            case FASTORE:
                xastore(stack, Float);
                break;
            case DASTORE:
                xastore(stack, Double);
                break;
            case AASTORE:
                {
                    Operand toStore = stack.popRef();
                    stack.popInt();
                    Operand array = stack.popArray();
                    verifyGuarantee(array == Null || array.getComponent().isReference(), "Trying to store " + toStore + " in " + array);
                    // Other checks are done at runtime
                    break;
                }
            case BASTORE:
                xastore(stack, ByteOrBoolean);
                break;
            case CASTORE:
                xastore(stack, Char);
                break;
            case SASTORE:
                xastore(stack, Short);
                break;
            case POP:
                stack.pop();
                break;
            case POP2:
                stack.pop2();
                break;
            case DUP:
                stack.dup();
                break;
            case DUP_X1:
                stack.dupx1();
                break;
            case DUP_X2:
                stack.dupx2();
                break;
            case DUP2:
                stack.dup2();
                break;
            case DUP2_X1:
                stack.dup2x1();
                break;
            case DUP2_X2:
                stack.dup2x2();
                break;
            case SWAP:
                stack.swap();
                break;
            case IADD:
                stack.popInt();
                stack.popInt();
                stack.pushInt();
                break;
            case LADD:
                stack.popLong();
                stack.popLong();
                stack.pushLong();
                break;
            case FADD:
                stack.popFloat();
                stack.popFloat();
                stack.pushFloat();
                break;
            case DADD:
                stack.popDouble();
                stack.popDouble();
                stack.pushDouble();
                break;
            case ISUB:
                stack.popInt();
                stack.popInt();
                stack.pushInt();
                break;
            case LSUB:
                stack.popLong();
                stack.popLong();
                stack.pushLong();
                break;
            case FSUB:
                stack.popFloat();
                stack.popFloat();
                stack.pushFloat();
                break;
            case DSUB:
                stack.popDouble();
                stack.popDouble();
                stack.pushDouble();
                break;
            case IMUL:
                stack.popInt();
                stack.popInt();
                stack.pushInt();
                break;
            case LMUL:
                stack.popLong();
                stack.popLong();
                stack.pushLong();
                break;
            case FMUL:
                stack.popFloat();
                stack.popFloat();
                stack.pushFloat();
                break;
            case DMUL:
                stack.popDouble();
                stack.popDouble();
                stack.pushDouble();
                break;
            case IDIV:
                stack.popInt();
                stack.popInt();
                stack.pushInt();
                break;
            case LDIV:
                stack.popLong();
                stack.popLong();
                stack.pushLong();
                break;
            case FDIV:
                stack.popFloat();
                stack.popFloat();
                stack.pushFloat();
                break;
            case DDIV:
                stack.popDouble();
                stack.popDouble();
                stack.pushDouble();
                break;
            case IREM:
                stack.popInt();
                stack.popInt();
                stack.pushInt();
                break;
            case LREM:
                stack.popLong();
                stack.popLong();
                stack.pushLong();
                break;
            case FREM:
                stack.popFloat();
                stack.popFloat();
                stack.pushFloat();
                break;
            case DREM:
                stack.popDouble();
                stack.popDouble();
                stack.pushDouble();
                break;
            case INEG:
                stack.popInt();
                stack.pushInt();
                break;
            case LNEG:
                stack.popLong();
                stack.pushLong();
                break;
            case FNEG:
                stack.popFloat();
                stack.pushFloat();
                break;
            case DNEG:
                stack.popDouble();
                stack.pushDouble();
                break;
            case ISHL:
                stack.popInt();
                stack.popInt();
                stack.pushInt();
                break;
            case LSHL:
                stack.popInt();
                stack.popLong();
                stack.pushLong();
                break;
            case ISHR:
                stack.popInt();
                stack.popInt();
                stack.pushInt();
                break;
            case LSHR:
                stack.popInt();
                stack.popLong();
                stack.pushLong();
                break;
            case IUSHR:
                stack.popInt();
                stack.popInt();
                stack.pushInt();
                break;
            case LUSHR:
                stack.popInt();
                stack.popLong();
                stack.pushLong();
                break;
            case IAND:
                stack.popInt();
                stack.popInt();
                stack.pushInt();
                break;
            case LAND:
                stack.popLong();
                stack.popLong();
                stack.pushLong();
                break;
            case IOR:
                stack.popInt();
                stack.popInt();
                stack.pushInt();
                break;
            case LOR:
                stack.popLong();
                stack.popLong();
                stack.pushLong();
                break;
            case IXOR:
                stack.popInt();
                stack.popInt();
                stack.pushInt();
                break;
            case LXOR:
                stack.popLong();
                stack.popLong();
                stack.pushLong();
                break;
            case IINC:
                locals.load(code.readLocalIndex(bci), Int);
                break;
            case I2L:
                stack.popInt();
                stack.pushLong();
                break;
            case I2F:
                stack.popInt();
                stack.pushFloat();
                break;
            case I2D:
                stack.popInt();
                stack.pushDouble();
                break;
            case L2I:
                stack.popLong();
                stack.pushInt();
                break;
            case L2F:
                stack.popLong();
                stack.pushFloat();
                break;
            case L2D:
                stack.popLong();
                stack.pushDouble();
                break;
            case F2I:
                stack.popFloat();
                stack.pushInt();
                break;
            case F2L:
                stack.popFloat();
                stack.pushLong();
                break;
            case F2D:
                stack.popFloat();
                stack.pushDouble();
                break;
            case D2I:
                stack.popDouble();
                stack.pushInt();
                break;
            case D2L:
                stack.popDouble();
                stack.pushLong();
                break;
            case D2F:
                stack.popDouble();
                stack.pushFloat();
                break;
            case I2B:
                stack.popInt();
                stack.pushInt();
                break;
            case I2C:
                stack.popInt();
                stack.pushInt();
                break;
            case I2S:
                stack.popInt();
                stack.pushInt();
                break;
            case LCMP:
                stack.popLong();
                stack.popLong();
                stack.pushInt();
                break;
            case FCMPL:
            case FCMPG:
                stack.popFloat();
                stack.popFloat();
                stack.pushInt();
                break;
            case DCMPL:
            case DCMPG:
                stack.popDouble();
                stack.popDouble();
                stack.pushInt();
                break;
            // fall through
            case IFEQ:
            // fall through
            case IFNE:
            // fall through
            case IFLT:
            // fall through
            case IFGE:
            // fall through
            case IFGT:
            case IFLE:
                stack.popInt();
                branch(code.readBranchDest(bci), stack, locals);
                break;
            // fall through
            case IF_ICMPEQ:
            // fall through
            case IF_ICMPNE:
            // fall through
            case IF_ICMPLT:
            // fall through
            case IF_ICMPGE:
            // fall through
            case IF_ICMPGT:
            case IF_ICMPLE:
                stack.popInt();
                stack.popInt();
                branch(code.readBranchDest(bci), stack, locals);
                break;
            // fall through
            case IF_ACMPEQ:
            case IF_ACMPNE:
                stack.popRef();
                stack.popRef();
                branch(code.readBranchDest(bci), stack, locals);
                break;
            case GOTO:
            case GOTO_W:
                branch(code.readBranchDest(bci), stack, locals);
                return bci;
            // fall through
            case IFNULL:
            case IFNONNULL:
                stack.popRef();
                branch(code.readBranchDest(bci), stack, locals);
                break;
            // fall through
            case JSR:
            case JSR_W:
                verifyJSR(bci, stack, locals);
                return bci;
            case RET:
                verifyRET(bci, stack, locals);
                return bci;
            case TABLESWITCH:
                return verifyTableSwitch(bci, stack, locals);
            case LOOKUPSWITCH:
                return verifyLookupSwitch(bci, stack, locals);
            case IRETURN:
                {
                    stack.pop(Int);
                    verifyGuarantee(returnOperand.getKind().isStackInt(), "Found an IRETURN when return type is " + returnOperand);
                    return bci;
                }
            case LRETURN:
                doReturn(stack, Long);
                return bci;
            case FRETURN:
                doReturn(stack, Float);
                return bci;
            case DRETURN:
                doReturn(stack, Double);
                return bci;
            case ARETURN:
                stack.popRef(returnOperand);
                return bci;
            case RETURN:
                verifyGuarantee(returnOperand == Void, "Encountered RETURN, but method return type is not void: " + returnOperand);
                // Only j.l.Object.<init> can omit calling another initializer.
                if (isInstanceInit(methodName) && thisKlass.getType() != Type.java_lang_Object) {
                    verifyGuarantee(calledConstructor, "Did not call super() or this() in constructor " + thisKlass.getType() + "." + methodName);
                }
                return bci;
            case GETSTATIC:
            case GETFIELD:
                verifyGetField(bci, stack, curOpcode);
                break;
            case PUTSTATIC:
            case PUTFIELD:
                verifyPutField(bci, stack, curOpcode);
                break;
            case INVOKEVIRTUAL:
                verifyInvokeVirtual(bci, stack);
                break;
            case INVOKESPECIAL:
                verifyInvokeSpecial(bci, stack, locals);
                break;
            case INVOKESTATIC:
                verifyInvokeStatic(bci, stack);
                break;
            case INVOKEINTERFACE:
                verifyInvokeInterface(bci, stack);
                break;
            case NEW:
                verifyNew(bci, stack);
                break;
            case NEWARRAY:
                verifyNewPrimitiveArray(bci, stack);
                break;
            case ANEWARRAY:
                verifyNewObjectArray(bci, stack);
                break;
            case ARRAYLENGTH:
                stack.popArray();
                stack.pushInt();
                break;
            case ATHROW:
                stack.popRef(jlThrowable);
                return bci;
            case CHECKCAST:
                verifyCheckCast(bci, stack);
                break;
            case INSTANCEOF:
                verifyInstanceOf(bci, stack);
                break;
            case MONITORENTER:
                stack.popRef();
                break;
            case MONITOREXIT:
                stack.popRef();
                break;
            case WIDE:
                curOpcode = code.currentBC(bci);
                verifyGuarantee(wideOpcodes(curOpcode), "invalid widened opcode: " + Bytecodes.nameOf(curOpcode));
                continue wideEscape;
            case MULTIANEWARRAY:
                verifyMultiNewArray(bci, stack);
                break;
            case BREAKPOINT:
                break;
            case INVOKEDYNAMIC:
                verifyInvokeDynamic(bci, stack);
                break;
            case QUICK:
                break;
            case SLIM_QUICK:
                break;
            default:
        }
        return code.nextBCI(bci);
    }
// Checkstyle: resume
// @formatter:on
}
Also used : PoolConstant(com.oracle.truffle.espresso.classfile.constantpool.PoolConstant)

Aggregations

PoolConstant (com.oracle.truffle.espresso.classfile.constantpool.PoolConstant)11 Type (com.oracle.truffle.espresso.descriptors.Symbol.Type)3 ClassConstant (com.oracle.truffle.espresso.classfile.constantpool.ClassConstant)2 FieldRefConstant (com.oracle.truffle.espresso.classfile.constantpool.FieldRefConstant)2 InvokeDynamicConstant (com.oracle.truffle.espresso.classfile.constantpool.InvokeDynamicConstant)2 RuntimeConstantPool (com.oracle.truffle.espresso.classfile.RuntimeConstantPool)1 DoubleConstant (com.oracle.truffle.espresso.classfile.constantpool.DoubleConstant)1 DynamicConstant (com.oracle.truffle.espresso.classfile.constantpool.DynamicConstant)1 FloatConstant (com.oracle.truffle.espresso.classfile.constantpool.FloatConstant)1 IntegerConstant (com.oracle.truffle.espresso.classfile.constantpool.IntegerConstant)1 LongConstant (com.oracle.truffle.espresso.classfile.constantpool.LongConstant)1 MethodHandleConstant (com.oracle.truffle.espresso.classfile.constantpool.MethodHandleConstant)1 MethodRefConstant (com.oracle.truffle.espresso.classfile.constantpool.MethodRefConstant)1 MethodTypeConstant (com.oracle.truffle.espresso.classfile.constantpool.MethodTypeConstant)1 StringConstant (com.oracle.truffle.espresso.classfile.constantpool.StringConstant)1 Utf8Constant (com.oracle.truffle.espresso.classfile.constantpool.Utf8Constant)1 Name (com.oracle.truffle.espresso.descriptors.Symbol.Name)1 ArrayKlass (com.oracle.truffle.espresso.impl.ArrayKlass)1 Klass (com.oracle.truffle.espresso.impl.Klass)1 StaticObject (com.oracle.truffle.espresso.runtime.StaticObject)1