mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
Add support for OR concatenated IF conditions
This commit is contained in:
parent
a019647094
commit
be77f59ac0
@ -298,12 +298,15 @@ 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;
|
||||||
}
|
}
|
||||||
|
int elsePos = 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 );
|
||||||
if( parsedBlock.nextPosition == endPos && parsedBlock.op == JavaBlockOperator.GOTO && parsedBlock.startPosition < parsedBlock.endPosition ) {
|
if( parsedBlock.nextPosition > elsePos ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( parsedBlock.nextPosition == elsePos && parsedBlock.op == JavaBlockOperator.GOTO && parsedBlock.startPosition < parsedBlock.endPosition ) {
|
||||||
parsedOperations.remove( i );
|
parsedOperations.remove( i );
|
||||||
int elsePos = startBlock.endPosition;
|
|
||||||
// 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 );
|
||||||
|
|
||||||
@ -322,28 +325,6 @@ class BranchManger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while( i > 0 ) {
|
|
||||||
// check if there is a second condition in the IF expression that is concatenated with "&&" operator
|
|
||||||
parsedBlock = parsedOperations.get( 0 );
|
|
||||||
if( parsedBlock.op == JavaBlockOperator.IF && parsedBlock.endPosition == 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();
|
|
||||||
for( int k = 0; k < instructions.size(); k++ ) {
|
|
||||||
WasmInstruction instr = instructions.get( k );
|
|
||||||
if( instr.getCodePosition() >= startPos ) {
|
|
||||||
instructions.add( k, new WasmConstInstruction( 0, startPos - 1, parsedBlock.lineNumber ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
branch = new BranchNode( startPos, elsePos, WasmBlockOperator.IF, null );
|
branch = new BranchNode( startPos, elsePos, WasmBlockOperator.IF, null );
|
||||||
parent.add( branch );
|
parent.add( branch );
|
||||||
if( i > 0 ) {
|
if( i > 0 ) {
|
||||||
@ -363,9 +344,30 @@ class BranchManger {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( parsedBlock.nextPosition > endPos ) {
|
|
||||||
break;
|
if( i== 0 && parsedBlock.op == JavaBlockOperator.IF ) {
|
||||||
|
// AND concatenation (&& operator)
|
||||||
|
if( endPos == elsePos && parsedBlock.endPosition == 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 ) {
|
||||||
@ -388,6 +390,58 @@ class BranchManger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search the start position of an ELSE branch.
|
||||||
|
*
|
||||||
|
* @param startBlock
|
||||||
|
* the start block of the if control structure
|
||||||
|
* @param parsedOperations
|
||||||
|
* the not consumed operations in the parent branch
|
||||||
|
* @return the position
|
||||||
|
*/
|
||||||
|
private int searchElsePosition( IfParsedBlock startBlock, List<ParsedBlock> parsedOperations ) {
|
||||||
|
int elsePos = startBlock.endPosition;
|
||||||
|
for( int i = 0; i < parsedOperations.size(); i++ ) {
|
||||||
|
ParsedBlock parsedBlock = parsedOperations.get( i );
|
||||||
|
if( parsedBlock.op == JavaBlockOperator.GOTO && elsePos == parsedBlock.nextPosition ) {
|
||||||
|
return elsePos;
|
||||||
|
}
|
||||||
|
if( parsedBlock.nextPosition > elsePos ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for( int i = 0; i < parsedOperations.size(); i++ ) {
|
||||||
|
ParsedBlock parsedBlock = parsedOperations.get( i );
|
||||||
|
if( parsedBlock.nextPosition > elsePos ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if( parsedBlock.op == JavaBlockOperator.IF && elsePos < parsedBlock.endPosition ) {
|
||||||
|
elsePos = parsedBlock.endPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return elsePos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a constant i32 operation before the given code position
|
||||||
|
*
|
||||||
|
* @param constant
|
||||||
|
* the i32 value
|
||||||
|
* @param pos
|
||||||
|
* the code position
|
||||||
|
* @param lineNumber
|
||||||
|
* the line number for possible error messages
|
||||||
|
*/
|
||||||
|
private void insertConstBeforePosition( int constant, int pos, int lineNumber ) {
|
||||||
|
for( int k = 0; k < instructions.size(); k++ ) {
|
||||||
|
WasmInstruction instr = instructions.get( k );
|
||||||
|
if( instr.getCodePosition() >= pos ) {
|
||||||
|
instructions.add( k, new WasmConstInstruction( constant, pos - 1, lineNumber ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate the deep of a break.
|
* Calculate the deep of a break.
|
||||||
*
|
*
|
||||||
@ -592,7 +646,6 @@ class BranchManger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new WasmException( "GOTO code without target loop/block", null, null, gotoBlock.lineNumber );
|
throw new WasmException( "GOTO code without target loop/block", null, null, gotoBlock.lineNumber );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,6 +61,11 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
|||||||
addParam( list, script, "ifAnd_6" );
|
addParam( list, script, "ifAnd_6" );
|
||||||
addParam( list, script, "if4And_6" );
|
addParam( list, script, "if4And_6" );
|
||||||
addParam( list, script, "if4And_7" );
|
addParam( list, script, "if4And_7" );
|
||||||
|
addParam( list, script, "ifOr0" );
|
||||||
|
addParam( list, script, "ifOr1" );
|
||||||
|
addParam( list, script, "ifOr3" );
|
||||||
|
addParam( list, script, "ifOr5" );
|
||||||
|
addParam( list, script, "ifOr7" );
|
||||||
}
|
}
|
||||||
rule.setTestParameters( list );
|
rule.setTestParameters( list );
|
||||||
return list;
|
return list;
|
||||||
@ -370,5 +375,40 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static int ifOr0() {
|
||||||
|
return ifOr( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static int ifOr1() {
|
||||||
|
return ifOr( 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static int ifOr3() {
|
||||||
|
return ifOr( 3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static int ifOr5() {
|
||||||
|
return ifOr( 5 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Export
|
||||||
|
static int ifOr7() {
|
||||||
|
return ifOr( 7 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int ifOr( 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