### 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);