From 30efaaed9507981a9c051096e3665c79d0a3eeb9 Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Sat, 18 May 2019 21:37:19 +0200 Subject: [PATCH] pass virtual function index --- .../jwebassembly/binary/BinaryModuleWriter.java | 10 +++++++++- .../inetsoftware/jwebassembly/module/ModuleWriter.java | 6 ++++-- .../module/WasmCallIndirectInstruction.java | 6 ++++-- .../jwebassembly/text/TextModuleWriter.java | 8 ++++++-- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java index 616b195..9a14593 100644 --- a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java @@ -1001,8 +1001,16 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod * {@inheritDoc} */ @Override - protected void writeFunctionCallIndirect( FunctionName name ) throws IOException { + protected void writeVirtualFunctionCall( FunctionName name, int virtualFunctionIdx ) throws IOException { callIndirect = true; + codeStream.writeOpCode( STRUCT_GET ); + codeStream.writeValueType( ValueType.i32 ); + 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 ); diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java b/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java index 8a4bcdd..62d9dae 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java @@ -225,14 +225,16 @@ public abstract class ModuleWriter implements Closeable { protected abstract void writeFunctionCall( FunctionName name ) throws IOException; /** - * Write a call indirect to a function. + * Write a function call to an instance function. On the stack there must be the object. * * @param name * the function name + * @param virtualFunctionIdx + * the index of the virtual method in the object. If the value < 0 a direct call should be used. * @throws IOException * if any I/O error occur */ - protected abstract void writeFunctionCallIndirect( FunctionName name ) throws IOException; + protected abstract void writeVirtualFunctionCall( FunctionName name, int virtualFunctionIdx ) throws IOException; /** * Write a block/branch code diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java index a8a6de2..03c1fd3 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmCallIndirectInstruction.java @@ -28,6 +28,8 @@ import javax.annotation.Nonnull; */ class WasmCallIndirectInstruction extends WasmCallInstruction { + private int virtualFunctionIdx = -1; + /** * Create an instance of a function call instruction * @@ -55,10 +57,10 @@ class WasmCallIndirectInstruction extends WasmCallInstruction { */ @Override public void writeTo( @Nonnull ModuleWriter writer ) throws IOException { - if( true ) { // TODO + if( virtualFunctionIdx < 0 ) { super.writeTo( writer ); } else { - writer.writeFunctionCallIndirect( getFunctionName() ); + writer.writeVirtualFunctionCall( getFunctionName(), virtualFunctionIdx ); } } diff --git a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java index 18246e7..c1396b3 100644 --- a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java @@ -529,10 +529,14 @@ public class TextModuleWriter extends ModuleWriter { * {@inheritDoc} */ @Override - protected void writeFunctionCallIndirect( FunctionName name ) throws IOException { + protected void writeVirtualFunctionCall( FunctionName name, int virtualFunctionIdx ) throws IOException { callIndirect = true; newline( methodOutput ); - methodOutput.append( "call_indirect $" ).append( normalizeName( name ) ); + methodOutput.append( "struct.get i32 0 ;;vtable" ); // vtable is ever on position 0 + newline( methodOutput ); + methodOutput.append( "i32.load offset=" ).append( virtualFunctionIdx * 4 ); // use default alignment + newline( methodOutput ); + methodOutput.append( "call_indirect (type $" ).append( normalizeName( name ) ).append( ')' ); } /**