mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 02:44:47 +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 ) );
|
||||
return;
|
||||
}
|
||||
int elsePos = searchElsePosition( startBlock, parsedOperations );
|
||||
BranchNode branch = null;
|
||||
for( ; i < parsedOperations.size(); 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 );
|
||||
int elsePos = startBlock.endPosition;
|
||||
// end position can not be outside of the parent
|
||||
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 );
|
||||
parent.add( branch );
|
||||
if( i > 0 ) {
|
||||
@ -363,9 +344,30 @@ class BranchManger {
|
||||
}
|
||||
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 ) {
|
||||
@ -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.
|
||||
*
|
||||
@ -592,7 +646,6 @@ class BranchManger {
|
||||
}
|
||||
}
|
||||
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, "if4And_6" );
|
||||
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 );
|
||||
return list;
|
||||
@ -370,5 +375,40 @@ public class ControlFlowOperators extends AbstractBaseTest {
|
||||
}
|
||||
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