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,37 +179,26 @@ class BranchManger {
int nextPos = parsedBlock.nextPosition;
for( int n = b + 1; n < allParsedOperations.size(); n++ ) {
ParsedBlock nextBlock = allParsedOperations.get( n );
if( nextBlock.op == JavaBlockOperator.IF && nextBlock.endPosition == nextPos ) {
int conditionStart = parsedBlock.endPosition; // 15
int conditionEnd = nextBlock.nextPosition; // 22
int conditionNew = parsedBlock.startPosition; // 4
int conditionIdx = -1;
int i;
for( i = 0; i < instructions.size(); i++ ) {
WasmInstruction instr = instructions.get( i );
int codePos = instr.getCodePosition();
if( codePos == nextPos ) {
conditionIdx = i;
}
if( codePos >= conditionEnd ) {
break;
}
if( codePos >= conditionStart ) {
instr.setCodePosition( conditionNew );
instructions.remove( i );
instructions.add( conditionIdx++, instr );
}
}
parsedBlock.op = JavaBlockOperator.LOOP;
parsedBlock.endPosition = conditionEnd;
if( nextBlock.op == JavaBlockOperator.IF && nextBlock.endPosition == nextPos ) { // Eclipse loop with normal goto
int conditionStart = parsedBlock.endPosition;
int conditionEnd = nextBlock.nextPosition;
convertToLoop( parsedBlock, conditionStart, conditionEnd );
allParsedOperations.remove( n );
instructions.add( i, new WasmBlockInstruction( WasmBlockOperator.BR, 0, conditionNew ) );
instructions.add( conditionIdx++, new WasmBlockInstruction( WasmBlockOperator.BR_IF, 1, conditionNew ) );
((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:
@ -220,6 +209,45 @@ class BranchManger {
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 i;
for( i = 0; i < instructions.size(); i++ ) {
WasmInstruction instr = instructions.get( i );
int codePos = instr.getCodePosition();
if( codePos == nextPos ) {
conditionIdx = i;
}
if( codePos >= conditionEnd ) {
break;
}
if( codePos >= conditionStart ) {
instr.setCodePosition( conditionNew );
instructions.remove( i );
instructions.add( conditionIdx++, instr );
}
}
gotoBlock.op = JavaBlockOperator.LOOP;
gotoBlock.endPosition = conditionEnd;
instructions.add( i, new WasmBlockInstruction( WasmBlockOperator.BR, 0, conditionNew ) );
instructions.add( conditionIdx++, new WasmBlockInstruction( WasmBlockOperator.BR_IF, 1, conditionNew ) );
}
/**
* Calculate the branch tree for the given branch and parsed sub operations.
*

View File

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