fixed critical bug with how unsigned integers were parsed for interpretter
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 26 Sep 2022 18:54:59 +0000 (13:54 -0500)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Mon, 26 Sep 2022 18:54:59 +0000 (13:54 -0500)
core/conv.onyx
interpreter/src/vm/vm.c
interpreter/src/wasm/module_parsing.h
shared/include/bh.h
shared/lib/linux_x86_64/lib/libovmwasm.so

index 81c5e95ca6941165eac494b3322e76901af936f9..11de869decdd0685a40bef664c56a98b0dd4d0f7 100644 (file)
@@ -226,6 +226,58 @@ i64_to_str :: (n: i64, base: u64, buf: [] u8, min_length := 0, prefix := false)
     return str.{ data = c + 1, count = len };
 }
 
+u64_to_str :: (n: u64, base: u64, buf: [] u8, min_length := 0, prefix := false) -> str {
+    c := ^buf[buf.count - 1];
+    len := 0;
+
+    BASE64_MAP := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
+
+    while n > 0 {
+        m := cast(u64) n % base;
+
+        *c = BASE64_MAP[cast(u32) m];
+        len += 1;
+        c -= 1;
+
+        n /= base;
+
+    } else {
+        *c = #char "0";
+        len += 1;
+        c -= 1;
+    }
+
+    if min_length > 0 && len < min_length {
+        for i: min_length - len {
+            *c = #char "0";
+            len += 1;
+            c -= 1;
+        }
+    }
+
+    if prefix {
+        if base == 16 {
+            *c = #char "x";
+            len += 1;
+            c -= 1;
+            *c = #char "0";
+            len += 1;
+            c -= 1;
+        }
+
+        if base == 2 {
+            *c = #char "b";
+            len += 1;
+            c -= 1;
+            *c = #char "0";
+            len += 1;
+            c -= 1;
+        }
+    }
+
+    return str.{ data = c + 1, count = len };
+}
+
 // This is better than what used to be, but still relies on converting the integer
 // part of the float to an integer, which could overflow.
 f64_to_str :: (f: f64, buf: [] u8, digits_after_decimal := 4) -> str {
@@ -556,13 +608,23 @@ format_any :: (output: ^Format_Output, formatting: ^Format, v: any) {
             }
         }
 
+        uint_case :: macro (T: type_expr) {
+            case T {
+                value := *(cast(^T) v.data);
+
+                ibuf : [128] u8;
+                istr := u64_to_str(~~value, formatting.base, ~~ibuf, min_length=formatting.minimum_width);
+                output->write(istr);
+            }
+        }
+
         int_case(i8);
         int_case(i16);
-        int_case(u16);
         int_case(i32);
-        int_case(u32);
         int_case(i64);
-        int_case(u64);
+        uint_case(u16);
+        uint_case(u32);
+        uint_case(u64);
 
         case f32 {
             value := *(cast(^f32) v.data);
index aa7e8d328ebfb0ab8196c530298d3b0cac64e51e..551c6caa023b3248c7b40b17cf1c3dd553b8c736 100644 (file)
@@ -982,10 +982,10 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t
                 VAL(instr.r).dtype = instr.stype; \
                 break;
 
-            OVM_IMM(OVM_TYPE_I8,  i8,  i)
-            OVM_IMM(OVM_TYPE_I16, i16, i)
-            OVM_IMM(OVM_TYPE_I32, i32, i)
-            OVM_IMM(OVM_TYPE_I64, i64, l)
+            OVM_IMM(OVM_TYPE_I8,  u8,  i)
+            OVM_IMM(OVM_TYPE_I16, u16, i)
+            OVM_IMM(OVM_TYPE_I32, u32, i)
+            OVM_IMM(OVM_TYPE_I64, u64, l)
             OVM_IMM(OVM_TYPE_F32, f32, f)
             OVM_IMM(OVM_TYPE_F64, f64, d)
 
@@ -1009,10 +1009,10 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t
                 break; \
             }
 
