aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-06-21 20:59:37 +0100
committerMichael Williamson <mike@zwobble.org>2023-06-21 20:59:37 +0100
commitb92d46a9fc641afca93571e1b398b968816b1b57 (patch)
tree63e8f70e5a06b632e2e6de7bbb982fabc0820c5e /src/main/java
parent46471000c1851940777f6dce77fa9a4bc2fe877c (diff)
Add LEB128 encoding
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/structure/BinaryWriter.java57
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/structure/Leb128Encoding.java65
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));
+ }
+ }
+}