diff --git a/src/de/inetsoftware/jwebassembly/module/BranchManger.java b/src/de/inetsoftware/jwebassembly/module/BranchManger.java index 725dc4a..9fe5580 100644 --- a/src/de/inetsoftware/jwebassembly/module/BranchManger.java +++ b/src/de/inetsoftware/jwebassembly/module/BranchManger.java @@ -328,9 +328,18 @@ class BranchManger { int startPos = startBlock.nextPosition; if( startPos > endPos ) { // the condition in a do while(condition) loop - parent.add( new BranchNode( startPos, startPos, WasmBlockOperator.BR_IF, null, 0 ) ); + int breakDeep = calculateContinueDeep( parent, endPos ); + for( int idx = 0; idx < instructions.size(); idx++ ) { + WasmInstruction instr = instructions.get( idx ); + int codePos = instr.getCodePosition(); + if( codePos >= startPos ) { + instructions.add( idx, new WasmBlockInstruction( WasmBlockOperator.BR_IF, breakDeep, startPos - 1, startBlock.lineNumber ) ); + break; + } + } return; } + BranchNode branch = null; for( ; i < parsedOperations.size(); i++ ) { ParsedBlock parsedBlock = parsedOperations.get( i ); @@ -462,6 +471,24 @@ class BranchManger { } } + /** + * Calculate the break deep for a continue in a do while(condition) loop. + * + * @param parent + * current branch + * @param startPos + * the start position of the loop + * @return the deep count + */ + private int calculateContinueDeep( BranchNode parent, int startPos ) { + int deep = 0; + while( parent != null && parent.startPos > startPos ) { + deep++; + parent = parent.parent; + } + return deep; + } + /** * 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. * diff --git a/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java b/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java index b2389d4..aa96dd1 100644 --- a/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java +++ b/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java @@ -50,6 +50,7 @@ public class ControlFlowOperators extends AbstractBaseTest { addParam( list, script, "switchDirect" ); addParam( list, script, "endlessLoop" ); addParam( list, script, "doWhileLoop" ); + addParam( list, script, "doWhileLoopTwoConditions" ); addParam( list, script, "doWhileLoopWithBreak" ); addParam( list, script, "whileLoop" ); addParam( list, script, "forLoop" ); @@ -292,6 +293,17 @@ public class ControlFlowOperators extends AbstractBaseTest { return d; } + @Export + static int doWhileLoopTwoConditions() { + int val = 42; + int shift = 1; + do { + val >>>= shift; + } while (val > 7 && shift > 0); + + return val; + } + @Export static double doWhileLoopWithBreak() { int a = 0;