storing and loading _onyx_libs in wasm binary
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 5 Dec 2021 19:14:35 +0000 (13:14 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 5 Dec 2021 19:14:35 +0000 (13:14 -0600)
include/bh.h
src/wasm_output.h
src/wasm_runtime.c

index 84a37a582594706fd3909075c6e5e20595195a55..f223754e3b2de23b0be90ad8a7a87d234ae01ae2 100644 (file)
@@ -166,6 +166,7 @@ u8* int_to_leb128(i64 n, i32* output_length);
 u8* float_to_ieee754(f32 f, b32 reverse);
 u8* double_to_ieee754(f64 f, b32 reverse);
 
+u64 uleb128_to_uint(u8* bytes, i32 *byte_walker);
 
 
 
@@ -1217,6 +1218,18 @@ u8* double_to_ieee754(f64 f, b32 reverse) {
     return buffer;
 }
 
+u64 uleb128_to_uint(u8* bytes, i32 *byte_count) {
+    u64 res = 0;
+    u64 shift = 0;
+
+    while (1) {
+        u8 byte = bytes[(*byte_count)++];
+        res |= (byte & 0x7f) << shift;
+        if ((byte & 0x80) == 0) break;
+        shift += 7;
+    }
+    return res;
+}
 
 
 
index 2ebb9d9510de5a3e415573cf51a433fc6e7afaf9..d24e8d00e3f04ddaeb693fb0fb3c772f03e02d60 100644 (file)
@@ -5,6 +5,7 @@
 // BINARY OUPUT
 //-------------------------------------------------
 
+#define WASM_SECTION_ID_CUSTOM 0
 #define WASM_SECTION_ID_TYPE 1
 #define WASM_SECTION_ID_IMPORT 2
 #define WASM_SECTION_ID_FUNCTION 3
@@ -664,6 +665,42 @@ static i32 output_datasection(OnyxWasmModule* module, bh_buffer* buff) {
     return buff->length - prev_len;
 }
 
+static i32 output_onyx_libraries_section(OnyxWasmModule* module, bh_buffer* buff) {
+    if (bh_arr_length(module->libraries) == 0) return 0;
+    i32 prev_len = buff->length;
+
+    bh_buffer_write_byte(buff, WASM_SECTION_ID_CUSTOM);
+
+    bh_buffer libs_buff;
+    bh_buffer_init(&libs_buff, buff->allocator, 128);
+
+    const char *custom_name = "_onyx_libs";
+    i32 leb_len;
+    u8* leb = uint_to_uleb128(strlen(custom_name), &leb_len);
+    bh_buffer_append(&libs_buff, leb, leb_len);
+    bh_buffer_append(&libs_buff, custom_name, strlen(custom_name));
+
+    leb = uint_to_uleb128((u64) bh_arr_length(module->libraries), &leb_len);
+    bh_buffer_append(&libs_buff, leb, leb_len);
+
+    bh_arr_each(char *, lib, module->libraries) {
+        assert(*lib != NULL);
+
+        u32 lib_len = strlen(*lib);
+        leb = uint_to_uleb128((u64) lib_len, &leb_len);
+        bh_buffer_append(&libs_buff, leb, leb_len);
+        bh_buffer_append(&libs_buff, *lib, lib_len);
+    }
+
+    leb = uint_to_uleb128((u64) (libs_buff.length), &leb_len);
+    bh_buffer_append(buff, leb, leb_len);
+
+    bh_buffer_concat(buff, libs_buff);
+    bh_buffer_free(&libs_buff);
+
+    return buff->length - prev_len;
+}
+
 void onyx_wasm_module_write_to_buffer(OnyxWasmModule* module, bh_buffer* buffer) {
     bh_buffer_init(buffer, global_heap_allocator, 128);
     bh_buffer_append(buffer, WASM_MAGIC_STRING, 4);
@@ -681,6 +718,7 @@ void onyx_wasm_module_write_to_buffer(OnyxWasmModule* module, bh_buffer* buffer)
     output_datacountsection(module, buffer);
     output_codesection(module, buffer);
     output_datasection(module, buffer);
+    output_onyx_libraries_section(module, buffer);
 }
 
 void onyx_wasm_module_write_to_file(OnyxWasmModule* module, bh_file file) {
index 735691d7f481c08694b9461a11b173538fbd543b..3eda2b283c73f368cf24b59b90beec6f5556f032 100644 (file)
@@ -524,20 +524,43 @@ static void onyx_load_library(char *name) {
     bh_arr_push(linkable_functions, funcs);
 }
 
-// NOCHECKIN TEMPORARY HACK
-// NOCHECKIN TEMPORARY HACK
-// NOCHECKIN TEMPORARY HACK
-#include "wasm_emit.h"
+static void onyx_lookup_and_load_custom_libraries(bh_buffer wasm_bytes) {
+    i32 cursor = 8; // skip the magic number and version
+    while (1) {
+        u64 section_number = uleb128_to_uint(wasm_bytes.data, &cursor);
+        u64 section_size   = uleb128_to_uint(wasm_bytes.data, &cursor);
+
+        i32 section_start = cursor;
+        if (section_number == 0) {
+            u64 name_len = uleb128_to_uint(wasm_bytes.data, &cursor);
+            if (!strncmp(wasm_bytes.data + cursor, "_onyx_libs", name_len)) {
+                cursor += name_len;
+                u64 lib_count = uleb128_to_uint(wasm_bytes.data, &cursor);
+
+                fori (i, 0, (i64) lib_count) {
+                    u64 lib_name_length = uleb128_to_uint(wasm_bytes.data, &cursor);
+                    lib_name_length = bh_min(lib_name_length, 256);
+
+                    char library_name[256];
+                    strncpy(library_name, wasm_bytes.data + cursor, lib_name_length);
+                    library_name[lib_name_length] = '\0';
+                    cursor += lib_name_length;
+
+                    onyx_load_library(library_name);
+                }
+                break;
+            }
+        }
+
+        cursor = section_start + section_size;
+    }
+}
 
 // Returns 1 if successful
 b32 onyx_run_wasm(bh_buffer wasm_bytes) {
     bh_arr_new(global_heap_allocator, linkable_functions, 4);
 
-    // NOCHECKIN TEMPORARY HACK
-    OnyxWasmModule* onyx_wasm_module = (OnyxWasmModule *) context.wasm_module;
-    bh_arr_each(char *, library_name, onyx_wasm_module->libraries) {
-        onyx_load_library(*library_name);
-    }
+    onyx_lookup_and_load_custom_libraries(wasm_bytes);
 
     wasm_instance_t* instance = NULL;
     wasmer_features_t* features = NULL;