X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/UnconditionalFlowInfo.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/UnconditionalFlowInfo.java index 9aa6a34..6907f62 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/UnconditionalFlowInfo.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/UnconditionalFlowInfo.java @@ -17,21 +17,23 @@ import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; /** * Record initialization status during definite assignment analysis - * + * * No caching of pre-allocated instances. */ public class UnconditionalFlowInfo extends FlowInfo { - public long definiteInits; + public long potentialInits; + public long extraDefiniteInits[]; + public long extraPotentialInits[]; - + public int reachMode = REACHABLE; // by default public int maxFieldCount; - + // Constants public static final int BitCacheSize = 64; // 64 bits in a long. @@ -44,24 +46,29 @@ public class UnconditionalFlowInfo extends FlowInfo { if (this == DEAD_END) return this; - UnconditionalFlowInfo otherInits = inits.unconditionalInits(); + UnconditionalFlowInfo otherInits = inits.unconditionalInits(); if (otherInits == DEAD_END) return this; - - // union of definitely assigned variables, + + // union of definitely assigned variables, definiteInits |= otherInits.definiteInits; // union of potentially set ones potentialInits |= otherInits.potentialInits; - + // treating extra storage if (extraDefiniteInits != null) { if (otherInits.extraDefiniteInits != null) { // both sides have extra storage int i = 0, length, otherLength; if ((length = extraDefiniteInits.length) < (otherLength = otherInits.extraDefiniteInits.length)) { - // current storage is shorter -> grow current (could maybe reuse otherInits extra storage?) - System.arraycopy(extraDefiniteInits, 0, (extraDefiniteInits = new long[otherLength]), 0, length); - System.arraycopy(extraPotentialInits, 0, (extraPotentialInits = new long[otherLength]), 0, length); + // current storage is shorter -> grow current (could maybe + // reuse otherInits extra storage?) + System.arraycopy(extraDefiniteInits, 0, + (extraDefiniteInits = new long[otherLength]), 0, + length); + System.arraycopy(extraPotentialInits, 0, + (extraPotentialInits = new long[otherLength]), 0, + length); while (i < length) { extraDefiniteInits[i] |= otherInits.extraDefiniteInits[i]; extraPotentialInits[i] |= otherInits.extraPotentialInits[i++]; @@ -81,39 +88,50 @@ public class UnconditionalFlowInfo extends FlowInfo { } else { // no extra storage on otherInits } - } else - if (otherInits.extraDefiniteInits != null) { - // no storage here, but other has extra storage. - int otherLength; - System.arraycopy(otherInits.extraDefiniteInits, 0, (extraDefiniteInits = new long[otherLength = otherInits.extraDefiniteInits.length]), 0, otherLength); - System.arraycopy(otherInits.extraPotentialInits, 0, (extraPotentialInits = new long[otherLength]), 0, otherLength); - } + } else if (otherInits.extraDefiniteInits != null) { + // no storage here, but other has extra storage. + int otherLength; + System + .arraycopy( + otherInits.extraDefiniteInits, + 0, + (extraDefiniteInits = new long[otherLength = otherInits.extraDefiniteInits.length]), + 0, otherLength); + System.arraycopy(otherInits.extraPotentialInits, 0, + (extraPotentialInits = new long[otherLength]), 0, + otherLength); + } return this; } // unions of both sets of initialization - used for try/finally public FlowInfo addPotentialInitializationsFrom(FlowInfo inits) { - - if (this == DEAD_END){ + + if (this == DEAD_END) { return this; } UnconditionalFlowInfo otherInits = inits.unconditionalInits(); - if (otherInits == DEAD_END){ + if (otherInits == DEAD_END) { return this; } // union of potentially set ones potentialInits |= otherInits.potentialInits; - + // treating extra storage if (extraDefiniteInits != null) { if (otherInits.extraDefiniteInits != null) { // both sides have extra storage int i = 0, length, otherLength; if ((length = extraDefiniteInits.length) < (otherLength = otherInits.extraDefiniteInits.length)) { - // current storage is shorter -> grow current (could maybe reuse otherInits extra storage?) - System.arraycopy(extraDefiniteInits, 0, (extraDefiniteInits = new long[otherLength]), 0, length); - System.arraycopy(extraPotentialInits, 0, (extraPotentialInits = new long[otherLength]), 0, length); + // current storage is shorter -> grow current (could maybe + // reuse otherInits extra storage?) + System.arraycopy(extraDefiniteInits, 0, + (extraDefiniteInits = new long[otherLength]), 0, + length); + System.arraycopy(extraPotentialInits, 0, + (extraPotentialInits = new long[otherLength]), 0, + length); while (i < length) { extraPotentialInits[i] |= otherInits.extraPotentialInits[i++]; } @@ -127,66 +145,75 @@ public class UnconditionalFlowInfo extends FlowInfo { } } } - } else - if (otherInits.extraDefiniteInits != null) { - // no storage here, but other has extra storage. - int otherLength; - extraDefiniteInits = new long[otherLength = otherInits.extraDefiniteInits.length]; - System.arraycopy(otherInits.extraPotentialInits, 0, (extraPotentialInits = new long[otherLength]), 0, otherLength); - } + } else if (otherInits.extraDefiniteInits != null) { + // no storage here, but other has extra storage. + int otherLength; + extraDefiniteInits = new long[otherLength = otherInits.extraDefiniteInits.length]; + System.arraycopy(otherInits.extraPotentialInits, 0, + (extraPotentialInits = new long[otherLength]), 0, + otherLength); + } return this; } // Report an error if necessary -// public boolean complainIfUnreachable(Statement statement, BlockScope scope, boolean didAlreadyComplain) { -// -// if ((this.reachMode & UNREACHABLE) != 0) { -// statement.bits &= ~ASTNode.IsReachableMASK; -// boolean reported = this == DEAD_END; -// if (!didAlreadyComplain && reported) { -// scope.problemReporter().unreachableCode(statement); -// } -// return reported; // keep going for fake reachable -// } -// return false; -// } - + // public boolean complainIfUnreachable(Statement statement, BlockScope + // scope, boolean didAlreadyComplain) { + // + // if ((this.reachMode & UNREACHABLE) != 0) { + // statement.bits &= ~ASTNode.IsReachableMASK; + // boolean reported = this == DEAD_END; + // if (!didAlreadyComplain && reported) { + // scope.problemReporter().unreachableCode(statement); + // } + // return reported; // keep going for fake reachable + // } + // return false; + // } + /** * Answers a copy of the current instance */ public FlowInfo copy() { - + // do not clone the DeadEnd if (this == DEAD_END) return this; - + // look for an unused preallocated object UnconditionalFlowInfo copy = new UnconditionalFlowInfo(); - + // copy slots copy.definiteInits = this.definiteInits; copy.potentialInits = this.potentialInits; copy.reachMode = this.reachMode; copy.maxFieldCount = this.maxFieldCount; - + if (this.extraDefiniteInits != null) { int length; - System.arraycopy(this.extraDefiniteInits, 0, (copy.extraDefiniteInits = new long[ (length = extraDefiniteInits.length)]), 0, length); - System.arraycopy(this.extraPotentialInits, 0, (copy.extraPotentialInits = new long[length]), 0, length); - }; + System + .arraycopy( + this.extraDefiniteInits, + 0, + (copy.extraDefiniteInits = new long[(length = extraDefiniteInits.length)]), + 0, length); + System.arraycopy(this.extraPotentialInits, 0, + (copy.extraPotentialInits = new long[length]), 0, length); + } + ; return copy; } - - public UnconditionalFlowInfo discardFieldInitializations(){ - + + public UnconditionalFlowInfo discardFieldInitializations() { + int limit = this.maxFieldCount; - + if (limit < BitCacheSize) { - long mask = (1L << limit)-1; + long mask = (1L << limit) - 1; this.definiteInits &= ~mask; this.potentialInits &= ~mask; return this; - } + } this.definiteInits = 0; this.potentialInits = 0; @@ -203,22 +230,22 @@ public class UnconditionalFlowInfo extends FlowInfo { this.extraDefiniteInits[i] = 0L; this.extraPotentialInits[i] = 0L; } - long mask = (1L << (limit % BitCacheSize))-1; + long mask = (1L << (limit % BitCacheSize)) - 1; this.extraDefiniteInits[vectorIndex] &= ~mask; this.extraPotentialInits[vectorIndex] &= ~mask; return this; } - public UnconditionalFlowInfo discardNonFieldInitializations(){ - + public UnconditionalFlowInfo discardNonFieldInitializations() { + int limit = this.maxFieldCount; - + if (limit < BitCacheSize) { - long mask = (1L << limit)-1; + long mask = (1L << limit) - 1; this.definiteInits &= mask; this.potentialInits &= mask; return this; - } + } // use extra vector if (extraDefiniteInits == null) { return this; // if vector not yet allocated, then not initialized @@ -227,33 +254,33 @@ public class UnconditionalFlowInfo extends FlowInfo { if ((vectorIndex = (limit / BitCacheSize) - 1) >= length) { return this; // not enough room yet } - long mask = (1L << (limit % BitCacheSize))-1; + long mask = (1L << (limit % BitCacheSize)) - 1; this.extraDefiniteInits[vectorIndex] &= mask; this.extraPotentialInits[vectorIndex] &= mask; - for (int i = vectorIndex+1; i < length; i++) { + for (int i = vectorIndex + 1; i < length; i++) { this.extraDefiniteInits[i] = 0L; this.extraPotentialInits[i] = 0L; } return this; } - + public FlowInfo initsWhenFalse() { - + return this; } - + public FlowInfo initsWhenTrue() { - + return this; } - + /** - * Check status of definite assignment at a given position. - * It deals with the dual representation of the InitializationInfo2: - * bits for the first 64 entries, then an array of booleans. + * Check status of definite assignment at a given position. It deals with + * the dual representation of the InitializationInfo2: bits for the first 64 + * entries, then an array of booleans. */ final private boolean isDefinitelyAssigned(int position) { - + // Dependant of CodeStream.isDefinitelyAssigned(..) // id is zero-based if (position < BitCacheSize) { @@ -264,27 +291,28 @@ public class UnconditionalFlowInfo extends FlowInfo { return false; // if vector not yet allocated, then not initialized int vectorIndex; if ((vectorIndex = (position / BitCacheSize) - 1) >= extraDefiniteInits.length) - return false; // if not enough room in vector, then not initialized + return false; // if not enough room in vector, then not + // initialized return ((extraDefiniteInits[vectorIndex]) & (1L << (position % BitCacheSize))) != 0; } - + /** * Check status of definite assignment for a field. */ final public boolean isDefinitelyAssigned(FieldBinding field) { - + // Dependant of CodeStream.isDefinitelyAssigned(..) // We do not want to complain in unreachable code - if ((this.reachMode & UNREACHABLE) != 0) + if ((this.reachMode & UNREACHABLE) != 0) return true; - return isDefinitelyAssigned(field.id); + return isDefinitelyAssigned(field.id); } - + /** * Check status of definite assignment for a local. */ final public boolean isDefinitelyAssigned(LocalVariableBinding local) { - + // Dependant of CodeStream.isDefinitelyAssigned(..) // We do not want to complain in unreachable code if ((this.reachMode & UNREACHABLE) != 0) @@ -292,25 +320,26 @@ public class UnconditionalFlowInfo extends FlowInfo { if (local.isArgument) { return true; } - // final constants are inlined, and thus considered as always initialized + // final constants are inlined, and thus considered as always + // initialized if (local.constant != Constant.NotAConstant) { return true; } return isDefinitelyAssigned(local.id + maxFieldCount); } - + public boolean isReachable() { - + return this.reachMode == REACHABLE; } - + /** - * Check status of potential assignment at a given position. - * It deals with the dual representation of the InitializationInfo3: - * bits for the first 64 entries, then an array of booleans. + * Check status of potential assignment at a given position. It deals with + * the dual representation of the InitializationInfo3: bits for the first 64 + * entries, then an array of booleans. */ final private boolean isPotentiallyAssigned(int position) { - + // id is zero-based if (position < BitCacheSize) { // use bits @@ -321,42 +350,44 @@ public class UnconditionalFlowInfo extends FlowInfo { return false; // if vector not yet allocated, then not initialized int vectorIndex; if ((vectorIndex = (position / BitCacheSize) - 1) >= extraPotentialInits.length) - return false; // if not enough room in vector, then not initialized + return false; // if not enough room in vector, then not + // initialized return ((extraPotentialInits[vectorIndex]) & (1L << (position % BitCacheSize))) != 0; } - + /** * Check status of definite assignment for a field. */ final public boolean isPotentiallyAssigned(FieldBinding field) { - - return isPotentiallyAssigned(field.id); + + return isPotentiallyAssigned(field.id); } - + /** * Check status of potential assignment for a local. */ final public boolean isPotentiallyAssigned(LocalVariableBinding local) { - + if (local.isArgument) { return true; } - // final constants are inlined, and thus considered as always initialized + // final constants are inlined, and thus considered as always + // initialized if (local.constant != Constant.NotAConstant) { return true; } return isPotentiallyAssigned(local.id + maxFieldCount); } - + /** - * Record a definite assignment at a given position. - * It deals with the dual representation of the InitializationInfo2: - * bits for the first 64 entries, then an array of booleans. + * Record a definite assignment at a given position. It deals with the dual + * representation of the InitializationInfo2: bits for the first 64 entries, + * then an array of booleans. */ final private void markAsDefinitelyAssigned(int position) { - + if (this != DEAD_END) { - + // position is zero-based if (position < BitCacheSize) { // use bits @@ -373,8 +404,18 @@ public class UnconditionalFlowInfo extends FlowInfo { } else { int oldLength; // might need to grow the arrays if (vectorIndex >= (oldLength = extraDefiniteInits.length)) { - System.arraycopy(extraDefiniteInits, 0, (extraDefiniteInits = new long[vectorIndex + 1]), 0, oldLength); - System.arraycopy(extraPotentialInits, 0, (extraPotentialInits = new long[vectorIndex + 1]), 0, oldLength); + System + .arraycopy( + extraDefiniteInits, + 0, + (extraDefiniteInits = new long[vectorIndex + 1]), + 0, oldLength); + System + .arraycopy( + extraPotentialInits, + 0, + (extraPotentialInits = new long[vectorIndex + 1]), + 0, oldLength); } } long mask; @@ -383,7 +424,7 @@ public class UnconditionalFlowInfo extends FlowInfo { } } } - + /** * Record a field got definitely assigned. */ @@ -391,7 +432,7 @@ public class UnconditionalFlowInfo extends FlowInfo { if (this != DEAD_END) markAsDefinitelyAssigned(field.id); } - + /** * Record a local got definitely assigned. */ @@ -399,15 +440,15 @@ public class UnconditionalFlowInfo extends FlowInfo { if (this != DEAD_END) markAsDefinitelyAssigned(local.id + maxFieldCount); } - + /** - * Clear initialization information at a given position. - * It deals with the dual representation of the InitializationInfo2: - * bits for the first 64 entries, then an array of booleans. + * Clear initialization information at a given position. It deals with the + * dual representation of the InitializationInfo2: bits for the first 64 + * entries, then an array of booleans. */ final private void markAsDefinitelyNotAssigned(int position) { if (this != DEAD_END) { - + // position is zero-based if (position < BitCacheSize) { // use bits @@ -418,11 +459,11 @@ public class UnconditionalFlowInfo extends FlowInfo { // use extra vector int vectorIndex = (position / BitCacheSize) - 1; if (extraDefiniteInits == null) { - return; // nothing to do, it was not yet set + return; // nothing to do, it was not yet set } else { // might need to grow the arrays if (vectorIndex >= extraDefiniteInits.length) { - return; // nothing to do, it was not yet set + return; // nothing to do, it was not yet set } } long mask; @@ -431,62 +472,70 @@ public class UnconditionalFlowInfo extends FlowInfo { } } } - + /** * Clear the initialization info for a field */ public void markAsDefinitelyNotAssigned(FieldBinding field) { - + if (this != DEAD_END) markAsDefinitelyNotAssigned(field.id); } - + /** * Clear the initialization info for a local variable */ - + public void markAsDefinitelyNotAssigned(LocalVariableBinding local) { - + if (this != DEAD_END) markAsDefinitelyNotAssigned(local.id + maxFieldCount); } - + /** - * Returns the receiver updated in the following way: