From 563075a578c56a2980ce2cef98b229e3d2f92ede Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Sat, 13 Oct 2018 18:10:05 +0200 Subject: [PATCH] write local method names if DebugNames is enabled --- .../binary/BinaryModuleWriter.java | 37 ++++++++++++++++--- .../jwebassembly/binary/Function.java | 5 ++- .../jwebassembly/module/ModuleGenerator.java | 24 +++++++++--- .../jwebassembly/module/ModuleWriter.java | 11 ++---- .../jwebassembly/text/TextModuleWriter.java | 19 ++++++---- 5 files changed, 70 insertions(+), 26 deletions(-) diff --git a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java index b4e0b36..ead2682 100644 --- a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java @@ -62,7 +62,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod private Map functions = new LinkedHashMap<>(); - private List locals; + private List locals = new ArrayList<>(); private Map globals = new LinkedHashMap<>(); @@ -197,6 +197,24 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod stream.writeVaruint32( section.size() ); section.writeTo( stream ); + // write function parameter names + stream.write( 2 ); // 2 - Local names + section.reset(); + section.writeVaruint32( functions.size() ); + for( Entry entry : functions.entrySet() ) { + Function func = entry.getValue(); + section.writeVaruint32( func.id ); // function index + List paramNames = func.paramNames; + int count = paramNames == null ? 0 : paramNames.size(); + section.writeVaruint32( count ); // count of locals + for( int i = 0; i < count; i++ ) { + section.writeVaruint32( i ); + section.writeString( paramNames.get( i ) ); + } + } + stream.writeVaruint32( section.size() ); + section.writeTo( stream ); + wasm.writeSection( SectionType.Custom, stream ); } @@ -251,20 +269,30 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod function = functions.get( name.signatureName ); functionType = new FunctionType(); codeStream.reset(); + locals.clear(); } /** * {@inheritDoc} */ @Override - protected void writeMethodParam( String kind, ValueType valueType ) throws IOException { + protected void writeMethodParam( String kind, ValueType valueType, @Nullable String name ) throws IOException { switch( kind ) { case "param": functionType.params.add( valueType ); - return; + break; case "result": functionType.result = valueType; return; + case "local": + locals.add( valueType ); + break; + } + if( debugNames && name != null ) { + if( function.paramNames == null ) { + function.paramNames = new ArrayList<>(); + } + function.paramNames.add( name ); } } @@ -272,14 +300,13 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod * {@inheritDoc} */ @Override - protected void writeMethodParamFinish( List locals ) throws IOException { + protected void writeMethodParamFinish() throws IOException { int typeId = functionTypes.indexOf( functionType ); if( typeId < 0 ) { typeId = functionTypes.size(); functionTypes.add( functionType ); } function.typeId = typeId; - this.locals = locals; } /** diff --git a/src/de/inetsoftware/jwebassembly/binary/Function.java b/src/de/inetsoftware/jwebassembly/binary/Function.java index 7282a7a..db40c5c 100644 --- a/src/de/inetsoftware/jwebassembly/binary/Function.java +++ b/src/de/inetsoftware/jwebassembly/binary/Function.java @@ -1,5 +1,5 @@ /* - * Copyright 2017 Volker Berlin (i-net software) + * Copyright 2017 - 2018 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. @@ -16,6 +16,7 @@ package de.inetsoftware.jwebassembly.binary; import java.io.IOException; +import java.util.List; /** * An entry in the function section of the WebAssembly. @@ -28,6 +29,8 @@ class Function extends SectionEntry { int typeId; + List paramNames; + /** * {@inheritDoc} */ diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java index 6656e63..5273b28 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java @@ -29,6 +29,7 @@ import de.inetsoftware.classparser.Code; import de.inetsoftware.classparser.CodeInputStream; import de.inetsoftware.classparser.ConstantPool; import de.inetsoftware.classparser.ConstantRef; +import de.inetsoftware.classparser.LocalVariableTable; import de.inetsoftware.classparser.MethodInfo; import de.inetsoftware.jwebassembly.WasmException; @@ -130,7 +131,7 @@ public class ModuleGenerator { String impoarModule = (String)annotationValues.get( "module" ); String importName = (String)annotationValues.get( "name" ); writer.prepareImport( name, impoarModule, importName ); - writeMethodSignature( method ); + writeMethodSignature( method, null ); } else { writer.prepareFunction( name ); } @@ -162,7 +163,7 @@ public class ModuleGenerator { byteCode = code.getByteCode(); writeCode( byteCode, method.getConstantPool() ); localVariables.calculate(); - writeMethodSignature( method ); + writeMethodSignature( method, code.getLocalVariableTable() ); for( WasmInstruction instruction : instructions ) { instruction.writeTo( writer ); @@ -207,7 +208,7 @@ public class ModuleGenerator { * @throws WasmException * if some Java code can't converted */ - private void writeMethodSignature( MethodInfo method ) throws IOException, WasmException { + private void writeMethodSignature( MethodInfo method, LocalVariableTable variables ) throws IOException, WasmException { String signature = method.getDescription(); String kind = "param"; int paramCount = 0; @@ -217,16 +218,29 @@ public class ModuleGenerator { kind = "result"; continue; } + String name = null; if( kind == "param" ) { + if( variables != null ) { + name = variables.getPosition( paramCount ).getName( method.getConstantPool() ); + } paramCount++; } type = ValueType.getValueType( signature, i ); if( type != null ) { - writer.writeMethodParam( kind, type ); + writer.writeMethodParam( kind, type, name ); } } this.returnType = type; - writer.writeMethodParamFinish( localVariables.getLocalTypes( paramCount ) ); + List localTypes = localVariables.getLocalTypes( paramCount ); + for( int i = 0; i < localTypes.size(); i++ ) { + type = localTypes.get( i ); + String name = null; + if( variables != null ) { + name = variables.getPosition( paramCount ).getName( method.getConstantPool() ); + } + writer.writeMethodParam( "local", type, name ); + } + writer.writeMethodParamFinish( ); } /** diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java b/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java index fe7e924..cd0c5dc 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java @@ -17,7 +17,6 @@ package de.inetsoftware.jwebassembly.module; import java.io.Closeable; import java.io.IOException; -import java.util.List; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -90,22 +89,20 @@ public abstract class ModuleWriter implements Closeable { * "param", "result" or "local" * @param valueType * the data type of the parameter + * @param name + * optional name of the parameter * @throws IOException * if any I/O error occur */ - protected abstract void writeMethodParam( String kind, ValueType valueType ) throws IOException; + protected abstract void writeMethodParam( String kind, ValueType valueType, @Nullable String name ) throws IOException; /** * Finish the function parameter. * - * @param locals - * a list with types of local variables - * - * * @throws IOException * if any I/O error occur */ - protected abstract void writeMethodParamFinish( List locals ) throws IOException; + protected abstract void writeMethodParamFinish() throws IOException; /** * Complete the method diff --git a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java index 221e1f0..ad72457 100644 --- a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java @@ -18,12 +18,12 @@ package de.inetsoftware.jwebassembly.text; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; -import java.util.List; import javax.annotation.Nonnull; import javax.annotation.Nullable; import de.inetsoftware.classparser.ConstantRef; +import de.inetsoftware.jwebassembly.JWebAssembly; import de.inetsoftware.jwebassembly.module.FunctionName; import de.inetsoftware.jwebassembly.module.ModuleWriter; import de.inetsoftware.jwebassembly.module.NumericOperator; @@ -41,6 +41,8 @@ public class TextModuleWriter extends ModuleWriter { private Appendable output; + private final boolean debugNames; + private StringBuilder methodOutput = new StringBuilder(); private int inset; @@ -61,6 +63,7 @@ public class TextModuleWriter extends ModuleWriter { */ public TextModuleWriter( Appendable output, HashMap properties ) throws IOException { this.output = output; + debugNames = Boolean.parseBoolean( properties.get( JWebAssembly.DEBUG_NAMES ) ); output.append( "(module" ); inset++; } @@ -112,22 +115,22 @@ public class TextModuleWriter extends ModuleWriter { * {@inheritDoc} */ @Override - protected void writeMethodParam( String kind, ValueType valueType ) throws IOException { - methodOutput.append( " (" ).append( kind ).append( ' ' ).append( valueType.toString() ).append( ')' ); + protected void writeMethodParam( String kind, ValueType valueType, @Nullable String name ) throws IOException { + methodOutput.append( " (" ).append( kind ); + if( debugNames && name != null ) { + methodOutput.append( " $" ).append( name ); + } + methodOutput.append( ' ' ).append( valueType.toString() ).append( ')' ); } /** * {@inheritDoc} */ @Override - protected void writeMethodParamFinish( List locals ) throws IOException { + protected void writeMethodParamFinish( ) throws IOException { if( isImport ) { isImport = false; output.append( "))" ); - } else { - for( ValueType valueType : locals ) { - methodOutput.append( " (local " ).append( valueType.toString() ).append( ')' ); - } } }