Class BranchManager
java.lang.Object
de.inetsoftware.jwebassembly.module.BranchManager
This calculate the goto offsets from Java back to block operations
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static classDescribed a code branch/block node in a tree structure.private static classDescribed a break to a block that will be added later.private static classDescription of a parsed IF operation.private static classPositions inside a IF control structure.private static classDescription of single block/branch from the parsed Java byte code.private static classHelper structure for caculateSwitchprivate static classDescription of a parsed switch structure.private static classDescription of a parsed try-Catch structure. -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final ArrayList<BranchManager.ParsedBlock> private final ArrayList<BranchManager.BreakBlock> private TryCatchFinally[]private final List<WasmInstruction> private final LocaleVariableManagerprivate final HashMap<Integer, BranchManager.ParsedBlock> private final WasmOptionsprivate final BranchManager.BranchNode -
Constructor Summary
ConstructorsConstructorDescriptionBranchManager(WasmOptions options, List<WasmInstruction> instructions, LocaleVariableManager localVariables) Create a branch manager. -
Method Summary
Modifier and TypeMethodDescriptionprivate booleanaddBreakIfLoopContinue(BranchManager.BranchNode parent, BranchManager.ParsedBlock startBlock) Add a break to the node if the block jump to the continue position of an outer loop.(package private) voidaddGotoOperator(int startPosition, int offset, int nextPosition, int lineNumber) Add a new GOTO operator to handle from this manager.(package private) voidaddIfOperator(int startPosition, int offset, int lineNumber, WasmNumericInstruction instr) Add a new IF operator.private voidaddLoops(List<BranchManager.ParsedBlock> parsedOperations) In the compiled Java byte code there is no marker for the start of loop.(package private) voidaddReturnOperator(int startPosition, int nextPosition, int lineNumber) Add a new RETURN to help analyze structures.(package private) voidaddSwitchOperator(int startPosition, int offset, int lineNumber, int[] keys, int[] positions, int defaultPosition) Add a new switch block.private voidaddUnboxExnref(BranchManager.BranchNode catchNode, TryCatchFinally tryCatch) Add an unboxing of the WASm exnref on the stack(package private) voidCalculate all block operators from the parsed information.private voidcalculate(BranchManager.BranchNode parent, List<BranchManager.ParsedBlock> parsedOperations) Calculate the branch tree for the given branch and parsed sub operations.private voidcalculateBreak(BranchManager.BreakBlock breakBlock) Add the break to the block hierarchy.private intcalculateBreakDeep(BranchManager.BranchNode parent, int endPos) Calculate the deep of a break.private intcalculateContinueDeep(BranchManager.BranchNode parent, int startPos) Calculate the break deep for a continue in a do while(condition) loop.private voidcalculateGoto(BranchManager.BranchNode parent, BranchManager.ParsedBlock gotoBlock, List<BranchManager.ParsedBlock> parsedOperations) The not consumed GOTO operators of IF THEN ELSE must be break or continue in a loop.private voidcalculateIf(BranchManager.BranchNode parent, BranchManager.IfParsedBlock startBlock, List<BranchManager.ParsedBlock> parsedOperations) Calculate the ELSE and END position of an IF control structure.private voidcalculateLoop(BranchManager.BranchNode parent, BranchManager.ParsedBlock loopBlock, List<BranchManager.ParsedBlock> parsedOperations) Calculate the needed nodes for a loop.private voidcalculateSwitch(BranchManager.BranchNode parent, BranchManager.SwitchParsedBlock switchBlock, List<BranchManager.ParsedBlock> parsedOperations) Calculate the blocks of a switch.private voidcalculateTry(BranchManager.BranchNode parent, BranchManager.TryCatchParsedBlock tryBlock, List<BranchManager.ParsedBlock> parsedOperations) Calculate the needed nodes for try/catch Sample: The follow Java code:private voidcalculateTrySubOperations(BranchManager.BranchNode catchNode, BranchManager.BranchNode node, List<BranchManager.ParsedBlock> parsedOperations) Calculate branch operations inside the CATCH/FINALLY blocks.private voidconvertToLoop(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.private intfindIdxOfCodePos(int codePosition) Find the index of the instruction with the given code position.(package private) AnyTypegetCatchType(int codePosition) Get the catch type if there are a start of a catch block on the code position.private AnyTypegetCatchType(TryCatchFinally tryCatch) (package private) voidhandle(CodeInputStream byteCode) Check on every instruction position if there any branch is endingprivate voidinsertConstBeforePosition(int constant, int pos, int lineNumber) Insert a constant i32 operation before the given code positionprivate static voidnormalizeEmptyThenBlocks(List<BranchManager.ParsedBlock> parsedOperations) Normalize all empty THEN blocks like:private voidpatchBrDeep(BranchManager.BranchNode newNode) Patch the existing BR instructions after a new BLOCK node was injected in the hierarchy.private voidpatchBrDeepInTree(BranchManager.BranchNode newNode, int deep) Patch the existing BR instructions in the tree after a new BLOCK node was injected in the hierarchy.(package private) voidRemove all branch information for reusing the manager.private BranchManager.IfPositionssearchElsePosition(BranchManager.IfParsedBlock startBlock, List<BranchManager.ParsedBlock> parsedOperations) Search the start positions of the THEN and ELSE branch from an IF control structure.
-
Field Details
-
allParsedOperations
-
root
-
loops
-
options
-
instructions
-
localVariables
-
exceptionTable
-
breakOperations
-
-
Constructor Details
-
BranchManager
public BranchManager(WasmOptions options, List<WasmInstruction> instructions, LocaleVariableManager localVariables) Create a branch manager.- Parameters:
options- compiler option/propertiesinstructions- the target for instructionslocalVariables- the local variables
-
-
Method Details
-
reset
-
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 positionoffset- the relative jump positionnextPosition- the position of the next instructionlineNumber- 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 positionnextPosition- the position of the next instructionlineNumber- the current line number
-
addIfOperator
Add a new IF operator.- Parameters:
startPosition- the byte position of the start positionoffset- the relative jump positionlineNumber- the current line numberinstr- 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 positionoffset- the relative jump positionlineNumber- the current line numberkeys- the values of the cases or null if a tableswitchpositions- the code positionsdefaultPosition- the code position of the default block
-
calculate
void calculate()Calculate all block operators from the parsed information. -
addLoops
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 blockconditionStart- the code position where condition code startconditionEnd- the end position
-
normalizeEmptyThenBlocks
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 breakstartBlock- 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 branchstartBlock- the start block of the if control structureparsedOperations- 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 structureparsedOperations- 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 valuepos- the code positionlineNumber- 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
Calculate the break deep for a continue in a do while(condition) loop.- Parameters:
parent- current branchstartPos- the start position of the loop- Returns:
- the deep count
-
calculateBreakDeep
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 returnand for lookupswitchblock 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 branchswitchBlock- the start block of the if control structureparsedOperations- the not consumed operations in the parent branch
-
patchBrDeep
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
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 nodedeep- 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 branchgotoBlock- the GOTO operationparsedOperations- 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 branchloopBlock- the virtual LOOP operationparsedOperations- 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 } code3Should 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 branchtryBlock- the virtual TRY operationparsedOperations- 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 nodenode- the most inner nodeparsedOperations- the not consumed operations in the parent branch
-
addUnboxExnref
Add an unboxing of the WASm exnref on the stack- Parameters:
catchNode- the catch nodetryCatch- the catch or finally block
-
getCatchType
-
getCatchType
-
calculateBreak
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
Check on every instruction position if there any branch is ending- Parameters:
byteCode- the byte code stream
-