mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 18:44:47 +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.module.FunctionName;
|
||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||
import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
|
||||
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
|
||||
import de.inetsoftware.jwebassembly.module.WasmTarget;
|
||||
import de.inetsoftware.jwebassembly.sourcemap.SourceMapWriter;
|
||||
@ -442,9 +443,19 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@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();
|
||||
functionTypes.add( new StructTypeEntry( fields ) );
|
||||
functionTypes.add( new StructTypeEntry( type.getFields() ) );
|
||||
return typeId;
|
||||
}
|
||||
|
||||
|
@ -443,9 +443,14 @@ public class ModuleGenerator {
|
||||
case Struct:
|
||||
WasmStructInstruction instr = (WasmStructInstruction)instruction;
|
||||
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 ) {
|
||||
writer.writeDefaultValue( storageType.getType() );
|
||||
if( TypeManager.VTABLE == storageType.getName() ) {
|
||||
writer.writeConst( structType.getVTable(), ValueType.i32 );
|
||||
} else {
|
||||
writer.writeDefaultValue( storageType.getType() );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -17,11 +17,11 @@ package de.inetsoftware.jwebassembly.module;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
|
||||
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
||||
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
|
||||
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
|
||||
@ -47,15 +47,13 @@ public abstract class ModuleWriter implements Closeable {
|
||||
/**
|
||||
* Write a type/struct.
|
||||
*
|
||||
* @param typeName
|
||||
* the name
|
||||
* @param fields
|
||||
* the fields
|
||||
* @param type
|
||||
* the type to declare/write
|
||||
* @return type ID
|
||||
* @throws IOException
|
||||
* 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
|
||||
|
@ -42,8 +42,9 @@ import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||
*/
|
||||
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.
|
||||
@ -110,7 +111,7 @@ public class TypeManager {
|
||||
*
|
||||
* @author Volker Berlin
|
||||
*/
|
||||
static class StructType implements AnyType {
|
||||
public static class StructType implements AnyType {
|
||||
|
||||
private final String name;
|
||||
|
||||
@ -118,7 +119,12 @@ public class TypeManager {
|
||||
|
||||
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
|
||||
@ -148,7 +154,7 @@ public class TypeManager {
|
||||
fields = new ArrayList<>();
|
||||
methods = new ArrayList<>();
|
||||
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();
|
||||
listStructFields( superClassName, functions, types, libraries );
|
||||
} else {
|
||||
fields.add( new NamedStorageType( ValueType.i32, className, ".vtable" ) );
|
||||
fields.add( new NamedStorageType( ValueType.i32, className, VTABLE ) );
|
||||
}
|
||||
|
||||
for( FieldInfo field : classFile.getFields() ) {
|
||||
@ -187,16 +193,23 @@ public class TypeManager {
|
||||
}
|
||||
|
||||
for( MethodInfo method : classFile.getMethods() ) {
|
||||
if( method.isStatic() ) {
|
||||
if( method.isStatic() || "<init>".equals( method.getName() ) ) {
|
||||
continue;
|
||||
}
|
||||
FunctionName funcName = new FunctionName( method );
|
||||
if( functions.needToWrite( funcName ) ) {
|
||||
String signature = funcName.methodName + funcName.signature;
|
||||
int idx = methods.indexOf( signature );
|
||||
if( idx < 0 ) {
|
||||
idx = methods.size();
|
||||
methods.add( signature );
|
||||
int idx = 0;
|
||||
// search if the method is already in our list
|
||||
for( ; idx < methods.size(); idx++ ) {
|
||||
FunctionName func = methods.get( idx );
|
||||
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 );
|
||||
}
|
||||
@ -227,6 +240,34 @@ public class TypeManager {
|
||||
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}
|
||||
*/
|
||||
|
@ -21,7 +21,6 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
@ -31,6 +30,7 @@ import de.inetsoftware.jwebassembly.JWebAssembly;
|
||||
import de.inetsoftware.jwebassembly.WasmException;
|
||||
import de.inetsoftware.jwebassembly.module.FunctionName;
|
||||
import de.inetsoftware.jwebassembly.module.ModuleWriter;
|
||||
import de.inetsoftware.jwebassembly.module.TypeManager.StructType;
|
||||
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
|
||||
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
||||
import de.inetsoftware.jwebassembly.wasm.ArrayOperator;
|
||||
@ -148,14 +148,24 @@ public class TextModuleWriter extends ModuleWriter {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@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;
|
||||
inset = 1;
|
||||
newline( output );
|
||||
typeName = normalizeName( typeName );
|
||||
String typeName = normalizeName( type.getName() );
|
||||
output.append( "(type $" ).append( typeName ).append( " (struct" );
|
||||
inset++;
|
||||
for( NamedStorageType field : fields ) {
|
||||
for( NamedStorageType field : type.getFields() ) {
|
||||
newline( output );
|
||||
output.append( "(field" );
|
||||
if( debugNames && field.getName() != null ) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user