Class BodyCodegen.ExceptionManager

java.lang.Object
org.htmlunit.corejs.javascript.optimizer.BodyCodegen.ExceptionManager
Enclosing class:
BodyCodegen

private class BodyCodegen.ExceptionManager extends 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.

  • Field Details

  • Constructor Details

    • ExceptionManager

      ExceptionManager()
  • Method Details

    • 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 type
      handlerLabel - the label of the exception handler
      startLabel - 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 handler
      startLabel - 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 type
      endLabel - 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 inlined
      finallyStart - 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 inlined
      finallyEnd - 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