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

📄 ctbehavior.java

📁 Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
        throws CannotCompileException    {        declaringClass.checkModify();        try {            Javac jv = new Javac(declaringClass);            if (delegateMethod != null)                jv.recordProceed(delegateObj, delegateMethod);            Bytecode b = jv.compileBody(this, src);            methodInfo.setCodeAttribute(b.toCodeAttribute());            methodInfo.setAccessFlags(methodInfo.getAccessFlags()                                      & ~AccessFlag.ABSTRACT);        }        catch (CompileError e) {            throw new CannotCompileException(e);        }    }    static void setBody0(CtClass srcClass, MethodInfo srcInfo,                         CtClass destClass, MethodInfo destInfo,                         ClassMap map)        throws CannotCompileException    {        destClass.checkModify();        map = new ClassMap(map);        map.put(srcClass.getName(), destClass.getName());        try {            CodeAttribute cattr = srcInfo.getCodeAttribute();            if (cattr != null) {                ConstPool cp = destInfo.getConstPool();                CodeAttribute ca = (CodeAttribute)cattr.copy(cp, map);                destInfo.setCodeAttribute(ca);            }        }        catch (CodeAttribute.RuntimeCopyException e) {            /* the exception may be thrown by copy() in CodeAttribute.             */            throw new CannotCompileException(e);        }        destInfo.setAccessFlags(destInfo.getAccessFlags()                                & ~AccessFlag.ABSTRACT);    }    /**     * Obtains an attribute with the given name.     * If that attribute is not found in the class file, this     * method returns null.     *     * <p>Note that an attribute is a data block specified by     * the class file format.  It is not an annotation.     * See {@link javassist.bytecode.AttributeInfo}.     *     * @param name              attribute name     */    public byte[] getAttribute(String name) {        AttributeInfo ai = methodInfo.getAttribute(name);        if (ai == null)            return null;        else            return ai.get();    }    /**     * Adds an attribute. The attribute is saved in the class file.     *     * <p>Note that an attribute is a data block specified by     * the class file format.  It is not an annotation.     * See {@link javassist.bytecode.AttributeInfo}.     *     * @param name      attribute name     * @param data      attribute value     */    public void setAttribute(String name, byte[] data) {        declaringClass.checkModify();        methodInfo.addAttribute(new AttributeInfo(methodInfo.getConstPool(),                                                  name, data));    }    /**     * Declares to use <code>$cflow</code> for this method/constructor.     * If <code>$cflow</code> is used, the class files modified     * with Javassist requires a support class     * <code>javassist.runtime.Cflow</code> at runtime     * (other Javassist classes are not required at runtime).     *     * <p>Every <code>$cflow</code> variable is given a unique name.     * For example, if the given name is <code>"Point.paint"</code>,     * then the variable is indicated by <code>$cflow(Point.paint)</code>.     *     * @param name      <code>$cflow</code> name.  It can include     *                  alphabets, numbers, <code>_</code>,     *                  <code>$</code>, and <code>.</code> (dot).     *     * @see javassist.runtime.Cflow     */    public void useCflow(String name) throws CannotCompileException {        CtClass cc = declaringClass;        cc.checkModify();        ClassPool pool = cc.getClassPool();        String fname;        int i = 0;        while (true) {            fname = "_cflow$" + i++;            try {                cc.getDeclaredField(fname);            }            catch(NotFoundException e) {                break;            }        }        pool.recordCflow(name, declaringClass.getName(), fname);        try {            CtClass type = pool.get("javassist.runtime.Cflow");            CtField field = new CtField(type, fname, cc);            field.setModifiers(Modifier.PUBLIC | Modifier.STATIC);            cc.addField(field, CtField.Initializer.byNew(type));            insertBefore(fname + ".enter();");            String src = fname + ".exit();";            insertAfter(src, true);        }        catch (NotFoundException e) {            throw new CannotCompileException(e);        }    }    /**     * Declares a new local variable.  The scope of this variable is the     * whole method body.  The initial value of that variable is not set.     * The declared variable can be accessed in the code snippet inserted     * by <code>insertBefore()</code>, <code>insertAfter()</code>, etc.     *     * <p>If the second parameter <code>asFinally</code> to     * <code>insertAfter()</code> is true, the declared local variable     * is not visible from the code inserted by <code>insertAfter()</code>.     *     * @param name      the name of the variable     * @param type      the type of the variable     * @see #insertBefore(String)     * @see #insertAfter(String)     */    public void addLocalVariable(String name, CtClass type)        throws CannotCompileException    {        declaringClass.checkModify();        ConstPool cp = methodInfo.getConstPool();        CodeAttribute ca = methodInfo.getCodeAttribute();        if (ca == null)            throw new CannotCompileException("no method body");        LocalVariableAttribute va = (LocalVariableAttribute)ca.getAttribute(                                                LocalVariableAttribute.tag);        if (va == null) {            va = new LocalVariableAttribute(cp);            ca.getAttributes().add(va);        }        int maxLocals = ca.getMaxLocals();        String desc = Descriptor.of(type);        va.addEntry(0, ca.getCodeLength(),                    cp.addUtf8Info(name), cp.addUtf8Info(desc), maxLocals);        ca.setMaxLocals(maxLocals + Descriptor.dataSize(desc));    }    /**     * Modifies the method/constructor body.     *     * @param converter         specifies how to modify.     */    public void instrument(CodeConverter converter)        throws CannotCompileException    {        declaringClass.checkModify();        ConstPool cp = methodInfo.getConstPool();        converter.doit(getDeclaringClass(), methodInfo, cp);    }    /**     * Modifies the method/constructor body.     *     * @param editor            specifies how to modify.     */    public void instrument(ExprEditor editor)        throws CannotCompileException    {        // if the class is not frozen,        // does not turn the modified flag on.        if (declaringClass.isFrozen())            declaringClass.checkModify();        if (editor.doit(declaringClass, methodInfo))            declaringClass.checkModify();    }    /**     * Inserts bytecode at the beginning of the body.     *     * <p>If this object represents a constructor,     * the bytecode is inserted before     * a constructor in the super class or this class is called.     * Therefore, the inserted bytecode is subject to constraints described     * in Section 4.8.2 of The Java Virtual Machine Specification (2nd ed).     * For example, it cannot access instance fields or methods although     * it may assign a value to an instance field directly declared in this     * class.  Accessing static fields and methods is allowed.     * Use <code>insertBeforeBody()</code> in <code>CtConstructor</code>.     *     * @param src       the source code representing the inserted bytecode.     *                  It must be a single statement or block.     * @see CtConstructor#insertBeforeBody(String)     */    public void insertBefore(String src) throws CannotCompileException {        declaringClass.checkModify();        CodeAttribute ca = methodInfo.getCodeAttribute();        if (ca == null)            throw new CannotCompileException("no method body");        CodeIterator iterator = ca.iterator();        Javac jv = new Javac(declaringClass);        try {            int nvars = jv.recordParams(getParameterTypes(),                                        Modifier.isStatic(getModifiers()));            jv.recordParamNames(ca, nvars);            jv.recordLocalVariables(ca, 0);            jv.compileStmnt(src);            Bytecode b = jv.getBytecode();            int stack = b.getMaxStack();            int locals = b.getMaxLocals();            if (stack > ca.getMaxStack())                ca.setMaxStack(stack);            if (locals > ca.getMaxLocals())                ca.setMaxLocals(locals);            int pos = iterator.insertEx(b.get());            iterator.insert(b.getExceptionTable(), pos);        }        catch (NotFoundException e) {            throw new CannotCompileException(e);        }        catch (CompileError e) {            throw new CannotCompileException(e);        }        catch (BadBytecode e) {            throw new CannotCompileException(e);        }    }    /**     * Inserts bytecode at the end of the body.     * The bytecode is inserted just before every return insturction.     * It is not executed when an exception is thrown.     *     * @param src       the source code representing the inserted bytecode.     *                  It must be a single statement or block.     */    public void insertAfter(String src)        throws CannotCompileException    {        insertAfter(src, false);    }    /**     * Inserts bytecode at the end of the body.     * The bytecode is inserted just before every return insturction.     *     * @param src       the source code representing the inserted bytecode.     *                  It must be a single statement or block.     * @param asFinally         true if the inserted bytecode is executed     *                  not only when the control normally returns     *                  but also when an exception is thrown.     *                  If this parameter is true, the inserted code cannot     *                  access local variables.     */    public void insertAfter(String src, boolean asFinally)        throws CannotCompileException    {        declaringClass.checkModify();        ConstPool pool = methodInfo.getConstPool();        CodeAttribute ca = methodInfo.getCodeAttribute();        if (ca == null)            throw new CannotCompileException("no method body");        CodeIterator iterator = ca.iterator();        int retAddr = ca.getMaxLocals();        Bytecode b = new Bytecode(pool, 0, retAddr + 1);        b.setStackDepth(ca.getMaxStack() + 1);        Javac jv = new Javac(b, declaringClass);        try {            int nvars = jv.recordParams(getParameterTypes(),                                        Modifier.isStatic(getModifiers()));            jv.recordParamNames(ca, nvars);            CtClass rtype = getReturnType0();            int varNo = jv.recordReturnType(rtype, true);            jv.recordLocalVariables(ca, 0);            int handlerLen = insertAfterHandler(asFinally, b, rtype, varNo);            byte[] save = makeSaveCode(pool, rtype, varNo);            byte[] restore = makeRestoreCode(b, pool, rtype, varNo);            b.addAstore(retAddr);            jv.compileStmnt(src);            b.addRet(retAddr);            ca.setMaxStack(b.getMaxStack());            ca.setMaxLocals(b.getMaxLocals());            int gapPos = iterator.append(b.get());            iterator.append(b.getExceptionTable(), gapPos);            if (asFinally)                ca.getExceptionTable().add(0, gapPos, gapPos, 0);            int gapLen = iterator.getCodeLength() - gapPos - handlerLen;            int subr = iterator.getCodeLength() - gapLen;            while (iterator.hasNext()) {                int pos = iterator.next();                if (pos >= subr)                    break;                int c = iterator.byteAt(pos);                if (c == Opcode.ARETURN || c == Opcode.IRETURN                    || c == Opcode.FRETURN || c == Opcode.LRETURN                    || c == Opcode.DRETURN || c == Opcode.RETURN) {                    insertJSR(iterator, subr, pos, save, restore);                    subr = iterator.getCodeLength() - gapLen;                }            }

⌨️ 快捷键说明

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