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

📄 expr.java

📁 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使
💻 JAVA
字号:
/* * Javassist, a Java-bytecode translator toolkit. * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License.  Alternatively, the contents of this file may be used under * the terms of the GNU Lesser General Public License Version 2.1 or later. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. */package javassist.expr;import javassist.CannotCompileException;import javassist.ClassPool;import javassist.CtBehavior;import javassist.CtClass;import javassist.CtConstructor;import javassist.CtPrimitiveType;import javassist.NotFoundException;import javassist.bytecode.AccessFlag;import javassist.bytecode.BadBytecode;import javassist.bytecode.Bytecode;import javassist.bytecode.ClassFile;import javassist.bytecode.CodeAttribute;import javassist.bytecode.CodeIterator;import javassist.bytecode.ConstPool;import javassist.bytecode.ExceptionTable;import javassist.bytecode.ExceptionsAttribute;import javassist.bytecode.MethodInfo;import javassist.bytecode.Opcode;import javassist.compiler.Javac;import java.util.Iterator;import java.util.LinkedList;/** * Expression. */public abstract class Expr implements Opcode {    int currentPos;    CodeIterator iterator;    CtClass thisClass;    MethodInfo thisMethod;    boolean edited;    int maxLocals, maxStack;    static final String javaLangObject = "java.lang.Object";    /**     * Undocumented constructor. Do not use; internal-use only.     */    protected Expr(int pos, CodeIterator i, CtClass declaring, MethodInfo m) {        currentPos = pos;        iterator = i;        thisClass = declaring;        thisMethod = m;    }    protected final ConstPool getConstPool() {        return thisMethod.getConstPool();    }    protected final boolean edited() {        return edited;    }    protected final int locals() {        return maxLocals;    }    protected final int stack() {        return maxStack;    }    /**     * Returns true if this method is static.     */    protected final boolean withinStatic() {        return (thisMethod.getAccessFlags() & AccessFlag.STATIC) != 0;    }    /**     * Returns the constructor or method containing the expression.     */    public CtBehavior where() {        MethodInfo mi = thisMethod;        CtBehavior[] cb = thisClass.getDeclaredBehaviors();        for (int i = cb.length - 1; i >= 0; --i)            if (cb[i].getMethodInfo2() == mi)                return cb[i];        CtConstructor init = thisClass.getClassInitializer();        if (init != null && init.getMethodInfo2() == mi)            return init;        /* getDeclaredBehaviors() returns a list of methods/constructors.         * Although the list is cached in a CtClass object, it might be         * recreated for some reason.  Thus, the member name and the signature         * must be also checked.         */        for (int i = cb.length - 1; i >= 0; --i) {            if (thisMethod.getName().equals(cb[i].getMethodInfo2().getName())                && thisMethod.getDescriptor()                             .equals(cb[i].getMethodInfo2().getDescriptor())) {                return cb[i];            }        }        throw new RuntimeException("fatal: not found");    }    /**     * Returns the list of exceptions that the expression may throw. This list     * includes both the exceptions that the try-catch statements including the     * expression can catch and the exceptions that the throws declaration     * allows the method to throw.     */    public CtClass[] mayThrow() {        ClassPool pool = thisClass.getClassPool();        ConstPool cp = thisMethod.getConstPool();        LinkedList list = new LinkedList();        try {            CodeAttribute ca = thisMethod.getCodeAttribute();            ExceptionTable et = ca.getExceptionTable();            int pos = currentPos;            int n = et.size();            for (int i = 0; i < n; ++i)                if (et.startPc(i) <= pos && pos < et.endPc(i)) {                    int t = et.catchType(i);                    if (t > 0)                        try {                            addClass(list, pool.get(cp.getClassInfo(t)));                        }                        catch (NotFoundException e) {                        }                }        }        catch (NullPointerException e) {        }        ExceptionsAttribute ea = thisMethod.getExceptionsAttribute();        if (ea != null) {            String[] exceptions = ea.getExceptions();            if (exceptions != null) {                int n = exceptions.length;                for (int i = 0; i < n; ++i)                    try {                        addClass(list, pool.get(exceptions[i]));                    }                    catch (NotFoundException e) {                    }            }        }        return (CtClass[])list.toArray(new CtClass[list.size()]);    }    private static void addClass(LinkedList list, CtClass c) {        Iterator it = list.iterator();        while (it.hasNext())            if (it.next() == c)                return;        list.add(c);    }    /**     * Returns the index of the bytecode corresponding to the expression. It is     * the index into the byte array containing the Java bytecode that     * implements the method.     */    public int indexOfBytecode() {        return currentPos;    }    /**     * Returns the line number of the source line containing the expression.     *      * @return -1 if this information is not available.     */    public int getLineNumber() {        return thisMethod.getLineNumber(currentPos);    }    /**     * Returns the source file containing the expression.     *      * @return null if this information is not available.     */    public String getFileName() {        ClassFile cf = thisClass.getClassFile2();        if (cf == null)            return null;        else            return cf.getSourceFile();    }    static final boolean checkResultValue(CtClass retType, String prog)            throws CannotCompileException {        /*         * Is $_ included in the source code?         */        boolean hasIt = (prog.indexOf(Javac.resultVarName) >= 0);        if (!hasIt && retType != CtClass.voidType)            throw new CannotCompileException(                    "the resulting value is not stored in "                            + Javac.resultVarName);        return hasIt;    }    /*     * If isStaticCall is true, null is assigned to $0. So $0 must be declared     * by calling Javac.recordParams().     *      * After executing this method, the current stack depth might be less than     * 0.     */    static final void storeStack(CtClass[] params, boolean isStaticCall,            int regno, Bytecode bytecode) {        storeStack0(0, params.length, params, regno + 1, bytecode);        if (isStaticCall)            bytecode.addOpcode(ACONST_NULL);        bytecode.addAstore(regno);    }    private static void storeStack0(int i, int n, CtClass[] params, int regno,            Bytecode bytecode) {        if (i >= n)            return;        else {            CtClass c = params[i];            int size;            if (c instanceof CtPrimitiveType)                size = ((CtPrimitiveType)c).getDataSize();            else                size = 1;            storeStack0(i + 1, n, params, regno + size, bytecode);            bytecode.addStore(regno, c);        }    }    /**     * Replaces this expression with the bytecode derived from     * the given source text.     *     * @param statement         a Java statement.     */    public abstract void replace(String statement) throws CannotCompileException;    /**     * Replaces this expression with the bytecode derived from     * the given source text and <code>ExprEditor</code>.     *     * @param statement         a Java statement.     * @param recursive         if not null, the substituted bytecode     *                          is recursively processed by the given     *                          <code>ExprEditor</code>.     * @since 3.1     */    public void replace(String statement, ExprEditor recursive)        throws CannotCompileException    {        replace(statement);        if (recursive != null)            runEditor(recursive, iterator);    }    protected void replace0(int pos, Bytecode bytecode, int size)            throws BadBytecode {        byte[] code = bytecode.get();        edited = true;        int gap = code.length - size;        for (int i = 0; i < size; ++i)            iterator.writeByte(NOP, pos + i);        if (gap > 0)            iterator.insertGap(pos, gap);        iterator.write(code, pos);        iterator.insert(bytecode.getExceptionTable(), pos);        maxLocals = bytecode.getMaxLocals();        maxStack = bytecode.getMaxStack();    }    protected void runEditor(ExprEditor ed, CodeIterator oldIterator)        throws CannotCompileException    {        CodeAttribute codeAttr = oldIterator.get();        int orgLocals = codeAttr.getMaxLocals();        int orgStack = codeAttr.getMaxStack();        int newLocals = locals();        codeAttr.setMaxStack(stack());        codeAttr.setMaxLocals(newLocals);        ExprEditor.LoopContext context            = new ExprEditor.LoopContext(newLocals);        int size = oldIterator.getCodeLength();        int endPos = oldIterator.lookAhead();        oldIterator.move(currentPos);        if (ed.doit(thisClass, thisMethod, context, oldIterator, endPos))            edited = true;        oldIterator.move(endPos + oldIterator.getCodeLength() - size);        codeAttr.setMaxLocals(orgLocals);        codeAttr.setMaxStack(orgStack);        maxLocals = context.maxLocals;        maxStack += context.maxStack;    }}

⌨️ 快捷键说明

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