mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 02:44:47 +01:00
Normalize empty THEN blocks to fix concated conditional operators
This commit is contained in:
parent
c9e34715c9
commit
d68c74f032
@ -160,6 +160,7 @@ class BranchManger {
|
||||
addLoops();
|
||||
List<ParsedBlock> parsedOperations = allParsedOperations;
|
||||
Collections.sort( parsedOperations );
|
||||
normalizeEmptyThenBlocks( parsedOperations );
|
||||
calculate( root, parsedOperations );
|
||||
for( BreakBlock breakBlock : breakOperations ) {
|
||||
calculateBreak( breakBlock );
|
||||
@ -283,6 +284,40 @@ class BranchManger {
|
||||
instructions.add( conditionIdx++, new WasmBlockInstruction( WasmBlockOperator.BR_IF, 1, conditionNew, gotoBlock.lineNumber ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize all empty THEN blocks like:
|
||||
*
|
||||
* <pre>
|
||||
* if (condition) {
|
||||
* } else {
|
||||
* ....
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* are changed to: if (!condition) { .... }
|
||||
* </pre>
|
||||
* The THEN block contains only a single GOTO operation. This operation is removed and the IF condition is negate.
|
||||
* The removing of the GOTO operation make it easer to convert it to a valid WebAssembly structure without GOTO.
|
||||
*
|
||||
* @param parsedOperations
|
||||
* the parsed operations
|
||||
*/
|
||||
private static void normalizeEmptyThenBlocks( List<ParsedBlock> parsedOperations ) {
|
||||
// occur also with cascaded conditional operator like: int result = (a < 0 ? false : a == c ) && (b < 0 ? false : b == c ) ? 17 : 18;
|
||||
for( int i = 0; i < parsedOperations.size() - 1; i++ ) {
|
||||
ParsedBlock ifBlock = parsedOperations.get( i );
|
||||
if( ifBlock.op == JavaBlockOperator.IF ) {
|
||||
ParsedBlock nextBlock = parsedOperations.get( i + 1 );
|
||||
if( nextBlock.op == JavaBlockOperator.GOTO && nextBlock.startPosition == ifBlock.nextPosition
|
||||
&& ifBlock.endPosition == nextBlock.nextPosition ) {
|
||||
((IfParsedBlock)ifBlock).negateCompare();
|
||||
ifBlock.endPosition = nextBlock.endPosition;
|
||||
parsedOperations.remove( i + 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the branch tree for the given branch and parsed sub operations.
|
||||
*
|
||||
@ -400,21 +435,6 @@ class BranchManger {
|
||||
// end position can not be outside of the parent
|
||||
endPos = Math.min( parsedBlock.endPosition, parent.endPos );
|
||||
|
||||
// special case if there is only one goto in the IF block. Occur with goto_w
|
||||
if( parsedBlock.startPosition == startPos ) {
|
||||
int nextPos = Math.min( parsedBlock.endPosition, parent.endPos );
|
||||
for( int j = i; j < parsedOperations.size(); j++ ) {
|
||||
ParsedBlock parsedBlock2 = parsedOperations.get( j );
|
||||
if( parsedBlock2.nextPosition == nextPos && parsedBlock2.op == JavaBlockOperator.GOTO && parsedBlock2.startPosition < parsedBlock2.endPosition ) {
|
||||
parsedOperations.remove( j );
|
||||
positions.elsePos = nextPos;
|
||||
endPos = parsedBlock2.endPosition;
|
||||
startBlock.negateCompare();
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
branch = new BranchNode( startPos, positions.elsePos, WasmBlockOperator.IF, null );
|
||||
parent.add( branch );
|
||||
if( i > 0 ) {
|
||||
|
@ -54,6 +54,7 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
||||
addParam( list, script, "forLoop" );
|
||||
addParam( list, script, "conditionalOperator" );
|
||||
addParam( list, script, "conditionalOperator2" );
|
||||
addParam( list, script, "conditionalOperatorConcated" );
|
||||
addParam( list, script, "redifineVariable" );
|
||||
addParam( list, script, "ifAnd_0" );
|
||||
addParam( list, script, "ifAnd_3" );
|
||||
@ -371,6 +372,15 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Export
|
||||
static int conditionalOperatorConcated () {
|
||||
int a = 7;
|
||||
int b = 13;
|
||||
int c = 42;
|
||||
int result = (a < 0 ? false : a == c ) && (b < 0 ? false : b == c ) ? 3 : 4;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Export
|
||||
static double redifineVariable() {
|
||||
int x = 42;
|
||||
|
Loading…
x
Reference in New Issue
Block a user