All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.jdo.api.persistence.enhancer.classfile.InsnConstOp Maven / Gradle / Ivy

/*
 * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.jdo.api.persistence.enhancer.classfile;


import java.io.PrintStream;

/**
 * An instruction which requires a single constant from the constant
 * pool as an immediate operand
 */
public class InsnConstOp extends Insn {
    /* The constant from the constant pool */
    private ConstBasic constValue;

    /* public accessors */

    public int nStackArgs() {
        int n = VMOp.ops[opcode()].nStackArgs();
        if (n >= 0)
            return n;
        switch (opcode()) {
            case opc_putstatic:
            case opc_putfield:
            {
                ConstFieldRef fld = (ConstFieldRef) constValue;
                String sig = fld.nameAndType().signature().asString();
                if (sig.equals("J") || sig.equals("D"))//NOI18N
                    return (opcode() == opc_putfield) ? 3 : 2;
                return (opcode() == opc_putfield) ? 2 : 1;
            }
            case opc_invokevirtual:
            case opc_invokespecial:
            case opc_invokestatic:
                /* handle interface invoke too */
            case opc_invokeinterface:
            {
                ConstBasicMemberRef meth = (ConstBasicMemberRef) constValue;
                String sig = meth.nameAndType().signature().asString();
                int nMethodArgWords = Descriptor.countMethodArgWords(sig);
                return nMethodArgWords +
                    ((opcode() == opc_invokestatic) ? 0 : 1);
            }
            default:
                throw new InsnError("unexpected variable opcode");//NOI18N
        }
    }

    public int nStackResults() {
        int n = VMOp.ops[opcode()].nStackResults();
        if (n >= 0)
            return n;
        switch (opcode()) {
            case opc_getstatic:
            case opc_getfield:
            {
                ConstFieldRef fld = (ConstFieldRef) constValue;
                String sig = fld.nameAndType().signature().asString();
                if (sig.equals("J") || sig.equals("D"))//NOI18N
                    return 2;
                return 1;
            }
            case opc_invokevirtual:
            case opc_invokespecial:
            case opc_invokestatic:
                /* handle interface invoke too */
            case opc_invokeinterface:
            {
                ConstBasicMemberRef meth = (ConstBasicMemberRef) constValue;
                return Descriptor.countMethodReturnWords(
                    meth.nameAndType().signature().asString());
            }
            default:
                throw new InsnError("unexpected variable opcode");//NOI18N
        }
    }

    public String argTypes() {
        switch (opcode()) {
            case opc_putstatic:
            case opc_putfield:
            {
                ConstFieldRef fld = (ConstFieldRef) constValue;
                String sig = fld.nameAndType().signature().asString();
                if (opcode() == opc_putstatic)
                    return sig;
                else
                    return descriptorTypeOfObject(fld) + sig;
            }
            case opc_invokevirtual:
            case opc_invokespecial:
            case opc_invokestatic:
                /* handle interface invoke too */
            case opc_invokeinterface:
            {
                ConstBasicMemberRef meth = (ConstBasicMemberRef) constValue;
                String argSig =
                    Descriptor.extractArgSig(meth.nameAndType().signature().asString());
                if (opcode() == opc_invokestatic)
                    return argSig;
                else
                    return descriptorTypeOfObject(meth) + argSig;
            }
            default:
                return VMOp.ops[opcode()].argTypes();
        }
    }

    public String resultTypes() {
        switch (opcode()) {
            case opc_invokevirtual:
            case opc_invokespecial:
            case opc_invokestatic:
                /* handle interface invoke too */
            case opc_invokeinterface:
            {
                ConstBasicMemberRef meth = (ConstBasicMemberRef) constValue;
                String resultSig = Descriptor.extractResultSig(
                    meth.nameAndType().signature().asString());
                if (resultSig.equals("V"))//NOI18N
                    return "";//NOI18N
                return resultSig;
            }
            case opc_getstatic:
            case opc_getfield:
            {
                ConstFieldRef fld = (ConstFieldRef) constValue;
                return fld.nameAndType().signature().asString();
            }
            case opc_ldc:
            case opc_ldc_w:
            case opc_ldc2_w:
            {
                ConstValue constVal = (ConstValue) constValue;
                return constVal.descriptor();
            }
            default:
                return VMOp.ops[opcode()].resultTypes();
        }
    }

