From 062e2aeb47cf7aa8c677415c6e12d9151dfa1ce1 Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Thu, 16 Jun 2022 22:47:22 +0200 Subject: [PATCH] fix while(true) inside a while(true) loop. #43 --- .../jwebassembly/module/BranchManager.java | 18 +++++++++++++--- .../runtime/ControlFlowOperators.java | 21 +++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/de/inetsoftware/jwebassembly/module/BranchManager.java b/src/de/inetsoftware/jwebassembly/module/BranchManager.java index f57c75be..f456c2e3 100644 --- a/src/de/inetsoftware/jwebassembly/module/BranchManager.java +++ b/src/de/inetsoftware/jwebassembly/module/BranchManager.java @@ -202,7 +202,7 @@ private void addLoops( List parsedOperations ) { if( loop == null ) { loop = new ParsedBlock( JavaBlockOperator.LOOP, start, 0, start, parsedBlock.lineNumber ); loops.put( start, loop ); - // if a condition form outside of the loop point inside the loop then it must be conditional return and a jump to the loop condition. + // if a condition before the loop points to a position within the loop, then it must be a conditional return and a jump to the loop condition. for( int n = b - 1; n >= 0; n-- ) { ParsedBlock prevBlock = parsedOperations.get( n ); switch( prevBlock.op ) { @@ -221,8 +221,20 @@ private void addLoops( List parsedOperations ) { } } } - loop.nextPosition = parsedBlock.startPosition; // Jump position for Continue - loop.endPosition = parsedBlock.nextPosition; + if( loop.endPosition < parsedBlock.nextPosition ) { + int nextPosition = parsedBlock.startPosition; // Jump position for Continue + int endPosition = parsedBlock.nextPosition; + // if a condition behind the loop points to a position inside the loop, the loop must be extended to avoid overlapping blocks. + for( int n = b + 1; n < parsedOperations.size(); n++ ) { + ParsedBlock block = parsedOperations.get( n ); + if( block.startPosition > endPosition && endPosition > block.endPosition && block.endPosition > start ) { + nextPosition = block.startPosition; + endPosition = block.nextPosition; + } + } + loop.nextPosition = nextPosition; // Jump position for Continue + loop.endPosition = endPosition; + } break; default: throw new WasmException( "Unimplemented loop code operation: " + parsedBlock.op, parsedBlock.lineNumber ); diff --git a/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java b/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java index b98f4321..a6f25119 100644 --- a/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java +++ b/test/de/inetsoftware/jwebassembly/runtime/ControlFlowOperators.java @@ -59,6 +59,7 @@ public static Collection data() { addParam( list, script, "whileLoopInElseAfterReturn" ); addParam( list, script, "whileLoopAfterIfWithReturn" ); addParam( list, script, "whileLoopInsideLoop" ); + addParam( list, script, "whileTrueInsideWhileTrue" ); addParam( list, script, "forLoop" ); addParam( list, script, "conditionalOperator" ); addParam( list, script, "conditionalOperator2" ); @@ -489,6 +490,26 @@ public static int whileLoopInsideLoop() { } } + @Export + static int whileTrueInsideWhileTrue() { + int sw = 1; + while( true ) { + if( sw != 1 ) { + sw++; + break; + } + sub: while( true ) { + if( sw == 1 ) { + sw = 2; + break; + } else { + sw = 17; + } + } + } + return sw; + } + @Export static int forLoop() { int a = 0;