diff --git a/src/de/inetsoftware/jwebassembly/module/FunctionManager.java b/src/de/inetsoftware/jwebassembly/module/FunctionManager.java index d96a0e5..d57e797 100644 --- a/src/de/inetsoftware/jwebassembly/module/FunctionManager.java +++ b/src/de/inetsoftware/jwebassembly/module/FunctionManager.java @@ -17,6 +17,7 @@ package de.inetsoftware.jwebassembly.module; import static de.inetsoftware.jwebassembly.module.WasmCodeBuilder.CLASS_INIT; +import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; @@ -110,8 +111,17 @@ class FunctionManager { * @param importAnannotation * the annotation of the import */ - void markAsImport( @Nonnull FunctionName name, Map importAnannotation ) { + void markAsImport( @Nonnull FunctionName name, @Nonnull Map importAnannotation ) { markAsImport( name, ( key ) -> importAnannotation.get( key ) ); + + // register possible callbacks as needed methods + Object callbacks = importAnannotation.get( "callbacks" ); + if( callbacks != null ) { + for( Object callback : (Object[])callbacks ) { + name = new FunctionName( (String)callback ); + markAsExport( name, Collections.emptyMap() ); + } + } } /** @@ -127,6 +137,19 @@ class FunctionManager { getOrCreate( name ).importAnannotation = importAnannotation; } + /** + * Mark the function as export function and as needed. + * + * @param name + * the function name + * @param exportAnannotation + * the annotation of the export + */ + void markAsExport( @Nonnull FunctionName name, @Nonnull Map exportAnannotation ) { + markAsNeeded( name, false ); + getOrCreate( name ).exportAnannotation = exportAnannotation; + } + /** * Same like markAsNeeded but it will replace the function name if already registered. * @@ -230,6 +253,17 @@ class FunctionManager { return getOrCreate( name ).importAnannotation; } + /** + * Get the annotation of an export function + * + * @param name + * the function name + * @return the annotation or null + */ + Map getExportAnannotation( FunctionName name ) { + return getOrCreate( name ).exportAnannotation; + } + /** * Get the first FunctionName that is required but was not scanned. * @@ -462,6 +496,7 @@ class FunctionManager { * State of a function/method */ private static class FunctionState { + private State state = State.None; private MethodInfo method; @@ -470,6 +505,8 @@ class FunctionManager { private Function importAnannotation; + private Map exportAnannotation; + private int vtableIdx = -1; private int itableIdx = -1; diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java index b96d90b..6b3c635 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java @@ -519,7 +519,7 @@ public class ModuleGenerator { if( !method.isStatic() ) { throw new WasmException( "Export method must be static: " + name.fullName, -1 ); } - functions.markAsNeeded( name, false ); + functions.markAsExport( name, annotationValues ); return; } } catch( Exception ioex ) { @@ -673,7 +673,7 @@ public class ModuleGenerator { * if any IOException occur */ private void writeExport( FunctionName name, MethodInfo method ) throws IOException { - Map export = method.getAnnotation( JWebAssembly.EXPORT_ANNOTATION ); + Map export = functions.getExportAnannotation( name ); if( export != null ) { String exportName = (String)export.get( "name" ); if( exportName == null ) {