From 63384e359a97234d99070c473d55f38c0a9c1801 Mon Sep 17 00:00:00 2001
From: Volker Berlin <volker.berlin@googlemail.com>
Date: Sat, 21 Mar 2020 21:16:10 +0100
Subject: [PATCH] fix do while with multiple conditions

---
 .../jwebassembly/module/BranchManger.java     | 29 ++++++++++++++++++-
 .../runtime/ControlFlowOperators.java         | 12 ++++++++
 2 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/src/de/inetsoftware/jwebassembly/module/BranchManger.java b/src/de/inetsoftware/jwebassembly/module/BranchManger.java
index 725dc4a..9fe5580 100644
--- a/src/de/inetsoftware/jwebassembly/module/BranchManger.java
+++ b/src/de/inetsoftware/jwebassembly/module/BranchManger.java
@@ -328,9 +328,18 @@ class BranchManger {
         int startPos = startBlock.nextPosition;
         if( startPos > endPos ) {
             // the condition in a do while(condition) loop
-            parent.add( new BranchNode( startPos, startPos, WasmBlockOperator.BR_IF, null, 0 ) );
+            int breakDeep = calculateContinueDeep( parent, endPos );
+            for( int idx = 0; idx < instructions.size(); idx++ ) {
+                WasmInstruction instr = instructions.get( idx );
+                int codePos = instr.getCodePosition();
+                if( codePos >= startPos ) {
+                    instructions.add( idx, new WasmBlockInstruction( WasmBlockOperator.BR_IF, breakDeep, startPos - 1, startBlock.lineNumber ) );
+                    break;
+                }
+            }
             return;
         }
+
         BranchNode branch = null;
         for( ; i < parsedOperations.size(); i++ ) {
             ParsedBlock parsedBlock = parsedOperations.get( i );
@@ -462,6 +471,24 @@ class BranchManger {
         }
     }
 
+    /**
+     * Calculate the break deep for a continue in a do while(condition) loop.
+     * 
+     * @param parent
+     *            current branch
+     * @param startPos
+     *            the start position of the loop
+     * @return the deep count
+     */
+    private int calculateContinueDeep( BranchNode parent, int startPos ) {
+        int deep = 0;
+        while( parent != null && parent.startPos > startPos ) {
+            deep++;
+            parent = parent.parent;
+        }
+        return deep;
+    }
+
     /**
      * Calculate the deep of a break. A GOTO or IF in Java can jump out multiple loops. We need to calculate how many levels we need to jump.
      * 
diff --git a/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java b/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java
index b2389d4..aa96dd1 100644
--- a/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java
+++ b/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java
@@ -50,6 +50,7 @@ public class ControlFlowOperators extends AbstractBaseTest {
             addParam( list, script, "switchDirect" );
             addParam( list, script, "endlessLoop" );
             addParam( list, script, "doWhileLoop" );
+            addParam( list, script, "doWhileLoopTwoConditions" );
             addParam( list, script, "doWhileLoopWithBreak" );
             addParam( list, script, "whileLoop" );
             addParam( list, script, "forLoop" );
@@ -292,6 +293,17 @@ public class ControlFlowOperators extends AbstractBaseTest {
             return d;
         }
 
+        @Export
+        static int doWhileLoopTwoConditions() {
+            int val = 42;
+            int shift = 1;
+            do {
+                val >>>= shift;
+            } while (val > 7 && shift > 0);
+
+            return val;
+        }
+
         @Export
         static double doWhileLoopWithBreak() {
             int a = 0;