diff --git a/src/de/inetsoftware/jwebassembly/module/TypeManager.java b/src/de/inetsoftware/jwebassembly/module/TypeManager.java index fee4196..dce8e59 100644 --- a/src/de/inetsoftware/jwebassembly/module/TypeManager.java +++ b/src/de/inetsoftware/jwebassembly/module/TypeManager.java @@ -369,6 +369,8 @@ public class TypeManager { * * @param typeName * the name (className) of the lambda class + * @param params + * the parameters of the constructor and type fields * @param interfaceType * the implemented interface * @param methodName @@ -377,10 +379,10 @@ public class TypeManager { * the name of the implemented method in the interface * @return the type */ - StructType lambdaType( String typeName, StructType interfaceType, FunctionName methodName, String interfaceMethodName ) { - StructType type = structTypes.get( typeName ); + LambdaType lambdaType( String typeName, ArrayList params, StructType interfaceType, FunctionName methodName, String interfaceMethodName ) { + LambdaType type = (LambdaType)structTypes.get( typeName ); if( type == null ) { - type = new LambdaType( typeName, interfaceType, methodName, interfaceMethodName, this ); + type = new LambdaType( typeName, params, interfaceType, methodName, interfaceMethodName, this ); structTypes.put( typeName, type ); } @@ -656,6 +658,7 @@ public class TypeManager { allNeededFields = new HashSet<>(); listStructFields( "java/lang/Object", functions, types, classFileLoader, allNeededFields ); LambdaType lambda = (LambdaType)this; + fields.addAll( lambda.getParamFields() ); List iMethods = new ArrayList<>(); iMethods.add( lambda.getLambdaMethod() ); interfaceMethods.put( lambda.getInterfaceType(), iMethods ); @@ -1088,17 +1091,21 @@ public class TypeManager { */ class LambdaType extends StructType { - private StructType interfaceType; + private ArrayList paramFields; - private FunctionName methodName; + private StructType interfaceType; - private String interfaceMethodName; + private FunctionName methodName; + + private String interfaceMethodName; /** * Create a lambda type * * @param name - * the Java class name + * the Lambda Java class name + * @param params + * the parameters of the constructor and type fields * @param interfaceType * the implemented interface type * @param methodName @@ -1108,13 +1115,26 @@ public class TypeManager { * @param manager * the manager which hold all StructTypes */ - LambdaType( String name, StructType interfaceType, FunctionName methodName, String interfaceMethodName, TypeManager manager ) { + LambdaType( String name, ArrayList params, StructType interfaceType, FunctionName methodName, String interfaceMethodName, TypeManager manager ) { super( name, StructTypeKind.lambda, manager ); + this.paramFields = new ArrayList<>( params.size() ); + for( int i = 0; i < params.size(); i++ ) { + paramFields.add( new NamedStorageType( params.get( i ), "", "arg$" + (i+1) ) ); + } this.interfaceType = interfaceType; this.methodName = methodName; this.interfaceMethodName = interfaceMethodName; } + /** + * The parameters of the constructor + * + * @return the parameters + */ + ArrayList getParamFields() { + return paramFields; + } + /** * The implemented interface type * diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java index 853d1a6..6c5e58d 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java @@ -35,6 +35,7 @@ import de.inetsoftware.classparser.MethodInfo; import de.inetsoftware.jwebassembly.WasmException; import de.inetsoftware.jwebassembly.javascript.NonGC; import de.inetsoftware.jwebassembly.module.StackInspector.StackValue; +import de.inetsoftware.jwebassembly.module.TypeManager.LambdaType; import de.inetsoftware.jwebassembly.module.TypeManager.StructType; import de.inetsoftware.jwebassembly.module.WasmInstruction.Type; import de.inetsoftware.jwebassembly.wasm.AnyType; @@ -866,14 +867,24 @@ public abstract class WasmCodeBuilder { ConstantMethodRef implMethod = method.getImplMethod(); FunctionName name = new FunctionName( implMethod ); functions.markAsNeeded( name ); - String typeName = implMethod.getClassName() + "$$" + implMethod.getName() + "/"; + String lambdaTypeName = implMethod.getClassName() + "$$" + implMethod.getName() + "/" + Math.abs( name.hashCode() ); ValueTypeParser parser = new ValueTypeParser( factorySignature, types ); - while( parser.next() != null ) { - // skip parameters TODO - } + ArrayList params = new ArrayList<>(); + do { + AnyType param = parser.next(); + if( param == null ) { + break; + } + params.add( param ); + } while( true ); StructType interfaceType = (StructType)parser.next(); - StructType type = types.lambdaType( typeName, interfaceType, name, interfaceMethodName ); - addStructInstruction( StructOperator.NEW_DEFAULT, typeName, null, javaCodePos, lineNumber ); + LambdaType type = types.lambdaType( lambdaTypeName, params, interfaceType, name, interfaceMethodName ); + addStructInstruction( StructOperator.NEW_DEFAULT, lambdaTypeName, null, javaCodePos, lineNumber ); + + for( NamedStorageType field : type.getParamFields() ) { + addDupInstruction( javaCodePos, lineNumber ); + instructions.add( new WasmStructInstruction( StructOperator.SET, lambdaTypeName, field, javaCodePos, lineNumber, types ) ); + } } /**