From f15fb1cdf9eab2cc460f046ac873cffaa4a642d1 Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Sat, 25 Apr 2020 19:31:30 +0200 Subject: [PATCH] implements dup_x1 instruction --- .../module/JavaMethodWasmCodeBuilder.java | 4 ++- .../jwebassembly/module/WasmCodeBuilder.java | 27 +++++++++++++++++++ .../jwebassembly/runtime/StructsGC.java | 5 ++-- .../jwebassembly/runtime/StructsNonGC.java | 6 ++--- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java index 32cb25a..e03c4cc 100644 --- a/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java @@ -306,8 +306,10 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder { addDupInstruction( codePos, lineNumber ); break; case 90: // dup_x1 - case 91: // dup_x2 case 93: // dup2_x1 + addDupX1Instruction( codePos, lineNumber ); + break; + case 91: // dup_x2 case 94: // dup2_x2 case 95: // swap // can be do with functions with more as one return value in future WASM standard diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java index 5db6f8c..3af6158 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java @@ -333,6 +333,33 @@ public abstract class WasmCodeBuilder { } } + /** + * Simulate the dup_x1 Java byte code instruction.

+ * + * ..., value2, value1 → ..., value1, value2, value1 + * + * @param javaCodePos + * the code position/offset in the Java method + * @param lineNumber + * the line number in the Java source code + */ + protected void addDupX1Instruction( int javaCodePos, int lineNumber ) { + AnyType type1 = findValueTypeFromStack( 1, javaCodePos ); + AnyType type2 = findValueTypeFromStack( 2, javaCodePos ); + + int varIndex1 = getTempVariable( type1, javaCodePos, javaCodePos + 1 ); + int varIndex2 = getTempVariable( type2, 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 ) ); + + // 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, 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/StructsGC.java b/test/de/inetsoftware/jwebassembly/runtime/StructsGC.java index 1d44f7b..e85d766 100644 --- a/test/de/inetsoftware/jwebassembly/runtime/StructsGC.java +++ b/test/de/inetsoftware/jwebassembly/runtime/StructsGC.java @@ -132,9 +132,8 @@ public class StructsGC extends AbstractBaseTest { static int multipleAssign() { Abc2 val = new Abc2(); for( int i = 0; i < 1_000; i++ ) { - val.a = 42; - // TODO - //val = val.abc = new Abc2(); + val = val.abc = new Abc2(); + val.a = i; } return val.a; } diff --git a/test/de/inetsoftware/jwebassembly/runtime/StructsNonGC.java b/test/de/inetsoftware/jwebassembly/runtime/StructsNonGC.java index 79804f0..3ed718d 100644 --- a/test/de/inetsoftware/jwebassembly/runtime/StructsNonGC.java +++ b/test/de/inetsoftware/jwebassembly/runtime/StructsNonGC.java @@ -26,6 +26,7 @@ import org.junit.runners.Parameterized.Parameters; import de.inetsoftware.jwebassembly.ScriptEngine; import de.inetsoftware.jwebassembly.WasmRule; import de.inetsoftware.jwebassembly.api.annotation.Export; +import de.inetsoftware.jwebassembly.runtime.StructsGC.Abc2; import de.inetsoftware.jwebassembly.web.JSObject; public class StructsNonGC extends AbstractBaseTest { @@ -140,9 +141,8 @@ public class StructsNonGC extends AbstractBaseTest { static int multipleAssign() { Abc2 val = new Abc2(); for( int i = 0; i < 1_000; i++ ) { - val.a = 42; - // TODO - //val = val.abc = new Abc2(); + val = val.abc = new Abc2(); + val.a = i; } return val.a; }