diff options
| author | Michael Williamson <mike@zwobble.org> | 2023-06-21 20:59:37 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2023-06-21 20:59:37 +0100 |
| commit | b92d46a9fc641afca93571e1b398b968816b1b57 (patch) | |
| tree | 63e8f70e5a06b632e2e6de7bbb982fabc0820c5e /src/main/java | |
| parent | 46471000c1851940777f6dce77fa9a4bc2fe877c (diff) | |
Add LEB128 encoding
Diffstat (limited to 'src/main/java')
| -rw-r--r-- | src/main/java/org/shedlang/compiler/backends/wasm/structure/BinaryWriter.java | 57 | ||||
| -rw-r--r-- | src/main/java/org/shedlang/compiler/backends/wasm/structure/Leb128Encoding.java | 65 |
2 files changed, 122 insertions, 0 deletions
diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/BinaryWriter.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/BinaryWriter.java new file mode 100644 index 00000000..d5600a5c --- /dev/null +++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/BinaryWriter.java @@ -0,0 +1,57 @@ +package org.shedlang.compiler.backends.wasm.structure; + +import java.nio.ByteBuffer; + +public class BinaryWriter { + private ByteBuffer buffer = ByteBuffer.allocate(1024); + + public void writeByte(byte value) { + ensureSpareCapacity(1); + buffer.put(value); + } + + public void writeBytes(byte[] bytes) { + ensureSpareCapacity(bytes.length); + buffer.put(bytes, 0, bytes.length); + } + + public ReservedBytes reserve(int length) { + var position = buffer.position(); + advance(length); + return new ReservedBytes(position); + } + + private void ensureSpareCapacity(int length) { + ensureCapacity(buffer.position() + length); + } + + private void ensureCapacity(int minCapacity) { + if (minCapacity > buffer.capacity()) { + var newCapacity = buffer.capacity() * 2; + while (minCapacity > newCapacity) { + newCapacity *= 2; + } + var newBuffer = ByteBuffer.allocate(newCapacity); + buffer.flip(); + newBuffer.put(buffer); + buffer = newBuffer; + } + } + + private void advance(int length) { + ensureSpareCapacity(length); + buffer.position(buffer.position() + length); + } + + public byte[] toBytes() { + var result = new byte[buffer.position()]; + buffer.get(0, result); + return result; + } + + public static class ReservedBytes { + public ReservedBytes(int position) { + + } + } +} diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/Leb128Encoding.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/Leb128Encoding.java new file mode 100644 index 00000000..bcd7de5f --- /dev/null +++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/Leb128Encoding.java @@ -0,0 +1,65 @@ +package org.shedlang.compiler.backends.wasm.structure; + +public class Leb128Encoding { + private Leb128Encoding() { + } + + static void encodeUnsignedInt32(int value, BinaryWriter writer) { + while (true) { + var nextByte = value & 0x7f; + value >>>= 7; + if (value == 0) { + writer.writeByte((byte) nextByte); + return; + } else { + writer.writeByte((byte) (nextByte | 0x80)); + } + } + } + + static void encodePaddedUnsignedInt32(int value, BinaryWriter writer) { + for (var byteIndex = 0; byteIndex < 4; byteIndex++) { + var nextByte = value & 0x7f; + writer.writeByte((byte) (nextByte | 0x80)); + value >>>= 7; + } + writer.writeByte((byte) value); + } + + static void encodeSignedInt32(int value, BinaryWriter writer) { + if (value >= 0) { + while (true) { + if ((value >> 6) == 0) { + writer.writeByte((byte) value); + return; + } else { + writer.writeByte((byte) ((value & 0x7f) | 0x80)); + value >>= 7; + } + } + } else { + while (true) { + if ((value >> 6) == -1) { + writer.writeByte((byte) (value & 0x7f)); + return; + } else { + writer.writeByte((byte) ((value & 0x7f) | 0x80)); + value >>= 7; + } + } + } + } + + static void encodePaddedSignedInt32(int value, BinaryWriter writer) { + if (value > 0) { + encodePaddedUnsignedInt32(value, writer); + } else { + for (var byteIndex = 0; byteIndex < 4; byteIndex++) { + var nextByte = value & 0x7f; + writer.writeByte((byte) (nextByte | 0x80)); + value >>= 7; + } + writer.writeByte((byte) (value & 0x7f)); + } + } +} |
