Search in sources :

Example 1 with InvokeDynamicConstant

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

the class MethodVerifier method verifyInvokeDynamic.

private void verifyInvokeDynamic(int bci, OperandStack stack) {
    // Check padding
    verifyGuarantee(code.readByte(bci + 2) == 0 && code.readByte(bci + 3) == 0, "bytes 3 and 4 after invokedynamic must be 0.");
    PoolConstant pc = poolAt(code.readCPI(bci));
    // Check CP validity
    verifyGuarantee(pc.tag() == ConstantPool.Tag.INVOKEDYNAMIC, "Invalid CP constant for INVOKEDYNAMIC: " + pc.toString());
    pc.validate(pool);
    InvokeDynamicConstant idc = (InvokeDynamicConstant) pc;
    Symbol<Name> name = idc.getName(pool);
    // Check invokedynamic does not call initializers
    verifyGuarantee(!isInstanceInit(name) && !isClassInit(name), "Invalid bootstrap method name: " + name);
    // Check and pop arguments
    Operand[] parsedSig = getOperandSig(idc.getSignature(pool));
    assert parsedSig.length > 0 : "Empty descriptor for method";
    for (int i = parsedSig.length - 2; i >= 0; i--) {
        stack.pop(parsedSig[i]);
    }
    // push result
    Operand returnKind = parsedSig[parsedSig.length - 1];
    if (returnKind != Void) {
        stack.push(returnKind);
    }
}
Also used : PoolConstant(com.oracle.truffle.espresso.classfile.constantpool.PoolConstant) InvokeDynamicConstant(com.oracle.truffle.espresso.classfile.constantpool.InvokeDynamicConstant) Name(com.oracle.truffle.espresso.descriptors.Symbol.Name)

Example 2 with InvokeDynamicConstant

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

the class BytecodeStream method printBytecode.

public void printBytecode(Klass klass, PrintStream out) {
    try {
        ConstantPool pool = klass.getConstantPool();
        int bci = 0;
        int nextBCI = 0;
        StringBuilder str = new StringBuilder();
        while (nextBCI < endBCI()) {
            str.setLength(0);
            bci = nextBCI;
            int opcode = currentBC(bci);
            str.append(bci).append(": ").append(Bytecodes.nameOf(opcode)).append(" ");
            nextBCI = nextBCI(bci);
            if (Bytecodes.isBranch(opcode)) {
                // {bci}: {branch bytecode} {target}
                str.append(readBranchDest(bci));
            } else if (opcode == Bytecodes.NEW) {
                // {bci}: new {class name}
                int cpi = readCPI(bci);
                ClassConstant cc = (ClassConstant) pool.at(cpi);
                str.append(cc.getName(pool));
            } else if (opcode == Bytecodes.INVOKEDYNAMIC) {
                // {bci}: #{bootstrap method index} -> {name}:{signature}
                int cpi = readCPI(bci);
                InvokeDynamicConstant idc = (InvokeDynamicConstant) pool.at(cpi);
                str.append("#").append(idc.getBootstrapMethodAttrIndex()).append(" -> ").append(idc.getName(pool)).append(":").append(idc.getSignature(pool));
            } else if (Bytecodes.isInvoke(opcode)) {
                // {bci}: invoke{} {class}.{method name}:{method signature}
                int cpi = readCPI(bci);
                MethodRefConstant mrc = (MethodRefConstant) pool.at(cpi);
                str.append(mrc.getHolderKlassName(pool)).append(".").append(mrc.getName(pool)).append(":").append(mrc.getDescriptor(pool));
            } else if (opcode == Bytecodes.TABLESWITCH) {
                // @formatter:off
                // checkstyle: stop
                // {bci}: tableswitch
                // {key1}: {target1}
                // ...
                // {keyN}: {targetN}
                // @formatter:on
                // Checkstyle: resume
                str.append('\n');
                BytecodeTableSwitch helper = BytecodeTableSwitch.INSTANCE;
                int low = helper.lowKey(this, bci);
                int high = helper.highKey(this, bci);
                for (int i = low; i != high + 1; i++) {
                    str.append('\t').append(i).append(": ").append(helper.targetAt(this, bci, i)).append('\n');
                }
                str.append("\tdefault: ").append(helper.defaultTarget(this, bci));
            } else if (opcode == Bytecodes.LOOKUPSWITCH) {
                // @formatter:off
                // checkstyle: stop
                // {bci}: lookupswitch
                // {key1}: {target1}
                // ...
                // {keyN}: {targetN}
                // @formatter:on
                // Checkstyle: resume
                str.append('\n');
                BytecodeLookupSwitch helper = BytecodeLookupSwitch.INSTANCE;
                int low = 0;
                int high = helper.numberOfCases(this, bci) - 1;
                for (int i = low; i <= high; i++) {
                    str.append('\t').append(helper.keyAt(this, bci, i)).append(": ").append(helper.targetAt(this, bci, i));
                }
                str.append("\tdefault: ").append(helper.defaultTarget(this, bci));
            } else if (opcode == Bytecodes.IINC) {
                str.append(" ").append(readLocalIndex(bci)).append(" ").append(readIncrement(bci));
            } else {
                // {bci}: {opcode} {corresponding value}
                if (nextBCI - bci == 2) {
                    str.append(readUByte(bci + 1));
                }
                if (nextBCI - bci == 3) {
                    str.append(readShort(bci));
                }
                if (nextBCI - bci == 5) {
                    str.append(readInt(bci + 1));
                }
            }
            out.println(str.toString());
        }
    } catch (Throwable e) {
        throw EspressoError.unexpected("Exception thrown during bytecode printing, aborting...", e);
    }
}
Also used : ConstantPool(com.oracle.truffle.espresso.classfile.ConstantPool) MethodRefConstant(com.oracle.truffle.espresso.classfile.constantpool.MethodRefConstant) InvokeDynamicConstant(com.oracle.truffle.espresso.classfile.constantpool.InvokeDynamicConstant) ClassConstant(com.oracle.truffle.espresso.classfile.constantpool.ClassConstant)

Aggregations

InvokeDynamicConstant (com.oracle.truffle.espresso.classfile.constantpool.InvokeDynamicConstant)2 ConstantPool (com.oracle.truffle.espresso.classfile.ConstantPool)1 ClassConstant (com.oracle.truffle.espresso.classfile.constantpool.ClassConstant)1 MethodRefConstant (com.oracle.truffle.espresso.classfile.constantpool.MethodRefConstant)1 PoolConstant (com.oracle.truffle.espresso.classfile.constantpool.PoolConstant)1 Name (com.oracle.truffle.espresso.descriptors.Symbol.Name)1