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.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.ToIntFunction;
@ -315,6 +316,7 @@ public class TypeManager {
+ " local.set 3" // set $table
+ " br 0 " //
+ "end " //
+ "unreachable" // should never reach
, 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 Map<StructType,List<FunctionName>> interfaceMethods;
/**
* The offset to the vtable in the data section.
*/
@ -448,8 +452,9 @@ public class TypeManager {
methods = new ArrayList<>();
instanceOFs = new LinkedHashSet<>(); // remembers the order from bottom to top class.
instanceOFs.add( this );
HashSet<String> allNeededFields = new HashSet<>();
interfaceMethods = new LinkedHashMap<>();
if( classIndex >= PRIMITIVE_CLASSES.length ) {
HashSet<String> allNeededFields = new HashSet<>();
listStructFields( name, functions, types, classFileLoader, allNeededFields );
}
}
@ -578,17 +583,25 @@ public class TypeManager {
for( ConstantClass interClass : classFile.getInterfaces() ) {
String interName = interClass.getName();
StructType type = types.structTypes.get( interName );
if( type != null ) {
// add all interfaces to the instanceof set
instanceOFs.add( type );
if( type == null ) {
continue;
}
// add all used interfaces to the instanceof set
instanceOFs.add( type );
List<FunctionName> iMethods = interfaceMethods.get( type );
ClassFile interClassFile = classFileLoader.get( interName );
for( MethodInfo interMethod : interClassFile.getMethods() ) {
FunctionName funcName = new FunctionName( interMethod );
if( functions.isUsed( funcName ) ) {
MethodInfo method = classFile.getMethod( funcName.methodName, funcName.signature );
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.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
// 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.module.TypeManager.StructType;
import de.inetsoftware.jwebassembly.wasm.ValueType;
import de.inetsoftware.jwebassembly.wasm.VariableOperator;
/**
* WasmInstruction for a function call.
@ -76,13 +77,15 @@ class WasmCallInterfaceInstruction extends WasmCallIndirectInstruction {
FunctionName name = getFunctionName();
StructType type = getThisType();
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( functionIndex, ValueType.i32 );
//writer.writeFunctionCall( callInterface ); // parameters: this, classIndex, functionIndex
writer.writeConst( interfaceFunctionIdx * 4, ValueType.i32 );
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() );
}
}