added exceptions when accessing address 0; bugfix
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 6 Dec 2022 04:35:24 +0000 (22:35 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Tue, 6 Dec 2022 04:35:24 +0000 (22:35 -0600)
core/string/string.onyx
interpreter/src/vm/vm.c
shared/lib/linux_x86_64/lib/libovmwasm.so

index c039af6272b400253153170337d201afa78e836d..55ed6e80161347bc7c29efa802ef62dd5744c118 100644 (file)
@@ -19,6 +19,8 @@ as_str :: macro (t: $T/HasAsStrMethod) -> str {
 free :: (s: str, allocator := context.allocator) do raw_free(allocator, s.data);
 
 alloc_copy :: (original: str, allocator := context.allocator) -> str {
+    if original.count == 0 do return .{};
+
     new_str : str;
     new_str.data = raw_alloc(allocator, sizeof u8 * original.count);
     new_str.count = original.count;
@@ -27,6 +29,8 @@ alloc_copy :: (original: str, allocator := context.allocator) -> str {
 }
 
 temp_copy :: (original: str) -> str {
+    if original.count == 0 do return .{};
+
     new_str := make([] u8, original.count, allocator=context.temp_allocator);
     copy(original, new_str);
     return new_str;
index d9d062f7619ca1eeabdc4501ba1bfaae2c32937a..9080e0f449185977471b3443f906e46aa0ec7e6a 100644 (file)
@@ -661,6 +661,16 @@ static inline double __ovm_copysign(a, b) double a, b; {
     return -a;
 }
 
+static inline void __ovm_trigger_exception(ovm_state_t *state) {
+    if (state->debug) {
+        state->debug->state = debug_state_pausing;
+        state->debug->pause_reason = debug_pause_exception;
+
+        assert(write(state->debug->state_change_write_fd, "1", 1));
+        sem_wait(&state->debug->wait_semaphore);
+    }
+}
+
 
 ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t *program) {
     ovm_assert(engine);
@@ -1003,6 +1013,7 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t
 #define OVM_LOAD(type_, stype) \
             case OVM_TYPED_INSTR(OVMI_LOAD, type_): {\
                 ovm_assert(VAL(instr.a).type == OVM_TYPE_I32); \
+                if ((VAL(instr.a).u32 + (u32) instr.b) == 0) __ovm_trigger_exception(state); \
                 tmp_val.type = type_; \
                 tmp_val.stype = * (stype *) &((u8 *) engine->memory)[VAL(instr.a).u32 + (u32) instr.b]; \
                 VAL(instr.r) = tmp_val; \
@@ -1021,6 +1032,7 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t
 #define OVM_STORE(type_, stype) \
             case OVM_TYPED_INSTR(OVMI_STORE, type_): \
                 ovm_assert(VAL(instr.r).type == OVM_TYPE_I32); \
+                if ((VAL(instr.r).u32 + (u32) instr.b) == 0) __ovm_trigger_exception(state); \
                 *(stype *) &((u8 *) engine->memory)[VAL(instr.r).u32 + (u32) instr.b] = VAL(instr.a).stype; \
                 break;
 
@@ -1038,6 +1050,8 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t
                 u32 src   = VAL(instr.a).u32;
                 u32 count = VAL(instr.b).u32;
 
+                if (!dest || !src) __ovm_trigger_exception(state);
+
                 u8 *base = engine->memory;
                 memmove(&base[dest], &base[src], count);
                 break;
@@ -1048,6 +1062,8 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t
                 u8  byte  = VAL(instr.a).u8;
                 i32 count = VAL(instr.b).i32;
 
+                if (!dest) __ovm_trigger_exception(state);
+
                 u8 *base = engine->memory;
                 memset(&base[dest], byte, count);
                 break;
@@ -1226,6 +1242,7 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t
 
 #define CMPXCHG(otype, ctype) \
     case OVM_TYPED_INSTR(OVMI_CMPXCHG, otype): {\
+        if (VAL(instr.r).u32 == 0) __ovm_trigger_exception(state); \
         ctype *addr = (ctype *) &((u8 *) engine->memory)[VAL(instr.r).u32]; \
  \
         VAL(instr.r).u64 = 0; \
@@ -1246,14 +1263,7 @@ ovm_value_t ovm_run_code(ovm_engine_t *engine, ovm_state_t *state, ovm_program_t
 #undef CMPXCHG
 
             case OVMI_BREAK:
-                if (state->debug) {
-                    state->debug->state = debug_state_pausing;
-                    state->debug->pause_reason = debug_pause_exception;
-
-                    assert(write(state->debug->state_change_write_fd, "1", 1));
-                    sem_wait(&state->debug->wait_semaphore);
-                }
-                
+                __ovm_trigger_exception(state);
                 printf("onyx: exiting early due to reaching an unreachable instruction.\n");
                 
                 return ((ovm_value_t) {0});
index 91bbd0468340e3040e5551e4a970a8fa1a81c89e..38a91eaf2da0183452f0f5a6f01cf9cb557dc58c 100755 (executable)
Binary files a/shared/lib/linux_x86_64/lib/libovmwasm.so and b/shared/lib/linux_x86_64/lib/libovmwasm.so differ