From: Brendan Hansen Date: Mon, 26 Sep 2022 18:54:59 +0000 (-0500) Subject: fixed critical bug with how unsigned integers were parsed for interpretter X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=31c473937c12b00e3c51966538fbd373b505b2bc;p=onyx.git fixed critical bug with how unsigned integers were parsed for interpretter --- diff --git a/core/conv.onyx b/core/conv.onyx index 81c5e95c..11de869d 100644 --- a/core/conv.onyx +++ b/core/conv.onyx @@ -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); diff --git a/interpreter/src/vm/vm.c b/interpreter/src/vm/vm.c index aa7e8d32..551c6caa 100644 --- a/interpreter/src/vm/vm.c +++ b/interpreter/src/vm/vm.c @@ -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) diff --git a/interpreter/src/wasm/module_parsing.h b/interpreter/src/wasm/module_parsing.h index 8eade304..ce36d5d0 100644 --- a/interpreter/src/wasm/module_parsing.h +++ b/interpreter/src/wasm/module_parsing.h @@ -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; } diff --git a/shared/include/bh.h b/shared/include/bh.h index 16a40da3..430b15fb 100644 --- a/shared/include/bh.h +++ b/shared/include/bh.h @@ -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; } diff --git a/shared/lib/linux_x86_64/lib/libovmwasm.so b/shared/lib/linux_x86_64/lib/libovmwasm.so index c836f358..9779da0d 100755 Binary files a/shared/lib/linux_x86_64/lib/libovmwasm.so and b/shared/lib/linux_x86_64/lib/libovmwasm.so differ