mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
add support for "instanceof", WIP
This commit is contained in:
parent
2ec9600d32
commit
f761e4bf44
@ -437,15 +437,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected int writeStructType( StructType type ) throws IOException {
|
protected int writeStructType( StructType type ) throws IOException {
|
||||||
type.setVTable( dataStream.size() );
|
type.writeToStream( dataStream, (funcName) -> getFunction( funcName ).id );
|
||||||
for( FunctionName funcName : type.getMethods() ) {
|
|
||||||
int functIdx = getFunction( funcName ).id;
|
|
||||||
// little-endian byte order
|
|
||||||
dataStream.write( functIdx >>> 0 );
|
|
||||||
dataStream.write( functIdx >>> 8 );
|
|
||||||
dataStream.write( functIdx >>> 16 );
|
|
||||||
dataStream.write( functIdx >>> 24 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !options.useGC() ) {
|
if( !options.useGC() ) {
|
||||||
return ValueType.anyref.getCode();
|
return ValueType.anyref.getCode();
|
||||||
|
@ -16,12 +16,16 @@
|
|||||||
*/
|
*/
|
||||||
package de.inetsoftware.jwebassembly.module;
|
package de.inetsoftware.jwebassembly.module;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.function.ToIntFunction;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
@ -34,6 +38,7 @@ import de.inetsoftware.jwebassembly.JWebAssembly;
|
|||||||
import de.inetsoftware.jwebassembly.WasmException;
|
import de.inetsoftware.jwebassembly.WasmException;
|
||||||
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
||||||
import de.inetsoftware.jwebassembly.wasm.ArrayType;
|
import de.inetsoftware.jwebassembly.wasm.ArrayType;
|
||||||
|
import de.inetsoftware.jwebassembly.wasm.LittleEndianOutputStream;
|
||||||
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
|
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
|
||||||
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||||
|
|
||||||
@ -47,6 +52,8 @@ public class TypeManager {
|
|||||||
/** name of virtual function table, start with a point for an invalid Java identifier */
|
/** name of virtual function table, start with a point for an invalid Java identifier */
|
||||||
static final String VTABLE = ".vtable";
|
static final String VTABLE = ".vtable";
|
||||||
|
|
||||||
|
private static final int VTABLE_FIRST_FUNCTION_INDEX = 2;
|
||||||
|
|
||||||
private Map<String, StructType> structTypes = new LinkedHashMap<>();
|
private Map<String, StructType> structTypes = new LinkedHashMap<>();
|
||||||
|
|
||||||
private Map<AnyType, ArrayType> arrayTypes = new LinkedHashMap<>();
|
private Map<AnyType, ArrayType> arrayTypes = new LinkedHashMap<>();
|
||||||
@ -161,6 +168,8 @@ public class TypeManager {
|
|||||||
|
|
||||||
private List<FunctionName> methods;
|
private List<FunctionName> methods;
|
||||||
|
|
||||||
|
private Set<StructType> instanceOFs;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The offset to the vtable in the data section.
|
* The offset to the vtable in the data section.
|
||||||
*/
|
*/
|
||||||
@ -207,6 +216,8 @@ public class TypeManager {
|
|||||||
JWebAssembly.LOGGER.fine( "write type: " + name );
|
JWebAssembly.LOGGER.fine( "write type: " + name );
|
||||||
fields = new ArrayList<>();
|
fields = new ArrayList<>();
|
||||||
methods = new ArrayList<>();
|
methods = new ArrayList<>();
|
||||||
|
instanceOFs = new LinkedHashSet<>(); // remembers the order from bottom to top class.
|
||||||
|
instanceOFs.add( this );
|
||||||
HashSet<String> allNeededFields = new HashSet<>();
|
HashSet<String> allNeededFields = new HashSet<>();
|
||||||
listStructFields( name, functions, types, classFileLoader, allNeededFields );
|
listStructFields( name, functions, types, classFileLoader, allNeededFields );
|
||||||
code = writer.writeStructType( this );
|
code = writer.writeStructType( this );
|
||||||
@ -244,6 +255,15 @@ public class TypeManager {
|
|||||||
StructType type = types.structTypes.get( className );
|
StructType type = types.structTypes.get( className );
|
||||||
if( type != null ) {
|
if( type != null ) {
|
||||||
allNeededFields.addAll( type.neededFields );
|
allNeededFields.addAll( type.neededFields );
|
||||||
|
instanceOFs.add( type );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add all interfaces to the instanceof
|
||||||
|
for(ConstantClass interClass : classFile.getInterfaces() ) {
|
||||||
|
StructType type = types.structTypes.get( className );
|
||||||
|
if( type != null ) {
|
||||||
|
instanceOFs.add( type );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +305,7 @@ public class TypeManager {
|
|||||||
// if a new needed method then add it
|
// if a new needed method then add it
|
||||||
methods.add( funcName );
|
methods.add( funcName );
|
||||||
}
|
}
|
||||||
functions.setFunctionIndex( funcName, idx );
|
functions.setFunctionIndex( funcName, idx + VTABLE_FIRST_FUNCTION_INDEX );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,13 +352,35 @@ public class TypeManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the offset of the vtable in the data section
|
* Write the struct/class meta data to the datastream and set the offset position.
|
||||||
*
|
*
|
||||||
* @param vtableOffset
|
* @param dataStream
|
||||||
* the offset
|
* the target stream
|
||||||
|
* @param getFunctionsID
|
||||||
|
* source for function IDs
|
||||||
|
* @throws IOException
|
||||||
|
* should never occur
|
||||||
*/
|
*/
|
||||||
public void setVTable( int vtableOffset ) {
|
public void writeToStream( ByteArrayOutputStream dataStream, ToIntFunction<FunctionName> getFunctionsID ) throws IOException {
|
||||||
this.vtableOffset = vtableOffset;
|
this.vtableOffset = dataStream.size();
|
||||||
|
|
||||||
|
LittleEndianOutputStream header = new LittleEndianOutputStream( dataStream );
|
||||||
|
LittleEndianOutputStream data = new LittleEndianOutputStream();
|
||||||
|
for( FunctionName funcName : methods ) {
|
||||||
|
int functIdx = getFunctionsID.applyAsInt( funcName );
|
||||||
|
data.writeInt32( functIdx );
|
||||||
|
}
|
||||||
|
|
||||||
|
header.writeInt32( data.size() + VTABLE_FIRST_FUNCTION_INDEX * 4 ); // offset of interface calls
|
||||||
|
//TODO interface calls
|
||||||
|
|
||||||
|
header.writeInt32( data.size() + VTABLE_FIRST_FUNCTION_INDEX * 4 ); // offset of instanceeof list
|
||||||
|
data.writeInt32( instanceOFs.size() );
|
||||||
|
for( StructType type : instanceOFs ) {
|
||||||
|
data.writeInt32( type.getClassIndex() );
|
||||||
|
}
|
||||||
|
|
||||||
|
data.writeTo( dataStream );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -186,15 +186,7 @@ public class TextModuleWriter extends ModuleWriter {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected int writeStructType( StructType type ) throws IOException {
|
protected int writeStructType( StructType type ) throws IOException {
|
||||||
type.setVTable( dataStream.size() );
|
type.writeToStream( dataStream, (funcName) -> getFunction( funcName ).id );
|
||||||
for( FunctionName funcName : type.getMethods() ) {
|
|
||||||
int functIdx = getFunction( funcName ).id;
|
|
||||||
// little-endian byte order
|
|
||||||
dataStream.write( functIdx >>> 0 );
|
|
||||||
dataStream.write( functIdx >>> 8 );
|
|
||||||
dataStream.write( functIdx >>> 16 );
|
|
||||||
dataStream.write( functIdx >>> 24 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !options.useGC() ) {
|
if( !options.useGC() ) {
|
||||||
return ValueType.anyref.getCode();
|
return ValueType.anyref.getCode();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user