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