Class BodyCodegen.ExceptionManager
- java.lang.Object
-
- org.mozilla.javascript.optimizer.BodyCodegen.ExceptionManager
-
- Enclosing class:
- BodyCodegen
private class BodyCodegen.ExceptionManager extends java.lang.Object
Manages placement of exception handlers for non-generator functions.For generator functions, there are mechanisms put into place to emulate jsr by using a goto with a return label. That is one mechanism for implementing finally blocks. The other, which is implemented by Sun, involves duplicating the finally block where jsr instructions would normally be. However, inlining finally blocks causes problems with translating exception handlers. Instead of having one big bytecode range for each exception, we now have to skip over the inlined finally blocks. This class is meant to help implement this.
Every time a try block is encountered during translation, exception information should be pushed into the manager, which is treated as a stack. The addHandler() and setHandlers() methods may be used to register exceptionHandlers for the try block; removeHandler() is used to reverse the operation. At the end of the try/catch/finally, the exception state for it should be popped.
The important function here is markInlineFinally. This finds which finally block on the exception state stack is being inlined and skips the proper exception handlers until the finally block is generated.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description private class
BodyCodegen.ExceptionManager.ExceptionInfo
-
Field Summary
Fields Modifier and Type Field Description private java.util.LinkedList<BodyCodegen.ExceptionManager.ExceptionInfo>
exceptionInfo
-
Constructor Summary
Constructors Constructor Description ExceptionManager()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description (package private) void
addHandler(int exceptionType, int handlerLabel, int startLabel)
Register an exception handler for the try block at the top of the exception information stack.private void
endCatch(BodyCodegen.ExceptionManager.ExceptionInfo ei, int exceptionType, int catchEnd)
Mark off the end of a bytecode chunk that should be handled by an exceptionHandler.private BodyCodegen.ExceptionManager.ExceptionInfo
getTop()
(package private) void
markInlineFinallyEnd(Node finallyBlock, int finallyEnd)
Mark the end of an inlined finally block.(package private) void
markInlineFinallyStart(Node finallyBlock, int finallyStart)
Mark the start of an inlined finally block.(package private) void
popExceptionInfo()
Remove the top try block from the exception information stack.(package private) void
pushExceptionInfo(Jump node)
Push a new try block onto the exception information stack.(package private) int
removeHandler(int exceptionType, int endLabel)
Remove an exception handler for the top try block.(package private) void
setHandlers(int[] handlerLabels, int startLabel)
Register multiple exception handlers for the top try block.
-
-
-
Field Detail
-
exceptionInfo
private java.util.LinkedList<BodyCodegen.ExceptionManager.ExceptionInfo> exceptionInfo
-
-
Method Detail
-
pushExceptionInfo
void pushExceptionInfo(Jump node)
Push a new try block onto the exception information stack.- Parameters:
node
- an exception handling node (node.getType() == Token.TRY)
-
addHandler
void addHandler(int exceptionType, int handlerLabel, int startLabel)
Register an exception handler for the try block at the top of the exception information stack.- Parameters:
exceptionType
- one of the integer constants representing an exception typehandlerLabel
- the label of the exception handlerstartLabel
- the label where the exception handling begins
-
setHandlers
void setHandlers(int[] handlerLabels, int startLabel)
Register multiple exception handlers for the top try block. If the exception type maps to a zero label, then it is ignored.- Parameters:
handlerLabels
- a map from integer constants representing an exception type to the label of the exception handlerstartLabel
- the label where all of the exception handling begins
-
removeHandler
int removeHandler(int exceptionType, int endLabel)
Remove an exception handler for the top try block.- Parameters:
exceptionType
- one of the integer constants representing an exception typeendLabel
- a label representing the end of the last bytecode that should be handled by the exception
-
popExceptionInfo
void popExceptionInfo()
Remove the top try block from the exception information stack.
-
markInlineFinallyStart
void markInlineFinallyStart(Node finallyBlock, int finallyStart)
Mark the start of an inlined finally block.When a finally block is inlined, any exception handlers that are lexically inside of its try block should not cover the range of the exception block. We scan from the innermost try block outward until we find the try block that matches the finally block. For any block whose exception handlers that aren't currently stopped by a finally block, we stop the handlers at the beginning of the finally block and set it as the finally block that has stopped the handlers. This prevents other inlined finally blocks from prematurely ending skip ranges and creating bad exception handler ranges.
- Parameters:
finallyBlock
- the finally block that is being inlinedfinallyStart
- the label of the beginning of the inlined code
-
markInlineFinallyEnd
void markInlineFinallyEnd(Node finallyBlock, int finallyEnd)
Mark the end of an inlined finally block.For any set of exception handlers that have been stopped by the inlined block, resume exception handling at the end of the finally block.
- Parameters:
finallyBlock
- the finally block that is being inlinedfinallyEnd
- the label of the end of the inlined code
-
endCatch
private void endCatch(BodyCodegen.ExceptionManager.ExceptionInfo ei, int exceptionType, int catchEnd)
Mark off the end of a bytecode chunk that should be handled by an exceptionHandler.The caller of this method must appropriately mark the start of the next bytecode chunk or remove the handler.
-
getTop
private BodyCodegen.ExceptionManager.ExceptionInfo getTop()
-
-