diff --git a/src/de/inetsoftware/jwebassembly/module/BranchManger.java b/src/de/inetsoftware/jwebassembly/module/BranchManger.java index 19cf356..5307e92 100644 --- a/src/de/inetsoftware/jwebassembly/module/BranchManger.java +++ b/src/de/inetsoftware/jwebassembly/module/BranchManger.java @@ -1,5 +1,5 @@ /* - Copyright 2018 - 2020 Volker Berlin (i-net software) + Copyright 2018 - 2021 Volker Berlin (i-net software) Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -32,7 +32,6 @@ import de.inetsoftware.classparser.CodeInputStream; import de.inetsoftware.classparser.ConstantClass; import de.inetsoftware.classparser.TryCatchFinally; import de.inetsoftware.jwebassembly.WasmException; -import de.inetsoftware.jwebassembly.module.TypeManager.BlockType; import de.inetsoftware.jwebassembly.module.TypeManager.StructType; import de.inetsoftware.jwebassembly.module.WasmInstruction.Type; import de.inetsoftware.jwebassembly.wasm.AnyType; @@ -434,16 +433,32 @@ class BranchManger { * @return the calculated positions */ private IfPositions searchElsePosition( IfParsedBlock startBlock, List parsedOperations ) { + int parsedOpCount = parsedOperations.size(); + // find the end position of the else block int endElse = startBlock.endPosition; - int parsedOpCount = parsedOperations.size(); + boolean newElsePositionFound = true; + LOOP: for( int i = 0; i < parsedOpCount; i++ ) { - ParsedBlock parsedBlock = parsedOperations.get( i ); + ParsedBlock parsedBlock; + if( newElsePositionFound ) { + newElsePositionFound = false; + for( int j = i; j < parsedOpCount; j++ ) { + parsedBlock = parsedOperations.get( j ); + if( parsedBlock.op == JavaBlockOperator.GOTO ) { + if( parsedBlock.nextPosition == endElse ) { + break LOOP; + } + } + } + } + parsedBlock = parsedOperations.get( i ); switch( parsedBlock.op ) { case IF: case GOTO: - if( parsedBlock.startPosition < endElse ) { - endElse = Math.max( endElse, parsedBlock.endPosition ); + if( parsedBlock.startPosition < endElse && endElse < parsedBlock.endPosition ) { + endElse = parsedBlock.endPosition; + newElsePositionFound = true; } break; } diff --git a/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java b/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java index 9c449e8..215b19c 100644 --- a/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java +++ b/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java @@ -1,5 +1,5 @@ /* - * Copyright 2018 - 2020 Volker Berlin (i-net software) + * Copyright 2018 - 2021 Volker Berlin (i-net software) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,6 +73,7 @@ public class ControlFlowOperators extends AbstractBaseTest { addParam( list, script, "ifWithoutElseAndLoop" ); addParam( list, script, "ifOrWithMulti" ); addParam( list, script, "ifMultipleInsideThen" ); + addParam( list, script, "ifWithConditionalInsideThen" ); addParam( list, script, "stringSwitchNormalFoo" ); addParam( list, script, "stringSwitchNormalBar" ); addParam( list, script, "stringSwitchNormalDefault" ); @@ -545,6 +546,20 @@ public class ControlFlowOperators extends AbstractBaseTest { return result; } + @Export + static int ifWithConditionalInsideThen() throws CloneNotSupportedException { + int val = 42; + int result = 0; + if( val > 20 ) { + if( val > 21 ) { + result = val == 42 ? 4 : 5; + } + } else { + result = 3; + } + return result + 13; + } + @Export static int stringSwitchNormalFoo() { return stringSwitchNormal( "foo" );