fix IF with complex && and || operations. see #17

This commit is contained in:
Volker Berlin 2020-05-27 21:21:50 +02:00
parent 9f9bfa05e6
commit a0d56ddcc3
2 changed files with 32 additions and 4 deletions

View File

@ -473,10 +473,25 @@ class BranchManger {
int elsePos = startBlock.endPosition;
for( ; ifCount < parsedOpCount; ifCount++ ) {
ParsedBlock parsedBlock = parsedOperations.get( ifCount );
if( parsedBlock.op != JavaBlockOperator.IF || parsedBlock.endPosition < elsePos || parsedBlock.endPosition > endElse ) {
if( parsedBlock.op != JavaBlockOperator.IF || parsedBlock.endPosition > endElse ) {
// seems a second IF inside the THEN part.
break;
}
if( parsedBlock.endPosition < elsePos ) {
// The IF jumps not to ELSE part. This can be an inner IF or it is a combination of (||) and (&&) operation
boolean isContinue = false;
for( int i = ifCount + 1; i < parsedOpCount; i++ ) {
ParsedBlock op = parsedOperations.get( i );
if( op.endPosition >= elsePos ) {
isContinue = true;
break;
}
}
if( !isContinue ) {
// really seems a second IF within the THEN part.
break;
}
}
if( parsedBlock.nextPosition > elsePos ) {
// occur if there are 2 IF blocks without ELSE behind the other, this IF is the second that we can cancel the analyze at this point
break;

View File

@ -15,13 +15,10 @@
*/
package de.inetsoftware.jwebassembly.runtime;
import static org.junit.Assume.assumeFalse;
import java.util.ArrayList;
import java.util.Collection;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.runners.Parameterized.Parameters;
import de.inetsoftware.jwebassembly.ScriptEngine;
@ -72,6 +69,7 @@ public class ControlFlowOperators extends AbstractBaseTest {
addParam( list, script, "ifAndOr4" );
addParam( list, script, "ifAndOr6" );
addParam( list, script, "ifAndOr8" );
addParam( list, script, "ifAndOrComplex" );
addParam( list, script, "ifWithoutElseAndLoop" );
addParam( list, script, "ifOrWithMulti" );
addParam( list, script, "ifMultipleInsideThen" );
@ -482,6 +480,21 @@ public class ControlFlowOperators extends AbstractBaseTest {
return result;
}
@Export
private static int ifAndOrComplex() {
int b1 = 0;
int b2 = 0;
int result;
if( (b1 == 0xf0 && (b2 < 0x90 || b2 > 0xbf)) ||
(b1 == 0xf4 && (b2 & 0xf0) != 0x80) ||
(b2 & 0xc0) != 0x80) {
result = 13;
} else {
result = 42;
}
return result;
}
private static int ifWithoutElseAndLoop;
@Export