From d4a22141310340d1108fcc956a32c57b5c680ed8 Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Fri, 13 Sep 2019 20:04:03 +0200 Subject: [PATCH] Move duplicated code from implementations of writeVirtualFunctionCall() into the caller WasmCallIndirectInstruction --- .../binary/BinaryModuleWriter.java | 26 ++++++++----------- .../jwebassembly/module/ModuleWriter.java | 16 ++++++++---- .../module/WasmCallIndirectInstruction.java | 12 ++++++++- .../jwebassembly/text/TextModuleWriter.java | 20 +++++++------- 4 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java index 5b6461c..4ecf8de 100644 --- a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java @@ -19,7 +19,6 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -28,7 +27,6 @@ import java.util.Map.Entry; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import de.inetsoftware.jwebassembly.JWebAssembly; import de.inetsoftware.jwebassembly.WasmException; import de.inetsoftware.jwebassembly.module.FunctionName; import de.inetsoftware.jwebassembly.module.ModuleWriter; @@ -1149,21 +1147,9 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod * {@inheritDoc} */ @Override - protected void writeVirtualFunctionCall( FunctionName name, AnyType type, int virtualFunctionIdx, int tempVarIdx ) throws IOException { + protected void writeVirtualFunctionCall( FunctionName name, AnyType type ) throws IOException { callIndirect = true; - // duplicate this on the stack - writeLocal( VariableOperator.tee, tempVarIdx ); - writeLocal( VariableOperator.get, tempVarIdx ); - - codeStream.writeOpCode( STRUCT_GET ); - codeStream.writeValueType( type ); - codeStream.writeVaruint32( 0 ); // vtable is ever on position 0 - - codeStream.writeOpCode( I32_LOAD ); - codeStream.write( 2 ); // 32 alignment - codeStream.writeVaruint32( virtualFunctionIdx * 4 ); - Function func = getFunction( name ); codeStream.writeOpCode( CALL_INDIRECT ); codeStream.writeVaruint32( func.typeId ); @@ -1327,4 +1313,14 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod codeStream.writeVaruint32( idx ); } } + + /** + * {@inheritDoc} + */ + @Override + protected void writeLoadI32( int offset ) throws IOException { + codeStream.writeOpCode( I32_LOAD ); + codeStream.write( 2 ); // 32 alignment + codeStream.writeVaruint32( offset ); + } } diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java b/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java index 74f5460..d5eb6e4 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java @@ -258,14 +258,10 @@ public abstract class ModuleWriter implements Closeable { * the function name * @param type * the base type that should be called - * @param virtualFunctionIdx - * the index of the virtual method in the object. If the value < 0 a direct call should be used. - * @param tempVarIdx - * the index of a temporary variable of type "type" to duplicate "this" * @throws IOException * if any I/O error occur */ - protected abstract void writeVirtualFunctionCall( FunctionName name, AnyType type, int virtualFunctionIdx, int tempVarIdx ) throws IOException; + protected abstract void writeVirtualFunctionCall( FunctionName name, AnyType type ) throws IOException; /** * Write a block/branch code @@ -306,4 +302,14 @@ public abstract class ModuleWriter implements Closeable { * if any I/O error occur */ protected abstract void writeStructOperator( StructOperator op, AnyType type, NamedStorageType fieldName, int idx ) throws IOException; + + /** + * Write a i32.load operation from linear memory + * + * @param offset + * the offset into the memory. Should be ideally a factor of 4. + * @throws IOException + * if any I/O error occur + */ + protected abstract void writeLoadI32( int offset ) throws IOException; } diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java index 53b43c2..7335359 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java @@ -21,6 +21,9 @@ import java.io.IOException; import javax.annotation.Nonnull; import de.inetsoftware.jwebassembly.module.TypeManager.StructType; +import de.inetsoftware.jwebassembly.wasm.NamedStorageType; +import de.inetsoftware.jwebassembly.wasm.StructOperator; +import de.inetsoftware.jwebassembly.wasm.VariableOperator; /** * WasmInstruction for a function call. @@ -89,7 +92,14 @@ class WasmCallIndirectInstruction extends WasmCallInstruction { super.writeTo( writer ); } else { int tempVarIdx = localVariables.get( tempVar, getCodePosition() ); - writer.writeVirtualFunctionCall( getFunctionName(), type, virtualFunctionIdx, tempVarIdx ); + + // duplicate this on the stack + writer.writeLocal( VariableOperator.tee, tempVarIdx ); + writer.writeLocal( VariableOperator.get, tempVarIdx ); + + writer.writeStructOperator( StructOperator.GET, type, new NamedStorageType( type, "", "vtable" ), 0 ); // vtable is ever on position 0 + writer.writeLoadI32( virtualFunctionIdx * 4 ); + writer.writeVirtualFunctionCall( getFunctionName(), type ); } } diff --git a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java index 6da0374..c059d38 100644 --- a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java @@ -656,18 +656,9 @@ public class TextModuleWriter extends ModuleWriter { * {@inheritDoc} */ @Override - protected void writeVirtualFunctionCall( FunctionName name, AnyType type, int virtualFunctionIdx, int tempVarIdx ) throws IOException { + protected void writeVirtualFunctionCall( FunctionName name, AnyType type ) throws IOException { callIndirect = true; - // duplicate this on the stack - writeLocal( VariableOperator.tee, tempVarIdx ); - writeLocal( VariableOperator.get, tempVarIdx ); - - newline( methodOutput ); - methodOutput.append( "struct.get " ).append( normalizeName( type.toString() ) ).append( " 0 ;;vtable" ); // vtable is ever on position 0 - newline( methodOutput ); - methodOutput.append( "i32.load offset=" ).append( virtualFunctionIdx * 4 ); // use default alignment - newline( methodOutput ); if(spiderMonkey) methodOutput.append( "call_indirect $t" ).append( functions.get( name.signatureName ).typeId ); // https://bugzilla.mozilla.org/show_bug.cgi?id=1556779 else @@ -820,4 +811,13 @@ public class TextModuleWriter extends ModuleWriter { methodOutput.append( ' ' ).append( idx ).append( " ;; $" ).append( normalizeName( fieldName.getName() ) ); } } + + /** + * {@inheritDoc} + */ + @Override + protected void writeLoadI32( int offset ) throws IOException { + newline( methodOutput ); + methodOutput.append( "i32.load offset=" ).append( offset ); // use default alignment + } }