Class BranchManager


  • class BranchManager
    extends java.lang.Object
    This calculate the goto offsets from Java back to block operations
    • Constructor Detail

      • BranchManager

        public BranchManager​(WasmOptions options,
                             java.util.List<WasmInstruction> instructions,
                             LocaleVariableManager localVariables)
        Create a branch manager.
        Parameters:
        options - compiler option/properties
        instructions - the target for instructions
        localVariables - the local variables
    • Method Detail

      • reset

        void reset​(@Nonnull
                   Code code)
        Remove all branch information for reusing the manager.
        Parameters:
        code - the Java method code
      • addGotoOperator

        void addGotoOperator​(int startPosition,
                             int offset,
                             int nextPosition,
                             int lineNumber)
        Add a new GOTO operator to handle from this manager.
        Parameters:
        startPosition - the byte position of the start position
        offset - the relative jump position
        nextPosition - the position of the next instruction
        lineNumber - the current line number
      • addReturnOperator

        void addReturnOperator​(int startPosition,
                               int nextPosition,
                               int lineNumber)
        Add a new RETURN to help analyze structures.
        Parameters:
        startPosition - the byte position of the start position
        nextPosition - the position of the next instruction
        lineNumber - the current line number
      • addIfOperator

        void addIfOperator​(int startPosition,
                           int offset,
                           int lineNumber,
                           WasmNumericInstruction instr)
        Add a new IF operator.
        Parameters:
        startPosition - the byte position of the start position
        offset - the relative jump position
        lineNumber - the current line number
        instr - the compare instruction
      • addSwitchOperator

        void addSwitchOperator​(int startPosition,
                               int offset,
                               int lineNumber,
                               int[] keys,
                               int[] positions,
                               int defaultPosition)
        Add a new switch block.
        Parameters:
        startPosition - the byte position of the start position
        offset - the relative jump position
        lineNumber - the current line number
        keys - the values of the cases or null if a tableswitch
        positions - the code positions
        defaultPosition - the code position of the default block
      • calculate

        void calculate()
        Calculate all block operators from the parsed information.
      • addLoops

        private void addLoops​(java.util.List<BranchManager.ParsedBlock> parsedOperations)
        In the compiled Java byte code there is no marker for the start of loop. But we need this marker. That we add a virtual loop operator on the target position of GOTO operators with a negative offset.
        Parameters:
        parsedOperations - the parsed operations
      • convertToLoop

        private void convertToLoop​(BranchManager.ParsedBlock gotoBlock,
                                   int conditionStart,
                                   int conditionEnd)
        Convert the GOTO block with condition at the end into a loop block and move the condition from the end to the start like wasm it required.
        Parameters:
        gotoBlock - the goto block
        conditionStart - the code position where condition code start
        conditionEnd - the end position
      • normalizeEmptyThenBlocks

        private static void normalizeEmptyThenBlocks​(java.util.List<BranchManager.ParsedBlock> parsedOperations)
        Normalize all empty THEN blocks like:
         if (condition) {
         } else {
              ....
         }
         
        are changed to: if (!condition) { .... } The THEN block contains only a single GOTO operation. This operation is removed and the IF condition is negate. The removing of the GOTO operation make it easer to convert it to a valid WebAssembly structure without GOTO.
        Parameters:
        parsedOperations - the parsed operations
      • calculate

        private void calculate​(BranchManager.BranchNode parent,
                               java.util.List<BranchManager.ParsedBlock> parsedOperations)
        Calculate the branch tree for the given branch and parsed sub operations.
        Parameters:
        parent - the parent branch/block in the hierarchy.
        parsedOperations - the not consumed parsed operations of the parent block.
      • addBreakIfLoopContinue

        private boolean addBreakIfLoopContinue​(BranchManager.BranchNode parent,
                                               BranchManager.ParsedBlock startBlock)
        Add a break to the node if the block jump to the continue position of an outer loop.
        Parameters:
        parent - the container for adding the break
        startBlock - an IF or GOTO block.
        Returns:
        true, if the break was added
      • calculateIf

        private void calculateIf​(BranchManager.BranchNode parent,
                                 BranchManager.IfParsedBlock startBlock,
                                 java.util.List<BranchManager.ParsedBlock> parsedOperations)
        Calculate the ELSE and END position of an IF control structure.
        Parameters:
        parent - the parent branch
        startBlock - the start block of the if control structure
        parsedOperations - the not consumed operations in the parent branch
      • searchElsePosition

        private BranchManager.IfPositions searchElsePosition​(BranchManager.IfParsedBlock startBlock,
                                                             java.util.List<BranchManager.ParsedBlock> parsedOperations)
        Search the start positions of the THEN and ELSE branch from an IF control structure.
        Parameters:
        startBlock - the start block of the IF control structure
        parsedOperations - the not consumed operations in the parent branch
        Returns:
        the calculated positions
      • insertConstBeforePosition

        private void insertConstBeforePosition​(int constant,
                                               int pos,
                                               int lineNumber)
        Insert a constant i32 operation before the given code position
        Parameters:
        constant - the i32 value
        pos - the code position
        lineNumber - the line number for possible error messages
      • findIdxOfCodePos

        private int findIdxOfCodePos​(int codePosition)
        Find the index of the instruction with the given code position.
        Parameters:
        codePosition - the java position
        Returns:
        the index
      • calculateContinueDeep

        private int calculateContinueDeep​(BranchManager.BranchNode parent,
                                          int startPos)
        Calculate the break deep for a continue in a do while(condition) loop.
        Parameters:
        parent - current branch
        startPos - the start position of the loop
        Returns:
        the deep count
      • calculateBreakDeep

        private int calculateBreakDeep​(BranchManager.BranchNode parent,
                                       int endPos)
        Calculate the deep of a break. A GOTO or IF in Java can jump out multiple loops. We need to calculate how many levels we need to jump.
        Parameters:
        parent - the current parent node.
        endPos - the end position of the jump
        Returns:
        the deep level for "br" or -1 if there is no parent node with this end position
      • calculateSwitch

        private void calculateSwitch​(BranchManager.BranchNode parent,
                                     BranchManager.SwitchParsedBlock switchBlock,
                                     java.util.List<BranchManager.ParsedBlock> parsedOperations)
        Calculate the blocks of a switch. Sample: The follow Java code:
         int b;
         switch( a ) {
             case 8:
                 b = 1;
                 break;
             default:
                 b = 9;
         }
         return b;
         
        Should be converted to the follow Wasm code for tableswitch:
          block
            block
              block
                get_local 0
                i32.const 8
                i32.sub
                br_table 0 1 
              end
              i32.const 1
              set_local 1
              br 1
            end
            i32.const 9
            set_local 1
          end
          get_local 1
          return
         
        and for lookupswitch
          block
            block
              block
                get_local 0
                tee_local $switch
                i32.const 8
                i32.eq
                br_if 0
                br 1 
              end
              i32.const 1
              set_local 1
              br 1
            end
            i32.const 9
            set_local 1
          end
          get_local 1
          return
         
        Parameters:
        parent - the parent branch
        switchBlock - the start block of the if control structure
        parsedOperations - the not consumed operations in the parent branch
      • patchBrDeep

        private void patchBrDeep​(BranchManager.BranchNode newNode)
        Patch the existing BR instructions after a new BLOCK node was injected in the hierarchy. The break position must only increment if the old break position is outside of the new BLOCK.
        Parameters:
        newNode - the new node
      • patchBrDeepInTree

        private void patchBrDeepInTree​(BranchManager.BranchNode newNode,
                                       int deep)
        Patch the existing BR instructions in the tree after a new BLOCK node was injected in the hierarchy. The break position must only increment if the old break position is outside of the new BLOCK.
        Parameters:
        newNode - the new node
        deep - the deep of recursion
      • calculateGoto

        private void calculateGoto​(@Nonnull
                                   BranchManager.BranchNode parent,
                                   @Nonnull
                                   BranchManager.ParsedBlock gotoBlock,
                                   java.util.List<BranchManager.ParsedBlock> parsedOperations)
        The not consumed GOTO operators of IF THEN ELSE must be break or continue in a loop.
        Parameters:
        parent - the parent branch
        gotoBlock - the GOTO operation
        parsedOperations - the not consumed operations in the parent branch
      • calculateTry

        private void calculateTry​(BranchManager.BranchNode parent,
                                  BranchManager.TryCatchParsedBlock tryBlock,
                                  java.util.List<BranchManager.ParsedBlock> parsedOperations)
        Calculate the needed nodes for try/catch Sample: The follow Java code:
         try {
           code1
         catch(Exception ex)
           code2
         }
         code3
         
        Should be converted to the follow Wasm code for try/catch:
         try
           code1
         catch
           block (param exnref)(result anyref)
             br_on_exn 0 0
             rethrow
           end
           local.tee $ex
           i32.const classIndex(Exception)
           call $.instanceof
           i32.eqz
           if
             local.get $ex
             throw 0
           end
           code2
         end
         code3
         
        Parameters:
        parent - the parent branch
        tryBlock - the virtual TRY operation
        parsedOperations - the not consumed operations in the parent branch
      • calculateTrySubOperations

        private void calculateTrySubOperations​(BranchManager.BranchNode catchNode,
                                               BranchManager.BranchNode node,
                                               java.util.List<BranchManager.ParsedBlock> parsedOperations)
        Calculate branch operations inside the CATCH/FINALLY blocks.
        Parameters:
        catchNode - the parent node
        node - the most inner node
        parsedOperations - the not consumed operations in the parent branch
      • addUnboxExnref

        private void addUnboxExnref​(BranchManager.BranchNode catchNode,
                                    TryCatchFinally tryCatch)
        Add an unboxing of the WASm exnref on the stack
        Parameters:
        catchNode - the catch node
        tryCatch - the catch or finally block
      • getCatchType

        @Nullable
        AnyType getCatchType​(int codePosition)
        Get the catch type if there are a start of a catch block on the code position.
        Parameters:
        codePosition - the code position
        Returns:
        the type or null
      • calculateBreak

        private void calculateBreak​(BranchManager.BreakBlock breakBlock)
        Add the break to the block hierarchy. Add an extra block if needed and correct the break deep of other instructions.
        Parameters:
        breakBlock - the description of the break.
      • handle

        void handle​(CodeInputStream byteCode)
        Check on every instruction position if there any branch is ending
        Parameters:
        byteCode - the byte code stream