mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-15 18:44:47 +01:00
Move the analyzing and writing of types in the TypeManager
This commit is contained in:
parent
8f09d4d04a
commit
fd43aca97b
@ -19,7 +19,6 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
@ -120,6 +119,7 @@ public class FunctionManager {
|
||||
case Needed:
|
||||
case Scanned:
|
||||
return entry.getKey();
|
||||
default:
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@ -200,27 +200,40 @@ public class FunctionManager {
|
||||
return newMethod != null ? newMethod : method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the index of a virtual function in a a type
|
||||
*
|
||||
* @param name
|
||||
* the name
|
||||
* @param functionIdx
|
||||
* the index
|
||||
*/
|
||||
void setFunctionIndex( FunctionName name, int functionIdx ) {
|
||||
getOrCreate( name ).functionIdx = functionIdx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all function names for the class.
|
||||
* Get the index of a virtual function in a a type
|
||||
*
|
||||
* @param className
|
||||
* the className
|
||||
* @return a stream with the names
|
||||
* @param name
|
||||
* the name
|
||||
* @return the index
|
||||
*/
|
||||
Stream<FunctionName> getNamesOfClass( String className ) {
|
||||
return states.keySet().stream().filter( ( name ) -> name.className.equals( className ) );
|
||||
int getFunctionIndex( FunctionName name ) {
|
||||
return getOrCreate( name ).functionIdx;
|
||||
}
|
||||
|
||||
/**
|
||||
* State of a function/method
|
||||
*/
|
||||
private static class FunctionState {
|
||||
private State state = State.None;
|
||||
private State state = State.None;
|
||||
|
||||
private MethodInfo method;
|
||||
private MethodInfo method;
|
||||
|
||||
private FunctionName alias;
|
||||
|
||||
private int functionIdx = -1;
|
||||
}
|
||||
|
||||
private static enum State {
|
||||
|
@ -22,8 +22,6 @@ import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -37,7 +35,6 @@ import javax.annotation.Nullable;
|
||||
import de.inetsoftware.classparser.ClassFile;
|
||||
import de.inetsoftware.classparser.Code;
|
||||
import de.inetsoftware.classparser.ConstantClass;
|
||||
import de.inetsoftware.classparser.FieldInfo;
|
||||
import de.inetsoftware.classparser.MethodInfo;
|
||||
import de.inetsoftware.jwebassembly.JWebAssembly;
|
||||
import de.inetsoftware.jwebassembly.WasmException;
|
||||
@ -198,7 +195,7 @@ public class ModuleGenerator {
|
||||
}
|
||||
functions.prepareFinish();
|
||||
|
||||
types.prepareFinish();
|
||||
types.prepareFinish( writer, functions, libraries );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -271,75 +268,6 @@ public class ModuleGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the struct type if not already write.
|
||||
*
|
||||
* @param type
|
||||
* the type
|
||||
* @throws IOException
|
||||
* if any I/O error occur
|
||||
*/
|
||||
private void writeStructType( StructType type ) throws IOException {
|
||||
if( type == null || type.getCode() != Integer.MAX_VALUE ) {
|
||||
return;
|
||||
}
|
||||
String className = type.getName();
|
||||
List<NamedStorageType> list = new ArrayList<>();
|
||||
listStructFields( className, list );
|
||||
|
||||
int id = writer.writeStruct( className, list );
|
||||
types.useType( type, id, list );
|
||||
for( NamedStorageType namedType : list ) {
|
||||
AnyType fieldType = namedType.getType();
|
||||
if( fieldType.getCode() == Integer.MAX_VALUE ) {
|
||||
writeStructType( (StructType)fieldType );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List the non static fields of the class and its super classes.
|
||||
*
|
||||
* @param className
|
||||
* the className
|
||||
* @param list
|
||||
* the container for the fields
|
||||
* @throws IOException
|
||||
* if any I/O error occur
|
||||
*/
|
||||
private void listStructFields( String className, List<NamedStorageType> list ) throws IOException {
|
||||
ClassFile classFile = ClassFile.get( className, libraries );
|
||||
if( classFile == null ) {
|
||||
throw new WasmException( "Missing class: " + className, -1 );
|
||||
}
|
||||
|
||||
ConstantClass superClass = classFile.getSuperClass();
|
||||
if( superClass != null ) {
|
||||
String superClassName = superClass.getName();
|
||||
listStructFields( superClassName, list );
|
||||
} else {
|
||||
list.add( new NamedStorageType( ValueType.i32, className, ".vtable" ) );
|
||||
}
|
||||
|
||||
for( FieldInfo field : classFile.getFields() ) {
|
||||
if( field.isStatic() ) {
|
||||
continue;
|
||||
}
|
||||
list.add( new NamedStorageType( className, field, types ) );
|
||||
}
|
||||
|
||||
HashMap<String,Boolean> virtualFunctions = new HashMap<>();
|
||||
functions.getNamesOfClass( className ).forEach( (name) -> {
|
||||
String methodName = name.methodName;
|
||||
Boolean virtual = virtualFunctions.get( methodName );
|
||||
if( virtual == null ) {
|
||||
virtualFunctions.put( methodName, Boolean.FALSE );
|
||||
} else {
|
||||
virtualFunctions.put( methodName, Boolean.TRUE );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate over all methods of the classFile and run the handler.
|
||||
*
|
||||
@ -513,7 +441,6 @@ public class ModuleGenerator {
|
||||
break;
|
||||
case Struct:
|
||||
WasmStructInstruction instr = (WasmStructInstruction)instruction;
|
||||
writeStructType( instr.getStructType() );
|
||||
if( instr.getOperator() == StructOperator.NEW_DEFAULT ) {
|
||||
List<NamedStorageType> list = instr.getStructType().getFields();
|
||||
for( NamedStorageType storageType : list ) {
|
||||
@ -572,7 +499,6 @@ public class ModuleGenerator {
|
||||
int paramCount = 0;
|
||||
if( !isStatic ) {
|
||||
StructType instanceType = types.valueOf( name.className );
|
||||
writeStructType( instanceType );
|
||||
writer.writeMethodParam( "param", instanceType, "this" );
|
||||
}
|
||||
Iterator<AnyType> parser = name.getSignature();
|
||||
|
@ -16,6 +16,8 @@
|
||||
*/
|
||||
package de.inetsoftware.jwebassembly.module;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -24,8 +26,14 @@ import java.util.Map;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import de.inetsoftware.classparser.ClassFile;
|
||||
import de.inetsoftware.classparser.ConstantClass;
|
||||
import de.inetsoftware.classparser.FieldInfo;
|
||||
import de.inetsoftware.classparser.MethodInfo;
|
||||
import de.inetsoftware.jwebassembly.WasmException;
|
||||
import de.inetsoftware.jwebassembly.wasm.AnyType;
|
||||
import de.inetsoftware.jwebassembly.wasm.NamedStorageType;
|
||||
import de.inetsoftware.jwebassembly.wasm.ValueType;
|
||||
|
||||
/**
|
||||
* Manage the written and to write types (classes)
|
||||
@ -38,10 +46,22 @@ public class TypeManager {
|
||||
|
||||
|
||||
/**
|
||||
* Finish the prepare. Now no new function should be added.
|
||||
* Finish the prepare and write the types. Now no new types and functions should be added.
|
||||
*
|
||||
* @param writer
|
||||
* the targets for the types
|
||||
* @param functions
|
||||
* the used functions for the vtables of the types
|
||||
* @param libraries
|
||||
* for loading the class files if not in the cache
|
||||
* @throws IOException
|
||||
* if any I/O error occur on loading or writing
|
||||
*/
|
||||
public void prepareFinish() {
|
||||
void prepareFinish( ModuleWriter writer, FunctionManager functions, ClassLoader libraries ) throws IOException {
|
||||
map = Collections.unmodifiableMap( map );
|
||||
for( StructType type : map.values() ) {
|
||||
type.writeStructType( writer, functions, this, libraries );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,6 +118,8 @@ public class TypeManager {
|
||||
|
||||
private List<NamedStorageType> fields;
|
||||
|
||||
private List<String> methods;
|
||||
|
||||
/**
|
||||
* Create a reference to type
|
||||
*
|
||||
@ -108,6 +130,79 @@ public class TypeManager {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write this struct type and initialize internal structures
|
||||
*
|
||||
* @param writer
|
||||
* the targets for the types
|
||||
* @param functions
|
||||
* the used functions for the vtables of the types
|
||||
* @param types
|
||||
* for types of fields
|
||||
* @param libraries
|
||||
* for loading the class files if not in the cache
|
||||
* @throws IOException
|
||||
* if any I/O error occur on loading or writing
|
||||
*/
|
||||
private void writeStructType( ModuleWriter writer, FunctionManager functions, TypeManager types, ClassLoader libraries ) throws IOException {
|
||||
fields = new ArrayList<>();
|
||||
methods = new ArrayList<>();
|
||||
listStructFields( name, functions, types, libraries );
|
||||
code = writer.writeStruct( name, fields );
|
||||
}
|
||||
|
||||
/**
|
||||
* List the non static fields of the class and its super classes.
|
||||
*
|
||||
* @param className
|
||||
* the className to list. because the recursion this must not the name of this class
|
||||
* @param functions
|
||||
* the used functions for the vtables of the types
|
||||
* @param types
|
||||
* for types of fields
|
||||
* @param libraries
|
||||
* for loading the class files if not in the cache
|
||||
* @throws IOException
|
||||
* if any I/O error occur on loading or writing
|
||||
*/
|
||||
private void listStructFields( String className, FunctionManager functions, TypeManager types, ClassLoader libraries ) throws IOException {
|
||||
ClassFile classFile = ClassFile.get( className, libraries );
|
||||
if( classFile == null ) {
|
||||
throw new WasmException( "Missing class: " + className, -1 );
|
||||
}
|
||||
|
||||
ConstantClass superClass = classFile.getSuperClass();
|
||||
if( superClass != null ) {
|
||||
String superClassName = superClass.getName();
|
||||
listStructFields( superClassName, functions, types, libraries );
|
||||
} else {
|
||||
fields.add( new NamedStorageType( ValueType.i32, className, ".vtable" ) );
|
||||
}
|
||||
|
||||
for( FieldInfo field : classFile.getFields() ) {
|
||||
if( field.isStatic() ) {
|
||||
continue;
|
||||
}
|
||||
fields.add( new NamedStorageType( className, field, types ) );
|
||||
}
|
||||
|
||||
for( MethodInfo method : classFile.getMethods() ) {
|
||||
if( method.isStatic() ) {
|
||||
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 );
|
||||
}
|
||||
functions.setFunctionIndex( funcName, idx );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -52,6 +52,15 @@ class WasmCallIndirectInstruction extends WasmCallInstruction {
|
||||
return Type.CallIndirect;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
void markAsNeeded( FunctionManager functions ) {
|
||||
super.markAsNeeded( functions );
|
||||
virtualFunctionIdx = functions.getFunctionIndex( getFunctionName() );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user