Move duplicated code from implementations of writeVirtualFunctionCall() into the caller WasmCallIndirectInstruction

This commit is contained in:
Volker Berlin 2019-09-13 20:04:03 +02:00
parent 88b925fbde
commit d4a2214131
4 changed files with 43 additions and 31 deletions

View File

@ -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 );
}
}

View File

@ -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;
}

View File

@ -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 );
}
}

View File

@ -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
}
}