mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 15:37:52 +01:00
add support for static constructors, WIP
This commit is contained in:
parent
41c795eaee
commit
645996ceb0
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package de.inetsoftware.jwebassembly.module;
|
package de.inetsoftware.jwebassembly.module;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -36,7 +37,9 @@ import de.inetsoftware.jwebassembly.WasmException;
|
|||||||
*/
|
*/
|
||||||
class FunctionManager {
|
class FunctionManager {
|
||||||
|
|
||||||
private final Map<FunctionName, FunctionState> states = new LinkedHashMap<>();
|
private final Map<FunctionName, FunctionState> states = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
private final Map<String, FunctionName> classesWithCInit = new HashMap<>();
|
||||||
|
|
||||||
private boolean isFinish;
|
private boolean isFinish;
|
||||||
|
|
||||||
@ -83,6 +86,16 @@ class FunctionManager {
|
|||||||
return states.get( name ) != null;
|
return states.get( name ) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark that a class has static initializer.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* the function name
|
||||||
|
*/
|
||||||
|
void markClassWithCInit( FunctionName name ) {
|
||||||
|
classesWithCInit.put( name.className, name );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark the a function as a import function. Only if the function is also needed then it will imported from
|
* Mark the a function as a import function. Only if the function is also needed then it will imported from
|
||||||
* compiler.
|
* compiler.
|
||||||
@ -109,6 +122,44 @@ class FunctionManager {
|
|||||||
getOrCreate( name ).importAnannotation = importAnannotation;
|
getOrCreate( name ).importAnannotation = importAnannotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same like markAsNeeded but it will replace the function name if already registered.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* the function name
|
||||||
|
*/
|
||||||
|
void markAsNeededAndReplaceIfExists( @Nonnull SyntheticFunctionName name ) {
|
||||||
|
FunctionState state = states.get( name );
|
||||||
|
if( state != null ) {
|
||||||
|
states.remove( name );
|
||||||
|
states.put( name, state );
|
||||||
|
}
|
||||||
|
markAsNeeded( name );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark a function as used/called and return the real name if there is an alias.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* the function name
|
||||||
|
* @return the real function name
|
||||||
|
*/
|
||||||
|
FunctionName markAsNeeded( @Nonnull FunctionName name ) {
|
||||||
|
FunctionState state = getOrCreate( name );
|
||||||
|
if( state.state == State.None ) {
|
||||||
|
if( isFinish ) {
|
||||||
|
throw new WasmException( "Prepare was already finish: " + name.signatureName, -1 );
|
||||||
|
}
|
||||||
|
state.state = State.Needed;
|
||||||
|
JWebAssembly.LOGGER.fine( "\t\tcall: " + name.signatureName );
|
||||||
|
FunctionName cInit = classesWithCInit.get( name.className );
|
||||||
|
if( cInit != null ) {
|
||||||
|
markAsNeeded( cInit );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state.alias == null ? name : state.alias;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark the a function as scanned in the prepare phase. This should only occur with needed functions.
|
* Mark the a function as scanned in the prepare phase. This should only occur with needed functions.
|
||||||
*
|
*
|
||||||
@ -148,40 +199,6 @@ class FunctionManager {
|
|||||||
getOrCreate( name ).state = State.Abstract;
|
getOrCreate( name ).state = State.Abstract;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Same like markAsNeeded but it will replace the function name if already registered.
|
|
||||||
*
|
|
||||||
* @param name
|
|
||||||
* the function name
|
|
||||||
*/
|
|
||||||
void markAsNeededAndReplaceIfExists( @Nonnull SyntheticFunctionName name ) {
|
|
||||||
FunctionState state = states.get( name );
|
|
||||||
if( state != null ) {
|
|
||||||
states.remove( name );
|
|
||||||
states.put( name, state );
|
|
||||||
}
|
|
||||||
markAsNeeded( name );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mark a function as used/called and return the real name if there is an alias.
|
|
||||||
*
|
|
||||||
* @param name
|
|
||||||
* the function name
|
|
||||||
* @return the real function name
|
|
||||||
*/
|
|
||||||
FunctionName markAsNeeded( @Nonnull FunctionName name ) {
|
|
||||||
FunctionState state = getOrCreate( name );
|
|
||||||
if( state.state == State.None ) {
|
|
||||||
if( isFinish ) {
|
|
||||||
throw new WasmException( "Prepare was already finish: " + name.signatureName, -1 );
|
|
||||||
}
|
|
||||||
state.state = State.Needed;
|
|
||||||
JWebAssembly.LOGGER.fine( "\t\tcall: " + name.signatureName );
|
|
||||||
}
|
|
||||||
return state.alias == null ? name : state.alias;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all FunctionNames that need imported
|
* Get all FunctionNames that need imported
|
||||||
*
|
*
|
||||||
|
@ -404,6 +404,9 @@ public class ModuleGenerator {
|
|||||||
private void prepareMethod( MethodInfo method ) throws WasmException {
|
private void prepareMethod( MethodInfo method ) throws WasmException {
|
||||||
try {
|
try {
|
||||||
FunctionName name = new FunctionName( method );
|
FunctionName name = new FunctionName( method );
|
||||||
|
if( "<clinit>".equals( name.methodName ) ) {
|
||||||
|
functions.markClassWithCInit( name );
|
||||||
|
}
|
||||||
if( functions.isKnown( name ) ) {
|
if( functions.isKnown( name ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user