    public boolean branches() {
        /* invokes don't count as a branch */
        return false;
    }

    /**
     * Return the constant pool entry which is the immediate operand
     */
    public ConstBasic value() {
        return constValue;
    }

    /**
     * Modify the referenced constant
     */
    public void setValue(ConstBasic newValue) {
        checkConstant(newValue);
        constValue = newValue;
    }

    /* package local methods */

    void print (PrintStream out, int indent) {
        ClassPrint.spaces(out, indent);
        out.println(offset() + "  " + opName(opcode()) + "  pool(" + //NOI18N
            constValue.getIndex() + ")");//NOI18N
    }

    int store(byte[] buf, int index) {
        if (opcode() == opc_ldc && !isNarrowldc())
            buf[index++] = (byte) opc_ldc_w;
        else
            buf[index++] = (byte) opcode();
        int constIndex = constValue.getIndex();
        if (size() == 3)
            buf[index++] = (byte) (constIndex >> 8);
        buf[index++] = (byte)(constIndex & 0xff);
        return index;
    }

    int size() {
        return isNarrowldc() ? 2 : 3;
    }

    private boolean isNarrowldc() {
        return (opcode() == opc_ldc && constValue.getIndex() < 256);
    }


    InsnConstOp (int theOpcode, ConstBasic theOperand) {
        this(theOpcode, theOperand, NO_OFFSET);
    }

    InsnConstOp (int theOpcode, ConstBasic theOperand, int pc) {
        super(theOpcode, pc);
        constValue = theOperand;
        checkConstant(theOperand);
        if (theOpcode == opc_invokeinterface)
            throw new InsnError("attempt to create an " + opName(theOpcode) +//NOI18N
                " as an InsnConstOp instead of InsnInterfaceInvoke");//NOI18N
    }

    /* used only by InsnInterfaceInvoke, to make sure that opc_invokeinterface cannot
     * come through the wrong path and miss its extra nArgsOp */
    InsnConstOp (int theOpcode, ConstInterfaceMethodRef theOperand, int pc) {
        super(theOpcode, pc);
        constValue = theOperand;
        checkConstant(theOperand);
    }

    private void checkConstant (ConstBasic operand) {
        switch(opcode()) {
            case opc_ldc:
            case opc_ldc_w:
            case opc_ldc2_w:
                /* ConstValue */
                if (operand == null ||
                (! (operand instanceof ConstValue)))
                    throw new InsnError ("attempt to create an " + opName(opcode()) +//NOI18N
                        " without a ConstValue operand");//NOI18N
                break;

            case opc_getstatic:
            case opc_putstatic:
            case opc_getfield:
            case opc_putfield:
                /* ConstFieldRef */
                if (operand == null ||
                (! (operand instanceof ConstFieldRef)))
                    throw new InsnError ("attempt to create an " + opName(opcode()) +//NOI18N
                        " without a ConstFieldRef operand");//NOI18N
                break;

            case opc_invokevirtual:
            case opc_invokespecial:
            case opc_invokestatic:
                /* ConstMethodRef */
                if (operand == null ||
                (! (operand instanceof ConstMethodRef)))
                    throw new InsnError ("attempt to create an " + opName(opcode()) +//NOI18N
                        " without a ConstMethodRef operand");//NOI18N
                break;

            case opc_invokeinterface:
                /* ConstInterfaceMethodRef */
                if (operand == null ||
                (! (operand instanceof ConstInterfaceMethodRef)))
                    throw new InsnError("Attempt to create an " + opName(opcode()) +//NOI18N
                        " without a ConstInterfaceMethodRef operand");//NOI18N
                break;

            case opc_new:
            case opc_anewarray:
            case opc_checkcast:
            case opc_instanceof:
                /* ConstClass */
                if (operand == null ||
                (! (operand instanceof ConstClass)))
                    throw new InsnError ("attempt to create an " + opName(opcode()) +//NOI18N
                        " without a ConstClass operand");//NOI18N
                break;

            default:
                throw new InsnError ("attempt to create an " + opName(opcode()) +//NOI18N
                    " with a constant operand");//NOI18N
        }
    }

    private final String descriptorTypeOfObject(ConstBasicMemberRef memRef) {
        String cname = memRef.className().className().asString();
        return "L" + cname + ";";//NOI18N
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy