methodbuilder.java

来自「JiBX是一个为Java提供的XML数据绑定框架。它可以和现存的类一起运行」· Java 代码 · 共 1,732 行 · 第 1/4 页

JAVA
1,732
字号
    /**     * Verify the top value in the stack state resulting from the current     * instruction list is an array.     *     * @return array item type     */    private String verifyArray() {        verifyStackDepth(1);        String type = m_stackState.peek();        if (type.endsWith("[]")) {            return type.substring(0, type.length()-2);        } else {            throw new IllegalStateException                ("Internal error: Expected array type on stack , found " +                type);        }    }        /**     * Verify the top value in the stack state resulting from the current     * instruction list is an array of the specified type.     *     * @param type array item type     */    private void verifyArray(String type) {        String atype = verifyArray();        if (!atype.equals(type)) {            throw new IllegalStateException                ("Internal error: Expected array of " + type +                " on stack , found array of " + atype);        }    }        /**     * Verify the top two values in the stack state resulting from the current     * instruction list.     *     * @param t1 expected type for first item on stack     * @param t2 expected type for second item on stack     */    private void verifyStack(String t1, String t2) {        verifyStackDepth(2);        verifyCompatible(m_stackState.peek(), t1);        verifyCompatible(m_stackState.peek(1), t2);    }    /**     * Verify the top values in the stack state resulting from the current     * instruction list. This form checks only the actual call parameters.     *     * @param types expected parameter types on stack     */    private void verifyCallStack(String[] types) {                // make sure there are enough items on stack        int count = types.length;        verifyStackDepth(count);                // verify all parameter types for call        for (int i = 0; i < count; i++) {            int slot = count - i - 1;            verifyCompatible(m_stackState.peek(slot), types[i]);        }    }    /**     * Verify the top values in the stack state resulting from the current     * instruction list. This form checks both the object being called and the     * actual call parameters.     *     * @param clas name of method class     * @param types expected parameter types on stack     */    private void verifyCallStack(String clas, String[] types) {                // start by verifying object reference        int count = types.length;        verifyStackDepth(count+1);        verifyCompatible(m_stackState.peek(count), clas);                // check values for call parameters        verifyCallStack(types);    }    /**     * Verify that the top value in the stack state resulting from the current     * instruction list is an object reference.     */    private void verifyStackObject() {        verifyStackDepth(1);        String top = m_stackState.peek();        if (ClassItem.isPrimitive(top)) {            throw new IllegalStateException("Internal error: " +                "Expected object reference on stack , found " +                 m_stackState.peek() + "\n full stack:\n" + describeStack());        }    }    /**     * Append IFEQ branch instruction to method.     *     * @param src object responsible for generating branch     * @return wrapper for appended conditional branch     */    public BranchWrapper appendIFEQ(Object src) {        verifyStack("int");        BranchHandle hand = m_instructionList.append(new IFEQ(null));        setTarget(hand);        m_stackState.pop();        return new BranchWrapper(hand, m_stackState.toArray(), src);    }    /**     * Append IFGE branch instruction to method.     *     * @param src object responsible for generating branch     * @return wrapper for appended conditional branch     */    public BranchWrapper appendIFGE(Object src) {        verifyStack("int");        BranchHandle hand = m_instructionList.append(new IFGE(null));        setTarget(hand);        m_stackState.pop();        return new BranchWrapper(hand, m_stackState.toArray(), src);    }    /**     * Append IFLT branch instruction to method.     *     * @param src object responsible for generating branch     * @return wrapper for appended conditional branch     */    public BranchWrapper appendIFLT(Object src) {        verifyStack("int");        BranchHandle hand = m_instructionList.append(new IFLT(null));        setTarget(hand);        m_stackState.pop();        return new BranchWrapper(hand, m_stackState.toArray(), src);    }    /**     * Append IFNE branch instruction to method.     *     * @param src object responsible for generating branch     * @return wrapper for appended conditional branch     */    public BranchWrapper appendIFNE(Object src) {        verifyStack("int");        BranchHandle hand = m_instructionList.append(new IFNE(null));        setTarget(hand);        m_stackState.pop();        return new BranchWrapper(hand, m_stackState.toArray(), src);    }    /**     * Append IFNONNULL branch instruction to method.     *     * @param src object responsible for generating branch     * @return wrapper for appended conditional branch     */    public BranchWrapper appendIFNONNULL(Object src) {        verifyStackObject();        BranchHandle hand = m_instructionList.append(new IFNONNULL(null));        setTarget(hand);        m_stackState.pop();        return new BranchWrapper(hand, m_stackState.toArray(), src);    }    /**     * Append IFNULL branch instruction to method.     *     * @param src object responsible for generating branch     * @return wrapper for appended conditional branch     */    public BranchWrapper appendIFNULL(Object src) {        verifyStackObject();        BranchHandle hand = m_instructionList.append(new IFNULL(null));        setTarget(hand);        m_stackState.pop();        return new BranchWrapper(hand, m_stackState.toArray(), src);    }    /**     * Append IF_ICMPNE branch instruction to method.     *     * @param src object responsible for generating branch     * @return wrapper for appended conditional branch     */    public BranchWrapper appendIF_ICMPNE(Object src) {        verifyStack("int", "int");        BranchHandle hand = m_instructionList.append(new IF_ICMPNE(null));        setTarget(hand);        m_stackState.pop(2);        return new BranchWrapper(hand, m_stackState.toArray(), src);    }    /**     * Append unconditional branch instruction to method.     *     * @param src object responsible for generating branch     * @return wrapper for appended unconditional branch     */    public BranchWrapper appendUnconditionalBranch(Object src) {        BranchHandle hand = m_instructionList.append(new GOTO(null));        setTarget(hand);        BranchWrapper wrapper =            new BranchWrapper(hand, m_stackState.toArray(), src);        m_stackState = null;        return wrapper;    }    /**     * Append compound instruction to method.     *     * @param ins instruction to be appended     */    private void append(CompoundInstruction ins) {        setTarget(m_instructionList.append(ins));    }    /**     * Append instruction to method.     *     * @param ins instruction to be appended     */    private void append(Instruction ins) {        setTarget(m_instructionList.append(ins));    }    /**     * Create load constant instruction and append to method. Builds the most     * appropriate type of instruction for the value.     *     * @param value constant value to be loaded     */    public void appendLoadConstant(int value) {        append(m_instructionBuilder.createLoadConstant(value));        m_stackState.push("int");    }    /**     * Create load constant instruction and append to method. Loads a     * <code>String</code> reference from the constant pool.     *     * @param value constant value to be loaded     */    public void appendLoadConstant(String value) {        append(m_instructionBuilder.createLoadConstant(value));        m_stackState.push("java.lang.String");    }    /**     * Create load constant instruction and append to method. Loads an     * unwrapped primitive value from the constant pool.     *     * @param value constant value to be loaded     */    public void appendLoadConstant(Object value) {        append(m_instructionBuilder.createLoadConstant(value));        if (value instanceof Integer || value instanceof Character ||            value instanceof Short || value instanceof Boolean ||            value instanceof Byte) {            m_stackState.push("int");        } else if (value instanceof Long) {            m_stackState.push("long");        } else if (value instanceof Float) {            m_stackState.push("float");        } else if (value instanceof Double) {            m_stackState.push("double");        } else {            throw new IllegalArgumentException("Unknown argument type");        }    }    /**     * Create getfield instruction and append to method. Uses the target field     * information to generate the instruction.     *     * @param item information for field to be gotton     */    public void appendGetField(ClassItem item) {        verifyStack(item.getClassFile().getName());        append(m_instructionBuilder.createGetField(item));        m_stackState.pop();        m_stackState.push(item.getTypeName());    }    /**     * Create getstatic instruction and append to method. Uses the target field     * information to generate the instruction.     *     * @param item information for field to be set     */    public void appendGetStatic(ClassItem item) {        append(m_instructionBuilder.createGetStatic(item));        m_stackState.push(item.getTypeName());    }    /**     * Create get instruction and append to method. This generates either a     * getstatic or a getfield instruction, as appropriate.     *     * @param item information for field to be gotten     */    public void appendGet(ClassItem item) {        if (item.isStatic()) {            appendGetStatic(item);        } else {            appendGetField(item);        }    }    /**     * Create putfield instruction and append to method. Uses the target field     * information to generate the instruction.     *     * @param item information for field to be set     */    public void appendPutField(ClassItem item) {        String tname = item.getTypeName();        verifyStack(tname, item.getClassFile().getName());        append(m_instructionBuilder.createPutField(item));        m_stackState.pop(2);    }    /**     * Create putstatic instruction and append to method. Uses the target field     * information to generate the instruction.     *     * @param item information for field to be set     */    public void appendPutStatic(ClassItem item) {        verifyStack(item.getTypeName());        append(m_instructionBuilder.createPutStatic(item));        m_stackState.pop();    }    /**     * Create put instruction and append to method. This generates either a     * putstatic or a putfield instruction, as appropriate.     *     * @param item information for field to be gotten     */    public void appendPut(ClassItem item) {        if (item.isStatic()) {            appendPutStatic(item);        } else {            appendPutField(item);        }    }    /**     * Create invoke instruction for static, member, or interface method and     * append to method. Uses the target method information to generate the     * correct instruction.     *     * @param item information for method to be called     */    public void appendCall(ClassItem item) {                // process based on call type        String[] types = item.getArgumentTypes();        int count = types.length;        if (item.getClassFile().isInterface()) {                        // process parameters and object reference for interface call            verifyCallStack(item.getClassFile().getName(), types);            append(m_instructionBuilder.createCallInterface(item));            m_stackState.pop(count+1);                    } else if ((item.getAccessFlags() & Constants.ACC_STATIC) != 0) {                        // process only parameters for static call            verifyCallStack(types);            append(m_instructionBuilder.createCallStatic(item));            if (count > 0) {                m_stackState.pop(count);            }                    } else {                        // process parameters and object reference for normal method call            verifyCallStack(item.getClassFile().getName(), types);            append(m_instructionBuilder.createCallVirtual(item));            m_stackState.pop(count+1);        }                // adjust stack state to reflect result of call        if (!"void".equals(item.getTypeName())) {            m_stackState.push(item.getTypeName());        }    }    /**     * Create invoke static method instruction from signature and append to     * method.     *     * @param method fully qualified class and method name     * @param signature method signature in standard form     */    public void appendCallStatic(String method, String signature) {                // verify all call parameters on stack        String[] types = ClassItem.getParametersFromSignature(signature);        verifyCallStack(types);                // generate the actual method call        append(m_instructionBuilder.createCallStatic(method, signature));                // change stack state to reflect result of call        if (types.length > 0) {            m_stackState.pop(types.length);        }        String result = ClassItem.getTypeFromSignature(signature);        if (!"void".equals(result)) {            m_stackState.push(result);        }    }    /**     * Create invoke virtual method instruction from signature and append to     * method.     *     * @param method fully qualified class and method name     * @param signature method signature in standard form     */    public void appendCallVirtual(String method, String signature) {                // verify all call parameters and object reference on stack        String[] types = ClassItem.getParametersFromSignature(signature);        int split = method.lastIndexOf('.');        if (split < 0) {            throw new IllegalArgumentException

⌨️ 快捷键说明

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