### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java,v retrieving revision 1.124 diff -u -r1.124 TypeDeclaration.java --- compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java 10 May 2006 09:20:34 -0000 1.124 +++ compiler/org/eclipse/jdt/internal/compiler/ast/TypeDeclaration.java 23 Aug 2006 15:30:04 -0000 @@ -668,6 +668,9 @@ staticFieldInfo.unconditionalInits().discardNonFieldInitializations().addInitializationsFrom(outerInfo).setReachMode(flowInfo.reachMode())); // reset reach mode in case initializers did abrupt completely } else { // constructor method.analyseCode(this.scope, initializerContext, constructorInfo.copy().setReachMode(flowInfo.reachMode())); // reset reach mode in case initializers did abrupt completely + if (method.needFreeReturn) { + method.needFreeReturn = (constructorInfo.tagBits & FlowInfo.UNREACHABLE) == 0; + } } } else { // regular method method.analyseCode(this.scope, null, flowInfo.copy()); Index: compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java,v retrieving revision 1.44 diff -u -r1.44 Clinit.java --- compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java 28 Mar 2006 20:29:57 -0000 1.44 +++ compiler/org/eclipse/jdt/internal/compiler/ast/Clinit.java 23 Aug 2006 15:30:03 -0000 @@ -155,6 +155,7 @@ codeStream.ifne(falseLabel); codeStream.iconst_1(); BranchLabel jumpLabel = new BranchLabel(codeStream); + codeStream.decrStackSize(1); codeStream.goto_(jumpLabel); falseLabel.place(); codeStream.iconst_0(); Index: compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java,v retrieving revision 1.99 diff -u -r1.99 TryStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java 11 Apr 2006 06:56:20 -0000 1.99 +++ compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java 23 Aug 2006 15:30:04 -0000 @@ -55,8 +55,9 @@ private final static int FINALLY_INLINE = 3; // finally block must be inlined since cannot use jsr/ret bytecodes >1.5 // for local variables table attributes - int preTryInitStateIndex = -1; int mergedInitStateIndex = -1; + int preTryInitStateIndex = -1; + int postTryInitStateIndex = -1; public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { @@ -94,10 +95,12 @@ FlowInfo tryInfo; if (this.tryBlock.isEmptyBlock()) { tryInfo = flowInfo; + this.postTryInitStateIndex = currentScope.methodScope().recordInitializationStates(tryInfo); } else { tryInfo = this.tryBlock.analyseCode(currentScope, handlingContext, flowInfo.copy()); if ((tryInfo.tagBits & FlowInfo.UNREACHABLE) != 0) this.bits |= ASTNode.IsTryBlockExiting; + this.postTryInitStateIndex = currentScope.methodScope().recordInitializationStates(tryInfo); } // check unreachable catch blocks @@ -203,10 +206,12 @@ FlowInfo tryInfo; if (this.tryBlock.isEmptyBlock()) { tryInfo = flowInfo; + this.postTryInitStateIndex = currentScope.methodScope().recordInitializationStates(tryInfo); } else { tryInfo = this.tryBlock.analyseCode(currentScope, handlingContext, flowInfo.copy()); if ((tryInfo.tagBits & FlowInfo.UNREACHABLE) != 0) this.bits |= ASTNode.IsTryBlockExiting; + this.postTryInitStateIndex = currentScope.methodScope().recordInitializationStates(tryInfo); } // check unreachable catch blocks @@ -341,6 +346,7 @@ int finallyMode = finallyMode(); boolean requiresNaturalExit = false; + boolean requiresCatchesExit = false; // preparing exception labels int maxCatches = this.catchArguments == null ? 0 : this.catchArguments.length; ExceptionLabel[] exceptionLabels; @@ -372,14 +378,28 @@ if (tryBlockHasSomeCode) { // natural exit may require subroutine invocation (if finally != null) BranchLabel naturalExitLabel = new BranchLabel(codeStream); + BranchLabel catchesExitLabel = null; + BranchLabel postCatchesFinallyLabel = null; + for (int i = 0; i < maxCatches; i++) { + exceptionLabels[i].placeEnd(); + } if ((this.bits & ASTNode.IsTryBlockExiting) == 0) { int position = codeStream.position; switch(finallyMode) { case FINALLY_SUBROUTINE : case FINALLY_INLINE : requiresNaturalExit = true; - // fall through + if (this.postTryInitStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.postTryInitStateIndex); + codeStream.addDefinitelyAssignedVariables(currentScope, this.postTryInitStateIndex); + } + codeStream.goto_(naturalExitLabel); + break; case NO_FINALLY : + if (this.postTryInitStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.postTryInitStateIndex); + codeStream.addDefinitelyAssignedVariables(currentScope, this.postTryInitStateIndex); + } codeStream.goto_(naturalExitLabel); break; case FINALLY_DOES_NOT_COMPLETE : @@ -389,18 +409,19 @@ codeStream.updateLastRecordedEndPC(this.tryBlock.scope, position); //goto is tagged as part of the try block } - for (int i = 0; i < maxCatches; i++) { - exceptionLabels[i].placeEnd(); - } /* generate sequence of handler, all starting by storing the TOS (exception thrown) into their own catch variables, the one specified in the source that must denote the handled exception. */ if (this.catchArguments != null) { + catchesExitLabel = new BranchLabel(codeStream); + postCatchesFinallyLabel = new BranchLabel(codeStream); + for (int i = 0; i < maxCatches; i++) { // May loose some local variable initializations : affecting the local variable attributes if (this.preTryInitStateIndex != -1) { codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preTryInitStateIndex); + codeStream.addDefinitelyAssignedVariables(currentScope, this.preTryInitStateIndex); } codeStream.pushOnStack(exceptionLabels[i].exceptionType); exceptionLabels[i].place(); @@ -420,11 +441,18 @@ this.catchBlocks[i].generateCode(this.scope, codeStream); if (!this.catchExits[i]) { switch(finallyMode) { - case FINALLY_SUBROUTINE : case FINALLY_INLINE : + requiresCatchesExit = true; + codeStream.goto_(catchesExitLabel); + break; + case FINALLY_SUBROUTINE : requiresNaturalExit = true; // fall through case NO_FINALLY : + if (this.postTryInitStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.postTryInitStateIndex); + codeStream.addDefinitelyAssignedVariables(currentScope, this.postTryInitStateIndex); + } codeStream.goto_(naturalExitLabel); break; case FINALLY_DOES_NOT_COMPLETE : @@ -452,8 +480,6 @@ this.placeAllAnyExceptionHandler(); if (naturalExitExceptionHandler != null) naturalExitExceptionHandler.place(); -// CaseLabel defaultReturnLocationLabel = null; // only used when emulating RET instruction -// CaseLabel naturalExitReturnLocationLabel = null; // only used when emulating RET instruction switch(finallyMode) { case FINALLY_SUBROUTINE : // any exception handler @@ -485,6 +511,9 @@ this.finallyBlock.generateCode(currentScope, codeStream); position = codeStream.position; codeStream.throwAnyException(this.anyExceptionVariable); + if (this.preTryInitStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preTryInitStateIndex); + } this.subRoutineStartLabel.place(); codeStream.recordPositionsFrom(position, this.finallyBlock.sourceEnd); break; @@ -497,11 +526,12 @@ this.finallyBlock.generateCode(this.scope, codeStream); break; } + // will naturally fall into subsequent code after subroutine invocation - naturalExitLabel.place(); if (requiresNaturalExit) { switch(finallyMode) { case FINALLY_SUBROUTINE : + naturalExitLabel.place(); int position = codeStream.position; naturalExitExceptionHandler.placeStart(); codeStream.jsr(this.subRoutineStartLabel); @@ -511,21 +541,46 @@ this.finallyBlock.sourceEnd); break; case FINALLY_INLINE : - // May loose some local variable initializations : affecting the local variable attributes - // needed since any exception handler got inlined subroutine - if (this.preTryInitStateIndex != -1) { - codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preTryInitStateIndex); + // inlined finally here can see all merged variables + if (this.postTryInitStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.postTryInitStateIndex); + codeStream.addDefinitelyAssignedVariables(currentScope, this.postTryInitStateIndex); } + naturalExitLabel.place(); // entire sequence for finally is associated to finally block this.finallyBlock.generateCode(this.scope, codeStream); + if (postCatchesFinallyLabel != null && requiresCatchesExit) { + codeStream.goto_(postCatchesFinallyLabel); + } break; case FINALLY_DOES_NOT_COMPLETE : break; + default : + naturalExitLabel.place(); + break; + } + } + if (requiresCatchesExit) { + switch(finallyMode) { + case FINALLY_INLINE : + // inlined finally here can see all merged variables + if (this.preTryInitStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preTryInitStateIndex); + codeStream.addDefinitelyAssignedVariables(currentScope, this.preTryInitStateIndex); + } + catchesExitLabel.place(); + // entire sequence for finally is associated to finally block + this.finallyBlock.generateCode(this.scope, codeStream); + postCatchesFinallyLabel.place(); + break; } } } else { // no subroutine, simply position end label (natural exit == end) naturalExitLabel.place(); + if (catchesExitLabel != null) { + catchesExitLabel.place(); + } } } else { // try block had no effect, only generate the body of the finally block if any Index: compiler/org/eclipse/jdt/internal/compiler/ast/SubRoutineStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SubRoutineStatement.java,v retrieving revision 1.11 diff -u -r1.11 SubRoutineStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/SubRoutineStatement.java 28 Mar 2006 20:29:57 -0000 1.11 +++ compiler/org/eclipse/jdt/internal/compiler/ast/SubRoutineStatement.java 23 Aug 2006 15:30:04 -0000 @@ -26,7 +26,7 @@ SubRoutineStatement sub = subroutines[i]; sub.enterAnyExceptionHandler(codeStream); sub.enterDeclaredExceptionHandlers(codeStream); - } + } } ExceptionLabel anyExceptionLabel; Index: compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java,v retrieving revision 1.52 diff -u -r1.52 ReturnStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java 28 Mar 2006 20:29:56 -0000 1.52 +++ compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java 23 Aug 2006 15:30:04 -0000 @@ -23,6 +23,7 @@ public SubRoutineStatement[] subroutines; public boolean isAnySubRoutineEscaping = false; public LocalVariableBinding saveValueVariable; + public int initStateIndex = -1; public ReturnStatement(Expression expression, int sourceStart, int sourceEnd) { this.sourceStart = sourceStart; @@ -37,6 +38,8 @@ if (this.expression != null) { flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo); + this.initStateIndex = + currentScope.methodScope().recordInitializationStates(flowInfo); } // compute the return sequence (running the finally blocks) FlowContext traversedContext = flowContext; @@ -130,6 +133,10 @@ SubRoutineStatement sub = this.subroutines[i]; boolean didEscape = sub.generateSubRoutineInvocation(currentScope, codeStream, reusableJSRTarget); if (didEscape) { + if (this.initStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.initStateIndex); + codeStream.addDefinitelyAssignedVariables(currentScope, this.initStateIndex); + } codeStream.recordPositionsFrom(pc, this.sourceStart); SubRoutineStatement.reenterAllExceptionHandlers(this.subroutines, i, codeStream); return; @@ -137,6 +144,7 @@ } } if (this.saveValueVariable != null) { + codeStream.addVariable(this.saveValueVariable); codeStream.load(this.saveValueVariable); } if (this.expression != null && !alreadyGeneratedExpression) { @@ -145,6 +153,13 @@ } // output the suitable return bytecode or wrap the value inside a descriptor for doits this.generateReturnBytecode(codeStream); + if (this.saveValueVariable != null) { + codeStream.removeVariable(this.saveValueVariable); + } + if (this.initStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.initStateIndex); + codeStream.addDefinitelyAssignedVariables(currentScope, this.initStateIndex); + } codeStream.recordPositionsFrom(pc, this.sourceStart); SubRoutineStatement.reenterAllExceptionHandlers(this.subroutines, -1, codeStream); } Index: compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java,v retrieving revision 1.7 diff -u -r1.7 BreakStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java 28 Mar 2006 20:29:56 -0000 1.7 +++ compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java 23 Aug 2006 15:30:03 -0000 @@ -39,6 +39,9 @@ return flowInfo; // pretend it did not break since no actual target } + this.initStateIndex = + currentScope.methodScope().recordInitializationStates(flowInfo); + this.targetLabel = targetContext.breakLabel(); FlowContext traversedContext = flowContext; int subCount = 0; Index: compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java,v retrieving revision 1.59 diff -u -r1.59 ForStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java 28 Mar 2006 20:29:56 -0000 1.59 +++ compiler/org/eclipse/jdt/internal/compiler/ast/ForStatement.java 23 Aug 2006 15:30:03 -0000 @@ -33,6 +33,7 @@ // for local variables table attributes int preCondInitStateIndex = -1; + int preIncrementsInitStateIndex = -1; int condIfTrueInitStateIndex = -1; int mergedInitStateIndex = -1; @@ -166,6 +167,8 @@ new LoopingFlowContext(flowContext, flowInfo, this, null, null, scope); FlowInfo incrementInfo = actionInfo; + this.preIncrementsInitStateIndex = + currentScope.methodScope().recordInitializationStates(incrementInfo); for (int i = 0, count = increments.length; i < count; i++) { incrementInfo = increments[i]. analyseCode(scope, incrementContext, incrementInfo); @@ -271,6 +274,10 @@ } else { actionLabel.place(); } + if (this.preIncrementsInitStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preIncrementsInitStateIndex); + codeStream.addDefinitelyAssignedVariables(currentScope, this.preIncrementsInitStateIndex); + } // continuation point if (continueLabel != null) { continueLabel.place(); Index: compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java,v retrieving revision 1.19 diff -u -r1.19 BranchStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java 28 Mar 2006 20:29:56 -0000 1.19 +++ compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java 23 Aug 2006 15:30:03 -0000 @@ -18,7 +18,8 @@ public char[] label; public BranchLabel targetLabel; public SubRoutineStatement[] subroutines; - + public int initStateIndex = -1; + /** * BranchStatement constructor comment. */ @@ -48,6 +49,10 @@ if (didEscape) { codeStream.recordPositionsFrom(pc, this.sourceStart); SubRoutineStatement.reenterAllExceptionHandlers(this.subroutines, i, codeStream); + if (this.initStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.initStateIndex); + codeStream.addDefinitelyAssignedVariables(currentScope, this.initStateIndex); + } return; } } @@ -55,6 +60,10 @@ codeStream.goto_(this.targetLabel); codeStream.recordPositionsFrom(pc, this.sourceStart); SubRoutineStatement.reenterAllExceptionHandlers(this.subroutines, -1, codeStream); + if (this.initStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.initStateIndex); + codeStream.addDefinitelyAssignedVariables(currentScope, this.initStateIndex); + } } public void resolve(BlockScope scope) { Index: compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java,v retrieving revision 1.9 diff -u -r1.9 ContinueStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java 28 Mar 2006 20:29:56 -0000 1.9 +++ compiler/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java 23 Aug 2006 15:30:03 -0000 @@ -43,6 +43,9 @@ currentScope.problemReporter().invalidContinue(this); return flowInfo; // pretend it did not continue since no actual target } + this.initStateIndex = + currentScope.methodScope().recordInitializationStates(flowInfo); + targetLabel = targetContext.continueLabel(); FlowContext traversedContext = flowContext; int subCount = 0; Index: compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java,v retrieving revision 1.44 diff -u -r1.44 SynchronizedStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java 28 Mar 2006 20:29:56 -0000 1.44 +++ compiler/org/eclipse/jdt/internal/compiler/ast/SynchronizedStatement.java 23 Aug 2006 15:30:04 -0000 @@ -26,6 +26,10 @@ public LocalVariableBinding synchroVariable; static final char[] SecretLocalDeclarationName = " syncValue".toCharArray(); //$NON-NLS-1$ + // for local variables table attributes + int preSynchronizedInitStateIndex = -1; + int mergedSynchronizedInitStateIndex = -1; + public SynchronizedStatement( Expression expression, Block statement, @@ -43,6 +47,8 @@ FlowContext flowContext, FlowInfo flowInfo) { + this.preSynchronizedInitStateIndex = + currentScope.methodScope().recordInitializationStates(flowInfo); // TODO (philippe) shouldn't it be protected by a check whether reachable statement ? // mark the synthetic variable as being used @@ -55,6 +61,9 @@ new InsideSubRoutineFlowContext(flowContext, this), expression.analyseCode(scope, flowContext, flowInfo)); + this.mergedSynchronizedInitStateIndex = + currentScope.methodScope().recordInitializationStates(flowInfo); + // optimizing code gen this.blockExit = (flowInfo.tagBits & FlowInfo.UNREACHABLE) != 0; @@ -104,6 +113,11 @@ // generate the body of the synchronized block this.enterAnyExceptionHandler(codeStream); block.generateCode(scope, codeStream); + if (scope != currentScope) { + // close all locals defined in the synchronized block except the secret local + codeStream.exitUserScope(scope, synchroVariable); + } + BranchLabel endLabel = new BranchLabel(codeStream); if (!blockExit) { codeStream.load(synchroVariable); @@ -114,13 +128,21 @@ } // generate the body of the exception handler codeStream.pushOnStack(scope.getJavaLangThrowable()); + if (this.preSynchronizedInitStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSynchronizedInitStateIndex); + } this.placeAllAnyExceptionHandler(); codeStream.load(synchroVariable); codeStream.monitorexit(); this.exitAnyExceptionHandler(); codeStream.athrow(); + // May loose some local variable initializations : affecting the local variable attributes + if (this.mergedSynchronizedInitStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedSynchronizedInitStateIndex); + codeStream.addDefinitelyAssignedVariables(currentScope, this.mergedSynchronizedInitStateIndex); + } if (scope != currentScope) { - codeStream.exitUserScope(scope); + codeStream.removeVariable(this.synchroVariable); } if (!blockExit) { endLabel.place(); Index: compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java,v retrieving revision 1.35.4.5 diff -u -r1.35.4.5 ForeachStatement.java --- compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java 12 Jul 2006 16:04:42 -0000 1.35.4.5 +++ compiler/org/eclipse/jdt/internal/compiler/ast/ForeachStatement.java 23 Aug 2006 15:30:04 -0000 @@ -282,7 +282,10 @@ if (!hasEmptyAction) { this.action.generateCode(scope, codeStream); } - + codeStream.removeVariable(this.elementVariable.binding); + if (this.postCollectionInitStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.postCollectionInitStateIndex); + } // continuation point if (this.continueLabel != null) { this.continueLabel.place(); @@ -299,10 +302,6 @@ } codeStream.recordPositionsFrom(continuationPC, this.elementVariable.sourceStart); } - - if (this.postCollectionInitStateIndex != -1) { - codeStream.removeNotDefinitelyAssignedVariables(currentScope, postCollectionInitStateIndex); - } // generate the condition conditionLabel.place(); int conditionPC = codeStream.position; Index: buildnotes_jdt-core.html =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/buildnotes_jdt-core.html,v retrieving revision 1.5274.2.15 diff -u -r1.5274.2.15 buildnotes_jdt-core.html --- buildnotes_jdt-core.html 15 Aug 2006 16:12:27 -0000 1.5274.2.15 +++ buildnotes_jdt-core.html 23 Aug 2006 15:30:03 -0000 @@ -37,6 +37,20 @@ + +


