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/12/28 20:14:07 UTC
svn commit: r359604 - in
/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser:
ControlFlowGraph.java Frame.java InstructionContext.java
LocalVariables.java OperandStack.java
Author: kohsuke
Date: Wed Dec 28 11:14:03 2005
New Revision: 359604
URL: http://svn.apache.org/viewcvs?rev=359604&view=rev
Log:
Found some redundant code, so merged them into one for better readability.
(I'm actually trying to fix a JSR/RET instrumentation issue here...)
Modified:
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/ControlFlowGraph.java
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Frame.java
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/InstructionContext.java
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/LocalVariables.java
jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/OperandStack.java
Modified: jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/ControlFlowGraph.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/ControlFlowGraph.java?rev=359604&r1=359603&r2=359604&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/ControlFlowGraph.java (original)
+++ jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/ControlFlowGraph.java Wed Dec 28 11:14:03 2005
@@ -50,15 +50,6 @@
private class InstructionContextImpl implements InstructionContext{
/**
- * The TAG field is here for external temporary flagging, such
- * as graph colouring.
- *
- * @see #getTag()
- * @see #setTag(int)
- */
- private int TAG;
-
- /**
* The InstructionHandle this InstructionContext is wrapped around.
*/
private InstructionHandle instruction;
@@ -89,16 +80,6 @@
instruction = inst;
inFrames = new java.util.HashMap();
outFrames = new java.util.HashMap();
- }
-
- /* Satisfies InstructionContext.getTag(). */
- public int getTag(){
- return TAG;
- }
-
- /* Satisfies InstructionContext.setTag(int). */
- public void setTag(int tag){
- TAG = tag;
}
/**
Modified: jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Frame.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Frame.java?rev=359604&r1=359603&r2=359604&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Frame.java (original)
+++ jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/Frame.java Wed Dec 28 11:14:03 2005
@@ -15,6 +15,12 @@
*/
package org.apache.commons.javaflow.bytecode.transformation.bcel.analyser;
+import org.apache.bcel.generic.Type;
+import org.apache.bcel.generic.ReferenceType;
+import org.apache.bcel.generic.ReturnaddressType;
+import org.apache.bcel.verifier.exc.StructuralCodeConstraintException;
+import org.apache.bcel.verifier.exc.AssertionViolatedException;
+
/**
* This class represents a JVM execution frame; that means,
* a local variable array and an operand stack.
@@ -24,89 +30,150 @@
* @version $Id$
* @author <A HREF="http://www.inf.fu-berlin.de/~ehaase"/>Enver Haase</A>
*/
-
+
public class Frame{
- /**
- * For instance initialization methods, it is important to remember
- * which instance it is that is not initialized yet. It will be
- * initialized invoking another constructor later.
- * NULL means the instance already *is* initialized.
- */
- public static UninitializedObjectType _this;
-
- /**
- *
- */
- private LocalVariables locals;
-
- /**
- *
- */
- private OperandStack stack;
-
- /**
- *
- */
- public Frame(int maxLocals, int maxStack){
- locals = new LocalVariables(maxLocals);
- stack = new OperandStack(maxStack);
- }
-
- /**
- *
- */
- public Frame(LocalVariables locals, OperandStack stack){
- this.locals = locals;
- this.stack = stack;
- }
-
- /**
- *
- */
- protected Object clone(){
- Frame f = new Frame(locals.getClone(), stack.getClone());
- return f;
- }
-
- /**
- *
- */
- public Frame getClone(){
- return (Frame) clone();
- }
-
- /**
- *
- */
- public LocalVariables getLocals(){
- return locals;
- }
-
- /**
- *
- */
- public OperandStack getStack(){
- return stack;
- }
-
- /**
- *
- */
- public boolean equals(Object o){
- if (!(o instanceof Frame)) return false; // implies "null" is non-equal.
- Frame f = (Frame) o;
- return this.stack.equals(f.stack) && this.locals.equals(f.locals);
- }
-
- /**
- * Returns a String representation of the Frame instance.
- */
- public String toString(){
- String s="Local Variables:\n";
- s += locals;
- s += "OperandStack:\n";
- s += stack;
- return s;
- }
+ /**
+ * For instance initialization methods, it is important to remember
+ * which instance it is that is not initialized yet. It will be
+ * initialized invoking another constructor later.
+ * NULL means the instance already *is* initialized.
+ */
+ public static UninitializedObjectType _this;
+
+ /**
+ *
+ */
+ private LocalVariables locals;
+
+ /**
+ *
+ */
+ private OperandStack stack;
+
+ /**
+ *
+ */
+ public Frame(int maxLocals, int maxStack){
+ locals = new LocalVariables(maxLocals);
+ stack = new OperandStack(maxStack);
+ }
+
+ /**
+ *
+ */
+ public Frame(LocalVariables locals, OperandStack stack){
+ this.locals = locals;
+ this.stack = stack;
+ }
+
+ /**
+ *
+ */
+ protected Object clone(){
+ Frame f = new Frame(locals.getClone(), stack.getClone());
+ return f;
+ }
+
+ /**
+ *
+ */
+ public Frame getClone(){
+ return (Frame) clone();
+ }
+
+ /**
+ *
+ */
+ public LocalVariables getLocals(){
+ return locals;
+ }
+
+ /**
+ *
+ */
+ public OperandStack getStack(){
+ return stack;
+ }
+
+ /**
+ *
+ */
+ public boolean equals(Object o){
+ if (!(o instanceof Frame)) return false; // implies "null" is non-equal.
+ Frame f = (Frame) o;
+ return this.stack.equals(f.stack) && this.locals.equals(f.locals);
+ }
+
+ /**
+ * Returns a String representation of the Frame instance.
+ */
+ public String toString(){
+ String s="Local Variables:\n";
+ s += locals;
+ s += "OperandStack:\n";
+ s += stack;
+ return s;
+ }
+
+
+ /**
+ * Merges two {@link Type}s into one.
+ *
+ * @param errorIfFailed
+ * if true, attempting to merge two types that are incompatible causes an error.
+ * if false, it yields {@link Type#UNKNOWN} value, indicating that value is unusable.
+ */
+ /*package*/ static Type merge(Type lhs, Type rhs, boolean errorIfFailed) {
+ try {
+
+ // We won't accept an unitialized object if we know it was initialized;
+ // compare vmspec2, 4.9.4, last paragraph.
+ if ((!(lhs instanceof UninitializedObjectType)) && (rhs instanceof UninitializedObjectType)) {
+ throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object in the local variables detected.");
+ }
+ // Even harder, what about _different_ uninitialized object types?!
+ if ((!(lhs.equals(rhs))) && (lhs instanceof UninitializedObjectType) && (rhs instanceof UninitializedObjectType)) {
+ throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object in the local variables detected.");
+ }
+ // If we just didn't know that it was initialized, we have now learned.
+ if (lhs instanceof UninitializedObjectType) {
+ if (! (rhs instanceof UninitializedObjectType)) {
+ lhs = ((UninitializedObjectType) lhs).getInitialized();
+ }
+ }
+ if ((lhs instanceof ReferenceType) && (rhs instanceof ReferenceType)) {
+ if(lhs.equals(rhs)) {
+ return lhs; // same type
+ }
+
+ Type sup = ((ReferenceType) lhs).getFirstCommonSuperclass((ReferenceType) rhs);
+
+ if (sup != null) {
+ return sup;
+ } else {
+ // We should have checked this in Pass2!
+ throw new AssertionViolatedException("Could not load all the super classes of '" + lhs + "' and '" + rhs + "'.");
+ }
+ }
+
+ if ((lhs instanceof ReturnaddressType) && (rhs instanceof ReturnaddressType)) {
+ // see 'FinallyFlow' test.
+ return lhs;
+ }
+
+ if (!lhs.equals(rhs)) {
+ if(errorIfFailed) {
+ throw new StructuralCodeConstraintException("Cannot merge different types:"+lhs+" and "+rhs);
+ } else {
+ return Type.UNKNOWN;
+ }
+ }
+
+ return lhs;
+ } catch (ClassNotFoundException e) {
+ // FIXME: maybe not the best way to handle this
+ throw new AssertionViolatedException("Missing class: " + e.toString());
+ }
+ }
}
Modified: jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/InstructionContext.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/InstructionContext.java?rev=359604&r1=359603&r2=359604&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/InstructionContext.java (original)
+++ jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/InstructionContext.java Wed Dec 28 11:14:03 2005
@@ -30,26 +30,6 @@
public interface InstructionContext{
/**
- * The getTag and setTag methods may be used for
- * temporary flagging, such as graph colouring.
- * Nothing in the InstructionContext object depends
- * on the value of the tag. JustIce does not use it.
- *
- * @see #setTag(int tag)
- */
- public int getTag();
-
- /**
- * The getTag and setTag methods may be used for
- * temporary flagging, such as graph colouring.
- * Nothing in the InstructionContext object depends
- * on the value of the tag. JustIce does not use it.
- *
- * @see #getTag()
- */
- public void setTag(int tag);
-
- /**
* This method symbolically executes the Instruction
* held in the InstructionContext.
* It "merges in" the incoming execution frame situation
Modified: jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/LocalVariables.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/LocalVariables.java?rev=359604&r1=359603&r2=359604&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/LocalVariables.java (original)
+++ jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/LocalVariables.java Wed Dec 28 11:14:03 2005
@@ -16,8 +16,7 @@
package org.apache.commons.javaflow.bytecode.transformation.bcel.analyser;
import org.apache.bcel.generic.Type;
-import org.apache.bcel.generic.ReferenceType;
-import org.apache.bcel.verifier.exc.*;
+import org.apache.bcel.verifier.exc.AssertionViolatedException;
/**
* This class implements an array of local variables used for symbolic JVM
@@ -49,9 +48,7 @@
*/
protected Object clone(){
LocalVariables lvs = new LocalVariables(locals.length);
- for (int i=0; i<locals.length; i++){
- lvs.locals[i] = this.locals[i];
- }
+ System.arraycopy(this.locals, 0, lvs.locals, 0, locals.length);
return lvs;
}
@@ -108,75 +105,23 @@
* Merges two local variables sets as described in the Java Virtual Machine Specification,
* Second Edition, section 4.9.2, page 146.
*/
- public void merge(LocalVariables lv){
+ public void merge(LocalVariables that){
- if (this.locals.length != lv.locals.length){
+ if (this.locals.length != that.locals.length){
throw new AssertionViolatedException("Merging LocalVariables of different size?!? From different methods or what?!?");
}
- for (int i=0; i<locals.length; i++){
- merge(lv, i);
+ for (int i=0; i<locals.length; i++) {
+ this.locals[i] = Frame.merge(this.locals[i], that.locals[i], false);
}
}
- /**
- * Merges a single local variable.
- *
- * @see #merge(LocalVariables)
- */
- private void merge(LocalVariables lv, int i){
- try {
-
- // We won't accept an unitialized object if we know it was initialized;
- // compare vmspec2, 4.9.4, last paragraph.
- if ( (!(locals[i] instanceof UninitializedObjectType)) && (lv.locals[i] instanceof UninitializedObjectType) ){
- throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object in the local variables detected.");
- }
- // Even harder, what about _different_ uninitialized object types?!
- if ( (!(locals[i].equals(lv.locals[i]))) && (locals[i] instanceof UninitializedObjectType) && (lv.locals[i] instanceof UninitializedObjectType) ){
- throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object in the local variables detected.");
- }
- // If we just didn't know that it was initialized, we have now learned.
- if (locals[i] instanceof UninitializedObjectType){
- if (! (lv.locals[i] instanceof UninitializedObjectType)){
- locals[i] = ((UninitializedObjectType) locals[i]).getInitialized();
- }
- }
- if ((locals[i] instanceof ReferenceType) && (lv.locals[i] instanceof ReferenceType)){
- if (! locals[i].equals(lv.locals[i])){ // needed in case of two UninitializedObjectType instances
- Type sup = ((ReferenceType) locals[i]).getFirstCommonSuperclass((ReferenceType) (lv.locals[i]));
-
- if (sup != null){
- locals[i] = sup;
- }
- else{
- // We should have checked this in Pass2!
- throw new AssertionViolatedException("Could not load all the super classes of '"+locals[i]+"' and '"+lv.locals[i]+"'.");
- }
- }
- }
- else{
- if (! (locals[i].equals(lv.locals[i])) ){
-/*TODO
- if ((locals[i] instanceof org.apache.bcel.generic.ReturnaddressType) && (lv.locals[i] instanceof org.apache.bcel.generic.ReturnaddressType)){
- //System.err.println("merging "+locals[i]+" and "+lv.locals[i]);
- throw new AssertionViolatedException("Merging different ReturnAddresses: '"+locals[i]+"' and '"+lv.locals[i]+"'.");
- }
-*/
- locals[i] = Type.UNKNOWN;
- }
- }
- } catch (ClassNotFoundException e) {
- // FIXME: maybe not the best way to handle this
- throw new AssertionViolatedException("Missing class: " + e.toString());
- }
- }
- /**
+ /**
* Returns a String representation of this object.
*/
public String toString(){
- String s = new String();
+ String s = "";
for (int i=0; i<locals.length; i++){
s += Integer.toString(i)+": "+locals[i]+"\n";
}
Modified: jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/OperandStack.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/OperandStack.java?rev=359604&r1=359603&r2=359604&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/OperandStack.java (original)
+++ jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/transformation/bcel/analyser/OperandStack.java Wed Dec 28 11:14:03 2005
@@ -191,41 +191,12 @@
* for details.
*/
public void merge(OperandStack s){
- try {
if ( (slotsUsed() != s.slotsUsed()) || (size() != s.size()) )
throw new StructuralCodeConstraintException("Cannot merge stacks of different size:\nOperandStack A:\n"+this+"\nOperandStack B:\n"+s);
for (int i=0; i<size(); i++){
- // If the object _was_ initialized and we're supposed to merge
- // in some uninitialized object, we reject the code (see vmspec2, 4.9.4, last paragraph).
- if ( (! (stack.get(i) instanceof UninitializedObjectType)) && (s.stack.get(i) instanceof UninitializedObjectType) ){
- throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object on the stack detected.");
- }
- // Even harder, we're not initialized but are supposed to broaden
- // the known object type
- if ( (!(stack.get(i).equals(s.stack.get(i)))) && (stack.get(i) instanceof UninitializedObjectType) && (!(s.stack.get(i) instanceof UninitializedObjectType))){
- throw new StructuralCodeConstraintException("Backwards branch with an uninitialized object on the stack detected.");
- }
- // on the other hand...
- if (stack.get(i) instanceof UninitializedObjectType){ //if we have an uninitialized object here
- if (! (s.stack.get(i) instanceof UninitializedObjectType)){ //that has been initialized by now
- stack.set(i, ((UninitializedObjectType) (stack.get(i))).getInitialized() ); //note that.
- }
- }
- if (! stack.get(i).equals(s.stack.get(i))){
- if ( (stack.get(i) instanceof ReferenceType) &&
- (s.stack.get(i) instanceof ReferenceType) ){
- stack.set(i, ((ReferenceType) stack.get(i)).getFirstCommonSuperclass((ReferenceType) (s.stack.get(i))));
- }
- else{
- throw new StructuralCodeConstraintException("Cannot merge stacks of different types:\nStack A:\n"+this+"\nStack B:\n"+s);
- }
- }
+ this.stack.set(i, Frame.merge((Type)this.stack.get(i), (Type)s.stack.get(i), true));
}
- } catch (ClassNotFoundException e) {
- // FIXME: maybe not the best way to handle this
- throw new AssertionViolatedException("Missing class: " + e.toString());
- }
}
/**
@@ -234,8 +205,7 @@
*/
public void initializeObject(UninitializedObjectType u){
for (int i=0; i<stack.size(); i++){
- if (stack.get(i) == u){
-// if (stack.get(i).equals(u)){
+ if (stack.get(i) == u){
stack.set(i, u.getInitialized());
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org