-            OVM_LOAD(OVM_TYPE_I8,  i8)
-            OVM_LOAD(OVM_TYPE_I16, i16)
-            OVM_LOAD(OVM_TYPE_I32, i32)
-            OVM_LOAD(OVM_TYPE_I64, i64)
+            OVM_LOAD(OVM_TYPE_I8,  u8)
+            OVM_LOAD(OVM_TYPE_I16, u16)
+            OVM_LOAD(OVM_TYPE_I32, u32)
+            OVM_LOAD(OVM_TYPE_I64, u64)
             OVM_LOAD(OVM_TYPE_F32, f32)
             OVM_LOAD(OVM_TYPE_F64, f64)
 
@@ -1024,10 +1024,10 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t
                 *(stype *) &((u8 *) engine->memory)[VAL(instr.r).u32 + (u32) instr.b] = VAL(instr.a).stype; \
                 break;
 
-            OVM_STORE(OVM_TYPE_I8,  i8)
-            OVM_STORE(OVM_TYPE_I16, i16)
-            OVM_STORE(OVM_TYPE_I32, i32)
-            OVM_STORE(OVM_TYPE_I64, i64)
+            OVM_STORE(OVM_TYPE_I8,  u8)
+            OVM_STORE(OVM_TYPE_I16, u16)
+            OVM_STORE(OVM_TYPE_I32, u32)
+            OVM_STORE(OVM_TYPE_I64, u64)
             OVM_STORE(OVM_TYPE_F32, f32)
             OVM_STORE(OVM_TYPE_F64, f64)
 
index 8eade3047c42c2179f4958ed5ebd809db04e121d..ce36d5d00aab506815fe152e7be0cd65d182a5b6 100644 (file)
@@ -727,7 +727,7 @@ static void parse_instruction(build_context *ctx) {
         }
 
         case 0x41: {
-            long long value = leb128_to_int(ctx->binary.data, &ctx->offset);
+            i64 value = leb128_to_int(ctx->binary.data, &ctx->offset);
 
             // NOTE: This assumes a little-endian CPU as the address is assumes
             // to be the least significant byte.
@@ -736,7 +736,7 @@ static void parse_instruction(build_context *ctx) {
         }
 
         case 0x42: {
-            long long value = leb128_to_int(ctx->binary.data, &ctx->offset);
+            i64 value = leb128_to_int(ctx->binary.data, &ctx->offset);
             ovm_code_builder_add_imm(&ctx->builder, OVM_TYPE_I64, &value);
             break;
         }
index 16a40da3890e7b57e40975012e12e94a5bdf805f..430b15fb442a032f8c50377a030c159f76b6df07 100644 (file)
@@ -1424,19 +1424,19 @@ u64 uleb128_to_uint(u8* bytes, i32 *byte_count) {
 }
 
 BH_DEF i64 leb128_to_int(u8* bytes, i32 *byte_count) {
-    i64 res = 0;
+    u64 res = 0;
     u64 shift = 0;
     u64 size = 64;
 
     u8 byte;
     do {
         byte = bytes[(*byte_count)++];
-        res |= (byte & 0x7f) << shift;
+        res |= ((u64) (byte & 0x7f)) << shift;
         shift += 7;
     } while ((byte & 0x80) != 0);
 
     if ((shift < size) && (byte & 0x40) != 0) {
-        i64 zero_shifted = ~ 0x0;
+        u64 zero_shifted = ~ 0x0;
         zero_shifted = zero_shifted << shift;
         return res | zero_shifted;
     }
index c836f358e234ab997d49dc259036e6d14d373361..9779da0dd8a3fc5bea34bb81f6d24b8b580aa11b 100755 (executable)
Binary files a/shared/lib/linux_x86_64/lib/libovmwasm.so and b/shared/lib/linux_x86_64/lib/libovmwasm.so differ