Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipe Mulet2001-10-13 17:15:58 +0000
committerPhilipe Mulet2001-10-13 17:15:58 +0000
commit837e74414fb9b240932cd6afae3110277fb777db (patch)
treec3bc7b3c17e4769c4a4c2f1917056c104106cfce
parent7750e1b5a6b245445fbc69259bf6412de07423cc (diff)
downloadeclipse.jdt.core-837e74414fb9b240932cd6afae3110277fb777db.tar.gz
eclipse.jdt.core-837e74414fb9b240932cd6afae3110277fb777db.tar.xz
eclipse.jdt.core-837e74414fb9b240932cd6afae3110277fb777db.zip
*** empty log message ***v_204_01
-rw-r--r--org.eclipse.jdt.core/changes.txt2
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java15
-rw-r--r--org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java80
3 files changed, 72 insertions, 25 deletions
diff --git a/org.eclipse.jdt.core/changes.txt b/org.eclipse.jdt.core/changes.txt
index 2e2816662d..46a4866edb 100644
--- a/org.eclipse.jdt.core/changes.txt
+++ b/org.eclipse.jdt.core/changes.txt
@@ -113,6 +113,8 @@ STREAM: 2.0
PRs Fixed in this Release
================================================================================
+ 4919 Cannot duplicate local variable in finally block
+ 4943 Verification error
4385 QualifiedAllocationExpression.sourceEnd incorrect if type is an AnonymousLocalTypeDeclaration
3230 Search - Too many type references for query ending with * (1GAZVGI)
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
index be02c40b31..394fe52b12 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TryStatement.java
@@ -29,8 +29,8 @@ public class TryStatement extends Statement {
Label subRoutineStartLabel;
LocalVariableBinding anyExceptionVariable, returnAddressVariable;
- final static char[] SecretReturnName = " returnAddress".toCharArray() ; //$NON-NLS-1$
- final static char[] SecretAnyHandlerName = " anyExceptionHandler".toCharArray(); //$NON-NLS-1$
+ public final static char[] SecretReturnName = " returnAddress".toCharArray() ; //$NON-NLS-1$
+ public final static char[] SecretAnyHandlerName = " anyExceptionHandler".toCharArray(); //$NON-NLS-1$
// for local variables table attributes
int preTryInitStateIndex = -1;
@@ -340,19 +340,24 @@ public void resolve(BlockScope upperScope) {
// special scope for secret locals optimization.
scope = new BlockScope(upperScope);
+
+ BlockScope tryScope = new BlockScope(scope);
+ BlockScope finallyScope = null;
if (finallyBlock != null && finallyBlock.statements != null) { // provision for returning and forcing the finally block to run
returnAddressVariable = new LocalVariableBinding(SecretReturnName, upperScope.getJavaLangObject(), 0); // the type does not matter as long as its not a normal base type
- scope.addLocalVariable(returnAddressVariable);
+ scope.methodScope().addLocalVariable(returnAddressVariable);
returnAddressVariable.constant = NotAConstant; // not inlinable
subRoutineStartLabel = new Label();
- BlockScope finallyScope = new BlockScope(scope);
+ finallyScope = new BlockScope(scope);
anyExceptionVariable = new LocalVariableBinding(SecretAnyHandlerName, scope.getJavaLangThrowable(), 0);
finallyScope.addLocalVariable(anyExceptionVariable);
anyExceptionVariable.constant = NotAConstant; // not inlinable
finallyBlock.resolveUsing(finallyScope);
+ // force the finally scope to have variable positions shifted after its try scope.
+ finallyScope.shiftScope = tryScope;
}
- tryBlock.resolve(scope);
+ tryBlock.resolveUsing(tryScope);
// arguments type are checked against JavaLangThrowable in resolveForCatch(..)
if (catchBlocks != null) {
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
index e5592d3caf..702a172166 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BlockScope.java
@@ -14,13 +14,16 @@ public class BlockScope extends Scope {
// Local variable management
public LocalVariableBinding[] locals;
public int localIndex; // position for next variable
- public int analysisIndex; // for setting flow-analysis id
+ public int analysisIndex; // for setting flow-analysis id
public int startIndex; // start position in this scope - for ordering scopes vs. variables
-
+ public int offset, maxOffset; // for variable allocation throughout scopes
+ public BlockScope shiftScope; // finally scopes must be shifted behind respective try scope
+
public final static VariableBinding[] EmulationPathToImplicitThis = {};
public Scope[] subscopes = new Scope[1]; // need access from code assist
public int scopeIndex = 0; // need access from code assist
+
protected BlockScope(int kind, Scope parent) {
super(kind, parent);
}
@@ -142,15 +145,32 @@ private void checkAndSetModifiersForVariable(LocalVariableBinding varBinding) {
}
/* Compute variable positions in scopes given an initial position offset
* ignoring unused local variables.
+*
+* Special treatment to have Try secret return address variables located at non
+* colliding positions. Return addresses are not allocated initially, but gathered
+* and allocated behind all other variables.
*/
-public final void computeLocalVariablePositions(int offset, CodeStream codeStream) {
+public final void computeLocalVariablePositions(int initOffset, CodeStream codeStream) {
+ ObjectVector returnAddresses = new ObjectVector();
+ computeLocalVariablePositions(initOffset, codeStream, returnAddresses);
+ for (int i = 0, length = returnAddresses.size(); i < length; i++){
+ LocalVariableBinding returnAddress = (LocalVariableBinding)returnAddresses.elementAt(i);
+ returnAddress.resolvedPosition = this.maxOffset ++;
+ }
+}
+
+public final void computeLocalVariablePositions(int initOffset, CodeStream codeStream, ObjectVector returnAddresses) {
+
+ this.offset = initOffset;
+ this.maxOffset = initOffset;
+
// local variable init
int ilocal = 0, maxLocals = 0, localsLength = locals.length;
while ((maxLocals < localsLength) && (locals[maxLocals] != null))
maxLocals++;
boolean hasMoreVariables = maxLocals > 0;
-
+
// scope init
int iscope = 0, maxScopes = 0, subscopesLength = subscopes.length;
while ((maxScopes < subscopesLength) && (subscopes[maxScopes] != null))
@@ -161,8 +181,12 @@ public final void computeLocalVariablePositions(int offset, CodeStream codeStrea
while (hasMoreVariables || hasMoreScopes) {
if (hasMoreScopes && (!hasMoreVariables || (subscopes[iscope].startIndex() <= ilocal))) {
// consider subscope first
- if (subscopes[iscope] instanceof BlockScope)
- ((BlockScope) subscopes[iscope]).computeLocalVariablePositions(offset, codeStream);
+ if (subscopes[iscope] instanceof BlockScope) {
+ BlockScope subscope = (BlockScope) subscopes[iscope];
+ int subOffset = subscope.shiftScope == null ? this.offset : subscope.shiftScope.offset;
+ subscope.computeLocalVariablePositions(subOffset, codeStream, returnAddresses);
+ if (subscope.maxOffset > this.maxOffset) this.maxOffset = subscope.maxOffset;
+ }
hasMoreScopes = ++iscope < maxScopes;
} else {
// consider variable first
@@ -183,30 +207,46 @@ public final void computeLocalVariablePositions(int offset, CodeStream codeStrea
}
}
if (generatesLocal) {
- if (local.declaration != null)
- codeStream.record(local); // record user local variables for attribute generation
- local.resolvedPosition = offset;
- // check for too many arguments/local variables
- if(local.isArgument){
- if (offset > 0xFF){ // no more than 255 words of arguments
- this.problemReporter().noMoreAvailableSpaceForArgument(local.declaration);
- }
+
+ // Return addresses are managed separately afterwards.
+ if (local.name == TryStatement.SecretReturnName){
+ returnAddresses.add(local);
} else {
- if(offset > 0xFFFF){ // no more than 65535 words of locals
- this.problemReporter().noMoreAvailableSpaceForLocal(local.declaration);
+
+ if (local.declaration != null){
+ codeStream.record(local); // record user local variables for attribute generation
+ }
+
+ // allocate variable position
+ local.resolvedPosition = this.offset;
+
+ // check for too many arguments/local variables
+ if(local.isArgument){
+ if (offset > 0xFF){ // no more than 255 words of arguments
+ this.problemReporter().noMoreAvailableSpaceForArgument(local.declaration);
+ }
+ } else {
+ if(offset > 0xFFFF){ // no more than 65535 words of locals
+ this.problemReporter().noMoreAvailableSpaceForLocal(local.declaration);
+ }
+ }
+
+ // increment offset
+ if ((local.type == LongBinding) || (local.type == DoubleBinding)){
+ this.offset += 2;
+ } else {
+ this.offset++;
}
}
- if ((local.type == LongBinding) || (local.type == DoubleBinding))
- offset += 2;
- else
- offset++;
} else {
local.resolvedPosition = -1; // not generated
}
hasMoreVariables = ++ilocal < maxLocals;
}
}
+ if (this.offset > this.maxOffset) this.maxOffset = this.offset;
}
+
/* Answer true if the variable name already exists within the receiver's scope.
*/

Back to the top