improve "goto_w" support

This commit is contained in:
Volker Berlin 2019-03-21 21:14:21 +01:00
parent 0b3c1987f5
commit 66945d2974
2 changed files with 72 additions and 35 deletions

View File

@ -179,10 +179,50 @@ class BranchManger {
int nextPos = parsedBlock.nextPosition; int nextPos = parsedBlock.nextPosition;
for( int n = b + 1; n < allParsedOperations.size(); n++ ) { for( int n = b + 1; n < allParsedOperations.size(); n++ ) {
ParsedBlock nextBlock = allParsedOperations.get( n ); ParsedBlock nextBlock = allParsedOperations.get( n );
if( nextBlock.op == JavaBlockOperator.IF && nextBlock.endPosition == nextPos ) { if( nextBlock.op == JavaBlockOperator.IF && nextBlock.endPosition == nextPos ) { // Eclipse loop with normal goto
int conditionStart = parsedBlock.endPosition; // 15 int conditionStart = parsedBlock.endPosition;
int conditionEnd = nextBlock.nextPosition; // 22 int conditionEnd = nextBlock.nextPosition;
int conditionNew = parsedBlock.startPosition; // 4 convertToLoop( parsedBlock, conditionStart, conditionEnd );
allParsedOperations.remove( n );
((IfParsedBlock)nextBlock).negateCompare();
break;
}
if( nextBlock.op == JavaBlockOperator.GOTO && nextBlock.endPosition == nextPos && n > 1 ) { // Eclipse loop with wide goto_w
ParsedBlock prevBlock = allParsedOperations.get( n - 1 );
if( prevBlock.op == JavaBlockOperator.IF && prevBlock.endPosition == nextBlock.nextPosition ) {
System.err.println( nextBlock );
int conditionStart = parsedBlock.endPosition;
int conditionEnd = prevBlock.nextPosition;
convertToLoop( parsedBlock, conditionStart, conditionEnd );
allParsedOperations.remove( n );
allParsedOperations.remove( n - 1 );
break;
}
}
}
break;
default:
}
}
}
allParsedOperations.addAll( loops.values() );
}
/**
* Convert the GOTO block with condition at the end into a loop block and move the condition from the end to the
* start like wasm it required.
*
* @param gotoBlock
* the goto block
* @param conditionStart
* the code position where condition code start
* @param conditionEnd
* the end position
*/
private void convertToLoop( ParsedBlock gotoBlock, int conditionStart, int conditionEnd ) {
int conditionNew = gotoBlock.startPosition;
int nextPos = gotoBlock.nextPosition;
int conditionIdx = -1; int conditionIdx = -1;
int i; int i;
@ -202,22 +242,10 @@ class BranchManger {
} }
} }
parsedBlock.op = JavaBlockOperator.LOOP; gotoBlock.op = JavaBlockOperator.LOOP;
parsedBlock.endPosition = conditionEnd; gotoBlock.endPosition = conditionEnd;
allParsedOperations.remove( n );
instructions.add( i, new WasmBlockInstruction( WasmBlockOperator.BR, 0, conditionNew ) ); instructions.add( i, new WasmBlockInstruction( WasmBlockOperator.BR, 0, conditionNew ) );
instructions.add( conditionIdx++, new WasmBlockInstruction( WasmBlockOperator.BR_IF, 1, conditionNew ) ); instructions.add( conditionIdx++, new WasmBlockInstruction( WasmBlockOperator.BR_IF, 1, conditionNew ) );
((IfParsedBlock)nextBlock).negateCompare();
break;
}
}
break;
default:
}
}
}
allParsedOperations.addAll( loops.values() );
} }
/** /**

View File

@ -39,26 +39,35 @@ public class Wide extends AbstractBaseTest {
ArrayList<Object[]> list = new ArrayList<>(); ArrayList<Object[]> list = new ArrayList<>();
for( ScriptEngine[] val : ScriptEngine.testParams() ) { for( ScriptEngine[] val : ScriptEngine.testParams() ) {
ScriptEngine script = val[0]; ScriptEngine script = val[0];
addParam( list, script, "abc" ); addParam( list, script, "thenBranch" );
addParam( list, script, "elseBranch" );
} }
return list; return list;
} }
static class TestClass { static class TestClass {
@Export
static int thenBranch() {
return wide(true);
}
@Export
static int elseBranch() {
return wide(false);
}
/** /**
* more as 255 variable slots * more as 255 variable slots
* @return * @return
*/ */
@Export @Export
static int abc() { static int wide( boolean then) {
int i = 42; int i = 42;
if( 42 == i ) { if( then ) {
// TODO for( int j = 0; j < 10; j++ ) {
// for( int j = 0; j < 10; j++ ) {
// i++;
// }
i++; i++;
}
} else { } else {
int j = 0; int j = 0;
long a0 = 0; long a0 = 0;