⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classfilewriter.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            case ByteCode.PUTFIELD :                newStack -= fieldSize;                break;            default :                throw new IllegalArgumentException(                    "bad opcode for field reference");        }        if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);        short fieldRefIndex = itsConstantPool.addFieldRef(className,                                             fieldName, fieldType);        addToCodeBuffer(theOpCode);        addToCodeInt16(fieldRefIndex);        itsStackTop = (short)newStack;        if (newStack > itsMaxStack) itsMaxStack = (short)newStack;        if (DEBUGSTACK) {            System.out.println("After "+bytecodeStr(theOpCode)                               +" stack = "+itsStackTop);        }    }    public void addInvoke(int theOpCode, String className, String methodName,                          String methodType)    {        if (DEBUGCODE) {            System.out.println("Add "+bytecodeStr(theOpCode)                               +", "+className+", "+methodName+", "                               +methodType);        }        int parameterInfo = sizeOfParameters(methodType);        int parameterCount = parameterInfo >>> 16;        int stackDiff = (short)parameterInfo;        int newStack = itsStackTop + stackDiff;        newStack += stackChange(theOpCode);     // adjusts for 'this'        if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);        switch (theOpCode) {            case ByteCode.INVOKEVIRTUAL :            case ByteCode.INVOKESPECIAL :            case ByteCode.INVOKESTATIC :            case ByteCode.INVOKEINTERFACE : {                    addToCodeBuffer(theOpCode);                    if (theOpCode == ByteCode.INVOKEINTERFACE) {                        short ifMethodRefIndex                                    = itsConstantPool.addInterfaceMethodRef(                                               className, methodName,                                               methodType);                        addToCodeInt16(ifMethodRefIndex);                        addToCodeBuffer(parameterCount + 1);                        addToCodeBuffer(0);                    }                    else {                        short methodRefIndex = itsConstantPool.addMethodRef(                                               className, methodName,                                               methodType);                        addToCodeInt16(methodRefIndex);                    }                }                break;            default :                throw new IllegalArgumentException(                    "bad opcode for method reference");        }        itsStackTop = (short)newStack;        if (newStack > itsMaxStack) itsMaxStack = (short)newStack;        if (DEBUGSTACK) {            System.out.println("After "+bytecodeStr(theOpCode)                               +" stack = "+itsStackTop);        }    }    /**     * Generate code to load the given integer on stack.     *     * @param k the constant     */    public void addPush(int k)    {        if ((byte)k == k) {            if (k == -1) {                add(ByteCode.ICONST_M1);            } else if (0 <= k && k <= 5) {                add((byte)(ByteCode.ICONST_0 + k));            } else {                add(ByteCode.BIPUSH, (byte)k);            }        } else if ((short)k == k) {            add(ByteCode.SIPUSH, (short)k);        } else {            addLoadConstant(k);        }    }    public void addPush(boolean k)    {        add(k ? ByteCode.ICONST_1 : ByteCode.ICONST_0);    }    /**     * Generate code to load the given long on stack.     *     * @param k the constant     */    public void addPush(long k)    {        int ik = (int)k;        if (ik == k) {            addPush(ik);            add(ByteCode.I2L);        } else {            addLoadConstant(k);        }    }    /**     * Generate code to load the given double on stack.     *     * @param k the constant     */    public void addPush(double k)    {        if (k == 0.0) {            // zero            add(ByteCode.DCONST_0);            if (1.0 / k < 0) {                // Negative zero                add(ByteCode.DNEG);            }        } else if (k == 1.0 || k == -1.0) {            add(ByteCode.DCONST_1);            if (k < 0) {                add(ByteCode.DNEG);            }        } else {            addLoadConstant(k);        }    }    /**     * Generate the code to leave on stack the given string even if the     * string encoding exeeds the class file limit for single string constant     *     * @param k the constant     */    public void addPush(String k) {        int length = k.length();        int limit = itsConstantPool.getUtfEncodingLimit(k, 0, length);        if (limit == length) {            addLoadConstant(k);            return;        }        // Split string into picies fitting the UTF limit and generate code for        // StringBuffer sb = new StringBuffer(length);        // sb.append(loadConstant(piece_1));        // ...        // sb.append(loadConstant(piece_N));        // sb.toString();        final String SB = "java/lang/StringBuffer";        add(ByteCode.NEW, SB);        add(ByteCode.DUP);        addPush(length);        addInvoke(ByteCode.INVOKESPECIAL, SB, "<init>", "(I)V");        int cursor = 0;        for (;;) {            add(ByteCode.DUP);            String s = k.substring(cursor, limit);            addLoadConstant(s);            addInvoke(ByteCode.INVOKEVIRTUAL, SB, "append",                      "(Ljava/lang/String;)Ljava/lang/StringBuffer;");            add(ByteCode.POP);            if (limit == length) {                break;            }            cursor = limit;            limit = itsConstantPool.getUtfEncodingLimit(k, limit, length);        }        addInvoke(ByteCode.INVOKEVIRTUAL, SB, "toString",                  "()Ljava/lang/String;");    }    /**     * Check if k fits limit on string constant size imposed by class file     * format.     *     * @param k the string constant     */    public boolean isUnderStringSizeLimit(String k)    {        return itsConstantPool.isUnderUtfEncodingLimit(k);    }    /**     * Store integer from stack top into the given local.     *     * @param local number of local register     */    public void addIStore(int local)    {        xop(ByteCode.ISTORE_0, ByteCode.ISTORE, local);    }    /**     * Store long from stack top into the given local.     *     * @param local number of local register     */    public void addLStore(int local)    {        xop(ByteCode.LSTORE_0, ByteCode.LSTORE, local);    }    /**     * Store float from stack top into the given local.     *     * @param local number of local register     */    public void addFStore(int local)    {        xop(ByteCode.FSTORE_0, ByteCode.FSTORE, local);    }    /**     * Store double from stack top into the given local.     *     * @param local number of local register     */    public void addDStore(int local)    {        xop(ByteCode.DSTORE_0, ByteCode.DSTORE, local);    }    /**     * Store object from stack top into the given local.     *     * @param local number of local register     */    public void addAStore(int local)    {        xop(ByteCode.ASTORE_0, ByteCode.ASTORE, local);    }    /**     * Load integer from the given local into stack.     *     * @param local number of local register     */    public void addILoad(int local)    {        xop(ByteCode.ILOAD_0, ByteCode.ILOAD, local);    }    /**     * Load long from the given local into stack.     *     * @param local number of local register     */    public void addLLoad(int local)    {        xop(ByteCode.LLOAD_0, ByteCode.LLOAD, local);    }    /**     * Load float from the given local into stack.     *     * @param local number of local register     */    public void addFLoad(int local)    {        xop(ByteCode.FLOAD_0, ByteCode.FLOAD, local);    }    /**     * Load double from the given local into stack.     *     * @param local number of local register     */    public void addDLoad(int local)    {        xop(ByteCode.DLOAD_0, ByteCode.DLOAD, local);    }    /**     * Load object from the given local into stack.     *     * @param local number of local register     */    public void addALoad(int local)    {        xop(ByteCode.ALOAD_0, ByteCode.ALOAD, local);    }    /**     * Load "this" into stack.     */    public void addLoadThis()    {        add(ByteCode.ALOAD_0);    }    private void xop(int shortOp, int op, int local)    {        switch (local) {          case 0:            add(shortOp);            break;          case 1:            add(shortOp + 1);            break;          case 2:            add(shortOp + 2);            break;          case 3:            add(shortOp + 3);            break;          default:            add(op, local);        }    }    public int addTableSwitch(int low, int high)    {        if (DEBUGCODE) {            System.out.println("Add "+bytecodeStr(ByteCode.TABLESWITCH)                               +" "+low+" "+high);        }        if (low > high)            throw new IllegalArgumentException("Bad bounds: "+low+' '+ high);        int newStack = itsStackTop + stackChange(ByteCode.TABLESWITCH);        if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack);        int entryCount = high - low + 1;        int padSize = 3 & ~itsCodeBufferTop; // == 3 - itsCodeBufferTop % 4        int N = addReservedCodeSpace(1 + padSize + 4 * (1 + 2 + entryCount));        int switchStart = N;        itsCodeBuffer[N++] = (byte)ByteCode.TABLESWITCH;        while (padSize != 0) {            itsCodeBuffer[N++] = 0;            --padSize;        }        N += 4; // skip default offset        N = putInt32(low, itsCodeBuffer, N);        putInt32(high, itsCodeBuffer, N);        itsStackTop = (short)newStack;        if (newStack > itsMaxStack) itsMaxStack = (short)newStack;        if (DEBUGSTACK) {            System.out.println("After "+bytecodeStr(ByteCode.TABLESWITCH)                               +" stack = "+itsStackTop);        }        return switchStart;    }    public final void markTableSwitchDefault(int switchStart)    {        setTableSwitchJump(switchStart, -1, itsCodeBufferTop);    }    public final void markTableSwitchCase(int switchStart, int caseIndex)    {        setTableSwitchJump(switchStart, caseIndex, itsCodeBufferTop);    }    public final void markTableSwitchCase(int switchStart, int caseIndex,                                          int stackTop)    {        if (!(0 <= stackTop && stackTop <= itsMaxStack))            throw new IllegalArgumentException("Bad stack index: "+stackTop);        itsStackTop = (short)stackTop;        setTableSwitchJump(switchStart, caseIndex, itsCodeBufferTop);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -