mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 15:37:52 +01:00
handle complex IF conditions
This commit is contained in:
parent
215d8ff70e
commit
ccbc633463
@ -290,6 +290,30 @@ class BranchManger {
|
|||||||
* the not consumed operations in the parent branch
|
* the not consumed operations in the parent branch
|
||||||
*/
|
*/
|
||||||
private void calculateIf( BranchNode parent, IfParsedBlock startBlock, List<ParsedBlock> parsedOperations ) {
|
private void calculateIf( BranchNode parent, IfParsedBlock startBlock, List<ParsedBlock> parsedOperations ) {
|
||||||
|
IfPositions positions = searchElsePosition( startBlock, parsedOperations );
|
||||||
|
|
||||||
|
BranchNode main = parent;
|
||||||
|
for( int i = 0; i < positions.ifCount; i++ ) {
|
||||||
|
IfParsedBlock parsedBlock = (IfParsedBlock)parsedOperations.remove( 0 );
|
||||||
|
if( startBlock.endPosition < positions.thenPos || startBlock.endPosition == positions.elsePos ) {
|
||||||
|
// AND concatenation (&& operator)
|
||||||
|
int pos = parsedBlock.startPosition + 1;
|
||||||
|
main.add( new BranchNode( startBlock.nextPosition, pos, WasmBlockOperator.IF, null ) );
|
||||||
|
main.add( new BranchNode( pos, pos + 1, WasmBlockOperator.ELSE, WasmBlockOperator.END ) );
|
||||||
|
startBlock.negateCompare();
|
||||||
|
insertConstBeforePosition( 0, pos + 1, parsedBlock.lineNumber ); // 0 --> FALSE for the next if expression
|
||||||
|
} else {
|
||||||
|
// OR concatenation (|| operator)
|
||||||
|
int pos = startBlock.startPosition + 2; // startBlock.startPosition is the position of the compare operation which need before this if construct
|
||||||
|
main.add( new BranchNode( pos, startBlock.nextPosition, WasmBlockOperator.IF, null ) );
|
||||||
|
BranchNode node = new BranchNode( startBlock.nextPosition, positions.thenPos, WasmBlockOperator.ELSE, WasmBlockOperator.END );
|
||||||
|
main.add( node );
|
||||||
|
main = node;
|
||||||
|
insertConstBeforePosition( 1, pos + 1, startBlock.lineNumber ); // 1 --> TRUE for the next if expression
|
||||||
|
}
|
||||||
|
startBlock = parsedBlock;
|
||||||
|
}
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int endPos = Math.min( startBlock.endPosition, parent.endPos );
|
int endPos = Math.min( startBlock.endPosition, parent.endPos );
|
||||||
int startPos = startBlock.nextPosition;
|
int startPos = startBlock.nextPosition;
|
||||||
@ -298,7 +322,6 @@ class BranchManger {
|
|||||||
parent.add( new BranchNode( startPos, startPos, WasmBlockOperator.BR_IF, null, 0 ) );
|
parent.add( new BranchNode( startPos, startPos, WasmBlockOperator.BR_IF, null, 0 ) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IfPositions positions = searchElsePosition( startBlock, parsedOperations );
|
|
||||||
BranchNode branch = null;
|
BranchNode branch = null;
|
||||||
for( ; i < parsedOperations.size(); i++ ) {
|
for( ; i < parsedOperations.size(); i++ ) {
|
||||||
ParsedBlock parsedBlock = parsedOperations.get( i );
|
ParsedBlock parsedBlock = parsedOperations.get( i );
|
||||||
@ -345,29 +368,6 @@ class BranchManger {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( i== 0 && parsedBlock.op == JavaBlockOperator.IF ) {
|
|
||||||
// AND concatenation (&& operator)
|
|
||||||
if( endPos == positions.elsePos && parsedBlock.endPosition == positions.elsePos ) {
|
|
||||||
parent.add( new BranchNode( startPos, parsedBlock.nextPosition - 1, WasmBlockOperator.IF, null ) );
|
|
||||||
parent.add( new BranchNode( parsedBlock.nextPosition - 1, parsedBlock.nextPosition, WasmBlockOperator.ELSE, WasmBlockOperator.END ) );
|
|
||||||
startPos = parsedBlock.nextPosition;
|
|
||||||
parsedOperations.remove( 0 );
|
|
||||||
i--;
|
|
||||||
((IfParsedBlock)parsedBlock).negateCompare();
|
|
||||||
insertConstBeforePosition( 0, startPos, parsedBlock.lineNumber ); // 0 --> FALSE for the next if expression
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// OR concatenation (|| operator)
|
|
||||||
if( startBlock.endPosition == parsedBlock.endPosition || startBlock.endPosition == parsedBlock.nextPosition ) {
|
|
||||||
int pos = startBlock.startPosition + 1; // startBlock.startPosition is the position of the compare operation which need before this if construct
|
|
||||||
parent.add( new BranchNode( pos, startPos, WasmBlockOperator.IF, null ) );
|
|
||||||
parent.add( new BranchNode( startPos, endPos, WasmBlockOperator.ELSE, WasmBlockOperator.END ) );
|
|
||||||
insertConstBeforePosition( 1, pos+1, startBlock.lineNumber ); // 1 --> TRUE for the next if expression
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( branch == null ) {
|
if( branch == null ) {
|
||||||
@ -800,11 +800,13 @@ class BranchManger {
|
|||||||
int nextCodePosition = instr.getCodePosition();
|
int nextCodePosition = instr.getCodePosition();
|
||||||
if( nextCodePosition <= codePosition ) {
|
if( nextCodePosition <= codePosition ) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
codePosition = nextCodePosition;
|
|
||||||
lineNumber = instr.getLineNumber();
|
|
||||||
}
|
}
|
||||||
|
lineNumber = instr.getLineNumber();
|
||||||
|
do {
|
||||||
|
// call it for every position for the case that a Jump is call to a intermediate position
|
||||||
|
codePosition++;
|
||||||
idx = root.handle( codePosition, instructions, idx, lineNumber );
|
idx = root.handle( codePosition, instructions, idx, lineNumber );
|
||||||
|
} while( codePosition < nextCodePosition );
|
||||||
}
|
}
|
||||||
root.handle( byteCode.getCodePosition(), instructions, instructions.size(), byteCode.getLineNumber() );
|
root.handle( byteCode.getCodePosition(), instructions, instructions.size(), byteCode.getLineNumber() );
|
||||||
|
|
||||||
|
@ -66,6 +66,11 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
|||||||
addParam( list, script, "ifOr3" );
|
addParam( list, script, "ifOr3" );
|
||||||
addParam( list, script, "ifOr5" );
|
addParam( list, script, "ifOr5" );
|
||||||
addParam( list, script, "ifOr7" );
|
addParam( list, script, "ifOr7" );
|
||||||
|
addParam( list, script, "ifAndOr0" );
|
||||||
|
addParam( list, script, "ifAndOr2" );
|
||||||
|
addParam( list, script, "ifAndOr4" );
|
||||||
|
addParam( list, script, "ifAndOr6" );
|
||||||
|
addParam( list, script, "ifAndOr8" );
|
||||||
}
|
}
|
||||||
rule.setTestParameters( list );
|
rule.setTestParameters( list );
|
||||||
return list;
|
return list;
|
||||||
@ -410,5 +415,40 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static int ifAndOr0() {
|
||||||
|
return ifAndOr( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static int ifAndOr2() {
|
||||||
|
return ifAndOr( 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static int ifAndOr4() {
|
||||||
|
return ifAndOr( 4 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static int ifAndOr6() {
|
||||||
|
return ifAndOr( 6 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static int ifAndOr8() {
|
||||||
|
return ifAndOr( 8 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int ifAndOr( int condition ) {
|
||||||
|
int result;
|
||||||
|
if( (condition >= 1 && condition <= 3) || (condition >= 5 && condition <= 7) ) {
|
||||||
|
result = 42;
|
||||||
|
} else {
|
||||||
|
result = 76;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user