Remove duplicate function types from type section.

This commit is contained in:
Volker Berlin 2018-05-30 21:19:01 +02:00
parent 19edad4898
commit ce78f9fe7a
3 changed files with 57 additions and 31 deletions

View File

@ -26,14 +26,13 @@ import java.util.Map;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import de.inetsoftware.classparser.MethodInfo;
import de.inetsoftware.jwebassembly.WasmException; import de.inetsoftware.jwebassembly.WasmException;
import de.inetsoftware.jwebassembly.module.WasmBlockOperator;
import de.inetsoftware.jwebassembly.module.FunctionName; import de.inetsoftware.jwebassembly.module.FunctionName;
import de.inetsoftware.jwebassembly.module.ModuleWriter; import de.inetsoftware.jwebassembly.module.ModuleWriter;
import de.inetsoftware.jwebassembly.module.NumericOperator; import de.inetsoftware.jwebassembly.module.NumericOperator;
import de.inetsoftware.jwebassembly.module.ValueType; import de.inetsoftware.jwebassembly.module.ValueType;
import de.inetsoftware.jwebassembly.module.ValueTypeConvertion; import de.inetsoftware.jwebassembly.module.ValueTypeConvertion;
import de.inetsoftware.jwebassembly.module.WasmBlockOperator;
/** /**
* Module Writer for binary format. http://webassembly.org/docs/binary-encoding/ * Module Writer for binary format. http://webassembly.org/docs/binary-encoding/
@ -58,7 +57,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
private Map<String, String> exports = new LinkedHashMap<>(); private Map<String, String> exports = new LinkedHashMap<>();
private Map<String, ImportEntry> imports = new LinkedHashMap<>(); private Map<String, ImportFunction> imports = new LinkedHashMap<>();
private Function function; private Function function;
@ -132,16 +131,15 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
if( count > 0 ) { if( count > 0 ) {
WasmOutputStream stream = new WasmOutputStream(); WasmOutputStream stream = new WasmOutputStream();
stream.writeVaruint32( count ); stream.writeVaruint32( count );
for( ImportEntry entry : imports.values() ) { for( ImportFunction importFunction : imports.values() ) {
byte[] bytes = entry.module.getBytes( StandardCharsets.UTF_8 ); byte[] bytes = importFunction.module.getBytes( StandardCharsets.UTF_8 );
stream.writeVaruint32( bytes.length ); stream.writeVaruint32( bytes.length );
stream.write( bytes ); stream.write( bytes );
bytes = entry.name.getBytes( StandardCharsets.UTF_8 ); bytes = importFunction.name.getBytes( StandardCharsets.UTF_8 );
stream.writeVaruint32( bytes.length ); stream.writeVaruint32( bytes.length );
stream.write( bytes ); stream.write( bytes );
stream.writeVaruint32( ExternalKind.Function.ordinal() ); stream.writeVaruint32( ExternalKind.Function.ordinal() );
int typeIdx = 0; //TODO stream.writeVaruint32( importFunction.typeId );
stream.writeVaruint32( typeIdx );
} }
wasm.writeSection( SectionType.Import, stream, null ); wasm.writeSection( SectionType.Import, stream, null );
} }
@ -212,7 +210,10 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
@Override @Override
protected void prepareFunction( FunctionName name, String importModule, String importName ) { protected void prepareFunction( FunctionName name, String importModule, String importName ) {
if( importName != null ) { if( importName != null ) {
imports.put( name.signatureName, new ImportEntry(importModule, importName) ); ImportFunction importFunction;
function = importFunction = new ImportFunction(importModule, importName);
imports.put( name.signatureName, importFunction );
functionType = new FunctionType();
} else { } else {
functions.put( name.signatureName, new Function() ); functions.put( name.signatureName, new Function() );
} }
@ -226,7 +227,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
// initialize the function index IDs // initialize the function index IDs
// https://github.com/WebAssembly/design/blob/master/Modules.md#function-index-space // https://github.com/WebAssembly/design/blob/master/Modules.md#function-index-space
int id = 0; int id = 0;
for( ImportEntry entry : imports.values() ) { for( ImportFunction entry : imports.values() ) {
entry.id = id++; entry.id = id++;
} }
for( Function function : functions.values() ) { for( Function function : functions.values() ) {
@ -272,9 +273,12 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
*/ */
@Override @Override
protected void writeMethodFinish( List<ValueType> locals ) throws IOException { protected void writeMethodFinish( List<ValueType> locals ) throws IOException {
// TODO optimize and search for duplicates int typeId = functionTypes.indexOf( functionType );
function.typeId = functionTypes.size(); if( typeId < 0 ) {
typeId = functionTypes.size();
functionTypes.add( functionType ); functionTypes.add( functionType );
}
function.typeId = typeId;
WasmOutputStream localsStream = new WasmOutputStream(); WasmOutputStream localsStream = new WasmOutputStream();
@ -656,7 +660,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod
if( func != null ) { if( func != null ) {
id = func.id; id = func.id;
} else { } else {
ImportEntry entry = imports.get( name ); ImportFunction entry = imports.get( name );
if( entry != null ) { if( entry != null ) {
id = entry.id; id = entry.id;
} else { } else {

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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@ package de.inetsoftware.jwebassembly.binary;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
import de.inetsoftware.jwebassembly.module.ValueType; import de.inetsoftware.jwebassembly.module.ValueType;
@ -27,7 +28,30 @@ import de.inetsoftware.jwebassembly.module.ValueType;
*/ */
class FunctionType { class FunctionType {
List<ValueType> params = new ArrayList<>(); final List<ValueType> params = new ArrayList<>();
ValueType result; // Java has only one return parameter ValueType result; // Java has only one return parameter
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
return params.hashCode() + 31 * Objects.hashCode( result );
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals( Object obj ) {
if( obj == this ) {
return true;
}
if( obj == null || obj.getClass() != getClass() ) {
return false;
}
FunctionType type = (FunctionType)obj;
return Objects.equals( params, type.params ) && Objects.equals( result, type.result );
}
} }

View File

@ -20,15 +20,13 @@ package de.inetsoftware.jwebassembly.binary;
* *
* @author Volker Berlin * @author Volker Berlin
*/ */
class ImportEntry { class ImportFunction extends Function {
final String module; final String module;
final String name; final String name;
int id; ImportFunction( String module, String name ) {
public ImportEntry( String module, String name ) {
this.module = module; this.module = module;
this.name = name; this.name = name;
} }