write itable into the memory; implement interface instruction; WIP

This commit is contained in:
Volker Berlin 2020-05-08 22:24:57 +02:00
parent 9416628961
commit e30deb315d
2 changed files with 35 additions and 10 deletions

View File

@ -24,6 +24,7 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import java.util.function.ToIntFunction; import java.util.function.ToIntFunction;
@ -315,6 +316,7 @@ public class TypeManager {
+ " local.set 3" // set $table + " local.set 3" // set $table
+ " br 0 " // + " br 0 " //
+ "end " // + "end " //
+ "unreachable" // should never reach
, valueOf( "java/lang/Object" ), ValueType.i32, ValueType.i32, null, ValueType.i32 ); // THIS, classIndex, virtualfunctionIndex, returns functionIndex , valueOf( "java/lang/Object" ), ValueType.i32, ValueType.i32, null, ValueType.i32 ); // THIS, classIndex, virtualfunctionIndex, returns functionIndex
} }
@ -400,6 +402,8 @@ public class TypeManager {
private Set<StructType> instanceOFs; private Set<StructType> instanceOFs;
private Map<StructType,List<FunctionName>> interfaceMethods;
/** /**
* The offset to the vtable in the data section. * The offset to the vtable in the data section.
*/ */
@ -448,8 +452,9 @@ public class TypeManager {
methods = new ArrayList<>(); methods = new ArrayList<>();
instanceOFs = new LinkedHashSet<>(); // remembers the order from bottom to top class. instanceOFs = new LinkedHashSet<>(); // remembers the order from bottom to top class.
instanceOFs.add( this ); instanceOFs.add( this );
HashSet<String> allNeededFields = new HashSet<>(); interfaceMethods = new LinkedHashMap<>();
if( classIndex >= PRIMITIVE_CLASSES.length ) { if( classIndex >= PRIMITIVE_CLASSES.length ) {
HashSet<String> allNeededFields = new HashSet<>();
listStructFields( name, functions, types, classFileLoader, allNeededFields ); listStructFields( name, functions, types, classFileLoader, allNeededFields );
} }
} }
@ -578,17 +583,25 @@ public class TypeManager {
for( ConstantClass interClass : classFile.getInterfaces() ) { for( ConstantClass interClass : classFile.getInterfaces() ) {
String interName = interClass.getName(); String interName = interClass.getName();
StructType type = types.structTypes.get( interName ); StructType type = types.structTypes.get( interName );
if( type != null ) { if( type == null ) {
// add all interfaces to the instanceof set continue;
instanceOFs.add( type );
} }
// add all used interfaces to the instanceof set
instanceOFs.add( type );
List<FunctionName> iMethods = interfaceMethods.get( type );
ClassFile interClassFile = classFileLoader.get( interName ); ClassFile interClassFile = classFileLoader.get( interName );
for( MethodInfo interMethod : interClassFile.getMethods() ) { for( MethodInfo interMethod : interClassFile.getMethods() ) {
FunctionName funcName = new FunctionName( interMethod ); FunctionName funcName = new FunctionName( interMethod );
if( functions.isUsed( funcName ) ) { if( functions.isUsed( funcName ) ) {
MethodInfo method = classFile.getMethod( funcName.methodName, funcName.signature ); MethodInfo method = classFile.getMethod( funcName.methodName, funcName.signature );
if( method != null ) { if( method != null ) {
functions.markAsNeeded( new FunctionName( method ) ); FunctionName methodName = new FunctionName( method );
functions.markAsNeeded( methodName );
if( iMethods == null ) {
interfaceMethods.put( type, iMethods = new ArrayList<>() );
}
iMethods.add( methodName );
} }
} }
} }
@ -701,7 +714,16 @@ public class TypeManager {
// header position TYPE_DESCRIPTION_INTERFACE_OFFSET // header position TYPE_DESCRIPTION_INTERFACE_OFFSET
header.writeInt32( data.size() + VTABLE_FIRST_FUNCTION_INDEX * 4 ); // offset of interface calls header.writeInt32( data.size() + VTABLE_FIRST_FUNCTION_INDEX * 4 ); // offset of interface calls
//TODO interface calls for( Entry<StructType, List<FunctionName>> entry : interfaceMethods.entrySet() ) {
data.writeInt32( entry.getKey().getClassIndex() );
List<FunctionName> iMethods = entry.getValue();
int nextClassPosition = data.size() + 4 * (1 + iMethods.size());
data.writeInt32( nextClassPosition );
for( FunctionName funcName : iMethods ) {
int functIdx = getFunctionsID.applyAsInt( funcName );
data.writeInt32( functIdx );
}
}
data.writeInt32( 0 ); // no more interface in itable data.writeInt32( 0 ); // no more interface in itable
// header position TYPE_DESCRIPTION_INSTANCEOF_OFFSET // header position TYPE_DESCRIPTION_INSTANCEOF_OFFSET

View File

@ -23,6 +23,7 @@ import javax.annotation.Nonnull;
import de.inetsoftware.jwebassembly.WasmException; import de.inetsoftware.jwebassembly.WasmException;
import de.inetsoftware.jwebassembly.module.TypeManager.StructType; import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
import de.inetsoftware.jwebassembly.wasm.ValueType; import de.inetsoftware.jwebassembly.wasm.ValueType;
import de.inetsoftware.jwebassembly.wasm.VariableOperator;
/** /**
* WasmInstruction for a function call. * WasmInstruction for a function call.
@ -76,13 +77,15 @@ class WasmCallInterfaceInstruction extends WasmCallIndirectInstruction {
FunctionName name = getFunctionName(); FunctionName name = getFunctionName();
StructType type = getThisType(); StructType type = getThisType();
int classIndex = type.getClassIndex(); int classIndex = type.getClassIndex();
int interfaceFunctionIdx = options.functions.getFunctionIndex( name );
//writer.writeLocal( VariableOperator.get, tempVarIdx ); // duplicate this on the stack // duplicate this on the stack
writer.writeLocal( VariableOperator.get, getVariableIndexOfThis() );
writer.writeConst( classIndex, ValueType.i32 ); writer.writeConst( classIndex, ValueType.i32 );
//writer.writeConst( functionIndex, ValueType.i32 ); writer.writeConst( interfaceFunctionIdx * 4, ValueType.i32 );
//writer.writeFunctionCall( callInterface ); // parameters: this, classIndex, functionIndex writer.writeFunctionCall( options.getCallInterface(), null ); // parameters: this, classIndex, functionIndex
//writer.writeVirtualFunctionCall( name, type ); writer.writeVirtualFunctionCall( name, type );
throw new WasmException( "Interface calls are not supported.", getLineNumber() ); throw new WasmException( "Interface calls are not supported.", getLineNumber() );
} }
} }