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 * @param startPosition
* the byte position of the start position * the byte position of the start position
* @param offset
* the relative jump position
* @param lineNumber * @param lineNumber
* the current line number * the current line number
* @param keys * @param keys
@ -165,8 +163,8 @@ class BranchManager {
* @param defaultPosition * @param defaultPosition
* the code position of the default block * the code position of the default block
*/ */
void addSwitchOperator( int startPosition, int offset, int lineNumber, int[] keys, int[] positions, int defaultPosition ) { void addSwitchOperator( int startPosition, int lineNumber, @Nullable int[] keys, @Nonnull int[] positions, int defaultPosition ) {
allParsedOperations.add( new SwitchParsedBlock( startPosition, offset, lineNumber, keys, positions, defaultPosition ) ); allParsedOperations.add( new SwitchParsedBlock( startPosition, lineNumber, keys, positions, defaultPosition ) );
} }
/** /**
@ -224,6 +222,7 @@ class BranchManager {
if( loop.endPosition < parsedBlock.nextPosition ) { if( loop.endPosition < parsedBlock.nextPosition ) {
int nextPosition = parsedBlock.startPosition; // Jump position for Continue int nextPosition = parsedBlock.startPosition; // Jump position for Continue
int endPosition = parsedBlock.nextPosition; 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. // 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++ ) { for( int n = b + 1; n < parsedOperations.size(); n++ ) {
ParsedBlock block = parsedOperations.get( n ); ParsedBlock block = parsedOperations.get( n );
@ -232,6 +231,21 @@ class BranchManager {
endPosition = block.nextPosition; 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.nextPosition = nextPosition; // Jump position for Continue
loop.endPosition = endPosition; loop.endPosition = endPosition;
} }
@ -1600,11 +1614,18 @@ class BranchManager {
private int defaultPosition; private int defaultPosition;
public SwitchParsedBlock( int startPosition, int offset, int lineNumber, int[] keys, int[] positions, int defaultPosition ) { public SwitchParsedBlock( int startPosition, int lineNumber, @Nullable int[] keys, @Nonnull int[] positions, int defaultPosition ) {
super( JavaBlockOperator.SWITCH, startPosition, offset, startPosition, lineNumber ); super( JavaBlockOperator.SWITCH, startPosition, 0, startPosition, lineNumber );
this.keys = keys; this.keys = keys;
this.positions = positions; this.positions = positions;
this.defaultPosition = defaultPosition; 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 ); 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, "whileLoopAfterIfWithReturn" );
addParam( list, script, "whileLoopInsideLoop" ); addParam( list, script, "whileLoopInsideLoop" );
addParam( list, script, "whileTrueInsideWhileTrue" ); addParam( list, script, "whileTrueInsideWhileTrue" );
addParam( list, script, "whileTrueContinueWithSwitch" );
addParam( list, script, "forLoop" ); addParam( list, script, "forLoop" );
addParam( list, script, "conditionalOperator" ); addParam( list, script, "conditionalOperator" );
addParam( list, script, "conditionalOperator2" ); addParam( list, script, "conditionalOperator2" );
@ -510,6 +511,25 @@ public class ControlFlowOperators extends AbstractBaseTest {
return sw; 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 @Export
static int forLoop() { static int forLoop() {
int a = 0; int a = 0;