Use a FunctionState in the FunctionManager for later improvements

This commit is contained in:
Volker Berlin 2019-05-08 19:52:16 +02:00
parent 61c6523f14
commit f52bca35e4

View File

@ -16,7 +16,7 @@
package de.inetsoftware.jwebassembly.module; package de.inetsoftware.jwebassembly.module;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.Map.Entry;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -30,11 +30,23 @@ import de.inetsoftware.classparser.MethodInfo;
*/ */
public class FunctionManager { public class FunctionManager {
private HashSet<String> writtenFunctions = new HashSet<>(); private HashMap<FunctionName, FunctionState> states = new HashMap<>();
private HashSet<FunctionName> toWriteLater = new HashSet<>(); /**
* Get an existing state or create one.
private HashMap<FunctionName, MethodInfo> replacement = new HashMap<>(); *
* @param name
* the FunctionName
* @return the state
*/
@Nonnull
private FunctionState getOrCreate( FunctionName name ) {
FunctionState state = states.get( name );
if( state == null ) {
states.put( name, state = new FunctionState() );
}
return state;
}
/** /**
* Mark the a function as written to the wasm file. * Mark the a function as written to the wasm file.
@ -43,8 +55,7 @@ public class FunctionManager {
* the function name * the function name
*/ */
void writeFunction( FunctionName name ) { void writeFunction( FunctionName name ) {
toWriteLater.remove( name ); getOrCreate( name ).state = State.Written;
writtenFunctions.add( name.signatureName );
} }
/** /**
@ -54,8 +65,9 @@ public class FunctionManager {
* the function name * the function name
*/ */
void functionCall( FunctionName name ) { void functionCall( FunctionName name ) {
if( !writtenFunctions.contains( name.signatureName ) ) { FunctionState state = getOrCreate( name );
toWriteLater.add( name ); if( state.state == State.None ) {
state.state = State.Need;
} }
} }
@ -66,10 +78,12 @@ public class FunctionManager {
*/ */
@Nullable @Nullable
FunctionName nextWriteLater() { FunctionName nextWriteLater() {
if( toWriteLater.isEmpty() ) { for( Entry<FunctionName, FunctionState> entry : states.entrySet() ) {
return null; if( entry.getValue().state == State.Need ) {
return entry.getKey();
}
} }
return toWriteLater.iterator().next(); return null;
} }
/** /**
@ -80,7 +94,7 @@ public class FunctionManager {
* @return true, if the function on the to do list * @return true, if the function on the to do list
*/ */
boolean isToWrite( FunctionName name ) { boolean isToWrite( FunctionName name ) {
return toWriteLater.contains( name ); return getOrCreate( name ).state == State.Need;
} }
/** /**
@ -92,7 +106,7 @@ public class FunctionManager {
* the new implementation * the new implementation
*/ */
void addReplacement( FunctionName name, MethodInfo method ) { void addReplacement( FunctionName name, MethodInfo method ) {
replacement.put( name, method ); getOrCreate( name ).method = method;
} }
/** /**
@ -106,7 +120,20 @@ public class FunctionManager {
*/ */
@Nonnull @Nonnull
MethodInfo replace( FunctionName name, MethodInfo method ) { MethodInfo replace( FunctionName name, MethodInfo method ) {
MethodInfo newMethod = replacement.get( name ); MethodInfo newMethod = getOrCreate( name ).method;
return newMethod != null ? newMethod : method; return newMethod != null ? newMethod : method;
} }
/**
* State of a function/method
*/
private static class FunctionState {
private State state = State.None;
private MethodInfo method;
}
private static enum State {
None, Need, Written;
}
} }