correct LOOP detection in an ELSE block

This commit is contained in:
Volker Berlin 2022-02-20 18:32:07 +01:00
parent d4cf26ee05
commit d629fbcd02

View File

@ -126,7 +126,7 @@ class BranchManager {
* the current line number * the current line number
*/ */
void addReturnOperator( int startPosition, int nextPosition, int lineNumber ) { void addReturnOperator( int startPosition, int nextPosition, int lineNumber ) {
allParsedOperations.add( new ParsedBlock( JavaBlockOperator.RETURN, startPosition, 0, nextPosition, lineNumber ) ); allParsedOperations.add( new ParsedBlock( JavaBlockOperator.RETURN, startPosition, Integer.MAX_VALUE - startPosition, nextPosition, lineNumber ) );
} }
/** /**
@ -188,6 +188,7 @@ class BranchManager {
* the parsed operations * the parsed operations
*/ */
private void addLoops( List<ParsedBlock> parsedOperations ) { private void addLoops( List<ParsedBlock> parsedOperations ) {
MAIN:
for( int b = 0; b < parsedOperations.size(); b++ ) { for( int b = 0; b < parsedOperations.size(); b++ ) {
ParsedBlock parsedBlock = parsedOperations.get( b ); ParsedBlock parsedBlock = parsedOperations.get( b );
if( parsedBlock.startPosition > parsedBlock.endPosition ) { if( parsedBlock.startPosition > parsedBlock.endPosition ) {
@ -229,6 +230,15 @@ class BranchManager {
// if<cond> START: // if<cond> START:
// we can not match this in WASM because a missing GOTO that we need to move the condition to the start of the loop // we can not match this in WASM because a missing GOTO that we need to move the condition to the start of the loop
int nextPos = parsedBlock.nextPosition; int nextPos = parsedBlock.nextPosition;
for( int n = b - 1; n >= 0; n-- ) {
ParsedBlock block = parsedOperations.get( n );
if( block.op == JavaBlockOperator.IF && block.endPosition == nextPos ) {
// a normal GOTO before the ELSE
continue MAIN;
}
}
for( int n = b + 1; n < parsedOperations.size(); n++ ) { for( int n = b + 1; n < parsedOperations.size(); n++ ) {
ParsedBlock nextBlock = parsedOperations.get( n ); ParsedBlock nextBlock = parsedOperations.get( n );
if( nextBlock.op == JavaBlockOperator.IF && nextBlock.endPosition == nextPos ) { // Eclipse loop with normal goto if( nextBlock.op == JavaBlockOperator.IF && nextBlock.endPosition == nextPos ) { // Eclipse loop with normal goto
@ -242,7 +252,7 @@ class BranchManager {
// The GOTO from the ELSE and the jump to the end of the WHILE loop is merged to one GOTO. // The GOTO from the ELSE and the jump to the end of the WHILE loop is merged to one GOTO.
for( n = b - 1; n >= 0; n-- ) { for( n = b - 1; n >= 0; n-- ) {
ParsedBlock prevBlock = parsedOperations.get( n ); ParsedBlock prevBlock = parsedOperations.get( n );
if( prevBlock.endPosition > nextPos ) { if( prevBlock.endPosition > nextPos && prevBlock.endPosition < conditionStart ) {
conditionStart = prevBlock.endPosition; conditionStart = prevBlock.endPosition;
prevBlock.endPosition = parsedBlock.nextPosition; prevBlock.endPosition = parsedBlock.nextPosition;
// Create the second GOTO // Create the second GOTO
@ -252,6 +262,9 @@ class BranchManager {
break; break;
} }
} }
if( conditionStart == conditionEnd ) {
throw new WasmException( "Loop condition start not found. Jump from " + parsedBlock.startPosition + " to " + parsedBlock.endPosition, parsedBlock.lineNumber );
}
} }
convertToLoop( parsedBlock, conditionStart, conditionEnd ); convertToLoop( parsedBlock, conditionStart, conditionEnd );
@ -1064,6 +1077,7 @@ class BranchManager {
parent = parent.parent; parent = parent.parent;
deep++; deep++;
} }
throw new WasmException( "GOTO code without target loop/block. Jump from " + start + " to " + jump, gotoBlock.lineNumber );
} else { } else {
if( gotoBlock.nextPosition == jump ) { if( gotoBlock.nextPosition == jump ) {
//A GOTO to the next position is like a NOP and can be ignored. //A GOTO to the next position is like a NOP and can be ignored.
@ -1838,7 +1852,7 @@ class BranchManager {
* @param endPosition * @param endPosition
* the Jump position * the Jump position
*/ */
public BreakBlock( BranchNode branch, int breakPos, int endPosition ) { public BreakBlock( @Nonnull BranchNode branch, int breakPos, int endPosition ) {
this.breakPos = breakPos; this.breakPos = breakPos;
this.endPosition = endPosition; this.endPosition = endPosition;
this.branch = branch; this.branch = branch;