Class BranchManager

java.lang.Object
de.inetsoftware.jwebassembly.module.BranchManager

class BranchManager extends Object
This calculate the goto offsets from Java back to block operations
  • Field Details

  • Constructor Details

    • BranchManager

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

    • 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(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(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, 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, 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, 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, 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, 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
    • calculateLoop

      private void calculateLoop(BranchManager.BranchNode parent, BranchManager.ParsedBlock loopBlock, List<BranchManager.ParsedBlock> parsedOperations)
      Calculate the needed nodes for a loop.
      Parameters:
      parent - the parent branch
      loopBlock - the virtual LOOP operation
      parsedOperations - the not consumed operations in the parent branch
    • calculateTry

      private void calculateTry(BranchManager.BranchNode parent, BranchManager.TryCatchParsedBlock tryBlock, 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, 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

      private AnyType getCatchType(TryCatchFinally tryCatch)
    • 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