Search in sources :

Example 1 with Javac

use of org.hotswap.agent.javassist.compiler.Javac in project HotswapAgent by HotswapProjects.

the class CtConstructor method insertBeforeBody.

/**
 * Inserts bytecode just after another constructor in the super class
 * or this class is called.
 * It does not work if this object represents a class initializer.
 *
 * @param src       the source code representing the inserted bytecode.
 *                  It must be a single statement or block.
 */
public void insertBeforeBody(String src) throws CannotCompileException {
    CtClass cc = declaringClass;
    cc.checkModify();
    if (isClassInitializer())
        throw new CannotCompileException("class initializer");
    CodeAttribute ca = methodInfo.getCodeAttribute();
    CodeIterator iterator = ca.iterator();
    Bytecode b = new Bytecode(methodInfo.getConstPool(), ca.getMaxStack(), ca.getMaxLocals());
    b.setStackDepth(ca.getMaxStack());
    Javac jv = new Javac(b, cc);
    try {
        jv.recordParams(getParameterTypes(), false);
        jv.compileStmnt(src);
        ca.setMaxStack(b.getMaxStack());
        ca.setMaxLocals(b.getMaxLocals());
        iterator.skipConstructor();
        int pos = iterator.insertEx(b.get());
        iterator.insert(b.getExceptionTable(), pos);
        methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2());
    } catch (NotFoundException e) {
        throw new CannotCompileException(e);
    } catch (CompileError e) {
        throw new CannotCompileException(e);
    } catch (BadBytecode e) {
        throw new CannotCompileException(e);
    }
}
Also used : CompileError(org.hotswap.agent.javassist.compiler.CompileError) Javac(org.hotswap.agent.javassist.compiler.Javac)

Example 2 with Javac

use of org.hotswap.agent.javassist.compiler.Javac in project HotswapAgent by HotswapProjects.

the class CtBehavior method setBody.

/**
 * Sets a method/constructor body.
 *
 * @param src       the source code representing the body.
 *                  It must be a single statement or block.
 *                  If it is <code>null</code>, the substituted
 *                  body does nothing except returning zero or null.
 * @param delegateObj       the source text specifying the object
 *                          that is called on by <code>$proceed()</code>.
 * @param delegateMethod    the name of the method
 *                          that is called by <code>$proceed()</code>.
 */
public void setBody(String src, String delegateObj, String delegateMethod) throws CannotCompileException {
    CtClass cc = declaringClass;
    cc.checkModify();
    try {
        Javac jv = new Javac(cc);
        if (delegateMethod != null)
            jv.recordProceed(delegateObj, delegateMethod);
        Bytecode b = jv.compileBody(this, src);
        methodInfo.setCodeAttribute(b.toCodeAttribute());
        methodInfo.setAccessFlags(methodInfo.getAccessFlags() & ~AccessFlag.ABSTRACT);
        methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2());
        declaringClass.rebuildClassFile();
    } catch (CompileError e) {
        throw new CannotCompileException(e);
    } catch (BadBytecode e) {
        throw new CannotCompileException(e);
    }
}
Also used : CompileError(org.hotswap.agent.javassist.compiler.CompileError) Javac(org.hotswap.agent.javassist.compiler.Javac)

Example 3 with Javac

use of org.hotswap.agent.javassist.compiler.Javac in project HotswapAgent by HotswapProjects.

the class CtBehavior method insertBefore.

private void insertBefore(String src, boolean rebuild) throws CannotCompileException {
    CtClass cc = declaringClass;
    cc.checkModify();
    CodeAttribute ca = methodInfo.getCodeAttribute();
    if (ca == null)
        throw new CannotCompileException("no method body");
    CodeIterator iterator = ca.iterator();
    Javac jv = new Javac(cc);
    try {
        int nvars = jv.recordParams(getParameterTypes(), Modifier.isStatic(getModifiers()));
        jv.recordParamNames(ca, nvars);
        jv.recordLocalVariables(ca, 0);
        jv.recordType(getReturnType0());
        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);
        if (rebuild)
            methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2());
    } catch (NotFoundException e) {
        throw new CannotCompileException(e);
    } catch (CompileError e) {
        throw new CannotCompileException(e);
    } catch (BadBytecode e) {
        throw new CannotCompileException(e);
    }
}
Also used : CompileError(org.hotswap.agent.javassist.compiler.CompileError) Javac(org.hotswap.agent.javassist.compiler.Javac)

Example 4 with Javac

