Author: kohsuke Date: Mon Dec 26 21:23:49 2005 New Revision: 359174 URL: http://svn.apache.org/viewcvs?rev=359174&view=rev Log: fixed a bug in the instrumentation of the null object in the stack
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=359174&r1=359173&r2=359174&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 Mon Dec 26 21:23:49 2005 @@ -17,6 +17,7 @@ import org.apache.bcel.Constants; import org.apache.bcel.Repository; +import org.apache.bcel.classfile.Attribute; import org.apache.bcel.classfile.ClassFormatException; import org.apache.bcel.classfile.ClassParser; import org.apache.bcel.classfile.ConstantCP; @@ -25,12 +26,10 @@ import org.apache.bcel.classfile.ConstantUtf8; import org.apache.bcel.classfile.JavaClass; import org.apache.bcel.classfile.Method; -import org.apache.bcel.classfile.Attribute; import org.apache.bcel.generic.ACONST_NULL; import org.apache.bcel.generic.BasicType; import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ConstantPoolGen; -import org.apache.bcel.generic.DUP2_X2; import org.apache.bcel.generic.GOTO; import org.apache.bcel.generic.IFEQ; import org.apache.bcel.generic.IFNULL; @@ -44,16 +43,14 @@ import org.apache.bcel.generic.InvokeInstruction; import org.apache.bcel.generic.MethodGen; import org.apache.bcel.generic.ObjectType; -import org.apache.bcel.generic.POP; -import org.apache.bcel.generic.POP2; import org.apache.bcel.generic.PUSH; import org.apache.bcel.generic.RET; import org.apache.bcel.generic.ReferenceType; import org.apache.bcel.generic.ReturnaddressType; -import org.apache.bcel.generic.SWAP; import org.apache.bcel.generic.TABLESWITCH; import org.apache.bcel.generic.TargetLostException; import org.apache.bcel.generic.Type; +import org.apache.bcel.generic.ASTORE; import org.apache.bcel.verifier.exc.AssertionViolatedException; import org.apache.commons.javaflow.bytecode.Continuable; import org.apache.commons.javaflow.bytecode.StackRecorder; @@ -591,26 +588,33 @@ // check for types with two words on stack if (type.equals(Type.LONG) || type.equals(Type.DOUBLE)) { - insList.append(new ACONST_NULL()); // create dummy stack entry + insList.append(InstructionConstants.ACONST_NULL); // create dummy stack entry insList.append(loadStackRecorder); - insList.append(new DUP2_X2()); // swap Stack object and long/float - insList.append(new POP2()); + insList.append(InstructionConstants.DUP2_X2); // swap Stack object and long/float + insList.append(InstructionConstants.POP2); } else { insList.append(loadStackRecorder); - insList.append(new SWAP()); + insList.append(InstructionConstants.SWAP); } insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, getPushMethod(type), Type.VOID, new Type[] { type }, Constants.INVOKEVIRTUAL)); if (type.equals(Type.LONG) || type.equals(Type.DOUBLE)) - insList.append(new POP()); // remove dummy stack entry + insList.append(InstructionConstants.POP); // remove dummy stack entry } else if (type == null) { insList.append(InstructionConstants.POP); } else if (type instanceof UninitializedObjectType) { // After the remove of new, there shouldn't be a // uninitialized object on the stack } else if (type instanceof ReferenceType) { - insList.append(loadStackRecorder); - insList.append(new SWAP()); - insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, getPushMethod(Type.OBJECT), Type.VOID, new Type[] { Type.OBJECT }, Constants.INVOKEVIRTUAL)); + if(type.equals(Type.NULL)) { + // if it's guaranteed to be null, no need to store. + // in fact, we can't really store this, because we'll never + // be able to restore it as the 'null' type. + insList.append(InstructionConstants.POP); + } else { + insList.append(loadStackRecorder); + insList.append(InstructionConstants.SWAP); + insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, getPushMethod(Type.OBJECT), Type.VOID, new Type[] { Type.OBJECT }, Constants.INVOKEVIRTUAL)); + } } } // add isCapturing test @@ -687,18 +691,26 @@ insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, getPopMethod(type), type, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); insList.append(InstructionFactory.createStore(type, i)); } else if (type == null) { - insList.append(new ACONST_NULL()); - insList.append(InstructionFactory.createStore(new ObjectType("<null object>"), i)); + insList.append(InstructionConstants.ACONST_NULL); + insList.append(new ASTORE(i)); } else if (type instanceof UninitializedObjectType) { // No uninitilaized objects should be found // in the local variables. + throw new Error("assertion failure"); } else if (type instanceof ReferenceType) { - insList.append(loadStackRecorder); - insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, getPopMethod(Type.OBJECT), Type.OBJECT, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); - if (!type.equals(Type.OBJECT) && (!type.equals(Type.NULL))) { - insList.append(insFactory.createCast(Type.OBJECT, type)); + if (type.equals(Type.NULL)) { + // null type is a special type assignable to any type, + // whereas popObject returns a java/lang/Object. + // the saveFrame method is written so that we don't save the 'null' object + insList.append(InstructionConstants.ACONST_NULL); + } else { + insList.append(loadStackRecorder); + insList.append(insFactory.createInvoke(STACK_RECORDER_CLASS, getPopMethod(Type.OBJECT), Type.OBJECT, Type.NO_ARGS, Constants.INVOKEVIRTUAL)); + if (!type.equals(Type.OBJECT)) { + insList.append(insFactory.createCast(Type.OBJECT, type)); + } } - insList.append(InstructionFactory.createStore(type, i)); + insList.append(new ASTORE(i)); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]