From d6a7ead579d288b66d466a2d4927c9e4b277bbad Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Sun, 12 Apr 2020 10:44:53 +0200 Subject: [PATCH] fix the stack inspector for catch blocks --- .../jwebassembly/module/BranchManger.java | 4 ++-- .../module/JavaMethodWasmCodeBuilder.java | 11 +++++++++-- .../jwebassembly/module/JumpInstruction.java | 13 +++++++++---- .../jwebassembly/module/WasmCodeBuilder.java | 6 ++++-- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/de/inetsoftware/jwebassembly/module/BranchManger.java b/src/de/inetsoftware/jwebassembly/module/BranchManger.java index 02a9cca..48012bc 100644 --- a/src/de/inetsoftware/jwebassembly/module/BranchManger.java +++ b/src/de/inetsoftware/jwebassembly/module/BranchManger.java @@ -117,7 +117,7 @@ class BranchManger { * the compare instruction */ void addIfOperator( int startPosition, int offset, int lineNumber, WasmNumericInstruction instr ) { - JumpInstruction jump = new JumpInstruction( startPosition + offset, 1, startPosition, lineNumber ); + JumpInstruction jump = new JumpInstruction( startPosition + offset, 1, null, startPosition, lineNumber ); instructions.add( jump ); allParsedOperations.add( new IfParsedBlock( startPosition, offset, lineNumber, instr, jump ) ); } @@ -927,7 +927,7 @@ class BranchManger { // add a "if $exception instanceof type" check to the WASM code StructType type = options.types.valueOf( tryCatch.getType().getName() ); FunctionName instanceOf = options.getInstanceOf(); - int instrPos = findIdxOfCodePos( catchPos ); + int instrPos = findIdxOfCodePos( catchPos ) + 1; WasmLoadStoreInstruction storeException = (WasmLoadStoreInstruction)instructions.get( instrPos ); int lineNumber = storeException.getLineNumber(); diff --git a/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java index 96c58d9..06b88e9 100644 --- a/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java @@ -228,7 +228,13 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder { addLoadStoreInstruction( ValueType.f64, false, byteCode.readUnsignedIndex( wide ), codePos, lineNumber ); break; case 58: // astore - addLoadStoreInstruction( ValueType.anyref, false, byteCode.readUnsignedIndex( wide ), codePos, lineNumber ); + if( branchManager.isCatch( codePos ) ) { + addJumpPlaceholder( codePos, 0, ValueType.anyref, codePos, lineNumber ); + storeType = ValueType.anyref; // for the catch there are no previous instructions + } else { + storeType = findValueTypeFromStack( 1, codePos ); + } + addLoadStoreInstruction( storeType, false, byteCode.readUnsignedIndex( wide ), codePos, lineNumber ); break; case 59: // istore_0 case 60: // istore_1 @@ -259,6 +265,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder { case 77: // astore_2 case 78: // astore_3 if( branchManager.isCatch( codePos ) ) { + addJumpPlaceholder( codePos, 0, ValueType.anyref, codePos, lineNumber ); storeType = ValueType.anyref; // for the catch there are no previous instructions } else { storeType = findValueTypeFromStack( 1, codePos ); @@ -530,7 +537,7 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder { case 167: // goto int offset = byteCode.readShort(); branchManager.addGotoOperator( codePos, offset, byteCode.getCodePosition(), lineNumber ); - addJumpPlaceholder( codePos + offset, 0, codePos, lineNumber ); // marker of the line number for the branch manager + addJumpPlaceholder( codePos + offset, 0, null, codePos, lineNumber ); // marker of the line number for the branch manager break; case 168: // jsr case 169: // ret diff --git a/src/de/inetsoftware/jwebassembly/module/JumpInstruction.java b/src/de/inetsoftware/jwebassembly/module/JumpInstruction.java index 26889ec..1b1574d 100644 --- a/src/de/inetsoftware/jwebassembly/module/JumpInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/JumpInstruction.java @@ -30,9 +30,11 @@ import de.inetsoftware.jwebassembly.wasm.AnyType; */ class JumpInstruction extends WasmInstruction { - private int jumpPos; + private int jumpPos; - private int popCount; + private int popCount; + + private AnyType pushValueType; /** * Create an instance of a nop instruction @@ -41,15 +43,18 @@ class JumpInstruction extends WasmInstruction { * the position of the jump * @param popCount * the the count of values that are removed from the stack. + * @param pushValueType + * optional type of a push value * @param javaCodePos * the code position/offset in the Java method * @param lineNumber * the line number in the Java source code */ - JumpInstruction( int jumpPos, int popCount, int javaCodePos, int lineNumber ) { + JumpInstruction( int jumpPos, int popCount, AnyType pushValueType, int javaCodePos, int lineNumber ) { super( javaCodePos, lineNumber ); this.jumpPos = jumpPos; this.popCount = popCount; + this.pushValueType = pushValueType; } /** @@ -71,7 +76,7 @@ class JumpInstruction extends WasmInstruction { * {@inheritDoc} */ AnyType getPushValueType() { - return null; + return pushValueType; } /** diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java index b83d46f..2ae92b6 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java @@ -591,13 +591,15 @@ public abstract class WasmCodeBuilder { * the position of the jump * @param popCount * the the count of values that are removed from the stack. + * @param pushValueType + * optional type of a push value * @param javaCodePos * the code position/offset in the Java method * @param lineNumber * the line number in the Java source code */ - protected void addJumpPlaceholder( int jumpPos, int popCount, int javaCodePos, int lineNumber ) { - instructions.add( new JumpInstruction( jumpPos, popCount, javaCodePos, lineNumber ) ); + protected void addJumpPlaceholder( int jumpPos, int popCount, AnyType pushValueType, int javaCodePos, int lineNumber ) { + instructions.add( new JumpInstruction( jumpPos, popCount, pushValueType, javaCodePos, lineNumber ) ); } /**