Skip to content

Commit

Permalink
expand a loop if there is a SWICH structure that point outside the lo…
Browse files Browse the repository at this point in the history
…op. #43
  • Loading branch information
Horcrux7 committed Jun 19, 2022
1 parent 47c28f7 commit 9d1c9ee
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 7 deletions.
33 changes: 27 additions & 6 deletions src/de/inetsoftware/jwebassembly/module/BranchManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,6 @@ void addIfOperator( int startPosition, int offset, int lineNumber, WasmNumericIn
*
* @param startPosition
* the byte position of the start position
* @param offset
* the relative jump position
* @param lineNumber
* the current line number
* @param keys
Expand All @@ -165,8 +163,8 @@ void addIfOperator( int startPosition, int offset, int lineNumber, WasmNumericIn
* @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 ) );
}

/**
Expand Down Expand Up @@ -224,6 +222,7 @@ private void addLoops( List<ParsedBlock> parsedOperations ) {
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 );
Expand All @@ -232,6 +231,21 @@ private void addLoops( List<ParsedBlock> parsedOperations ) {
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;
}
Expand Down Expand Up @@ -1600,11 +1614,18 @@ private static class SwitchParsedBlock extends ParsedBlock {

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ private void writeSwitchCode( CodeInputStream byteCode, boolean isLookupSwitch )
addNumericInstruction( NumericOperator.sub, ValueType.i32, codePos, lineNumber );
}
}
branchManager.addSwitchOperator( startPosition, 0, lineNumber, keys, positions, defaultPosition );
branchManager.addSwitchOperator( startPosition, lineNumber, keys, positions, defaultPosition );
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public static Collection<Object[]> data() {
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" );
Expand Down Expand Up @@ -510,6 +511,25 @@ static int whileTrueInsideWhileTrue() {
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;
Expand Down

0 comments on commit 9d1c9ee

Please sign in to comment.