diff --git a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java index c5c9d4b..9fb60b6 100644 --- a/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/binary/BinaryModuleWriter.java @@ -63,6 +63,8 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod private final boolean createSourceMap; + private WasmOutputStream dataStream = new WasmOutputStream(); + private WasmOutputStream codeStream = new WasmOutputStream(); private List functionTypes = new ArrayList<>(); @@ -121,10 +123,12 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod writeSection( SectionType.Type, functionTypes ); writeSection( SectionType.Import, imports.values() ); writeSection( SectionType.Function, functions.values() ); + writeMemorySection(); writeSection( SectionType.Global, globals.values() ); writeEventSection(); writeExportSection(); writeCodeSection(); + writeDataSection(); writeDebugNames(); writeSourceMappingUrl(); writeProducersSection(); @@ -154,6 +158,25 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod } } + /** + * Write the memory section. + * + * @throws IOException + * if any I/O error occur + */ + private void writeMemorySection() throws IOException { + WasmOutputStream stream = new WasmOutputStream(); + int pages = (dataStream.size() + 0xFFFF) / 0x10000; // a page is defined with a size of 64KiB + int count = 1; + stream.writeVaruint32( count ); + for( int i = 0; i < count; i++ ) { + stream.writeVaruint32( 1 ); // flags; 1-maximum is available, 0-no maximum value available + stream.writeVaruint32( pages ); // initial length + stream.writeVaruint32( pages ); // maximum length + } + wasm.writeSection( SectionType.Memory, stream ); + } + /** * Write the event section if needed. * @@ -233,6 +256,31 @@ public class BinaryModuleWriter extends ModuleWriter implements InstructionOpcod } } + /** + * Write the data section + * + * @throws IOException + * if any I/O error occur + */ + private void writeDataSection() throws IOException { + int size = dataStream.size(); + if( size == 0 ) { + return; + } + + WasmOutputStream stream = new WasmOutputStream(); + stream.writeVaruint32( 1 ); // count, we use one large segment + + // one data segment + stream.writeVaruint32( 0 ); // index (0 in the MVP) + stream.writeConst( 0, ValueType.i32 ); // the offset on which the data start + stream.writeOpCode( END ); // end of offset instruction + stream.writeVaruint32( size ); + dataStream.writeTo( stream ); + + wasm.writeSection( SectionType.Data, stream ); + } + /** * Write optional the debug names into the name section * diff --git a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java index bb3f29e..d802031 100644 --- a/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java +++ b/src/de/inetsoftware/jwebassembly/text/TextModuleWriter.java @@ -15,6 +15,7 @@ */ package de.inetsoftware.jwebassembly.text; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -52,6 +53,8 @@ public class TextModuleWriter extends ModuleWriter { private final boolean debugNames; + private final ByteArrayOutputStream dataStream = new ByteArrayOutputStream(); + private final ArrayList methodParamNames = new ArrayList<>(); private StringBuilder methodOutput = new StringBuilder(); @@ -90,6 +93,22 @@ public class TextModuleWriter extends ModuleWriter { @Override public void close() throws IOException { output.append( methodOutput ); + + int dataSize = dataStream.size(); + if( dataSize > 0 ) { + int pages = (dataSize + 0xFFFF) / 0x10000; + newline( output ); + String pagesStr = Integer.toString( pages ); + output.append( "(memory " ).append( pagesStr ).append( ' ' ).append( pagesStr ).append( ')' ); + newline( output ); + output.append( "(data (i32.const 0) \"" ); + byte[] data = dataStream.toByteArray(); + for( byte b : data ) { + output.append( '\\' ).append( Character.forDigit( (b >> 4) & 0xF, 16 ) ).append( Character.forDigit( b & 0xF, 16 ) ); + } + output.append( "\")" ); + } + inset--; newline( output ); output.append( ')' );