From 645996ceb00c270aa0eb7ae2ebbd4917466f146e Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Mon, 30 Mar 2020 22:27:30 +0200 Subject: [PATCH] add support for static constructors, WIP --- .../jwebassembly/module/FunctionManager.java | 87 +++++++++++-------- .../jwebassembly/module/ModuleGenerator.java | 3 + 2 files changed, 55 insertions(+), 35 deletions(-) diff --git a/src/de/inetsoftware/jwebassembly/module/FunctionManager.java b/src/de/inetsoftware/jwebassembly/module/FunctionManager.java index 703d91d..c835f8b 100644 --- a/src/de/inetsoftware/jwebassembly/module/FunctionManager.java +++ b/src/de/inetsoftware/jwebassembly/module/FunctionManager.java @@ -15,6 +15,7 @@ */ package de.inetsoftware.jwebassembly.module; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; @@ -36,7 +37,9 @@ import de.inetsoftware.jwebassembly.WasmException; */ class FunctionManager { - private final Map states = new LinkedHashMap<>(); + private final Map states = new LinkedHashMap<>(); + + private final Map classesWithCInit = new HashMap<>(); private boolean isFinish; @@ -83,6 +86,16 @@ class FunctionManager { 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 * compiler. @@ -109,6 +122,44 @@ class FunctionManager { 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. * @@ -148,40 +199,6 @@ class FunctionManager { 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 * diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java index 6bb8631..4025ac4 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java @@ -404,6 +404,9 @@ public class ModuleGenerator { private void prepareMethod( MethodInfo method ) throws WasmException { try { FunctionName name = new FunctionName( method ); + if( "".equals( name.methodName ) ) { + functions.markClassWithCInit( name ); + } if( functions.isKnown( name ) ) { return; }