diff --git a/src/de/inetsoftware/classparser/MethodInfo.java b/src/de/inetsoftware/classparser/MethodInfo.java index 51910f9..9fd00d9 100644 --- a/src/de/inetsoftware/classparser/MethodInfo.java +++ b/src/de/inetsoftware/classparser/MethodInfo.java @@ -119,6 +119,15 @@ public class MethodInfo implements Member { return (accessFlags & 0x1000) > 0; } + /** + * If the method is a synthetic lambda method + * + * @return true, if lambda method + */ + public boolean isLambda() { + return (accessFlags & 0x1000) > 0 && name.startsWith( "lambda$" ); + } + /** * @return the name */ diff --git a/src/de/inetsoftware/jwebassembly/module/LocaleVariableManager.java b/src/de/inetsoftware/jwebassembly/module/LocaleVariableManager.java index d5d40e8..13c139b 100644 --- a/src/de/inetsoftware/jwebassembly/module/LocaleVariableManager.java +++ b/src/de/inetsoftware/jwebassembly/module/LocaleVariableManager.java @@ -1,5 +1,5 @@ /* - Copyright 2018 - 2020 Volker Berlin (i-net software) + Copyright 2018 - 2021 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. @@ -87,6 +87,13 @@ class LocaleVariableManager { void reset( LocalVariableTable variableTable, MethodInfo method, Iterator signature ) { size = 0; + if( method != null && method.isLambda() ) { + AnyType type = types.options.useGC() ? types.valueOf( "java/lang/Object" ) : ValueType.externref; + resetAddVar( type, -1 ); + variables[0].name = "this"; + } + int baseSize = size; + int maxLocals; if( variableTable == null ) { maxLocals = 0; @@ -160,7 +167,7 @@ class LocaleVariableManager { } // add missing slots from signature - if( (maxLocals > 0 || variableTable == null) && size == 0 && (method != null || signature != null )) { + if( (maxLocals > 0 || variableTable == null) && size == baseSize && (method != null || signature != null )) { Iterator parser = signature == null ? new ValueTypeParser( method.getType(), types ) : signature; if( method != null && !method.isStatic() ) { resetAddVar( ValueType.externref, size ); @@ -170,12 +177,12 @@ class LocaleVariableManager { if( type == null ) { break; } - resetAddVar( type, size ); + resetAddVar( type, size - baseSize ); } } // add all missing slots that we can add self temporary variables - NEXT: for( int i = 0; i < maxLocals; i++ ) { + NEXT: for( int i = 0; i < maxLocals + baseSize; i++ ) { for( int j = 0; j < size; j++ ) { Variable var = variables[j]; if( var.idx == i ) { diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java index 4966a7a..e27dc2b 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java @@ -224,7 +224,7 @@ public class ModuleGenerator { createInstructions( functions.replace( next, method ) ); boolean needThisParameter = !method.isStatic() // if not static there is a not declared THIS parameter || "".equals( method.getName() ) // constructor method need also the THIS parameter also if marked as static - || (method.isSynthetic() && method.getName().startsWith( "lambda$" )); // lambda functions are static but will call with a THIS parameter which need be removed from stack + || (method.isLambda() ); // lambda functions are static but will call with a THIS parameter which need be removed from stack functions.markAsScanned( next, needThisParameter ); if( needThisParameter ) { types.valueOf( next.className ); // for the case that the type unknown yet