From 11f338eea86cd84b1d58f5fe585251f2b041cb03 Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Sat, 25 Apr 2020 22:22:18 +0200 Subject: [PATCH] implements dup_x2 instruction --- .../module/JavaMethodWasmCodeBuilder.java | 5 +-- .../jwebassembly/module/WasmCodeBuilder.java | 33 ++++++++++++++++++- .../jwebassembly/runtime/ArrayOperations.java | 14 ++++++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java index e03c4cc..1caa27d 100644 --- a/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java @@ -311,9 +311,10 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder { break; case 91: // dup_x2 case 94: // dup2_x2 + addDupX2Instruction( codePos, lineNumber ); + break; case 95: // swap - // can be do with functions with more as one return value in future WASM standard - throw new WasmException( "Stack duplicate is not supported in current WASM. try to save immediate values in a local variable: " + throw new WasmException( "Stack swap is not supported in current WASM. try to save immediate values in a local variable: " + op, lineNumber ); case 96: // iadd addNumericInstruction( NumericOperator.add, ValueType.i32, codePos, lineNumber ); diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java index 3af6158..49e791e 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java @@ -348,7 +348,7 @@ public abstract class WasmCodeBuilder { AnyType type2 = findValueTypeFromStack( 2, javaCodePos ); int varIndex1 = getTempVariable( type1, javaCodePos, javaCodePos + 1 ); - int varIndex2 = getTempVariable( type2, javaCodePos, javaCodePos + 1 );; + int varIndex2 = getTempVariable( type2, javaCodePos, javaCodePos + 1 ); // save in temp variables instructions.add( new WasmLocalInstruction( VariableOperator.set, varIndex1, localVariables, javaCodePos, lineNumber ) ); @@ -360,6 +360,37 @@ public abstract class WasmCodeBuilder { instructions.add( new WasmLocalInstruction( VariableOperator.get, varIndex1, localVariables, javaCodePos, lineNumber ) ); } + /** + * Simulate the dup_x2 Java byte code instruction.

+ * + * ..., value3, value2, value1 → ..., value1, value3, value2, value1 + * + * @param javaCodePos + * the code position/offset in the Java method + * @param lineNumber + * the line number in the Java source code + */ + protected void addDupX2Instruction( int javaCodePos, int lineNumber ) { + AnyType type1 = findValueTypeFromStack( 1, javaCodePos ); + AnyType type2 = findValueTypeFromStack( 2, javaCodePos ); + AnyType type3 = findValueTypeFromStack( 3, javaCodePos ); + + int varIndex1 = getTempVariable( type1, javaCodePos, javaCodePos + 1 ); + int varIndex2 = getTempVariable( type2, javaCodePos, javaCodePos + 1 ); + int varIndex3 = getTempVariable( type3, javaCodePos, javaCodePos + 1 ); + + // save in temp variables + instructions.add( new WasmLocalInstruction( VariableOperator.set, varIndex1, localVariables, javaCodePos, lineNumber ) ); + instructions.add( new WasmLocalInstruction( VariableOperator.set, varIndex2, localVariables, javaCodePos, lineNumber ) ); + instructions.add( new WasmLocalInstruction( VariableOperator.set, varIndex3, localVariables, javaCodePos, lineNumber ) ); + + // and restore it in new order on the stack + instructions.add( new WasmLocalInstruction( VariableOperator.get, varIndex1, localVariables, javaCodePos, lineNumber ) ); + instructions.add( new WasmLocalInstruction( VariableOperator.get, varIndex3, localVariables, javaCodePos, lineNumber ) ); + instructions.add( new WasmLocalInstruction( VariableOperator.get, varIndex2, localVariables, javaCodePos, lineNumber ) ); + instructions.add( new WasmLocalInstruction( VariableOperator.get, varIndex1, localVariables, javaCodePos, lineNumber ) ); + } + /** * Add a global instruction * diff --git a/test/de/inetsoftware/jwebassembly/runtime/ArrayOperations.java b/test/de/inetsoftware/jwebassembly/runtime/ArrayOperations.java index e0967e3..6af6ab1 100644 --- a/test/de/inetsoftware/jwebassembly/runtime/ArrayOperations.java +++ b/test/de/inetsoftware/jwebassembly/runtime/ArrayOperations.java @@ -59,6 +59,7 @@ public class ArrayOperations extends AbstractBaseTest { addParam( list, script, "loopObject" ); addParam( list, script, "copyBack2Front" ); addParam( list, script, "copyFront2Back" ); + addParam( list, script, "dup_x2" ); } rule.setTestParameters( list ); return list; @@ -183,5 +184,18 @@ public class ArrayOperations extends AbstractBaseTest { crc.update( a ); return crc.getValue(); } + + @Export + static int dup_x2() { + Object[] data = {null,null,null}; + int index = 1; + Object value = null; + + if ((data[index] = value) != null) { // test for instruction dup_x2 + return 1; + } else { + return 2; + } + } } }