From 2d2a5f4b681117e4e6366dbe7492d153c4ab5f29 Mon Sep 17 00:00:00 2001 From: Volker Berlin Date: Wed, 27 Feb 2019 21:55:55 +0100 Subject: [PATCH] write event section if exception handling is used. --- .../binary/BinaryModuleWriter.java | 42 ++++++++++++++++++- .../jwebassembly/module/ModuleGenerator.java | 9 ++++ .../jwebassembly/module/ModuleWriter.java | 8 ++++ .../module/WasmBlockInstruction.java | 9 +++- .../jwebassembly/text/TextModuleWriter.java | 17 ++++++++ 5 files changed, 82 insertions(+), 3 deletions(-) diff --git a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java index d6df8c8..216b43b 100644 --- a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java @@ -64,7 +64,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod private Map functions = new LinkedHashMap<>(); - private List locals = new ArrayList<>(); + private List locals = new ArrayList<>(); private Map globals = new LinkedHashMap<>(); @@ -74,7 +74,9 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod private Function function; - private FunctionTypeEntry functionType; + private FunctionTypeEntry functionType; + + private int exceptionSignatureIndex = -1; /** * Create new instance. @@ -109,6 +111,7 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod writeSection( SectionType.Import, imports.values() ); writeSection( SectionType.Function, functions.values() ); writeSection( SectionType.Global, globals.values() ); + writeEventSection(); writeExportSection(); writeCodeSection(); writeDebugNames(); @@ -138,6 +141,25 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod } } + /** + * Write the event section if needed. + * + * @throws IOException + * if any I/O error occur + */ + private void writeEventSection() throws IOException { + if( exceptionSignatureIndex >= 0 ) { + WasmOutputStream stream = new WasmOutputStream(); + stream.writeVaruint32( 1 ); + + // event declaration + stream.writeVaruint32( 0 ); // event type: exception = 0 + stream.writeVaruint32( exceptionSignatureIndex ); + + wasm.writeSection( SectionType.Export, stream ); + } + } + /** * Write the export section to the output. This section contains a mapping from the external index to the type signature index. * @@ -238,6 +260,22 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod return typeId; } + /** + * {@inheritDoc} + */ + @Override + protected void writeException() throws IOException { + if( exceptionSignatureIndex <= 0 ) { + FunctionTypeEntry exceptionType = new FunctionTypeEntry(); + exceptionType.params.add( ValueType.anyref ); + exceptionSignatureIndex = functionTypes.indexOf( exceptionType ); + if( exceptionSignatureIndex < 0 ) { + exceptionSignatureIndex = functionTypes.size(); + functionTypes.add( exceptionType ); + } + } + } + /** * {@inheritDoc} */ diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java index 11092b5..a86dbde 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleGenerator.java @@ -371,6 +371,15 @@ public class ModuleGenerator { optimizer.optimze( instructions ); for( WasmInstruction instruction : instructions ) { switch( instruction.getType() ) { + case Block: + switch( ((WasmBlockInstruction)instruction).getOperation() ) { + case TRY: + case CATCH: + writer.writeException(); + break; + default: + } + break; case Call: functions.functionCall( ((WasmCallInstruction)instruction).getFunctionName() ); break; diff --git a/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java b/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java index 4cd1c6d..c3e05fe 100644 --- a/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/module/ModuleWriter.java @@ -60,6 +60,14 @@ public abstract class ModuleWriter implements Closeable { */ protected abstract int writeStruct( String typeName, List fields ) throws IOException; + /** + * Mark to write exceptions + * + * @throws IOException + * if any I/O error occur + */ + protected abstract void writeException() throws IOException; + /** * Prepare a imported single function in the prepare phase. * diff --git a/src/de/inetsoftware/jwebassembly/module/WasmBlockInstruction.java b/src/de/inetsoftware/jwebassembly/module/WasmBlockInstruction.java index 8547485..9d5ea96 100644 --- a/src/de/inetsoftware/jwebassembly/module/WasmBlockInstruction.java +++ b/src/de/inetsoftware/jwebassembly/module/WasmBlockInstruction.java @@ -21,7 +21,6 @@ import java.io.IOException; import javax.annotation.Nonnull; import javax.annotation.Nullable; -import de.inetsoftware.jwebassembly.module.WasmInstruction.Type; import de.inetsoftware.jwebassembly.wasm.AnyType; import de.inetsoftware.jwebassembly.wasm.ValueType; import de.inetsoftware.jwebassembly.wasm.WasmBlockOperator; @@ -62,6 +61,14 @@ class WasmBlockInstruction extends WasmInstruction { return Type.Block; } + /** + * Get the operation + * @return the op + */ + WasmBlockOperator getOperation() { + return op; + } + /** * {@inheritDoc} */ diff --git a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java index d212827..3c34910 100644 --- a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java @@ -57,6 +57,8 @@ public class TextModuleWriter extends ModuleWriter { private HashSet globals = new HashSet<>(); + private boolean useExceptions; + /** * Create a new instance. * @@ -117,6 +119,21 @@ public class TextModuleWriter extends ModuleWriter { return 0; } + /** + * {@inheritDoc} + */ + @Override + protected void writeException() throws IOException { + if( !useExceptions ) { + useExceptions = true; + int oldInset = inset; + inset = 1; + newline( output ); + output.append( "(event (param anyref))" ); + inset = oldInset; + } + } + /** * {@inheritDoc} */