You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ko...@apache.org on 2005/08/25 08:02:10 UTC
svn commit: r240003 -
/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/BcelClassTransformer.java
Author: kohsuke
Date: Wed Aug 24 23:02:07 2005
New Revision: 240003
URL: http://svn.apache.org/viewcvs?rev=240003&view=rev
Log:
isolated debug code so that it runs only when the debug mode is on
Modified:
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/BcelClassTransformer.java
Modified: jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/BcelClassTransformer.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/BcelClassTransformer.java?rev=240003&r1=240002&r2=240003&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/BcelClassTransformer.java (original)
+++ jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/BcelClassTransformer.java Wed Aug 24 23:02:07 2005
@@ -59,6 +59,7 @@
import org.apache.bcel.generic.TABLESWITCH;
import org.apache.bcel.generic.TargetLostException;
import org.apache.bcel.generic.Type;
+import org.apache.bcel.generic.IFNONNULL;
import org.apache.bcel.verifier.exc.AssertionViolatedException;
import org.apache.commons.javaflow.bytecode.Continuable;
import org.apache.commons.javaflow.bytecode.StackRecorder;
@@ -83,12 +84,9 @@
private final static Log log = LogFactory.getLog(BcelClassTransformer.class);
-// private static final String CONTINUATION_CLASS = Continuation.class.getName();
-// private static final ObjectType CONTINUATION_TYPE = new ObjectType(CONTINUATION_CLASS);
private static final String STACK_RECORDER_CLASS = StackRecorder.class.getName();
private static final ObjectType STACK_RECORDER_TYPE = new ObjectType(STACK_RECORDER_CLASS);
private static final String CONTINUABLE_CLASS = Continuable.class.getName();
-// private static final String CONTINUATION_METHOD = "currentContinuation";
private static final String STACK_METHOD = "get";
private static final String POP_METHOD = "pop";
private static final String PUSH_METHOD = "push";
@@ -96,7 +94,15 @@
private static final String CAPURING_METHOD = "isCapturing";
private boolean currentMethodStatic = false;
- private boolean debug = true;
+ public static boolean debug = false;
+
+ static {
+ try {
+ debug = System.getProperty(BcelClassTransformer.class.getName()+".debug")!=null;
+ } catch (SecurityException e) {
+ // assume no debugging
+ }
+ }
public byte[] transform(final byte[] original) {
@@ -122,45 +128,8 @@
final ClassGen clazzGen = new ClassGen(javaClazz);
final ConstantPoolGen cp = clazzGen.getConstantPool();
- final String path = clazzGen.getClassName();
-
- FileOutputStream out = null;
-
- final byte[] orig = clazzGen.getJavaClass().getBytes();
- try {
- out = new FileOutputStream(path + ".orig");
- out.write(orig);
- out.flush();
- } catch (final IOException e) {
- e.printStackTrace();
-
- try {
- if (out != null) {
- out.close();
- }
- } catch (final IOException e1) {
- log.error(e1.getMessage(), e1);
- } finally {
- out = null;
- }
- }
-
- try {
- out = new FileOutputStream(path + ".orig.java");
- final DecompilingVisitor v = new DecompilingVisitor(javaClazz, out);
- v.start();
- } catch (final Exception e) {
- e.printStackTrace();
-
- try {
- if (out != null) {
- out.close();
- }
- } catch (final IOException e1) {
- log.error(e1.getMessage(), e1);
- } finally {
- out = null;
- }
+ if(debug) {
+ dump(javaClazz, "orig");
}
// vistor to build the frame information
@@ -194,11 +163,28 @@
}
clazzGen.addInterface(CONTINUABLE_CLASS);
+ JavaClass newClass = clazzGen.getJavaClass();
+ final byte[] changed = newClass.getBytes();
+
+ if(debug) {
+ dump(newClass, ".rewritten");
+ }
+
+ return changed;
+ }
+
+ /**
+ * Dumps the class file to the curent directory for debugging.
+ */
+ private void dump(JavaClass javaClazz, String suffix) {
+ String path = javaClazz.getClassName()+suffix;
+
+ final byte[] orig = javaClazz.getBytes();
- final byte[] changed = clazzGen.getJavaClass().getBytes();
+ FileOutputStream out = null;
try {
- out = new FileOutputStream(clazzGen.getClassName() + ".rewritten");
- out.write(changed);
+ out = new FileOutputStream(path);
+ out.write(orig);
out.flush();
} catch (final IOException e) {
e.printStackTrace();
@@ -215,8 +201,8 @@
}
try {
- out = new FileOutputStream(path + ".rewritten.java");
- final DecompilingVisitor v = new DecompilingVisitor(clazzGen.getJavaClass(), out);
+ out = new FileOutputStream(path + ".java");
+ final DecompilingVisitor v = new DecompilingVisitor(javaClazz, out);
v.start();
} catch (final Exception e) {
e.printStackTrace();
@@ -231,8 +217,6 @@
out = null;
}
}
-
- return changed;
}
private boolean needsRewriting(MethodGen m) {
@@ -478,8 +462,29 @@
final InstructionList insList = new InstructionList();
final Type[] arguments = invoke.getArgumentTypes(method.getConstantPool());
- // pop all arguments for the constructor from the stack
Instruction loadStackRecorder = InstructionFactory.createLoad(STACK_RECORDER_TYPE, method.getMaxLocals());
+
+ {
+ // make sure that the stack recorder exists, if not create a temporary one.
+ // this is rather wasteful when executing the instrumented bytecode outside
+ // the continuation environment (because it creates a dummy object just to save/load few
+ // variables.), but at least it lets the code run.
+ //
+ // the alternative is to store arguments in local variables. If you do so,
+ // make sure to erase them to null when you finish restoring them onto the stack,
+ // or otherwise they'll be left reachable.
+ IFNONNULL x;
+ insList.append(loadStackRecorder);
+ insList.append(x=new IFNONNULL(null));
+ insList.append(insFactory.createNew(STACK_RECORDER_TYPE));
+ insList.append(InstructionFactory.DUP);
+ insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS,"<init>",Type.VOID,new Type[0],Constants.INVOKESPECIAL));
+ insList.append(InstructionFactory.createStore(STACK_RECORDER_TYPE, method.getMaxLocals()));
+ x.setTarget(
+ insList.append(InstructionFactory.NOP));
+ }
+
+ // pop all arguments for the constructor from the stack
for (int i = arguments.length - 1; i >= 0; i--) {
Type type = arguments[i];
insList.append(loadStackRecorder);
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org