+
+
+//-------------------------------------------------------------------------------------
+// Conversion functions
+//-------------------------------------------------------------------------------------
+
+// Converts an unsigned integer to the unsigned LEB128 format
+u8* uint_to_uleb128(u64 n, i32* output_length);
+u8* int_to_leb128(i64 n, i32* output_length);
+
+
+
+
+
//-------------------------------------------------------------------------------------
// Helpful macros
//-------------------------------------------------------------------------------------
typedef struct bh_buffer {
bh_allocator allocator;
i32 length, capacity;
- ptr data;
+ u8* data;
} bh_buffer;
#ifndef BH_BUFFER_GROW_FORMULA
void bh_buffer_init(bh_buffer* buffer, bh_allocator alloc, i32 length);
void bh_buffer_grow(bh_buffer* buffer, i32 length);
-void bh_buffer_append(bh_buffer* buffer, ptr data, i32 length);
+void bh_buffer_append(bh_buffer* buffer, const void * data, i32 length);
void bh_buffer_concat(bh_buffer* buffer, bh_buffer other);
+void bh_buffer_write_byte(bh_buffer* buffer, u8 byte);
+//-------------------------------------------------------------------------------------
+// CONVERSION FUNCTIONS IMPLEMENTATION
+//-------------------------------------------------------------------------------------
+u8* uint_to_uleb128(u64 n, i32* output_length) {
+ static u8 buffer[16];
+
+ *output_length = 0;
+ u8* output = buffer;
+ u8 byte;
+ do {
+ byte = n & 0x7f;
+ n >>= 7;
+ if (n != 0) byte |= (1 << 7);
+ *output++ = byte;
+ (*output_length)++;
+ } while (n != 0);
+
+ return buffer;
+}
+
+
+// Converts a signed integer to the signed LEB128 format
+u8* int_to_leb128(i64 n, i32* output_length) {
+ static u8 buffer[16];
+
+ *output_length = 0;
+ u8* output = buffer;
+ b32 more = 1;
+
+ i32 size = 64;
+
+ u8 byte;
+ do {
+ byte = n & 0x7f;
+ n >>= 7;
+
+ more = !(((n == 0) && (byte & 0x40) == 0) || ((n == -1) && (byte & 0x40) != 0));
+ if (more)
+ byte |= 0x80;
+ *output++ = byte;
+ (*output_length)++;
+ } while (more);
+
+ return buffer;
+}
buffer->data = new_data;
}
-void bh_buffer_append(bh_buffer* buffer, ptr data, i32 length) {
+void bh_buffer_append(bh_buffer* buffer, const void * data, i32 length) {
if (buffer == NULL) return;
if (buffer->length + length > buffer->capacity) {
bh_buffer_grow(buffer, buffer->length + length);
}
- memcpy(bh_pointer_add(buffer->data, buffer->length), data, length);
+ memcpy(buffer->data + buffer->length, data, length);
buffer->length += length;
}
bh_buffer_append(buffer, other.data, other.length);
}
+void bh_buffer_write_byte(bh_buffer* buffer, u8 byte) {
+ bh_buffer_grow(buffer, buffer->length + 1);
+ buffer->data[buffer->length++] = byte;
+}
bh_hash_free(module->type_map);
bh_hash_free(module->exports);
}
+
+static const u8 WASM_MAGIC_STRING[] = { 0x00, 0x61, 0x73, 0x6D };
+static const u8 WASM_VERSION[] = { 0x01, 0x00, 0x00, 0x00 };
+
+void onyx_wasm_module_write_to_file(OnyxWasmModule* module, bh_file file) {
+ bh_buffer master_buffer;
+ bh_buffer_init(&master_buffer, bh_heap_allocator(), 128);
+ bh_buffer_append(&master_buffer, WASM_MAGIC_STRING, 4);
+ bh_buffer_append(&master_buffer, WASM_VERSION, 4);
+
+
+
+
+
+
+
+ bh_file_write(&file, master_buffer.data, master_buffer.length);
+}