diff --git a/src/de/inetsoftware/jwebassembly/JWebAssembly.java b/src/de/inetsoftware/jwebassembly/JWebAssembly.java index 6a19050..8d432b1 100644 --- a/src/de/inetsoftware/jwebassembly/JWebAssembly.java +++ b/src/de/inetsoftware/jwebassembly/JWebAssembly.java @@ -258,5 +258,6 @@ public class JWebAssembly { ClassFile classFile = new ClassFile( new BufferedInputStream( url.openStream() ) ); generator.write( classFile ); } + generator.finish(); } } diff --git a/src/de/inetsoftware/jwebassembly/module/FunctionManager.java b/src/de/inetsoftware/jwebassembly/module/FunctionManager.java new file mode 100644 index 0000000..d45c0ee --- /dev/null +++ b/src/de/inetsoftware/jwebassembly/module/FunctionManager.java @@ -0,0 +1,53 @@ +/* + * Copyright 2018 Volker Berlin (i-net software) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.inetsoftware.jwebassembly.module; + +import java.util.HashSet; + +/** + * Manage the required function/methods + * + * @author Volker Berlin + */ +public class FunctionManager { + + private HashSet writtenFunctions = new HashSet<>(); + + private HashSet toWriteLater = new HashSet<>(); + + /** + * Mark the a function as written to the wasm file. + * + * @param name + * the function name + */ + void writeFunction( FunctionName name ) { + toWriteLater.remove( name ); + writtenFunctions.add( name.signatureName ); + } + + /** + * Mark a function as used/called. + * + * @param name + * the function name + */ + void functionCall( FunctionName name ) { + if( !writtenFunctions.contains( name.signatureName ) ) { + toWriteLater.add( name ); + } + } +} diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java index a0d32d8..7f959f0 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java @@ -53,6 +53,8 @@ public class ModuleGenerator { private String className; + private FunctionManager functions = new FunctionManager(); + /** * Create a new generator. * @@ -98,6 +100,23 @@ public class ModuleGenerator { iterateMethods( classFile, m -> writeMethod( m ) ); } + /** + * Finish the code generation. + */ + public void finish() { + + } + + /** + * Iterate over all methods of the classFile and run the handler. + * + * @param classFile + * the classFile + * @param handler + * the handler + * @throws WasmException + * if some Java code can't converted + */ private void iterateMethods( ClassFile classFile, Consumer handler ) throws WasmException { sourceFile = null; // clear previous value for the case an IO exception occur className = null; @@ -131,6 +150,7 @@ public class ModuleGenerator { FunctionName name = new FunctionName( method ); Map annotationValues = method.getAnnotation( JWebAssembly.IMPORT_ANNOTATION ); if( annotationValues != null ) { + functions.writeFunction( name ); String impoarModule = (String)annotationValues.get( "module" ); String importName = (String)annotationValues.get( "name" ); writer.prepareImport( name, impoarModule, importName ); @@ -179,10 +199,13 @@ public class ModuleGenerator { FunctionName name = new FunctionName( method ); writeExport( name, method ); writer.writeMethodStart( name ); - + functions.writeFunction( name ); writeMethodSignature( signature, code.getLocalVariableTable(), codeBuilder ); for( WasmInstruction instruction : codeBuilder.getInstructions() ) { + if( instruction instanceof WasmCallInstruction ) { + functions.functionCall( ((WasmCallInstruction)instruction).getFunctionName() ); + } instruction.writeTo( writer ); } writer.writeMethodFinish();