write local method names if DebugNames is enabled

This commit is contained in:
Volker Berlin 2018-10-13 18:10:05 +02:00
parent 103ae245a9
commit 563075a578
5 changed files with 70 additions and 26 deletions

View File

@ -62,7 +62,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
private Map<String, Function> functions = new LinkedHashMap<>();
private List<ValueType> locals;
private List<ValueType> locals = new ArrayList<>();
private Map<String, Global> 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<String, Function> entry : functions.entrySet() ) {
Function func = entry.getValue();
section.writeVaruint32( func.id ); // function index
List<String> 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<ValueType> 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;
}
/**

View File

@ -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<String> paramNames;
/**
* {@inheritDoc}
*/

View File

@ -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<ValueType> 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( );
}
/**

View File

@ -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<ValueType> locals ) throws IOException;
protected abstract void writeMethodParamFinish() throws IOException;
/**
* Complete the method

View File

@ -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<String, String> 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<ValueType> 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( ')' );
}
}
}