diff --git a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java index d9b1e78..ad1cb28 100644 --- a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java @@ -26,14 +26,13 @@ import java.util.Map; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import de.inetsoftware.classparser.MethodInfo; import de.inetsoftware.jwebassembly.WasmException; -import de.inetsoftware.jwebassembly.module.WasmBlockOperator; import de.inetsoftware.jwebassembly.module.FunctionName; import de.inetsoftware.jwebassembly.module.ModuleWriter; import de.inetsoftware.jwebassembly.module.NumericOperator; import de.inetsoftware.jwebassembly.module.ValueType; import de.inetsoftware.jwebassembly.module.ValueTypeConvertion; +import de.inetsoftware.jwebassembly.module.WasmBlockOperator; /** * Module Writer for binary format. http://webassembly.org/docs/binary-encoding/ @@ -42,27 +41,27 @@ import de.inetsoftware.jwebassembly.module.ValueTypeConvertion; */ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcodes { - private static final byte[] WASM_BINARY_MAGIC = { 0, 'a', 's', 'm' }; + private static final byte[] WASM_BINARY_MAGIC = { 0, 'a', 's', 'm' }; - private static final int WASM_BINARY_VERSION = 1; + private static final int WASM_BINARY_VERSION = 1; - private WasmOutputStream wasm; + private WasmOutputStream wasm; - private WasmOutputStream codeStream = new WasmOutputStream(); + private WasmOutputStream codeStream = new WasmOutputStream(); - private WasmOutputStream functionsStream = new WasmOutputStream(); + private WasmOutputStream functionsStream = new WasmOutputStream(); - private List functionTypes = new ArrayList<>(); + private List functionTypes = new ArrayList<>(); - private Map functions = new LinkedHashMap<>(); + private Map functions = new LinkedHashMap<>(); - private Map exports = new LinkedHashMap<>(); + private Map exports = new LinkedHashMap<>(); - private Map imports = new LinkedHashMap<>(); + private Map imports = new LinkedHashMap<>(); - private Function function; + private Function function; - private FunctionType functionType; + private FunctionType functionType; /** * Create new instance. @@ -132,16 +131,15 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod if( count > 0 ) { WasmOutputStream stream = new WasmOutputStream(); stream.writeVaruint32( count ); - for( ImportEntry entry : imports.values() ) { - byte[] bytes = entry.module.getBytes( StandardCharsets.UTF_8 ); + for( ImportFunction importFunction : imports.values() ) { + byte[] bytes = importFunction.module.getBytes( StandardCharsets.UTF_8 ); stream.writeVaruint32( bytes.length ); stream.write( bytes ); - bytes = entry.name.getBytes( StandardCharsets.UTF_8 ); + bytes = importFunction.name.getBytes( StandardCharsets.UTF_8 ); stream.writeVaruint32( bytes.length ); stream.write( bytes ); stream.writeVaruint32( ExternalKind.Function.ordinal() ); - int typeIdx = 0; //TODO - stream.writeVaruint32( typeIdx ); + stream.writeVaruint32( importFunction.typeId ); } wasm.writeSection( SectionType.Import, stream, null ); } @@ -212,7 +210,10 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod @Override protected void prepareFunction( FunctionName name, String importModule, String importName ) { 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 { functions.put( name.signatureName, new Function() ); } @@ -226,7 +227,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod // initialize the function index IDs // https://github.com/WebAssembly/design/blob/master/Modules.md#function-index-space int id = 0; - for( ImportEntry entry : imports.values() ) { + for( ImportFunction entry : imports.values() ) { entry.id = id++; } for( Function function : functions.values() ) { @@ -272,9 +273,12 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod */ @Override protected void writeMethodFinish( List locals ) throws IOException { - // TODO optimize and search for duplicates - function.typeId = functionTypes.size(); - functionTypes.add( functionType ); + int typeId = functionTypes.indexOf( functionType ); + if( typeId < 0 ) { + typeId = functionTypes.size(); + functionTypes.add( functionType ); + } + function.typeId = typeId; WasmOutputStream localsStream = new WasmOutputStream(); @@ -656,7 +660,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod if( func != null ) { id = func.id; } else { - ImportEntry entry = imports.get( name ); + ImportFunction entry = imports.get( name ); if( entry != null ) { id = entry.id; } else { diff --git a/src/de/inetsoftware/jwebassembly/binary/FunctionType.java b/src/de/inetsoftware/jwebassembly/binary/FunctionType.java index 31ebdc5..33bb3b4 100644 --- a/src/de/inetsoftware/jwebassembly/binary/FunctionType.java +++ b/src/de/inetsoftware/jwebassembly/binary/FunctionType.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. @@ -17,6 +17,7 @@ package de.inetsoftware.jwebassembly.binary; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import de.inetsoftware.jwebassembly.module.ValueType; @@ -27,7 +28,30 @@ import de.inetsoftware.jwebassembly.module.ValueType; */ class FunctionType { - List params = new ArrayList<>(); + final List 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 ); + } } diff --git a/src/de/inetsoftware/jwebassembly/binary/ImportEntry.java b/src/de/inetsoftware/jwebassembly/binary/ImportFunction.java similarity index 90% rename from src/de/inetsoftware/jwebassembly/binary/ImportEntry.java rename to src/de/inetsoftware/jwebassembly/binary/ImportFunction.java index d172081..d33a4ad 100644 --- a/src/de/inetsoftware/jwebassembly/binary/ImportEntry.java +++ b/src/de/inetsoftware/jwebassembly/binary/ImportFunction.java @@ -20,15 +20,13 @@ package de.inetsoftware.jwebassembly.binary; * * @author Volker Berlin */ -class ImportEntry { +class ImportFunction extends Function { final String module; final String name; - int id; - - public ImportEntry( String module, String name ) { + ImportFunction( String module, String name ) { this.module = module; this.name = name; }