mirror of
https://github.com/i-net-software/JWebAssembly.git
synced 2025-03-25 07:27:52 +01:00
fix assignment of parameters from stack for lambda expressions with parameters
This commit is contained in:
parent
d480471e27
commit
f4fd312d31
@ -17,6 +17,7 @@ package de.inetsoftware.jwebassembly.module;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@ -854,7 +855,7 @@ public abstract class WasmCodeBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add invoke dynamic operation.
|
* Add invoke dynamic operation. (Creating of a lambda expression)
|
||||||
*
|
*
|
||||||
* @param method
|
* @param method
|
||||||
* the BootstrapMethod, described the method that should be executed
|
* the BootstrapMethod, described the method that should be executed
|
||||||
@ -869,9 +870,12 @@ public abstract class WasmCodeBuilder {
|
|||||||
* the line number in the Java source code
|
* the line number in the Java source code
|
||||||
*/
|
*/
|
||||||
protected void addInvokeDynamic( BootstrapMethod method, String factorySignature, String interfaceMethodName, int javaCodePos, int lineNumber ) {
|
protected void addInvokeDynamic( BootstrapMethod method, String factorySignature, String interfaceMethodName, int javaCodePos, int lineNumber ) {
|
||||||
|
// mark the static, synthetic method which implement the lambda code, as needed
|
||||||
ConstantMethodRef implMethod = method.getImplMethod();
|
ConstantMethodRef implMethod = method.getImplMethod();
|
||||||
FunctionName name = new FunctionName( implMethod );
|
FunctionName name = new FunctionName( implMethod );
|
||||||
functions.markAsNeeded( name );
|
functions.markAsNeeded( name );
|
||||||
|
|
||||||
|
// Create the synthetic lambda class that hold the lambda expression.
|
||||||
String lambdaTypeName = implMethod.getClassName() + "$$" + implMethod.getName() + "/" + Math.abs( name.hashCode() );
|
String lambdaTypeName = implMethod.getClassName() + "$$" + implMethod.getName() + "/" + Math.abs( name.hashCode() );
|
||||||
ValueTypeParser parser = new ValueTypeParser( factorySignature, types );
|
ValueTypeParser parser = new ValueTypeParser( factorySignature, types );
|
||||||
ArrayList<AnyType> params = new ArrayList<>();
|
ArrayList<AnyType> params = new ArrayList<>();
|
||||||
@ -884,11 +888,28 @@ public abstract class WasmCodeBuilder {
|
|||||||
} while( true );
|
} while( true );
|
||||||
StructType interfaceType = (StructType)parser.next();
|
StructType interfaceType = (StructType)parser.next();
|
||||||
LambdaType type = types.lambdaType( lambdaTypeName, params, interfaceType, name, interfaceMethodName );
|
LambdaType type = types.lambdaType( lambdaTypeName, params, interfaceType, name, interfaceMethodName );
|
||||||
addStructInstruction( StructOperator.NEW_DEFAULT, lambdaTypeName, null, javaCodePos, lineNumber );
|
|
||||||
|
|
||||||
for( NamedStorageType field : type.getParamFields() ) {
|
// Create the instance of the synthetic lambda class and save the parameters in fields
|
||||||
addDupInstruction( javaCodePos, lineNumber );
|
ArrayList<NamedStorageType> paramFields = type.getParamFields();
|
||||||
instructions.add( new WasmStructInstruction( StructOperator.SET, lambdaTypeName, field, javaCodePos, lineNumber, types ) );
|
int paramCount = paramFields.size();
|
||||||
|
if( paramCount == 0 ) {
|
||||||
|
addStructInstruction( StructOperator.NEW_DEFAULT, lambdaTypeName, null, javaCodePos, lineNumber );
|
||||||
|
} else {
|
||||||
|
// Lambda with parameters from the stack
|
||||||
|
int idx = StackInspector.findInstructionThatPushValue( instructions, paramCount, javaCodePos ).idx;
|
||||||
|
int pos = instructions.size();
|
||||||
|
addStructInstruction( StructOperator.NEW_DEFAULT, lambdaTypeName, null, javaCodePos, lineNumber );
|
||||||
|
int slot = ((WasmLocalInstruction)findInstructionThatPushValue( 1, javaCodePos )).getSlot();
|
||||||
|
|
||||||
|
// move the creating of the lambda instance before the parameters on the stack
|
||||||
|
Collections.rotate( instructions.subList( idx, instructions.size() ), idx - pos );
|
||||||
|
|
||||||
|
for( int i = 0; i < paramCount; i++ ) {
|
||||||
|
NamedStorageType field = paramFields.get( i );
|
||||||
|
idx = StackInspector.findInstructionThatPushValue( instructions, paramCount - i, javaCodePos ).idx;
|
||||||
|
instructions.add( idx, new WasmLoadStoreInstruction( VariableOperator.get, slot, localVariables, javaCodePos, lineNumber ) );
|
||||||
|
instructions.add( new WasmStructInstruction( StructOperator.SET, lambdaTypeName, field, javaCodePos, lineNumber, types ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user