use of org.hotswap.agent.javassist.compiler.Javac in project HotswapAgent by HotswapProjects.

the class CtBehavior method insertAfter.

/**
 * 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 {
    CtClass cc = declaringClass;
    cc.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, cc);
    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);
        // finally clause for exceptions
        int handlerLen = insertAfterHandler(asFinally, b, rtype, varNo, jv, src);
        int handlerPos = iterator.getCodeLength();
        if (asFinally)
            ca.getExceptionTable().add(getStartPosOfBody(ca), handlerPos, handlerPos, 0);
        int adviceLen = 0;
        int advicePos = 0;
        boolean noReturn = true;
        while (iterator.hasNext()) {
            int pos = iterator.next();
            if (pos >= handlerPos)
                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) {
                if (noReturn) {
                    // finally clause for normal termination
                    adviceLen = insertAfterAdvice(b, jv, src, pool, rtype, varNo);
                    handlerPos = iterator.append(b.get());
                    iterator.append(b.getExceptionTable(), handlerPos);
                    advicePos = iterator.getCodeLength() - adviceLen;
                    handlerLen = advicePos - handlerPos;
                    noReturn = false;
                }
                insertGoto(iterator, advicePos, pos);
                advicePos = iterator.getCodeLength() - adviceLen;
                handlerPos = advicePos - handlerLen;
            }
        }
        if (noReturn) {
            handlerPos = iterator.append(b.get());
            iterator.append(b.getExceptionTable(), handlerPos);
        }
        ca.setMaxStack(b.getMaxStack());
        ca.setMaxLocals(b.getMaxLocals());
        methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2());
    } catch (NotFoundException e) {
        throw new CannotCompileException(e);
    } catch (CompileError e) {
        throw new CannotCompileException(e);
    } catch (BadBytecode e) {
        throw new CannotCompileException(e);
    }
}
Also used : CompileError(org.hotswap.agent.javassist.compiler.CompileError) Javac(org.hotswap.agent.javassist.compiler.Javac)

Example 5 with Javac

use of org.hotswap.agent.javassist.compiler.Javac in project HotswapAgent by HotswapProjects.

the class CtBehavior method addCatch.

/**
 * Adds a catch clause that handles an exception thrown in the
 * body.  The catch clause must end with a return or throw statement.
 *
 * @param src       the source code representing the catch clause.
 *                  It must be a single statement or block.
 * @param exceptionType     the type of the exception handled by the
 *                          catch clause.
 * @param exceptionName     the name of the variable containing the
 *                          caught exception, for example,
 *                          <code>$e</code>.
 */
public void addCatch(String src, CtClass exceptionType, String exceptionName) throws CannotCompileException {
    CtClass cc = declaringClass;
    cc.checkModify();
    ConstPool cp = methodInfo.getConstPool();
    CodeAttribute ca = methodInfo.getCodeAttribute();
    CodeIterator iterator = ca.iterator();
    Bytecode b = new Bytecode(cp, ca.getMaxStack(), ca.getMaxLocals());
    b.setStackDepth(1);
    Javac jv = new Javac(b, cc);
    try {
        jv.recordParams(getParameterTypes(), Modifier.isStatic(getModifiers()));
        int var = jv.recordVariable(exceptionType, exceptionName);
        b.addAstore(var);
        jv.compileStmnt(src);
        int stack = b.getMaxStack();
        int locals = b.getMaxLocals();
        if (stack > ca.getMaxStack())
            ca.setMaxStack(stack);
        if (locals > ca.getMaxLocals())
            ca.setMaxLocals(locals);
        int len = iterator.getCodeLength();
        int pos = iterator.append(b.get());
        ca.getExceptionTable().add(getStartPosOfBody(ca), len, len, cp.addClassInfo(exceptionType));
        iterator.append(b.getExceptionTable(), pos);
        methodInfo.rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2());
    } catch (NotFoundException e) {
        throw new CannotCompileException(e);
    } catch (CompileError e) {
        throw new CannotCompileException(e);
    } catch (BadBytecode e) {
        throw new CannotCompileException(e);
    }
}
Also used : CompileError(org.hotswap.agent.javassist.compiler.CompileError) Javac(org.hotswap.agent.javassist.compiler.Javac)

Aggregations

Javac (org.hotswap.agent.javassist.compiler.Javac)8 CompileError (org.hotswap.agent.javassist.compiler.CompileError)7 BadBytecode (org.hotswap.agent.javassist.bytecode.BadBytecode)1 Bytecode (org.hotswap.agent.javassist.bytecode.Bytecode)1