Add support for callbacks in import annotations.

This commit is contained in:
Volker Berlin 2022-04-03 13:58:43 +02:00
parent d8a1d6abf0
commit a6b8862e25
2 changed files with 40 additions and 3 deletions

View File

@ -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<String, Object> importAnannotation ) {
void markAsImport( @Nonnull FunctionName name, @Nonnull Map<String, Object> 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<String, Object> 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<String, Object> 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<String, Object> importAnannotation;
private Map<String, Object> exportAnannotation;
private int vtableIdx = -1;
private int itableIdx = -1;

View File

@ -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<String,Object> export = method.getAnnotation( JWebAssembly.EXPORT_ANNOTATION );
Map<String,Object> export = functions.getExportAnannotation( name );
if( export != null ) {
String exportName = (String)export.get( "name" );
if( exportName == null ) {