From 86defc379282dd5c7fba90ea65b14744d3ac6b45 Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Sat, 9 Mar 2019 13:22:40 +0100 Subject: [PATCH] improve exception handling --- .../jwebassembly/module/BranchManger.java | 24 ++++++--- .../inetsoftware/jwebassembly/WasmRule.java | 2 +- .../jwebassembly/runtime/Exceptions.java | 54 +++++++++++++++++-- 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/src/de/inetsoftware/jwebassembly/module/BranchManger.java b/src/de/inetsoftware/jwebassembly/module/BranchManger.java index 0d119ec..46a4650 100644 --- a/src/de/inetsoftware/jwebassembly/module/BranchManger.java +++ b/src/de/inetsoftware/jwebassembly/module/BranchManger.java @@ -332,7 +332,7 @@ class BranchManger { */ private int calculateBreakDeep( BranchNode parent, int endPos ) { int deep = -1; - while( parent != null && parent.endPos == endPos ) { + while( parent != null && parent.endPos == endPos && parent.data == null ) { deep++; parent = parent.parent; } @@ -630,12 +630,13 @@ class BranchManger { private void calculateTry( BranchNode parent, TryCatchParsedBlock tryBlock, List parsedOperations ) { TryCatchFinally tryCatch = tryBlock.tryCatch; - int gotoPos = tryCatch.getEnd(); // alternativ we can use tryCatch.getHandler()-3 + int gotoPos = tryCatch.getHandler()-3; //tryCatch.getEnd() points some time bevore and some time after the goto int endPos = parent.endPos; - for( int i = 0; i < parsedOperations.size(); i++ ) { - ParsedBlock parsedBlock = parsedOperations.get( i ); + int idx; + for( idx = 0; idx < parsedOperations.size(); idx++ ) { + ParsedBlock parsedBlock = parsedOperations.get( idx ); if( parsedBlock.startPosition == gotoPos && parsedBlock.op == JavaBlockOperator.GOTO && parsedBlock.startPosition < parsedBlock.endPosition ) { - parsedOperations.remove( i ); + parsedOperations.remove( idx ); endPos = parsedBlock.endPosition; break; } @@ -653,12 +654,19 @@ class BranchManger { parent.add( node ); parent = node; - parent.add( new BranchNode( startPos, catchPos, WasmBlockOperator.TRY, null ) ); + BranchNode tryNode = new BranchNode( startPos, catchPos, WasmBlockOperator.TRY, null ); + parent.add( tryNode ); + calculate( tryNode, parsedOperations.subList( 0, idx ) ); + BranchNode catchNode = new BranchNode( catchPos, catchPos, WasmBlockOperator.CATCH, WasmBlockOperator.END ); parent.add( catchNode ); - catchNode.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.BR_ON_EXN, null, 1 ) ); - catchNode.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.RETHROW, null ) ); + if( tryCatch.isFinally() ) { + catchNode.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.DROP, null ) ); + } else { + catchNode.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.BR_ON_EXN, null, 1 ) ); + catchNode.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.RETHROW, null ) ); + } parent.add( new BranchNode( catchPos, catchPos, WasmBlockOperator.BR, null, 1 ) ); } diff --git a/test/de/inetsoftware/jwebassembly/WasmRule.java b/test/de/inetsoftware/jwebassembly/WasmRule.java index 023a8ac..2379f95 100644 --- a/test/de/inetsoftware/jwebassembly/WasmRule.java +++ b/test/de/inetsoftware/jwebassembly/WasmRule.java @@ -180,7 +180,7 @@ public class WasmRule extends TemporaryFolder { File wat2WasmFile = new File( getRoot(), "wat2Wasm.wasm" ); // the wat2wasm tool ProcessBuilder processBuilder = - new ProcessBuilder( cmd, watFile.toString(), "-o", wat2WasmFile.toString(), "--enable-saturating-float-to-int", "--enable-sign-extension", "--enable-multi-value", "--enable-exceptions" ); + new ProcessBuilder( cmd, watFile.toString(), "-o", wat2WasmFile.toString(), "--enable-saturating-float-to-int", "--enable-sign-extension", "--enable-multi-value", "--enable-exceptions", "--enable-reference-types" ); execute( processBuilder ); // create the node script diff --git a/test/de/inetsoftware/jwebassembly/runtime/Exceptions.java b/test/de/inetsoftware/jwebassembly/runtime/Exceptions.java index ecea257..096b3d9 100644 --- a/test/de/inetsoftware/jwebassembly/runtime/Exceptions.java +++ b/test/de/inetsoftware/jwebassembly/runtime/Exceptions.java @@ -42,6 +42,10 @@ public class Exceptions extends AbstractBaseTest { for( ScriptEngine[] val : ScriptEngine.testParams() ) { ScriptEngine script = val[0]; addParam( list, script, "simple" ); + addParam( list, script, "direct" ); + addParam( list, script, "rethrow" ); + addParam( list, script, "tryFinally" ); + addParam( list, script, "complex" ); } return list; } @@ -56,10 +60,6 @@ public class Exceptions extends AbstractBaseTest { @Export static int simple() { - return 1; - } - - static int simple2() { int r; try { r = 5 / 0; @@ -77,5 +77,51 @@ public class Exceptions extends AbstractBaseTest { return 2; } } + + @Export + static int rethrow() { + try { + return 5 / 0; + } catch(Exception ex ) { + throw ex; + } + } + + @Export + static int tryFinally() { + int v = 1; + try { + v++; + v = 5 / 0; + } finally { + v++; + return v; + } + } + + @Export + static int complex() { + int v = 1; + try { + if( v == 1 ) { + v++; + v = divNull(); + } else { + v += 2; + } + } finally { + v++; + return v; + } + } + + private static int divNull() { + return 5 / 0; + } +// @Export +// static int npe() { +// Object obj = new NullPointerException(); +// return 3; +// } } }