mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +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();
|
addLoops();
|
||||||
List<ParsedBlock> parsedOperations = allParsedOperations;
|
List<ParsedBlock> parsedOperations = allParsedOperations;
|
||||||
Collections.sort( parsedOperations );
|
Collections.sort( parsedOperations );
|
||||||
|
normalizeEmptyThenBlocks( parsedOperations );
|
||||||
calculate( root, parsedOperations );
|
calculate( root, parsedOperations );
|
||||||
for( BreakBlock breakBlock : breakOperations ) {
|
for( BreakBlock breakBlock : breakOperations ) {
|
||||||
calculateBreak( breakBlock );
|
calculateBreak( breakBlock );
|
||||||
@ -283,6 +284,40 @@ class BranchManger {
|
|||||||
instructions.add( conditionIdx++, new WasmBlockInstruction( WasmBlockOperator.BR_IF, 1, conditionNew, gotoBlock.lineNumber ) );
|
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.
|
* 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
|
// end position can not be outside of the parent
|
||||||
endPos = Math.min( parsedBlock.endPosition, parent.endPos );
|
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 );
|
branch = new BranchNode( startPos, positions.elsePos, WasmBlockOperator.IF, null );
|
||||||
parent.add( branch );
|
parent.add( branch );
|
||||||
if( i > 0 ) {
|
if( i > 0 ) {
|
||||||
|
@ -54,6 +54,7 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
|||||||
addParam( list, script, "forLoop" );
|
addParam( list, script, "forLoop" );
|
||||||
addParam( list, script, "conditionalOperator" );
|
addParam( list, script, "conditionalOperator" );
|
||||||
addParam( list, script, "conditionalOperator2" );
|
addParam( list, script, "conditionalOperator2" );
|
||||||
|
addParam( list, script, "conditionalOperatorConcated" );
|
||||||
addParam( list, script, "redifineVariable" );
|
addParam( list, script, "redifineVariable" );
|
||||||
addParam( list, script, "ifAnd_0" );
|
addParam( list, script, "ifAnd_0" );
|
||||||
addParam( list, script, "ifAnd_3" );
|
addParam( list, script, "ifAnd_3" );
|
||||||
@ -371,6 +372,15 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
|||||||
return result;
|
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
|
@Export
|
||||||
static double redifineVariable() {
|
static double redifineVariable() {
|
||||||
int x = 42;
|
int x = 42;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user