fix do while with multiple conditions

This commit is contained in:
Volker Berlin 2020-03-21 21:16:10 +01:00
parent ab95396471
commit 63384e359a
2 changed files with 40 additions and 1 deletions

View File

@ -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.
*

View File

@ -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;