diff --git a/src/de/inetsoftware/jwebassembly/module/FunctionManager.java b/src/de/inetsoftware/jwebassembly/module/FunctionManager.java index 5d58408..d6aaa0e 100644 --- a/src/de/inetsoftware/jwebassembly/module/FunctionManager.java +++ b/src/de/inetsoftware/jwebassembly/module/FunctionManager.java @@ -63,6 +63,15 @@ class FunctionManager { return state; } + /** + * Get the count of known functions + * + * @return the count + */ + int size() { + return states.size(); + } + /** * Check if this function is already known/registered. * diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java index fba8c2e..458e48d 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java @@ -222,6 +222,9 @@ public class ModuleGenerator { createInstructions( functions.replace( next, method ) ); boolean needThisParameter = !method.isStatic() || "".equals( method.getName() ); functions.markAsScanned( next, needThisParameter ); + if( needThisParameter ) { + types.valueOf( next.className ); // for the case that the type unknown yet + } continue; } @@ -267,7 +270,12 @@ public class ModuleGenerator { * if any I/O error occur */ public void prepareFinish() throws IOException { - scanFunctions(); + int functCount; + do { + scanFunctions(); + functCount = functions.size(); // scan the functions can find new needed types + types.scanTypeHierarchy( classFileLoader ); // scan the type hierarchy can find new functions + } while( functCount < functions.size() ); // write only the needed imports to the output for( Iterator iterator = functions.getNeededImports(); iterator.hasNext(); ) { @@ -297,8 +305,7 @@ public class ModuleGenerator { } JWebAssembly.LOGGER.fine( "scan finsih" ); - types.prepareFinish( writer, functions, classFileLoader ); - scanFunctions(); // prepare of types can add some override methods as needed + types.prepareFinish( writer, classFileLoader ); functions.prepareFinish(); strings.prepareFinish( writer ); writer.prepareFinish(); diff --git a/src/de/inetsoftware/jwebassembly/module/TypeManager.java b/src/de/inetsoftware/jwebassembly/module/TypeManager.java index 819b767..08ac8eb 100644 --- a/src/de/inetsoftware/jwebassembly/module/TypeManager.java +++ b/src/de/inetsoftware/jwebassembly/module/TypeManager.java @@ -111,21 +111,33 @@ public class TypeManager { } /** - * Finish the prepare and write the types. Now no new types and functions should be added. + * Scan the hierarchy of the types. * - * @param writer - * the targets for the types - * @param functions - * the used functions for the vtables of the types * @param classFileLoader * for loading the class files * @throws IOException * if any I/O error occur on loading or writing */ - void prepareFinish( ModuleWriter writer, FunctionManager functions, ClassFileLoader classFileLoader ) throws IOException { + void scanTypeHierarchy( ClassFileLoader classFileLoader ) throws IOException { + for( StructType type : structTypes.values() ) { + type.scanTypeHierarchy( options.functions, this, classFileLoader ); + } + } + + /** + * Finish the prepare and write the types. Now no new types and functions should be added. + * + * @param writer + * the targets for the types + * @param classFileLoader + * for loading the class files + * @throws IOException + * if any I/O error occur on loading or writing + */ + void prepareFinish( ModuleWriter writer, ClassFileLoader classFileLoader ) throws IOException { isFinish = true; for( StructType type : structTypes.values() ) { - type.writeStructType( writer, functions, this, classFileLoader ); + type.writeStructType( writer, options.functions, this, classFileLoader ); } // write type table @@ -153,6 +165,11 @@ public class TypeManager { return offsetFunction; } + /** + * Get the function name to get a constant class. + * @return the function + */ + @Nonnull FunctionName getClassConstantFunction() { return CLASS_CONSTANT_FUNCTION; } @@ -339,14 +356,32 @@ public class TypeManager { * @throws IOException * if any I/O error occur on loading or writing */ - private void writeStructType( ModuleWriter writer, FunctionManager functions, TypeManager types, ClassFileLoader classFileLoader ) throws IOException { - JWebAssembly.LOGGER.fine( "write type: " + name ); + private void scanTypeHierarchy( FunctionManager functions, TypeManager types, ClassFileLoader classFileLoader ) throws IOException { + JWebAssembly.LOGGER.fine( "scan type hierachy: " + name ); fields = new ArrayList<>(); methods = new ArrayList<>(); instanceOFs = new LinkedHashSet<>(); // remembers the order from bottom to top class. instanceOFs.add( this ); HashSet allNeededFields = new HashSet<>(); listStructFields( name, functions, types, classFileLoader, allNeededFields ); + } + + /** + * 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 classFileLoader + * for loading the class files + * @throws IOException + * if any I/O error occur on loading or writing + */ + private void writeStructType( ModuleWriter writer, FunctionManager functions, TypeManager types, ClassFileLoader classFileLoader ) throws IOException { + JWebAssembly.LOGGER.fine( "write type: " + name ); code = writer.writeStructType( this ); }