public void add()

in rhino/src/main/java/org/mozilla/classfile/ClassFileWriter.java [440:591]


    public void add(int theOpCode, int theOperand) {
        if (DEBUGCODE) {
            System.out.println(
                    "Add " + bytecodeStr(theOpCode) + ", " + Integer.toHexString(theOperand));
        }
        int newStack = itsStackTop + stackChange(theOpCode);
        if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);

        switch (theOpCode) {
            case ByteCode.GOTO:
                // This is necessary because dead code is seemingly being
                // generated and Sun's verifier is expecting type state to be
                // placed even at dead blocks of code.
                addSuperBlockStart(itsCodeBufferTop + 3);
            // fall through...
            case ByteCode.IFEQ:
            case ByteCode.IFNE:
            case ByteCode.IFLT:
            case ByteCode.IFGE:
            case ByteCode.IFGT:
            case ByteCode.IFLE:
            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:
            case ByteCode.JSR:
            case ByteCode.IFNULL:
            case ByteCode.IFNONNULL:
                {
                    if ((theOperand & 0x80000000) != 0x80000000) {
                        if ((theOperand < 0) || (theOperand > 65535))
                            throw new IllegalArgumentException("Bad label for branch");
                    }
                    int branchPC = itsCodeBufferTop;
                    addToCodeBuffer(theOpCode);
                    if ((theOperand & 0x80000000) != 0x80000000) {
                        // hard displacement
                        addToCodeInt16(theOperand);
                        int target = theOperand + branchPC;
                        addSuperBlockStart(target);
                        itsJumpFroms.put(target, branchPC);
                    } else { // a label
                        int targetPC = getLabelPC(theOperand);
                        if (DEBUGLABELS) {
                            int theLabel = theOperand & 0x7FFFFFFF;
                            System.out.println(
                                    "Fixing branch to "
                                            + theLabel
                                            + " at "
                                            + targetPC
                                            + " from "
                                            + branchPC);
                        }
                        if (targetPC != -1) {
                            int offset = targetPC - branchPC;
                            addToCodeInt16(offset);
                            addSuperBlockStart(targetPC);
                            itsJumpFroms.put(targetPC, branchPC);
                        } else {
                            addLabelFixup(theOperand, branchPC + 1);
                            addToCodeInt16(0);
                        }
                    }
                }
                break;

            case ByteCode.BIPUSH:
                if ((byte) theOperand != theOperand)
                    throw new IllegalArgumentException("out of range byte");
                addToCodeBuffer(theOpCode);
                addToCodeBuffer((byte) theOperand);
                break;

            case ByteCode.SIPUSH:
                if ((short) theOperand != theOperand)
                    throw new IllegalArgumentException("out of range short");
                addToCodeBuffer(theOpCode);
                addToCodeInt16(theOperand);
                break;

            case ByteCode.NEWARRAY:
                if (!(0 <= theOperand && theOperand < 256))
                    throw new IllegalArgumentException("out of range index");
                addToCodeBuffer(theOpCode);
                addToCodeBuffer(theOperand);
                break;

            case ByteCode.GETFIELD:
            case ByteCode.PUTFIELD:
                if (!(0 <= theOperand && theOperand < 65536))
                    throw new IllegalArgumentException("out of range field");
                addToCodeBuffer(theOpCode);
                addToCodeInt16(theOperand);
                break;

            case ByteCode.LDC:
            case ByteCode.LDC_W:
            case ByteCode.LDC2_W:
                if (!(0 <= theOperand && theOperand < 65536))
                    throw new ClassFileFormatException("out of range index");
                if (theOperand >= 256
                        || theOpCode == ByteCode.LDC_W
                        || theOpCode == ByteCode.LDC2_W) {
                    if (theOpCode == ByteCode.LDC) {
                        addToCodeBuffer(ByteCode.LDC_W);
                    } else {
                        addToCodeBuffer(theOpCode);
                    }
                    addToCodeInt16(theOperand);
                } else {
                    addToCodeBuffer(theOpCode);
                    addToCodeBuffer(theOperand);
                }
                break;

            case ByteCode.RET:
            case ByteCode.ILOAD:
            case ByteCode.LLOAD:
            case ByteCode.FLOAD:
            case ByteCode.DLOAD:
            case ByteCode.ALOAD:
            case ByteCode.ISTORE:
            case ByteCode.LSTORE:
            case ByteCode.FSTORE:
            case ByteCode.DSTORE:
            case ByteCode.ASTORE:
                if (theOperand < 0 || 65536 <= theOperand)
                    throw new ClassFileFormatException("out of range variable");
                if (theOperand >= 256) {
                    addToCodeBuffer(ByteCode.WIDE);
                    addToCodeBuffer(theOpCode);
                    addToCodeInt16(theOperand);
                } else {
                    addToCodeBuffer(theOpCode);
                    addToCodeBuffer(theOperand);
                }
                break;

            default:
                throw new IllegalArgumentException("Unexpected opcode for 1 operand");
        }

        itsStackTop = (short) newStack;
        if (newStack > itsMaxStack) itsMaxStack = (short) newStack;
        if (DEBUGSTACK) {
            System.out.println("After " + bytecodeStr(theOpCode) + " stack = " + itsStackTop);
        }
    }