/******************************************************************************* | |
* Copyright (c) 2000, 2004 IBM Corporation and others. | |
* All rights reserved. This program and the accompanying materials | |
* are made available under the terms of the Common Public License v1.0 | |
* which accompanies this distribution, and is available at | |
* http://www.eclipse.org/legal/cpl-v10.html | |
* | |
* Contributors: | |
* IBM Corporation - initial API and implementation | |
*******************************************************************************/ | |
package org.eclipse.wst.jsdt.internal.compiler.ast; | |
import org.eclipse.wst.jsdt.internal.compiler.codegen.CodeStream; | |
import org.eclipse.wst.jsdt.internal.compiler.codegen.ExceptionLabel; | |
import org.eclipse.wst.jsdt.internal.compiler.lookup.BlockScope; | |
/** | |
* Extra behavior for statements which are generating subroutines | |
*/ | |
public abstract class SubRoutineStatement extends Statement { | |
public static final ExceptionLabel[] NO_EXCEPTION_HANDLER = new ExceptionLabel[0]; | |
ExceptionLabel[] anyExceptionLabels = NO_EXCEPTION_HANDLER; | |
int anyExceptionLabelsCount = 0; | |
public abstract boolean isSubRoutineEscaping(); | |
public abstract void generateSubRoutineInvocation(BlockScope currentScope, CodeStream codeStream); | |
public ExceptionLabel enterAnyExceptionHandler(CodeStream codeStream) { | |
int length; | |
if ((length = this.anyExceptionLabelsCount) == this.anyExceptionLabels.length) { | |
System.arraycopy(this.anyExceptionLabels, 0 , this.anyExceptionLabels=new ExceptionLabel[length*2 + 1], 0, length); | |
} | |
ExceptionLabel exceptionLabel = new ExceptionLabel(codeStream, null); | |
this.anyExceptionLabels[this.anyExceptionLabelsCount++] = exceptionLabel; | |
return exceptionLabel; | |
} | |
public void exitAnyExceptionHandler() { | |
if (this.anyExceptionLabelsCount == 0) return; | |
ExceptionLabel currentLabel = this.anyExceptionLabels[this.anyExceptionLabelsCount-1]; | |
if (currentLabel.start == currentLabel.codeStream.position) { | |
// discard empty exception handler | |
this.anyExceptionLabels[--this.anyExceptionLabelsCount] = null; | |
currentLabel.codeStream.removeExceptionHandler(currentLabel); | |
} else { | |
currentLabel.placeEnd(); | |
} | |
} | |
public void placeAllAnyExceptionHandlers() { | |
for (int i = 0; i < this.anyExceptionLabelsCount; i++) { | |
this.anyExceptionLabels[i].place(); | |
} | |
} | |
public static void reenterExceptionHandlers(SubRoutineStatement[] subroutines, int max, CodeStream codeStream) { | |
if (subroutines == null) return; | |
if (max < 0) max = subroutines.length; | |
for (int i = 0; i < max; i++) { | |
subroutines[i].enterAnyExceptionHandler(codeStream); | |
} | |
} | |
} |