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

📄 expreditor.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.bytecode.*;import javassist.CtClass;import javassist.CannotCompileException;/** * A translator of method bodies. * * <p>The users can define a subclass of this class to customize how to * modify a method body.  The overall architecture is similar to the * strategy pattern. * * <p>If <code>instrument()</code> is called in * <code>CtMethod</code>, the method body is scanned from the beginning * to the end. * Whenever an expression, such as a method call and a <tt>new</tt> * expression (object creation), * is found, <code>edit()</code> is called in <code>ExprEdit</code>. * <code>edit()</code> can inspect and modify the given expression. * The modification is reflected on the original method body.  If * <code>edit()</code> does nothing, the original method body is not * changed. * * <p>The following code is an example: * * <ul><pre> * CtMethod cm = ...; * cm.instrument(new ExprEditor() { *     public void edit(MethodCall m) throws CannotCompileException { *         if (m.getClassName().equals("Point")) { *             System.out.println(m.getMethodName() + " line: " *                                + m.getLineNumber()); *     } * }); * </pre></ul> * * <p>This code inspects all method calls appearing in the method represented * by <code>cm</code> and it prints the names and the line numbers of the * methods declared in class <code>Point</code>.  This code does not modify * the body of the method represented by <code>cm</code>.  If the method * body must be modified, call <code>replace()</code> * in <code>MethodCall</code>. * * @see javassist.CtClass#instrument(ExprEditor) * @see javassist.CtMethod#instrument(ExprEditor) * @see javassist.CtConstructor#instrument(ExprEditor) * @see MethodCall * @see NewExpr * @see FieldAccess * * @see javassist.CodeConverter */public class ExprEditor {    /**     * Default constructor.  It does nothing.     */    public ExprEditor() {}    /**     * Undocumented method.  Do not use; internal-use only.     */    public boolean doit(CtClass clazz, MethodInfo minfo)        throws CannotCompileException    {        CodeAttribute codeAttr = minfo.getCodeAttribute();        if (codeAttr == null)            return false;        CodeIterator iterator = codeAttr.iterator();        boolean edited = false;        LoopContext context = new LoopContext(codeAttr.getMaxLocals());        while (iterator.hasNext())            if (loopBody(iterator, clazz, minfo, context))                edited = true;        ExceptionTable et = codeAttr.getExceptionTable();        int n = et.size();        for (int i = 0; i < n; ++i) {            Handler h = new Handler(et, i, iterator, clazz, minfo);            edit(h);            if (h.edited()) {                edited = true;                context.updateMax(h.locals(), h.stack());            }        }        codeAttr.setMaxLocals(context.maxLocals);        codeAttr.setMaxStack(codeAttr.getMaxStack() + context.maxStack);        return edited;    }    /**     * Visits each bytecode in the given range.      */    boolean doit(CtClass clazz, MethodInfo minfo, LoopContext context,                 CodeIterator iterator, int endPos)        throws CannotCompileException    {        boolean edited = false;        while (iterator.hasNext() && iterator.lookAhead() < endPos) {            int size = iterator.getCodeLength();            if (loopBody(iterator, clazz, minfo, context)) {                edited = true;                int size2 = iterator.getCodeLength();                if (size != size2)  // the body was modified.                    endPos += size2 - size;            }        }        return edited;    }    final static class NewOp {        NewOp next;        int pos;        String type;        NewOp(NewOp n, int p, String t) {            next = n;            pos = p;            type = t;        }    }    final static class LoopContext {        NewOp newList;        int maxLocals;        int maxStack;        LoopContext(int locals) {            maxLocals = locals;            maxStack = 0;            newList = null;        }        void updateMax(int locals, int stack) {            if (maxLocals < locals)                maxLocals = locals;            if (maxStack < stack)                maxStack = stack;        }    }    final boolean loopBody(CodeIterator iterator, CtClass clazz,                           MethodInfo minfo, LoopContext context)        throws CannotCompileException    {        try {            Expr expr = null;            int pos = iterator.next();            int c = iterator.byteAt(pos);            if (c < Opcode.GETSTATIC)   // c < 178                /* skip */;            else if (c < Opcode.NEWARRAY) { // c < 188                if (c == Opcode.INVOKESTATIC                    || c == Opcode.INVOKEINTERFACE                    || c == Opcode.INVOKEVIRTUAL) {                    expr = new MethodCall(pos, iterator, clazz, minfo);                    edit((MethodCall)expr);                }                else if (c == Opcode.GETFIELD || c == Opcode.GETSTATIC                         || c == Opcode.PUTFIELD                         || c == Opcode.PUTSTATIC) {                    expr = new FieldAccess(pos, iterator, clazz, minfo, c);                    edit((FieldAccess)expr);                }                else if (c == Opcode.NEW) {                    int index = iterator.u16bitAt(pos + 1);                    context.newList = new NewOp(context.newList, pos,                                        minfo.getConstPool().getClassInfo(index));                }                else if (c == Opcode.INVOKESPECIAL) {                    NewOp newList = context.newList;                    if (newList != null                        && minfo.getConstPool().isConstructor(newList.type,                                            iterator.u16bitAt(pos + 1)) > 0) {                        expr = new NewExpr(pos, iterator, clazz, minfo,                                           newList.type, newList.pos);                        edit((NewExpr)expr);                        context.newList = newList.next;                    }                    else {                        MethodCall mcall = new MethodCall(pos, iterator, clazz, minfo);                        if (mcall.getMethodName().equals(MethodInfo.nameInit)) {                            ConstructorCall ccall = new ConstructorCall(pos, iterator, clazz, minfo);                            expr = ccall;                            edit(ccall);                        }                        else {                            expr = mcall;                            edit(mcall);                        }                    }                }            }            else {  // c >= 188                if (c == Opcode.NEWARRAY || c == Opcode.ANEWARRAY                    || c == Opcode.MULTIANEWARRAY) {                    expr = new NewArray(pos, iterator, clazz, minfo, c);                    edit((NewArray)expr);                }                else if (c == Opcode.INSTANCEOF) {                    expr = new Instanceof(pos, iterator, clazz, minfo);                    edit((Instanceof)expr);                }                else if (c == Opcode.CHECKCAST) {                    expr = new Cast(pos, iterator, clazz, minfo);                    edit((Cast)expr);                }            }            if (expr != null && expr.edited()) {                context.updateMax(expr.locals(), expr.stack());                return true;            }            else                return false;        }        catch (BadBytecode e) {            throw new CannotCompileException(e);        }    }    /**     * Edits a <tt>new</tt> expression (overridable).     * The default implementation performs nothing.     *     * @param e         the <tt>new</tt> expression creating an object.     */    public void edit(NewExpr e) throws CannotCompileException {}    /**     * Edits an expression for array creation (overridable).     * The default implementation performs nothing.     *     * @param a         the <tt>new</tt> expression for creating an array.     * @throws CannotCompileException     */    public void edit(NewArray a) throws CannotCompileException {}    /**     * Edits a method call (overridable).     *     * The default implementation performs nothing.     */    public void edit(MethodCall m) throws CannotCompileException {}    /**     * Edits a constructor call (overridable).     * The constructor call is either     * <code>super()</code> or <code>this()</code>     * included in a constructor body.     *     * The default implementation performs nothing.     *     * @see #edit(NewExpr)     */    public void edit(ConstructorCall c) throws CannotCompileException {}    /**     * Edits a field-access expression (overridable).     * Field access means both read and write.     * The default implementation performs nothing.     */    public void edit(FieldAccess f) throws CannotCompileException {}    /**     * Edits an instanceof expression (overridable).     * The default implementation performs nothing.     */    public void edit(Instanceof i) throws CannotCompileException {}    /**     * Edits an expression for explicit type casting (overridable).     * The default implementation performs nothing.     */    public void edit(Cast c) throws CannotCompileException {}    /**     * Edits a catch clause (overridable).     * The default implementation performs nothing.     */    public void edit(Handler h) throws CannotCompileException {}}

⌨️ 快捷键说明

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