+Eclipse Platform Build Notes
+Java Development Tooling Core

+Eclipse SDK 3.2.1 - 23rd August 2006 +
Project org.eclipse.jdt.core v_674_R32x +(cvs). +

What's new in this drop

+ +

Problem Reports Fixed

+145397 +[1.6][compiler] Invalid StackMap attribute +
151153 +[1.6][compiler] Invalid Stackmap attribute generated for ternary operator


Index: compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java,v retrieving revision 1.133.4.1 diff -u -r1.133.4.1 CodeStream.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java 2 Jul 2006 10:11:43 -0000 1.133.4.1 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java 23 Aug 2006 15:30:04 -0000 @@ -246,6 +246,10 @@ System.arraycopy(visibleLocals, 0, visibleLocals = new LocalVariableBinding[visibleLocalsCount * 2], 0, visibleLocalsCount); visibleLocals[visibleLocalsCount++] = localBinding; } + +public void addVariable(LocalVariableBinding localBinding) { + /* do nothing */ +} public void aload(int iArg) { if (DEBUG) System.out.println(position + "\t\taload:"+iArg); //$NON-NLS-1$ countLabels = 0; @@ -1025,18 +1029,41 @@ if (((this.generateAttributes & ClassFileConstants.ATTR_VARS) == 0) && ((this.generateAttributes & ClassFileConstants.ATTR_STACK_MAP) == 0)) return; - while (visibleLocalsCount > 0) { - LocalVariableBinding visibleLocal = visibleLocals[this.visibleLocalsCount - 1]; + int index = this.visibleLocalsCount - 1; + while (index >= 0) { + LocalVariableBinding visibleLocal = visibleLocals[index]; if (visibleLocal == null || visibleLocal.declaringScope != currentScope) { // left currentScope - break; + index--; + continue; } // there may be some preserved locals never initialized if (visibleLocal.initializationCount > 0 && ((this.generateAttributes & ClassFileConstants.ATTR_VARS) != 0)){ visibleLocal.recordInitializationEndPC(position); } - visibleLocals[--this.visibleLocalsCount] = null; // this variable is no longer visible afterwards + visibleLocals[index--] = null; // this variable is no longer visible afterwards + } +} +public void exitUserScope(BlockScope currentScope, LocalVariableBinding binding) { + // mark all the scope's locals as losing their definite assignment + + if (((this.generateAttributes & ClassFileConstants.ATTR_VARS) == 0) + && ((this.generateAttributes & ClassFileConstants.ATTR_STACK_MAP) == 0)) + return; + int index = this.visibleLocalsCount - 1; + while (index >= 0) { + LocalVariableBinding visibleLocal = visibleLocals[index]; + if (visibleLocal == null || visibleLocal.declaringScope != currentScope || visibleLocal == binding) { + // left currentScope + index--; + continue; + } + // there may be some preserved locals never initialized + if (visibleLocal.initializationCount > 0 && ((this.generateAttributes & ClassFileConstants.ATTR_VARS) != 0)){ + visibleLocal.recordInitializationEndPC(position); + } + visibleLocals[index--] = null; // this variable is no longer visible afterwards } } public void f2d() { @@ -2935,7 +2962,7 @@ /** * We didn't call it goto, because there is a conflit with the goto keyword */ -final public void goto_(BranchLabel label) { +public void goto_(BranchLabel label) { if (this.wideMode) { this.goto_w(label); return; @@ -2976,7 +3003,7 @@ bCodeStream[classFileOffset++] = Opcodes.OPC_goto; label.branch(); } -final public void goto_w(BranchLabel lbl) { +public void goto_w(BranchLabel lbl) { if (DEBUG) System.out.println(position + "\t\tgotow:"+lbl); //$NON-NLS-1$ if (classFileOffset >= bCodeStream.length) { resizeByteArray(); @@ -5820,7 +5847,6 @@ // no need to resize. So just add the new exception label exceptionLabels[exceptionLabelsCounter++] = anExceptionLabel; } - public void removeNotDefinitelyAssignedVariables(Scope scope, int initStateIndex) { // given some flow info, make sure we did not loose some variables initialization // if this happens, then we must update their pc entries to reflect it in debug attributes @@ -5842,6 +5868,19 @@ } } } +public void removeVariable(LocalVariableBinding localBinding) { + if (localBinding == null) return; + if (localBinding.initializationCount > 0) { + localBinding.recordInitializationEndPC(position); + } + for (int i = visibleLocalsCount - 1; i >= 0; i--) { + LocalVariableBinding visibleLocal = visibleLocals[i]; + if (visibleLocal == localBinding){ + visibleLocals[i] = null; // this variable is no longer visible afterwards + return; + } + } +} /** * @param referenceMethod org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration * @param targetClassFile org.eclipse.jdt.internal.compiler.codegen.ClassFile Index: compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java,v retrieving revision 1.3.2.1 diff -u -r1.3.2.1 StackMapFrame.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java 2 Jul 2006 10:11:43 -0000 1.3.2.1 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrame.java 23 Aug 2006 15:30:04 -0000 @@ -31,8 +31,6 @@ public int localIndex; public VerificationTypeInfo[] locals; public VerificationTypeInfo[] stackItems; - public StackMapFrame nextFrame; - public StackMapFrame prevFrame; private int numberOfDifferentLocals = -1; public int tagBits; @@ -40,11 +38,11 @@ this.numberOfLocals = -1; this.numberOfDifferentLocals = -1; } -public int getFrameType() { - final int offsetDelta = this.getOffsetDelta(); +public int getFrameType(StackMapFrame prevFrame) { + final int offsetDelta = this.getOffsetDelta(prevFrame); switch(this.numberOfStackItems) { case 0 : - switch(this.numberOfDifferentLocals()) { + switch(this.numberOfDifferentLocals(prevFrame)) { case 0 : return offsetDelta <= 63 ? SAME_FRAME : SAME_FRAME_EXTENDED; case 1 : @@ -58,7 +56,7 @@ } break; case 1 : - switch(this.numberOfDifferentLocals()) { + switch(this.numberOfDifferentLocals(prevFrame)) { case 0 : return offsetDelta <= 63 ? SAME_LOCALS_1_STACK_ITEMS : SAME_LOCALS_1_STACK_ITEMS_EXTENDED; } @@ -119,21 +117,23 @@ } return result; } -public int numberOfDiffentStackItems() { - if (this.prevFrame == null) return this.numberOfStackItems; - return this.numberOfStackItems - this.prevFrame.numberOfStackItems; +public int numberOfDiffentStackItems(StackMapFrame prevFrame) { + if (prevFrame == null) { + return this.numberOfStackItems; + } + return this.numberOfStackItems - prevFrame.numberOfStackItems; } -public int numberOfDifferentLocals() { +public int numberOfDifferentLocals(StackMapFrame prevFrame) { if (this.numberOfDifferentLocals != -1) return this.numberOfDifferentLocals; - if (this.prevFrame == null) { + if (prevFrame == null) { this.numberOfDifferentLocals = 0; return 0; } - VerificationTypeInfo[] prevLocals = this.prevFrame.locals; + VerificationTypeInfo[] prevLocals = prevFrame.locals; VerificationTypeInfo[] currentLocals = this.locals; int prevLocalsLength = prevLocals == null ? 0 : prevLocals.length; int currentLocalsLength = currentLocals == null ? 0 : currentLocals.length; - int prevNumberOfLocals = this.prevFrame.getNumberOfLocals(); + int prevNumberOfLocals = prevFrame.getNumberOfLocals(); int currentNumberOfLocals = this.getNumberOfLocals(); int result = 0; @@ -287,9 +287,9 @@ this.numberOfLocals = result; return result; } -public int getOffsetDelta() { - if (this.prevFrame == null) return this.pc; - return this.prevFrame.pc == -1 ? this.pc : this.pc - this.prevFrame.pc - 1; +public int getOffsetDelta(StackMapFrame prevFrame) { + if (prevFrame == null) return this.pc; + return prevFrame.pc == -1 ? this.pc : this.pc - prevFrame.pc - 1; } public String toString() { StringBuffer buffer = new StringBuffer(); @@ -309,11 +309,6 @@ print(frame.stackItems, frame.numberOfStackItems) } )); - final StackMapFrame next = frame.nextFrame; - if (next != null) { - buffer.append('\n'); - printFrame(buffer, next); - } } private String print(VerificationTypeInfo[] infos, int length) { StringBuffer buffer = new StringBuffer(); @@ -355,7 +350,7 @@ } } public void removeLocals(int resolvedPosition) { - if (this.locals == null) return; + if (this.locals == null || resolvedPosition < 0) return; if (resolvedPosition < this.locals.length) { this.locals[resolvedPosition] = null; } @@ -404,4 +399,25 @@ if (info2 == null) return false; return info.equals(info2); } +public void mergeLocals(StackMapFrame currentFrame) { + int currentFrameLocalsLength = currentFrame.locals == null ? 0 : currentFrame.locals.length; + int localsLength = this.locals == null ? 0 : this.locals.length; + for (int i = 0, max = Math.min(currentFrameLocalsLength, localsLength); i < max; i++) { + VerificationTypeInfo info = this.locals[i]; + VerificationTypeInfo info2 = currentFrame.locals[i]; + if (info == null) { + if (info2 != null) { + this.locals[i] = info2; + } + } else if (info2 == null) { + this.locals[i] = null; + } else { + int tag1 = info.tag; + int tag2 = info2.tag; + if (tag1 != tag2) { + this.locals[i] = null; + } + } + } +} } \ No newline at end of file Index: compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java,v retrieving revision 1.7.4.1 diff -u -r1.7.4.1 StackMapFrameCodeStream.java --- compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java 2 Jul 2006 10:11:44 -0000 1.7.4.1 +++ compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java 23 Aug 2006 15:30:04 -0000 @@ -10,6 +10,10 @@ *******************************************************************************/ package org.eclipse.jdt.internal.compiler.codegen; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.ClassFile; import org.eclipse.jdt.internal.compiler.ast.ASTNode; @@ -28,9 +32,11 @@ public class StackMapFrameCodeStream extends CodeStream { public StackMapFrame currentFrame; - public StackMapFrame frames; + public ArrayList frames; - public int framesCounter; + public Set framePositions; + + public ArrayList variablesModificationsPositions; public StackMapFrameCodeStream(ClassFile givenClassFile) { super(givenClassFile); @@ -70,8 +76,18 @@ } } } + Integer newValue = new Integer(this.position); + if (this.variablesModificationsPositions.size() == 0 || !this.variablesModificationsPositions.get(this.variablesModificationsPositions.size() - 1).equals(newValue)) { + this.variablesModificationsPositions.add(newValue); + } + storeStackMapFrame(); super.addDefinitelyAssignedVariables(scope, initStateIndex); } +public void addVariable(LocalVariableBinding localBinding) { + currentFrame.putLocal(localBinding.resolvedPosition, new VerificationTypeInfo(localBinding.type)); + storeStackMapFrame(); + super.addVariable(localBinding); +} public void aload(int iArg) { super.aload(iArg); this.currentFrame.addStackItem(getLocal(iArg, this.currentFrame)); @@ -100,6 +116,7 @@ public void areturn() { super.areturn(); this.currentFrame.numberOfStackItems--; + framePositions.add(new Integer(this.position)); } public void arraylength() { super.arraylength(); @@ -133,6 +150,7 @@ public void athrow() { super.athrow(); this.currentFrame.numberOfStackItems--; + framePositions.add(new Integer(this.position)); } public void baload() { super.baload(); @@ -274,6 +292,7 @@ public void dreturn() { super.dreturn(); this.currentFrame.numberOfStackItems--; + this.framePositions.add(new Integer(this.position)); } public void dstore(int iArg) { super.dstore(iArg); @@ -436,11 +455,12 @@ } } public void exitUserScope(BlockScope currentScope) { - int index = this.visibleLocalsCount; - while (index > 0) { - LocalVariableBinding visibleLocal = visibleLocals[index - 1]; + int index = this.visibleLocalsCount - 1; + while (index >= 0) { + LocalVariableBinding visibleLocal = visibleLocals[index]; if (visibleLocal == null) { - return; + index--; + continue; } if (visibleLocal.declaringScope != currentScope) // left currentScope break; @@ -464,6 +484,37 @@ } super.exitUserScope(currentScope); } +public void exitUserScope(BlockScope currentScope, LocalVariableBinding binding) { + int index = this.visibleLocalsCount - 1; + while (index >= 0) { + LocalVariableBinding visibleLocal = visibleLocals[index]; + if (visibleLocal == null || visibleLocal == binding) { + index--; + continue; + } + if (visibleLocal.declaringScope != currentScope) // left currentScope + break; + + // there may be some preserved locals never initialized + if (visibleLocal.initializationCount > 0){ + this.currentFrame.removeLocals(visibleLocal.resolvedPosition); + } + index--; + } + if (currentScope != null) { + int localIndex = currentScope.localIndex; + if (localIndex != 0) { + for (int i = 0; i < localIndex; i++) { + LocalVariableBinding variableBinding = currentScope.locals[i]; + if (variableBinding != null && variableBinding != binding && variableBinding.useFlag == LocalVariableBinding.USED && variableBinding.resolvedPosition != -1) { + this.currentFrame.removeLocals(variableBinding.resolvedPosition); + } + } + } + } + this.storeStackMapFrame(); + super.exitUserScope(currentScope, binding); +} public void f2d() { super.f2d(); this.currentFrame.stackItems[this.currentFrame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE); @@ -546,6 +597,7 @@ public void freturn() { super.freturn(); this.currentFrame.numberOfStackItems--; + this.framePositions.add(new Integer(this.position)); } public void fstore(int iArg) { super.fstore(iArg); @@ -716,26 +768,25 @@ this.currentFrame.stackItems[this.currentFrame.numberOfStackItems - 1] = new VerificationTypeInfo(fieldBinding.type); } private VerificationTypeInfo getLocal(int resolvedPosition, StackMapFrame frame) { - return frame.locals[resolvedPosition]; + final VerificationTypeInfo verificationTypeInfo = frame.locals[resolvedPosition]; + if (verificationTypeInfo == null) { + return null; + } + try { + if (verificationTypeInfo.tag == VerificationTypeInfo.ITEM_UNINITIALIZED_THIS + || verificationTypeInfo.tag == VerificationTypeInfo.ITEM_UNINITIALIZED) { + return verificationTypeInfo; + } + return (VerificationTypeInfo) verificationTypeInfo.clone(); + } catch (CloneNotSupportedException e) { + return verificationTypeInfo; + } } protected int getPosition() { // need to record a new stack frame at this position int pos = super.getPosition(); - try { - if (this.frames.pc != pos) { - StackMapFrame newFrame = (StackMapFrame) this.currentFrame.clone(); - this.frames.nextFrame = newFrame; - newFrame.pc = pos; - newFrame.prevFrame = this.frames; - this.frames = newFrame; - framesCounter++; - } else { - // the frame already exists - this.frames.tagBits |= StackMapFrame.USED; - } - } catch (CloneNotSupportedException e) { - e.printStackTrace(); - } + this.framePositions.add(new Integer(this.position)); + storeStackMapFrame(); return pos; } public void getstatic(FieldBinding fieldBinding) { @@ -746,6 +797,17 @@ super.getTYPE(baseTypeID); this.currentFrame.addStackItem(new VerificationTypeInfo(TypeIds.T_JavaLangClass, ConstantPool.JavaLangClassConstantPoolName)); } +/** + * We didn't call it goto, because there is a conflit with the goto keyword + */ +public void goto_(BranchLabel label) { + super.goto_(label); + this.framePositions.add(new Integer(this.position)); +} +public void goto_w(BranchLabel label) { + super.goto_w(label); + this.framePositions.add(new Integer(this.position)); +} public void i2b() { super.i2b(); this.currentFrame.stackItems[this.currentFrame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.BYTE); @@ -966,7 +1028,6 @@ } public void init(ClassFile targetClassFile) { super.init(targetClassFile); - this.framesCounter = 0; this.frames = null; this.currentFrame = null; } @@ -974,7 +1035,6 @@ super.initializeMaxLocals(methodBinding); StackMapFrame frame = new StackMapFrame(); frame.pc = -1; - this.framesCounter = 1; if (this.maxLocals != 0) { int resolvedPosition = 0; @@ -1042,11 +1102,14 @@ } } try { - this.frames = (StackMapFrame) frame.clone(); + this.frames = new ArrayList(); + this.frames.add(frame.clone()); } catch (CloneNotSupportedException e) { e.printStackTrace(); } this.currentFrame = frame; + this.framePositions = new HashSet(); + this.variablesModificationsPositions = new ArrayList(); } public void instance_of(TypeBinding typeBinding) { super.instance_of(typeBinding); @@ -1284,6 +1347,7 @@ public void ireturn() { super.ireturn(); this.currentFrame.numberOfStackItems--; + this.framePositions.add(new Integer(this.position)); } public void ishl() { super.ishl(); @@ -1439,6 +1503,7 @@ public void lreturn() { super.lreturn(); this.currentFrame.numberOfStackItems--; + this.framePositions.add(new Integer(this.position)); } public void lshl() { super.lshl(); @@ -1616,44 +1681,28 @@ } public void optimizeBranch(int oldPosition, BranchLabel lbl) { super.optimizeBranch(oldPosition, lbl); - if (lbl.forwardReferenceCount > 0) { - StackMapFrame frame = this.frames; - loop: while (frame != null) { - if (frame.pc == oldPosition) { - frame.pc = this.position; - if (frame.prevFrame.pc == this.position) { - // remove the current frame - StackMapFrame prev = frame.prevFrame; - frame.prevFrame = null; - prev.nextFrame = null; - this.frames = prev; - } - break loop; + int frameIndex = this.frames.size() - 1; + loop: while(frameIndex > 0) { + StackMapFrame frame = (StackMapFrame) this.frames.get(frameIndex); + if (frame.pc == oldPosition) { + if (this.framePositions.remove(new Integer(oldPosition))) { + this.framePositions.add(new Integer(this.position)); } - } - } else { - StackMapFrame frame = this.frames; - loop: while (frame != null) { - if (frame.pc == oldPosition) { - if ((frame.tagBits & StackMapFrame.USED) != 0) { - frame.pc = this.position; - if (frame.prevFrame.pc == this.position) { - // remove the current frame - StackMapFrame prev = frame.prevFrame; - frame.prevFrame = null; - prev.nextFrame = null; - this.frames = prev; - } - } else { - // we completely remove this entry if the prevFrame has the same position - StackMapFrame prev = frame.prevFrame; - frame.prevFrame = null; - prev.nextFrame = null; - this.frames = prev; - } - break loop; + if (this.variablesModificationsPositions.remove(new Integer(oldPosition))) { + this.variablesModificationsPositions.add(new Integer(this.position)); } + frame.pc = this.position; + StackMapFrame previousFrame = (StackMapFrame) this.frames.get(frameIndex - 1); + if (previousFrame.pc == this.position) { + // remove the current frame + this.frames.set(frameIndex - 1, frame); + this.frames.remove(frameIndex); + } + break loop; + } else if (frame.pc > oldPosition) { + return; } + frameIndex--; } } public void pop() { @@ -1687,6 +1736,10 @@ super.recordExpressionType(typeBinding); this.currentFrame.setTopOfStack(typeBinding); } +public void removeVariable(LocalVariableBinding localBinding) { + this.currentFrame.removeLocals(localBinding.resolvedPosition); + super.removeVariable(localBinding); +} public void removeNotDefinitelyAssignedVariables(Scope scope, int initStateIndex) { int index = this.visibleLocalsCount; for (int i = 0; i < index; i++) { @@ -1696,8 +1749,37 @@ this.currentFrame.removeLocals(localBinding.resolvedPosition); } } + Integer newValue = new Integer(this.position); + if (this.variablesModificationsPositions.size() == 0 || !this.variablesModificationsPositions.get(this.variablesModificationsPositions.size() - 1).equals(newValue)) { + this.variablesModificationsPositions.add(newValue); + } + storeStackMapFrame(); super.removeNotDefinitelyAssignedVariables(scope, initStateIndex); } +public void storeStackMapFrame() { + int frameSize = this.frames.size(); + StackMapFrame mapFrame = null; + try { + mapFrame = (StackMapFrame) this.currentFrame.clone(); + mapFrame.pc = this.position; + } catch(CloneNotSupportedException e) { + // ignore + } + if (frameSize == 0) { + this.frames.add(mapFrame); + } else { + StackMapFrame lastFrame = (StackMapFrame) this.frames.get(frameSize - 1); + if (lastFrame.pc == this.position) { + this.frames.set(frameSize - 1, mapFrame); + } else { + this.frames.add(mapFrame); + } + } +} +public void return_() { + super.return_(); + this.framePositions.add(new Integer(this.position)); +} public void saload() { super.saload(); this.currentFrame.numberOfStackItems--; @@ -1717,7 +1799,7 @@ switch(typeBinding.id) { default: // Reference object - this.currentFrame.locals[localBinding.resolvedPosition].setBinding(typeBinding); + this.currentFrame.locals[localBinding.resolvedPosition] = new VerificationTypeInfo(typeBinding); } } public void swap() { @@ -1736,36 +1818,30 @@ this.currentFrame.numberOfStackItems--; } public void throwAnyException(LocalVariableBinding anyExceptionVariable) { + this.currentFrame.putLocal(anyExceptionVariable.resolvedPosition, new VerificationTypeInfo(VerificationTypeInfo.ITEM_OBJECT, anyExceptionVariable.type)); super.throwAnyException(anyExceptionVariable); this.currentFrame.removeLocals(anyExceptionVariable.resolvedPosition); } public void removeStackFrameFor(int pos) { - StackMapFrame frame = this.frames; - while (frame.prevFrame != null && frame.pc >= pos) { - if (frame.pc == pos) { - StackMapFrame next = frame.nextFrame; - StackMapFrame prev = frame.prevFrame; - prev.nextFrame = next; - if (next != null) { - next.prevFrame = prev; - } - frame.nextFrame = null; - frame.prevFrame = null; - frame = prev; - while (frame.nextFrame != null) { - frame = frame.nextFrame; - } - this.frames = frame; - this.framesCounter--; - return; - } - frame = frame.prevFrame; - } + // TODO (olivier) need to see how to get rid of some unnecessary frames } public void reset(ClassFile givenClassFile) { super.reset(givenClassFile); - this.framesCounter = 0; this.frames = null; this.currentFrame = null; + this.framePositions = null; + this.variablesModificationsPositions = null; +} +protected void writePosition(BranchLabel label) { + super.writePosition(label); + framePositions.add(new Integer(label.position)); +} +protected void writeWidePosition(BranchLabel label) { + super.writeWidePosition(label); + framePositions.add(new Integer(label.position)); +} +protected void writePosition(BranchLabel label, int forwardReference) { + super.writePosition(label, forwardReference); + framePositions.add(new Integer(label.position)); } } Index: batch/org/eclipse/jdt/internal/compiler/batch/messages.properties =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/batch/org/eclipse/jdt/internal/compiler/batch/messages.properties,v retrieving revision 1.546.2.2 diff -u -r1.546.2.2 messages.properties --- batch/org/eclipse/jdt/internal/compiler/batch/messages.properties 3 Aug 2006 17:33:11 -0000 1.546.2.2 +++ batch/org/eclipse/jdt/internal/compiler/batch/messages.properties 23 Aug 2006 15:30:03 -0000 @@ -14,7 +14,7 @@ #Format: compiler.name = word1 word2 word3 compiler.name = Eclipse Java Compiler #Format: compiler.version = 0.XXX[, other words (don't forget the comma if adding other words)] -compiler.version = v_673_R32x, pre-3.2.1 release +compiler.version = v_674_R32x, 3.2.1 release compiler.copyright = Copyright IBM Corp 2000, 2006. All rights reserved. ### scanning Index: eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java,v retrieving revision 1.38 diff -u -r1.38 CodeSnippetClassFile.java --- eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java 29 Mar 2006 02:57:52 -0000 1.38 +++ eval/org/eclipse/jdt/internal/eval/CodeSnippetClassFile.java 23 Aug 2006 15:30:04 -0000 @@ -116,6 +116,7 @@ this.creatingProblemType = creatingProblemType; if (this.targetJDK >= ClassFileConstants.JDK1_6) { this.codeStream = new StackMapFrameCodeStream(this); + this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP; } else { this.codeStream = new CodeStream(this); } Index: compiler/org/eclipse/jdt/internal/compiler/ClassFile.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java,v retrieving revision 1.137.4.1 diff -u -r1.137.4.1 ClassFile.java --- compiler/org/eclipse/jdt/internal/compiler/ClassFile.java 2 Jul 2006 10:11:42 -0000 1.137.4.1 +++ compiler/org/eclipse/jdt/internal/compiler/ClassFile.java 23 Aug 2006 15:30:03 -0000 @@ -14,6 +14,9 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Set; import java.util.StringTokenizer; import org.eclipse.jdt.core.compiler.CategorizedProblem; @@ -1785,8 +1788,13 @@ } if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { - int numberOfFrames = ((StackMapFrameCodeStream) codeStream).framesCounter; - if (numberOfFrames >=2) { + final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; + final int framesPositionsSize = framesPositions.size(); + int numberOfFrames = framesPositionsSize - 1; // -1 because last return doesn't count + if (numberOfFrames > 0) { + ArrayList framePositions = new ArrayList(framesPositionsSize); + framePositions.addAll(framesPositions); + Collections.sort(framePositions); int stackMapTableAttributeOffset = localContentsOffset; // add the stack map table attribute if (localContentsOffset + 8 >= this.contents.length) { @@ -1809,23 +1817,32 @@ if (localContentsOffset + 2 >= this.contents.length) { resizeContents(2); } - // generate all frames - StackMapFrame currentFrame = ((StackMapFrameCodeStream) codeStream).frames; - while (currentFrame.prevFrame != null) { - currentFrame = currentFrame.prevFrame; - } - currentFrame = currentFrame.nextFrame; - while (currentFrame != null && currentFrame.pc < code_length) { + ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; + StackMapFrame currentFrame = (StackMapFrame) frames.get(0); + StackMapFrame prevFrame = null; + int framesSize = frames.size(); + int frameIndex = 0; + for (int j = 0; j < framesPositionsSize && ((Integer) framePositions.get(j)).intValue() < code_length; j++) { + // select next frame + prevFrame = currentFrame; + currentFrame = null; + for (; frameIndex < framesSize; frameIndex++) { + currentFrame = (StackMapFrame) frames.get(frameIndex); + if (currentFrame.pc == ((Integer) framePositions.get(j)).intValue()) { + break; + } + } + if (currentFrame == null) break; // generate current frame // need to find differences between the current frame and the previous frame numberOfFrames++; - int offsetDelta = currentFrame.getOffsetDelta(); - switch (currentFrame.getFrameType()) { + int offsetDelta = currentFrame.getOffsetDelta(prevFrame); + switch (currentFrame.getFrameType(prevFrame)) { case StackMapFrame.APPEND_FRAME : if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } - int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(); + int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals); this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++] = (byte) offsetDelta; @@ -1897,7 +1914,7 @@ if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } - numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(); + numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals); this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++] = (byte) offsetDelta; @@ -2111,7 +2128,6 @@ } } } - currentFrame = currentFrame.nextFrame; } if (numberOfFrames != 0) { @@ -2416,8 +2432,13 @@ } if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { - int numberOfFrames = ((StackMapFrameCodeStream) codeStream).framesCounter; - if (numberOfFrames >=2) { + final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; + final int framesPositionsSize = framesPositions.size(); + int numberOfFrames = framesPositionsSize - 1; // -1 because last return doesn't count + if (numberOfFrames > 0) { + ArrayList framePositions = new ArrayList(framesPositionsSize); + framePositions.addAll(framesPositions); + Collections.sort(framePositions); // add the stack map table attribute if (localContentsOffset + 8 >= this.contents.length) { resizeContents(8); @@ -2434,22 +2455,30 @@ int numberOfFramesOffset = localContentsOffset; localContentsOffset += 2; // generate all frames - StackMapFrame currentFrame = ((StackMapFrameCodeStream) codeStream).frames; - while (currentFrame.prevFrame != null) { - currentFrame = currentFrame.prevFrame; - } - currentFrame = currentFrame.nextFrame; - while (currentFrame != null && currentFrame.pc < code_length) { - // generate current frame - // need to find differences between the current frame and the previous frame + ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; + StackMapFrame currentFrame = (StackMapFrame) frames.get(0); + StackMapFrame prevFrame = null; + int framesSize = frames.size(); + int frameIndex = 0; + for (int j = 0; j < framesPositionsSize && ((Integer) framePositions.get(j)).intValue() < code_length; j++) { + // select next frame + prevFrame = currentFrame; + currentFrame = null; + for (; frameIndex < framesSize; frameIndex++) { + currentFrame = (StackMapFrame) frames.get(frameIndex); + if (currentFrame.pc == ((Integer) framePositions.get(j)).intValue()) { + break; + } + } + if (currentFrame == null) break; numberOfFrames++; - int offsetDelta = currentFrame.getOffsetDelta(); - switch (currentFrame.getFrameType()) { + int offsetDelta = currentFrame.getOffsetDelta(prevFrame); + switch (currentFrame.getFrameType(prevFrame)) { case StackMapFrame.APPEND_FRAME : if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } - int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(); + int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals); this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++] = (byte) offsetDelta; @@ -2521,7 +2550,7 @@ if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } - numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(); + numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals); this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++] = (byte) offsetDelta; @@ -2733,7 +2762,6 @@ } } } - currentFrame = currentFrame.nextFrame; } this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8); @@ -2863,8 +2891,13 @@ } if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { - int numberOfFrames = ((StackMapFrameCodeStream) codeStream).framesCounter; - if (numberOfFrames >=2) { + final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; + final int framesPositionsSize = framesPositions.size(); + int numberOfFrames = framesPositionsSize - 1; // -1 because last return doesn't count + if (numberOfFrames > 0) { + ArrayList framePositions = new ArrayList(framesPositionsSize); + framePositions.addAll(framesPositions); + Collections.sort(framePositions); // add the stack map table attribute if (localContentsOffset + 8 >= this.contents.length) { resizeContents(8); @@ -2881,22 +2914,32 @@ int numberOfFramesOffset = localContentsOffset; localContentsOffset += 2; // generate all frames - StackMapFrame currentFrame = ((StackMapFrameCodeStream) codeStream).frames; - while (currentFrame.prevFrame != null) { - currentFrame = currentFrame.prevFrame; - } - currentFrame = currentFrame.nextFrame; - while (currentFrame != null && currentFrame.pc < code_length) { + ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; + StackMapFrame currentFrame = (StackMapFrame) frames.get(0); + StackMapFrame prevFrame = null; + int framesSize = frames.size(); + int frameIndex = 0; + for (int j = 0; j < framesPositionsSize && ((Integer) framePositions.get(j)).intValue() < code_length; j++) { + // select next frame + prevFrame = currentFrame; + currentFrame = null; + for (; frameIndex < framesSize; frameIndex++) { + currentFrame = (StackMapFrame) frames.get(frameIndex); + if (currentFrame.pc == ((Integer) framePositions.get(j)).intValue()) { + break; + } + } + if (currentFrame == null) break; // generate current frame // need to find differences between the current frame and the previous frame numberOfFrames++; - int offsetDelta = currentFrame.getOffsetDelta(); - switch (currentFrame.getFrameType()) { + int offsetDelta = currentFrame.getOffsetDelta(prevFrame); + switch (currentFrame.getFrameType(prevFrame)) { case StackMapFrame.APPEND_FRAME : if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } - int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(); + int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals); this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++] = (byte) offsetDelta; @@ -2968,7 +3011,7 @@ if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } - numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(); + numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals); this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++] = (byte) offsetDelta; @@ -3180,7 +3223,6 @@ } } } - currentFrame = currentFrame.nextFrame; } this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8); @@ -3281,8 +3323,13 @@ } if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { - int numberOfFrames = ((StackMapFrameCodeStream) codeStream).framesCounter; - if (numberOfFrames >=2) { + final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; + final int framesPositionsSize = framesPositions.size(); + int numberOfFrames = framesPositionsSize - 1; // -1 because last return doesn't count + if (numberOfFrames > 0) { + ArrayList framePositions = new ArrayList(framesPositionsSize); + framePositions.addAll(framesPositions); + Collections.sort(framePositions); // add the stack map table attribute if (localContentsOffset + 8 >= this.contents.length) { resizeContents(8); @@ -3299,22 +3346,30 @@ int numberOfFramesOffset = localContentsOffset; localContentsOffset += 2; // generate all frames - StackMapFrame currentFrame = ((StackMapFrameCodeStream) codeStream).frames; - while (currentFrame.prevFrame != null) { - currentFrame = currentFrame.prevFrame; - } - currentFrame = currentFrame.nextFrame; - while (currentFrame != null && currentFrame.pc < code_length) { - // generate current frame - // need to find differences between the current frame and the previous frame + ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; + StackMapFrame currentFrame = (StackMapFrame) frames.get(0); + StackMapFrame prevFrame = null; + int framesSize = frames.size(); + int frameIndex = 0; + for (int j = 0; j < framesPositionsSize && ((Integer) framePositions.get(j)).intValue() < code_length; j++) { + // select next frame + prevFrame = currentFrame; + currentFrame = null; + for (; frameIndex < framesSize; frameIndex++) { + currentFrame = (StackMapFrame) frames.get(frameIndex); + if (currentFrame.pc == ((Integer) framePositions.get(j)).intValue()) { + break; + } + } + if (currentFrame == null) break; numberOfFrames++; - int offsetDelta = currentFrame.getOffsetDelta(); - switch (currentFrame.getFrameType()) { + int offsetDelta = currentFrame.getOffsetDelta(prevFrame); + switch (currentFrame.getFrameType(prevFrame)) { case StackMapFrame.APPEND_FRAME : if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } - int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(); + int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals); this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++] = (byte) offsetDelta; @@ -3386,7 +3441,7 @@ if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } - numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(); + numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals); this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++] = (byte) offsetDelta; @@ -3598,7 +3653,6 @@ } } } - currentFrame = currentFrame.nextFrame; } this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8); @@ -3932,8 +3986,13 @@ } if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { - int numberOfFrames = ((StackMapFrameCodeStream) codeStream).framesCounter; - if (numberOfFrames >=2) { + final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; + final int framesPositionsSize = framesPositions.size(); + int numberOfFrames = framesPositionsSize - 1; // -1 because last return doesn't count + if (numberOfFrames > 0) { + ArrayList framePositions = new ArrayList(framesPositionsSize); + framePositions.addAll(framesPositions); + Collections.sort(framePositions); // add the stack map table attribute if (localContentsOffset + 8 >= this.contents.length) { resizeContents(8); @@ -3950,22 +4009,30 @@ int numberOfFramesOffset = localContentsOffset; localContentsOffset += 2; // generate all frames - StackMapFrame currentFrame = ((StackMapFrameCodeStream) codeStream).frames; - while (currentFrame.prevFrame != null) { - currentFrame = currentFrame.prevFrame; - } - currentFrame = currentFrame.nextFrame; - while (currentFrame != null && currentFrame.pc < code_length) { - // generate current frame - // need to find differences between the current frame and the previous frame + ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; + StackMapFrame currentFrame = (StackMapFrame) frames.get(0); + StackMapFrame prevFrame = null; + int framesSize = frames.size(); + int frameIndex = 0; + for (int j = 0; j < framesPositionsSize && ((Integer) framePositions.get(j)).intValue() < code_length; j++) { + // select next frame + prevFrame = currentFrame; + currentFrame = null; + for (; frameIndex < framesSize; frameIndex++) { + currentFrame = (StackMapFrame) frames.get(frameIndex); + if (currentFrame.pc == ((Integer) framePositions.get(j)).intValue()) { + break; + } + } + if (currentFrame == null) break; numberOfFrames++; - int offsetDelta = currentFrame.getOffsetDelta(); - switch (currentFrame.getFrameType()) { + int offsetDelta = currentFrame.getOffsetDelta(prevFrame); + switch (currentFrame.getFrameType(prevFrame)) { case StackMapFrame.APPEND_FRAME : if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } - int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(); + int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals); this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++] = (byte) offsetDelta; @@ -4037,7 +4104,7 @@ if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } - numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(); + numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals); this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++] = (byte) offsetDelta; @@ -4249,7 +4316,6 @@ } } } - currentFrame = currentFrame.nextFrame; } this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8); @@ -4543,8 +4609,13 @@ } if ((this.produceAttributes & ClassFileConstants.ATTR_STACK_MAP) != 0) { - int numberOfFrames = ((StackMapFrameCodeStream) codeStream).framesCounter; - if (numberOfFrames >=2) { + final Set framesPositions = ((StackMapFrameCodeStream) codeStream).framePositions; + final int framesPositionsSize = framesPositions.size(); + int numberOfFrames = framesPositionsSize - 1; // -1 because last return doesn't count + if (numberOfFrames > 0) { + ArrayList framePositions = new ArrayList(framesPositionsSize); + framePositions.addAll(framesPositions); + Collections.sort(framePositions); // add the stack map table attribute if (localContentsOffset + 8 >= this.contents.length) { resizeContents(8); @@ -4561,22 +4632,30 @@ int numberOfFramesOffset = localContentsOffset; localContentsOffset += 2; // generate all frames - StackMapFrame currentFrame = ((StackMapFrameCodeStream) codeStream).frames; - while (currentFrame.prevFrame != null) { - currentFrame = currentFrame.prevFrame; - } - currentFrame = currentFrame.nextFrame; - while (currentFrame != null && currentFrame.pc < code_length) { - // generate current frame - // need to find differences between the current frame and the previous frame + ArrayList frames = ((StackMapFrameCodeStream) codeStream).frames; + StackMapFrame currentFrame = (StackMapFrame) frames.get(0); + StackMapFrame prevFrame = null; + int framesSize = frames.size(); + int frameIndex = 0; + for (int j = 0; j < framesPositionsSize && ((Integer) framePositions.get(j)).intValue() < code_length; j++) { + // select next frame + prevFrame = currentFrame; + currentFrame = null; + for (; frameIndex < framesSize; frameIndex++) { + currentFrame = (StackMapFrame) frames.get(frameIndex); + if (currentFrame.pc == ((Integer) framePositions.get(j)).intValue()) { + break; + } + } + if (currentFrame == null) break; numberOfFrames++; - int offsetDelta = currentFrame.getOffsetDelta(); - switch (currentFrame.getFrameType()) { + int offsetDelta = currentFrame.getOffsetDelta(prevFrame); + switch (currentFrame.getFrameType(prevFrame)) { case StackMapFrame.APPEND_FRAME : if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } - int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(); + int numberOfDifferentLocals = currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++] = (byte) (251 + numberOfDifferentLocals); this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++] = (byte) offsetDelta; @@ -4648,7 +4727,7 @@ if (localContentsOffset + 3 >= this.contents.length) { resizeContents(3); } - numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(); + numberOfDifferentLocals = -currentFrame.numberOfDifferentLocals(prevFrame); this.contents[localContentsOffset++] = (byte) (251 - numberOfDifferentLocals); this.contents[localContentsOffset++] = (byte) (offsetDelta >> 8); this.contents[localContentsOffset++] = (byte) offsetDelta; @@ -4860,7 +4939,6 @@ } } } - currentFrame = currentFrame.nextFrame; } this.contents[numberOfFramesOffset++] = (byte) (numberOfFrames >> 8);