From d1bb7cac23e2f8752709b89931432733758b710f Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Mon, 23 Sep 2019 20:33:21 +0200 Subject: [PATCH] pass the method with signature to the VariableManager as fallback --- .../module/JavaMethodWasmCodeBuilder.java | 10 ++-- .../module/LocaleVariableManager.java | 50 +++++++++++++++---- .../jwebassembly/module/ModuleGenerator.java | 4 +- .../jwebassembly/module/WasmCodeBuilder.java | 6 ++- .../module/WatCodeSyntheticFunctionName.java | 2 +- .../jwebassembly/watparser/WatParser.java | 7 ++- .../jwebassembly/module/WatParserTest.java | 2 +- 7 files changed, 58 insertions(+), 23 deletions(-) diff --git a/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java index 38f17ce..ece25af 100644 --- a/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/JavaMethodWasmCodeBuilder.java @@ -25,6 +25,7 @@ import de.inetsoftware.classparser.CodeInputStream; import de.inetsoftware.classparser.ConstantClass; import de.inetsoftware.classparser.ConstantPool; import de.inetsoftware.classparser.ConstantRef; +import de.inetsoftware.classparser.MethodInfo; import de.inetsoftware.jwebassembly.WasmException; import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.ArrayOperator; @@ -49,18 +50,19 @@ class JavaMethodWasmCodeBuilder extends WasmCodeBuilder { * * @param code * the Java method code - * @param hasReturn - * true, if the method has a return value; false, if it is void + * @param method + * the method with signature as fallback for a missing variable table * @throws WasmException * if some Java code can't converted */ - void buildCode( @Nonnull Code code, boolean hasReturn ) { + void buildCode( @Nonnull Code code, MethodInfo method ) { CodeInputStream byteCode = null; try { - reset( code.getLocalVariableTable() ); + reset( code.getLocalVariableTable(), method ); branchManager.reset( code ); byteCode = code.getByteCode(); + boolean hasReturn = !method.getType().endsWith( ")V" ); writeCode( byteCode, code.getConstantPool(), hasReturn ); calculateVariables(); } catch( Exception ioex ) { diff --git a/src/de/inetsoftware/jwebassembly/module/LocaleVariableManager.java b/src/de/inetsoftware/jwebassembly/module/LocaleVariableManager.java index 4448e40..8a8b0c8 100644 --- a/src/de/inetsoftware/jwebassembly/module/LocaleVariableManager.java +++ b/src/de/inetsoftware/jwebassembly/module/LocaleVariableManager.java @@ -19,7 +19,6 @@ package de.inetsoftware.jwebassembly.module; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; -import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -27,6 +26,7 @@ import javax.annotation.Nullable; import de.inetsoftware.classparser.LocalVariable; import de.inetsoftware.classparser.LocalVariableTable; +import de.inetsoftware.classparser.MethodInfo; import de.inetsoftware.jwebassembly.WasmException; import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.ValueType; @@ -78,8 +78,10 @@ class LocaleVariableManager { * * @param variableTable * variable table of the Java method. + * @param method + * the method with signature as fallback for a missing variable table */ - void reset( LocalVariableTable variableTable ) { + void reset( LocalVariableTable variableTable, MethodInfo method ) { size = 0; if( variableTable == null ) { @@ -150,8 +152,24 @@ class LocaleVariableManager { var.name = findUniqueVarName( var.name ); } - // add all missing slots that we can add self temporary variables int maxLocals = variableTable.getMaxLocals(); + + // add missing slots from signature + if( maxLocals > 0 && vars.length == 0 && method != null ) { + ValueTypeParser parser = new ValueTypeParser( method.getType(), types ); + if( !method.isStatic() ) { + resetAddVar( ValueType.anyref ); + } + while( size < maxLocals ) { + AnyType type = parser.next(); + if( type == null ) { + break; + } + resetAddVar( type ); + } + } + + // add all missing slots that we can add self temporary variables NEXT: for( int i = 0; i < maxLocals; i++ ) { for( int j = 0; j < size; j++ ) { Variable var = variables[j]; @@ -159,17 +177,27 @@ class LocaleVariableManager { continue NEXT; } } - ensureCapacity( size + 1 ); - Variable var = variables[size]; - var.valueType = null; - var.name = null; - var.idx = i; - var.startPos = 0; - var.endPos = Integer.MAX_VALUE; - size++; + resetAddVar( null ); } } + /** + * Add a variable in the reset with range. + * + * @param type + * the type of the variable + */ + private void resetAddVar( AnyType type ) { + ensureCapacity( size + 1 ); + Variable var = variables[size]; + var.valueType = type; + var.name = null; + var.idx = size; + var.startPos = 0; + var.endPos = Integer.MAX_VALUE; + size++; + } + /** * Find a unique variable name. * diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java index e6e4b03..22a6c4c 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java @@ -436,10 +436,10 @@ public class ModuleGenerator { if( signature == null ) { signature = method.getType(); } - watParser.parse( watCode, code == null ? -1 : code.getFirstLineNr() ); + watParser.parse( watCode, method, code == null ? -1 : code.getFirstLineNr() ); return watParser; } else if( code != null ) { // abstract methods and interface methods does not have code - javaCodeBuilder.buildCode( code, !method.getType().endsWith( ")V" ) ); + javaCodeBuilder.buildCode( code, method ); return javaCodeBuilder; } else { throw new WasmException( "Abstract or native method can not be used: " + new FunctionName( method ).signatureName, -1 ); diff --git a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java index 2006254..4c91fb0 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmCodeBuilder.java @@ -147,10 +147,12 @@ public abstract class WasmCodeBuilder { * * @param variableTable * variable table of the Java method. + * @param method + * the method with signature as fallback for a missing variable table */ - protected void reset( LocalVariableTable variableTable ) { + protected void reset( LocalVariableTable variableTable, MethodInfo method ) { instructions.clear(); - localVariables.reset( variableTable ); + localVariables.reset( variableTable, method ); } /** diff --git a/src/de/inetsoftware/jwebassembly/module/WatCodeSyntheticFunctionName.java b/src/de/inetsoftware/jwebassembly/module/WatCodeSyntheticFunctionName.java index c2e58e4..f6e4a9a 100644 --- a/src/de/inetsoftware/jwebassembly/module/WatCodeSyntheticFunctionName.java +++ b/src/de/inetsoftware/jwebassembly/module/WatCodeSyntheticFunctionName.java @@ -56,7 +56,7 @@ class WatCodeSyntheticFunctionName extends SyntheticFunctionName { */ @Override protected WasmCodeBuilder getCodeBuilder( WatParser watParser ) { - watParser.parse( code, -1 ); + watParser.parse( code, null, -1 ); return watParser; } } diff --git a/src/de/inetsoftware/jwebassembly/watparser/WatParser.java b/src/de/inetsoftware/jwebassembly/watparser/WatParser.java index bdbbc2e..0e62287 100644 --- a/src/de/inetsoftware/jwebassembly/watparser/WatParser.java +++ b/src/de/inetsoftware/jwebassembly/watparser/WatParser.java @@ -23,6 +23,7 @@ import javax.annotation.Nonnegative; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import de.inetsoftware.classparser.MethodInfo; import de.inetsoftware.jwebassembly.WasmException; import de.inetsoftware.jwebassembly.module.ValueTypeConvertion; import de.inetsoftware.jwebassembly.module.WasmCodeBuilder; @@ -44,10 +45,12 @@ public class WatParser extends WasmCodeBuilder { * the text format content of a function * @param lineNumber * the line number for an error message + * @param method + * the method with signature as fallback for a missing variable table */ - public void parse( String wat, int lineNumber ) { + public void parse( String wat, MethodInfo method, int lineNumber ) { try { - reset( null ); + reset( null, method ); List tokens = splitTokens( wat ); for( int i = 0; i < tokens.size(); i++ ) { diff --git a/test/de/inetsoftware/jwebassembly/module/WatParserTest.java b/test/de/inetsoftware/jwebassembly/module/WatParserTest.java index a03c0af..9aecdf4 100644 --- a/test/de/inetsoftware/jwebassembly/module/WatParserTest.java +++ b/test/de/inetsoftware/jwebassembly/module/WatParserTest.java @@ -41,7 +41,7 @@ public class WatParserTest { WatParser parser = new WatParser(); WasmCodeBuilder codeBuilder = parser; codeBuilder.init( null, null, options ); - parser.parse( wat, 100 ); + parser.parse( wat, null, 100 ); StringBuilder builder = new StringBuilder(); ModuleWriter writer = new TextModuleWriter( new WasmTarget( builder ), options ); writer.writeMethodStart( new FunctionName( "A.a()V" ), null );