mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 02:44:47 +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
|
||||
*/
|
||||
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 endPos = Math.min( startBlock.endPosition, parent.endPos );
|
||||
int startPos = startBlock.nextPosition;
|
||||
@ -298,7 +322,6 @@ class BranchManger {
|
||||
parent.add( new BranchNode( startPos, startPos, WasmBlockOperator.BR_IF, null, 0 ) );
|
||||
return;
|
||||
}
|
||||
IfPositions positions = searchElsePosition( startBlock, parsedOperations );
|
||||
BranchNode branch = null;
|
||||
for( ; i < parsedOperations.size(); i++ ) {
|
||||
ParsedBlock parsedBlock = parsedOperations.get( i );
|
||||
@ -345,29 +368,6 @@ class BranchManger {
|
||||
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 ) {
|
||||
@ -800,11 +800,13 @@ class BranchManger {
|
||||
int nextCodePosition = instr.getCodePosition();
|
||||
if( nextCodePosition <= codePosition ) {
|
||||
continue;
|
||||
} else {
|
||||
codePosition = nextCodePosition;
|
||||
lineNumber = instr.getLineNumber();
|
||||
}
|
||||
idx = root.handle( codePosition, instructions, idx, lineNumber );
|
||||
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 );
|
||||
} while( codePosition < nextCodePosition );
|
||||
}
|
||||
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, "ifOr5" );
|
||||
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 );
|
||||
return list;
|
||||
@ -410,5 +415,40 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
||||
}
|
||||
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