mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
write the vtable of objects to the data section. Use the vtable offset into the data section in the new operation of objects.
This commit is contained in:
parent
6da4a93918
commit
1ee77584d9
@ -31,6 +31,7 @@ import javax.annotation.Nullable;
|
|||||||
import de.inetsoftware.jwebassembly.JWebAssembly;
|
import de.inetsoftware.jwebassembly.JWebAssembly;
|
||||||
import de.inetsoftware.jwebassembly.module.FunctionName;
|
import de.inetsoftware.jwebassembly.module.FunctionName;
|
||||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||||
|
import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
|
||||||
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
|
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
|
||||||
import de.inetsoftware.jwebassembly.module.WasmTarget;
|
import de.inetsoftware.jwebassembly.module.WasmTarget;
|
||||||
import de.inetsoftware.jwebassembly.sourcemap.SourceMapWriter;
|
import de.inetsoftware.jwebassembly.sourcemap.SourceMapWriter;
|
||||||
@ -442,9 +443,19 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected int writeStruct( String typeName, List<NamedStorageType> fields ) throws IOException {
|
protected int writeStructType( StructType type ) throws IOException {
|
||||||
|
type.setVTable( dataStream.size() );
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
int typeId = functionTypes.size();
|
int typeId = functionTypes.size();
|
||||||
functionTypes.add( new StructTypeEntry( fields ) );
|
functionTypes.add( new StructTypeEntry( type.getFields() ) );
|
||||||
return typeId;
|
return typeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -443,9 +443,14 @@ public class ModuleGenerator {
|
|||||||
case Struct:
|
case Struct:
|
||||||
WasmStructInstruction instr = (WasmStructInstruction)instruction;
|
WasmStructInstruction instr = (WasmStructInstruction)instruction;
|
||||||
if( instr.getOperator() == StructOperator.NEW_DEFAULT ) {
|
if( instr.getOperator() == StructOperator.NEW_DEFAULT ) {
|
||||||
List<NamedStorageType> list = instr.getStructType().getFields();
|
StructType structType = instr.getStructType();
|
||||||
|
List<NamedStorageType> list = structType.getFields();
|
||||||
for( NamedStorageType storageType : list ) {
|
for( NamedStorageType storageType : list ) {
|
||||||
writer.writeDefaultValue( storageType.getType() );
|
if( TypeManager.VTABLE == storageType.getName() ) {
|
||||||
|
writer.writeConst( structType.getVTable(), ValueType.i32 );
|
||||||
|
} else {
|
||||||
|
writer.writeDefaultValue( storageType.getType() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -17,11 +17,11 @@ package de.inetsoftware.jwebassembly.module;
|
|||||||
|
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
|
||||||
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
||||||
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
|
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
|
||||||
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
|
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
|
||||||
@ -47,15 +47,13 @@ public abstract class ModuleWriter implements Closeable {
|
|||||||
/**
|
/**
|
||||||
* Write a type/struct.
|
* Write a type/struct.
|
||||||
*
|
*
|
||||||
* @param typeName
|
* @param type
|
||||||
* the name
|
* the type to declare/write
|
||||||
* @param fields
|
|
||||||
* the fields
|
|
||||||
* @return type ID
|
* @return type ID
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if any I/O error occur
|
* if any I/O error occur
|
||||||
*/
|
*/
|
||||||
protected abstract int writeStruct( String typeName, List<NamedStorageType> fields ) throws IOException;
|
protected abstract int writeStructType( StructType type ) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark to write exceptions
|
* Mark to write exceptions
|
||||||
|
@ -42,8 +42,9 @@ import de.inetsoftware.jwebassembly.wasm.ValueType;
|
|||||||
*/
|
*/
|
||||||
public class TypeManager {
|
public class TypeManager {
|
||||||
|
|
||||||
private Map<String, StructType> map = new LinkedHashMap<>();
|
static final String VTABLE = ".vtable";
|
||||||
|
|
||||||
|
private Map<String, StructType> map = new LinkedHashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finish the prepare and write the types. Now no new types and functions should be added.
|
* Finish the prepare and write the types. Now no new types and functions should be added.
|
||||||
@ -110,7 +111,7 @@ public class TypeManager {
|
|||||||
*
|
*
|
||||||
* @author Volker Berlin
|
* @author Volker Berlin
|
||||||
*/
|
*/
|
||||||
static class StructType implements AnyType {
|
public static class StructType implements AnyType {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
@ -118,7 +119,12 @@ public class TypeManager {
|
|||||||
|
|
||||||
private List<NamedStorageType> fields;
|
private List<NamedStorageType> fields;
|
||||||
|
|
||||||
private List<String> methods;
|
private List<FunctionName> methods;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The offset to the vtable in the data section.
|
||||||
|
*/
|
||||||
|
private int vtableOffset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a reference to type
|
* Create a reference to type
|
||||||
@ -148,7 +154,7 @@ public class TypeManager {
|
|||||||
fields = new ArrayList<>();
|
fields = new ArrayList<>();
|
||||||
methods = new ArrayList<>();
|
methods = new ArrayList<>();
|
||||||
listStructFields( name, functions, types, libraries );
|
listStructFields( name, functions, types, libraries );
|
||||||
code = writer.writeStruct( name, fields );
|
code = writer.writeStructType( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -176,7 +182,7 @@ public class TypeManager {
|
|||||||
String superClassName = superClass.getName();
|
String superClassName = superClass.getName();
|
||||||
listStructFields( superClassName, functions, types, libraries );
|
listStructFields( superClassName, functions, types, libraries );
|
||||||
} else {
|
} else {
|
||||||
fields.add( new NamedStorageType( ValueType.i32, className, ".vtable" ) );
|
fields.add( new NamedStorageType( ValueType.i32, className, VTABLE ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( FieldInfo field : classFile.getFields() ) {
|
for( FieldInfo field : classFile.getFields() ) {
|
||||||
@ -187,16 +193,23 @@ public class TypeManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for( MethodInfo method : classFile.getMethods() ) {
|
for( MethodInfo method : classFile.getMethods() ) {
|
||||||
if( method.isStatic() ) {
|
if( method.isStatic() || "<init>".equals( method.getName() ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
FunctionName funcName = new FunctionName( method );
|
FunctionName funcName = new FunctionName( method );
|
||||||
if( functions.needToWrite( funcName ) ) {
|
if( functions.needToWrite( funcName ) ) {
|
||||||
String signature = funcName.methodName + funcName.signature;
|
int idx = 0;
|
||||||
int idx = methods.indexOf( signature );
|
// search if the method is already in our list
|
||||||
if( idx < 0 ) {
|
for( ; idx < methods.size(); idx++ ) {
|
||||||
idx = methods.size();
|
FunctionName func = methods.get( idx );
|
||||||
methods.add( signature );
|
if( func.methodName.equals( funcName.methodName ) && func.signature.equals( funcName.signature ) ) {
|
||||||
|
methods.set( idx, funcName ); // use the override method
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( idx == methods.size() ) {
|
||||||
|
// if a new method
|
||||||
|
methods.add( funcName );
|
||||||
}
|
}
|
||||||
functions.setFunctionIndex( funcName, idx );
|
functions.setFunctionIndex( funcName, idx );
|
||||||
}
|
}
|
||||||
@ -227,6 +240,34 @@ public class TypeManager {
|
|||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the virtual function/methods
|
||||||
|
*
|
||||||
|
* @return the methods
|
||||||
|
*/
|
||||||
|
public List<FunctionName> getMethods() {
|
||||||
|
return methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the offset of the vtable in the data section
|
||||||
|
*
|
||||||
|
* @param vtableOffset
|
||||||
|
* the offset
|
||||||
|
*/
|
||||||
|
public void setVTable( int vtableOffset ) {
|
||||||
|
this.vtableOffset = vtableOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the vtable offset.
|
||||||
|
*
|
||||||
|
* @return the offset
|
||||||
|
*/
|
||||||
|
public int getVTable() {
|
||||||
|
return this.vtableOffset;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
|
@ -21,7 +21,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
@ -31,6 +30,7 @@ import de.inetsoftware.jwebassembly.JWebAssembly;
|
|||||||
import de.inetsoftware.jwebassembly.WasmException;
|
import de.inetsoftware.jwebassembly.WasmException;
|
||||||
import de.inetsoftware.jwebassembly.module.FunctionName;
|
import de.inetsoftware.jwebassembly.module.FunctionName;
|
||||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||||
|
import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
|
||||||
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
|
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
|
||||||
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
||||||
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
|
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
|
||||||
@ -148,14 +148,24 @@ public class TextModuleWriter extends ModuleWriter {
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected int writeStruct( String typeName, List<NamedStorageType> fields ) throws IOException {
|
protected int writeStructType( StructType type ) throws IOException {
|
||||||
|
type.setVTable( dataStream.size() );
|
||||||
|
for( FunctionName funcName : type.getMethods() ) {
|
||||||
|
int functIdx = functions.get( funcName.signatureName );
|
||||||
|
// little-endian byte order
|
||||||
|
dataStream.write( functIdx >>> 0 );
|
||||||
|
dataStream.write( functIdx >>> 8 );
|
||||||
|
dataStream.write( functIdx >>> 16 );
|
||||||
|
dataStream.write( functIdx >>> 24 );
|
||||||
|
}
|
||||||
|
|
||||||
int oldInset = inset;
|
int oldInset = inset;
|
||||||
inset = 1;
|
inset = 1;
|
||||||
newline( output );
|
newline( output );
|
||||||
typeName = normalizeName( typeName );
|
String typeName = normalizeName( type.getName() );
|
||||||
output.append( "(type $" ).append( typeName ).append( " (struct" );
|
output.append( "(type $" ).append( typeName ).append( " (struct" );
|
||||||
inset++;
|
inset++;
|
||||||
for( NamedStorageType field : fields ) {
|
for( NamedStorageType field : type.getFields() ) {
|
||||||
newline( output );
|
newline( output );
|
||||||
output.append( "(field" );
|
output.append( "(field" );
|
||||||
if( debugNames && field.getName() != null ) {
|
if( debugNames && field.getName() != null ) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user