expand a loop if there is a SWICH structure that point outside the loop. #43

This commit is contained in:
Volker Berlin 2022-06-19 16:20:17 +02:00
parent 47c28f7d46
commit 9d1c9ee93b
No known key found for this signature in database
GPG Key ID: 988423EF815BE4CB
3 changed files with 48 additions and 7 deletions

View File

@ -154,8 +154,6 @@ class BranchManager {
*
* @param startPosition
* the byte position of the start position
* @param offset
* the relative jump position
* @param lineNumber
* the current line number
* @param keys
@ -165,8 +163,8 @@ class BranchManager {
* @param defaultPosition
* the code position of the default block
*/
void addSwitchOperator( int startPosition, int offset, int lineNumber, int[] keys, int[] positions, int defaultPosition ) {
allParsedOperations.add( new SwitchParsedBlock( startPosition, offset, lineNumber, keys, positions, defaultPosition ) );
void addSwitchOperator( int startPosition, int lineNumber, @Nullable int[] keys, @Nonnull int[] positions, int defaultPosition ) {
allParsedOperations.add( new SwitchParsedBlock( startPosition, lineNumber, keys, positions, defaultPosition ) );
}
/**
@ -224,6 +222,7 @@ class BranchManager {
if( loop.endPosition < parsedBlock.nextPosition ) {
int nextPosition = parsedBlock.startPosition; // Jump position for Continue
int endPosition = parsedBlock.nextPosition;
// if a condition behind the loop points to a position inside the loop, the loop must be extended to avoid overlapping blocks.
for( int n = b + 1; n < parsedOperations.size(); n++ ) {
ParsedBlock block = parsedOperations.get( n );
@ -232,6 +231,21 @@ class BranchManager {
endPosition = block.nextPosition;
}
}
// if there is a structure like a SWITCH that overlap the loop then we must be extended the loop to avoid this.
for( int n = b - 1; n >= 0; n-- ) {
ParsedBlock prevBlock = parsedOperations.get( n );
switch( prevBlock.op ) {
case SWITCH:
if( start < prevBlock.startPosition && prevBlock.endPosition > endPosition ) {
nextPosition = prevBlock.endPosition;
endPosition = nextPosition;
}
break;
default:
}
}
loop.nextPosition = nextPosition; // Jump position for Continue
loop.endPosition = endPosition;
}
@ -1600,11 +1614,18 @@ class BranchManager {
private int defaultPosition;
public SwitchParsedBlock( int startPosition, int offset, int lineNumber, int[] keys, int[] positions, int defaultPosition ) {
super( JavaBlockOperator.SWITCH, startPosition, offset, startPosition, lineNumber );
public SwitchParsedBlock( int startPosition, int lineNumber, @Nullable int[] keys, @Nonnull int[] positions, int defaultPosition ) {
super( JavaBlockOperator.SWITCH, startPosition, 0, startPosition, lineNumber );
this.keys = keys;
this.positions = positions;
this.defaultPosition = defaultPosition;
// calculate the end position of the switch
int end = defaultPosition;
for( int i = positions.length - 1; i >= 0; i-- ) {
end = Math.max( defaultPosition, positions[i] );
}
this.endPosition = end;
}
}

View File

@ -845,7 +845,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder {
addNumericInstruction( NumericOperator.sub, ValueType.i32, codePos, lineNumber );
}
}
branchManager.addSwitchOperator( startPosition, 0, lineNumber, keys, positions, defaultPosition );
branchManager.addSwitchOperator( startPosition, lineNumber, keys, positions, defaultPosition );
}
/**

View File

@ -60,6 +60,7 @@ public class ControlFlowOperators extends AbstractBaseTest {
addParam( list, script, "whileLoopAfterIfWithReturn" );
addParam( list, script, "whileLoopInsideLoop" );
addParam( list, script, "whileTrueInsideWhileTrue" );
addParam( list, script, "whileTrueContinueWithSwitch" );
addParam( list, script, "forLoop" );
addParam( list, script, "conditionalOperator" );
addParam( list, script, "conditionalOperator2" );
@ -510,6 +511,25 @@ public class ControlFlowOperators extends AbstractBaseTest {
return sw;
}
@Export
static int whileTrueContinueWithSwitch() {
int sw = 1;
LOOP:
while( true ) {
switch(sw) {
case 1:
sw++;
continue LOOP;
case 5:
return sw;
default:
sw++;
}
break;
}
return sw;
}
@Export
static int forLoop() {
int a = 0;