diff options
author | Mårten Hedborg <marten.hedborg@cinnober.com> | 2014-11-28 13:50:50 +0100 |
---|---|---|
committer | Mårten Hedborg <marten.hedborg@cinnober.com> | 2014-11-28 13:50:50 +0100 |
commit | 1025384fe04e05dee846b8db3fd6c9de853c7012 (patch) | |
tree | 66c350296d6ef7628aba6cad1b8e551d953c4b21 /src | |
parent | f2093c28be24336593e1ebd9c2c633ee0f8c5b5c (diff) | |
download | javassist-1025384fe04e05dee846b8db3fd6c9de853c7012.tar.gz javassist-1025384fe04e05dee846b8db3fd6c9de853c7012.zip |
Added call back feature to CtBehaviour
Diffstat (limited to 'src')
-rw-r--r-- | src/main/javassist/CtBehavior.java | 108 | ||||
-rw-r--r-- | src/main/javassist/tools/Callback.java | 39 |
2 files changed, 147 insertions, 0 deletions
diff --git a/src/main/javassist/CtBehavior.java b/src/main/javassist/CtBehavior.java index 92513159..e52fcb79 100644 --- a/src/main/javassist/CtBehavior.java +++ b/src/main/javassist/CtBehavior.java @@ -20,6 +20,7 @@ import javassist.bytecode.*; import javassist.compiler.Javac; import javassist.compiler.CompileError; import javassist.expr.ExprEditor; +import javassist.tools.Callback; /** * <code>CtBehavior</code> represents a method, a constructor, @@ -714,6 +715,29 @@ public abstract class CtBehavior extends CtMember { } /** + * Inserts callback at the beginning of the body. + * + * <p>If this object represents a constructor, + * the callback is inserted before + * a constructor in the super class or this class is called. + * Therefore, the inserted callback 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 callback the source code representing the inserted bytecode. + * It must be a single statement or block. + * @see CtConstructor#insertBeforeBody(String) + */ + public void insertBefore(Callback callback) + throws CannotCompileException + { + insertBefore(callback.toString(), true); + } + + /** * Inserts bytecode at the beginning of the body. * * <p>If this object represents a constructor, @@ -779,6 +803,39 @@ public abstract class CtBehavior extends CtMember { } /** + * Inserts callback bytecode at the end of the body. + * The callback is inserted just before every return insturction. + * It is not executed when an exception is thrown. + * + * @param callback the source code representing the inserted bytecode. + * It must be a single statement or block. + */ + public void insertAfter(Callback callback) + throws CannotCompileException + { + insertAfter(callback.toString(), false); + } + + /** + * Inserts callback bytecode at the end of the body. + * The callback is inserted just before every return insturction. + * It is not executed when an exception is thrown. + * + * @param callback the callback 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(Callback callback, boolean asFinally) + throws CannotCompileException + { + insertAfter(callback.toString(), asFinally); + } + + /** * 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. @@ -1135,6 +1192,29 @@ public abstract class CtBehavior extends CtMember { } /** + * Inserts callback bytecode at the specified line in the body. + * It is equivalent to: + * + * <br><code>insertAt(lineNum, true, src)</code> + * + * <br>See this method as well. + * + * @param lineNum the line number. The bytecode is inserted at the + * beginning of the code at the line specified by this + * line number. + * @param callback the callback source code representing the inserted bytecode. + * It must be a single statement or block. + * @return the line number at which the callback bytecode has been inserted. + * + * @see CtBehavior#insertAt(int,boolean,String) + */ + public int insertAt(int lineNum, Callback callback) + throws CannotCompileException + { + return insertAt(lineNum, true, callback.toString()); + } + + /** * Inserts bytecode at the specified line in the body. * * <p>If there is not @@ -1210,4 +1290,32 @@ public abstract class CtBehavior extends CtMember { throw new CannotCompileException(e); } } + + /** + * Inserts callback bytecode at the specified line in the body. + * + * <p>If there is not + * a statement at the specified line, the bytecode might be inserted + * at the line including the first statement after that line specified. + * For example, if there is only a closing brace at that line, the + * bytecode would be inserted at another line below. + * To know exactly where the bytecode will be inserted, call with + * <code>modify</code> set to <code>false</code>. + * + * @param lineNum the line number. The bytecode is inserted at the + * beginning of the code at the line specified by this + * line number. + * @param modify if false, this method does not insert the bytecode. + * It instead only returns the line number at which + * the bytecode would be inserted. + * @param callback the callback source code representing the inserted bytecode. + * It must be a single statement or block. + * If modify is false, the value of src can be null. + * @return the line number at which the bytecode has been inserted. + */ + public int insertAt(int lineNum, boolean modify, Callback callback) + throws CannotCompileException + { + return insertAt(lineNum,modify,callback.toString()); + } } diff --git a/src/main/javassist/tools/Callback.java b/src/main/javassist/tools/Callback.java new file mode 100644 index 00000000..0cf5db47 --- /dev/null +++ b/src/main/javassist/tools/Callback.java @@ -0,0 +1,39 @@ +package javassist.tools; + +import java.util.HashMap; +import java.util.UUID; + +/** + * Creates bytecode that when executed calls back to the objects result method. + */ +public abstract class Callback { + + public static HashMap<String, Callback> callbacks = new HashMap<String, Callback>(); + + private final String callbackCode; + + /** + * Constructs a new <code>Callback</code> object. + * + * @param src java code that returns one or many objects. if many objects + * are returned they should be comma separated + */ + public Callback(String src){ + String uuid = UUID.randomUUID().toString(); + callbacks.put(uuid, this); + callbackCode = "((javassist.tools.Callback) javassist.tools.Callback.callbacks.get(\""+uuid+"\")).result(new Object[]{"+src+"});"; + } + + /** + * Gets called when bytecode is executed + * + * @param objects java code that returns one or many objects. if many objects + * are returned they should be comma separated + */ + public abstract void result(Object... objects); + + @Override + public String toString(){ + return callbackCode; + } +} |