1 11 package org.eclipse.jdt.internal.compiler.ast; 12 13 import org.eclipse.jdt.internal.compiler.ASTVisitor; 14 import org.eclipse.jdt.internal.compiler.impl.*; 15 import org.eclipse.jdt.internal.compiler.codegen.*; 16 import org.eclipse.jdt.internal.compiler.flow.*; 17 import org.eclipse.jdt.internal.compiler.lookup.*; 18 19 public class OR_OR_Expression extends BinaryExpression { 21 22 int rightInitStateIndex = -1; 23 int mergedInitStateIndex = -1; 24 25 public OR_OR_Expression(Expression left, Expression right, int operator) { 26 super(left, right, operator); 27 } 28 29 public FlowInfo analyseCode( 30 BlockScope currentScope, 31 FlowContext flowContext, 32 FlowInfo flowInfo) { 33 34 Constant cst = this.left.optimizedBooleanConstant(); 35 boolean isLeftOptimizedTrue = cst != Constant.NotAConstant && cst.booleanValue() == true; 36 boolean isLeftOptimizedFalse = cst != Constant.NotAConstant && cst.booleanValue() == false; 37 38 if (isLeftOptimizedFalse) { 39 FlowInfo mergedInfo = left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits(); 43 mergedInfo = right.analyseCode(currentScope, flowContext, mergedInfo); 44 mergedInitStateIndex = 45 currentScope.methodScope().recordInitializationStates(mergedInfo); 46 return mergedInfo; 47 } 48 49 FlowInfo leftInfo = left.analyseCode(currentScope, flowContext, flowInfo); 50 51 FlowInfo rightInfo = leftInfo.initsWhenFalse().unconditionalCopy(); 54 rightInitStateIndex = 55 currentScope.methodScope().recordInitializationStates(rightInfo); 56 57 int previousMode = rightInfo.reachMode(); 58 if (isLeftOptimizedTrue){ 59 rightInfo.setReachMode(FlowInfo.UNREACHABLE); 60 } 61 rightInfo = right.analyseCode(currentScope, flowContext, rightInfo); 62 FlowInfo mergedInfo = FlowInfo.conditional( 63 leftInfo.initsWhenTrue().unconditionalInits().mergedWith( 65 rightInfo.safeInitsWhenTrue().setReachMode(previousMode).unconditionalInits()), 66 rightInfo.initsWhenFalse()); 67 mergedInitStateIndex = 68 currentScope.methodScope().recordInitializationStates(mergedInfo); 69 return mergedInfo; 70 } 71 72 75 public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { 76 int pc = codeStream.position; 77 if (constant != Constant.NotAConstant) { 78 if (valueRequired) 80 codeStream.generateConstant(constant, implicitConversion); 81 codeStream.recordPositionsFrom(pc, this.sourceStart); 82 return; 83 } 84 Constant cst = right.constant; 85 if (cst != Constant.NotAConstant) { 86 if (cst.booleanValue() == true) { 88 this.left.generateCode(currentScope, codeStream, false); 89 if (valueRequired) codeStream.iconst_1(); 90 } else { 91 this.left.generateCode(currentScope, codeStream, valueRequired); 93 } 94 if (mergedInitStateIndex != -1) { 95 codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex); 96 } 97 codeStream.generateImplicitConversion(implicitConversion); 98 codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); 99 codeStream.recordPositionsFrom(pc, this.sourceStart); 100 return; 101 } 102 103 BranchLabel trueLabel = new BranchLabel(codeStream), endLabel; 104 cst = left.optimizedBooleanConstant(); 105 boolean leftIsConst = cst != Constant.NotAConstant; 106 boolean leftIsTrue = leftIsConst && cst.booleanValue() == true; 107 108 cst = right.optimizedBooleanConstant(); 109 boolean rightIsConst = cst != Constant.NotAConstant; 110 boolean rightIsTrue = rightIsConst && cst.booleanValue() == true; 111 112 generateOperands : { 113 if (leftIsConst) { 114 left.generateCode(currentScope, codeStream, false); 115 if (leftIsTrue) { 116 break generateOperands; } 118 } else { 119 left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, null, true); 120 } 122 if (rightInitStateIndex != -1) { 123 codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex); 124 } 125 if (rightIsConst) { 126 right.generateCode(currentScope, codeStream, false); 127 } else { 128 right.generateOptimizedBoolean(currentScope, codeStream, trueLabel, null, valueRequired); 129 } 130 } 131 if (mergedInitStateIndex != -1) { 132 codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex); 133 } 134 139 if (valueRequired) { 140 if (leftIsConst && leftIsTrue) { 141 codeStream.iconst_1(); 142 codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); 143 } else { 144 if (rightIsConst && rightIsTrue) { 145 codeStream.iconst_1(); 146 codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); 147 } else { 148 codeStream.iconst_0(); 149 } 150 if (trueLabel.forwardReferenceCount() > 0) { 151 if ((bits & IsReturnedValue) != 0) { 152 codeStream.generateImplicitConversion(this.implicitConversion); 153 codeStream.generateReturnBytecode(this); 154 trueLabel.place(); 155 codeStream.iconst_1(); 156 } else { 157 codeStream.goto_(endLabel = new BranchLabel(codeStream)); 158 codeStream.decrStackSize(1); 159 trueLabel.place(); 160 codeStream.iconst_1(); 161 endLabel.place(); 162 } 163 } else { 164 trueLabel.place(); 165 } 166 } 167 codeStream.generateImplicitConversion(implicitConversion); 168 codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); 169 } else { 170 trueLabel.place(); 171 } 172 } 173 174 177 public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel, boolean valueRequired) { 178 if (constant != Constant.NotAConstant) { 179 super.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired); 180 return; 181 } 182 183 Constant cst = right.constant; 185 if (cst != Constant.NotAConstant && cst.booleanValue() == false) { 186 int pc = codeStream.position; 187 this.left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired); 188 if (mergedInitStateIndex != -1) { 189 codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex); 190 } 191 codeStream.recordPositionsFrom(pc, this.sourceStart); 192 return; 193 } 194 195 cst = left.optimizedBooleanConstant(); 196 boolean leftIsConst = cst != Constant.NotAConstant; 197 boolean leftIsTrue = leftIsConst && cst.booleanValue() == true; 198 199 cst = right.optimizedBooleanConstant(); 200 boolean rightIsConst = cst != Constant.NotAConstant; 201 boolean rightIsTrue = rightIsConst && cst.booleanValue() == true; 202 203 generateOperands : { 205 if (falseLabel == null) { 206 if (trueLabel != null) { 207 left.generateOptimizedBoolean(currentScope, codeStream, trueLabel, null, !leftIsConst); 209 if (leftIsTrue) { 211 if (valueRequired) codeStream.goto_(trueLabel); 212 codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); 213 break generateOperands; } 215 if (rightInitStateIndex != -1) { 216 codeStream.addDefinitelyAssignedVariables(currentScope, rightInitStateIndex); 217 } 218 right.generateOptimizedBoolean(currentScope, codeStream, trueLabel, null, valueRequired && !rightIsConst); 219 if (valueRequired && rightIsTrue) { 220 codeStream.goto_(trueLabel); 221 codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); 222 } 223 } 224 } else { 225 if (trueLabel == null) { 227 BranchLabel internalTrueLabel = new BranchLabel(codeStream); 228 left.generateOptimizedBoolean(currentScope, codeStream, internalTrueLabel, null, !leftIsConst); 229 if (leftIsTrue) { 231 internalTrueLabel.place(); 232 break generateOperands; } 234 if (rightInitStateIndex != -1) { 235 codeStream 236 .addDefinitelyAssignedVariables(currentScope, rightInitStateIndex); 237 } 238 right.generateOptimizedBoolean(currentScope, codeStream, null, falseLabel, valueRequired && !rightIsConst); 239 if (valueRequired && rightIsConst && !rightIsTrue) { 240 codeStream.goto_(falseLabel); 241 codeStream.updateLastRecordedEndPC(currentScope, codeStream.position); 242 } 243 internalTrueLabel.place(); 244 } else { 245 } 247 } 248 } 249 if (mergedInitStateIndex != -1) { 250 codeStream.removeNotDefinitelyAssignedVariables(currentScope, mergedInitStateIndex); 251 } 252 } 253 254 public boolean isCompactableOperation() { 255 return false; 256 } 257 258 public void traverse(ASTVisitor visitor, BlockScope scope) { 259 if (visitor.visit(this, scope)) { 260 left.traverse(visitor, scope); 261 right.traverse(visitor, scope); 262 } 263 visitor.endVisit(this, scope); 264 } 265 } 266 | Popular Tags |