From 073a23152e509d42ce256f635fbb3da99e0d176a Mon Sep 17 00:00:00 2001
From: Aryadev Chavali <aryadev@aryadevchavali.com>
Date: Sun, 22 Oct 2023 20:29:02 +0100
Subject: Use conversion functions for (h)word to and from bytes instead of bit
 shifting

Wasn't very secure for endianness, and using these helpers abstracts
the details away a bit in case I want to enforce a certain system.
---
 src/runtime.c | 55 +++++++++++++++++++++++++++++--------------------------
 src/runtime.h |  7 ++++---
 2 files changed, 33 insertions(+), 29 deletions(-)

(limited to 'src')

diff --git a/src/runtime.c b/src/runtime.c
index 5c9b985..a5ffd09 100644
--- a/src/runtime.c
+++ b/src/runtime.c
@@ -63,7 +63,7 @@ void vm_execute(vm_t *vm)
   else if (OPCODE_IS_TYPE(instruction.opcode, OP_MOV))
   {
     data_t d =
-        MOV_ROUTINES[instruction.opcode](vm, instruction.operand.as_word);
+        MOV_ROUTINES[instruction.opcode](vm, instruction.operand.as_byte);
     vm->registers.ret = d.as_word;
     prog->ptr++;
   }
@@ -274,30 +274,32 @@ data_t vm_peek(vm_t *vm, data_type_t type)
       return DBYTE(0);
     return DBYTE(vm->stack.data[vm->stack.ptr - 1]);
     break;
-  case DATA_TYPE_HWORD:
+  case DATA_TYPE_HWORD: {
     if (vm->stack.ptr < HWORD_SIZE)
       // TODO: Error STACK_UNDERFLOW
       return DHWORD(0);
-    hword h = 0;
+    byte bytes[HWORD_SIZE] = {0};
     for (size_t i = 0; i < HWORD_SIZE; ++i)
     {
-      byte b = vm->stack.data[vm->stack.ptr - 1 - i];
-      h      = h | (((word)b) << (i * 8));
+      byte b                    = vm->stack.data[vm->stack.ptr - i - 1];
+      bytes[HWORD_SIZE - 1 - i] = b;
     }
-    return DWORD(h);
+    return DWORD(convert_bytes_to_hword(bytes));
     break;
-  case DATA_TYPE_WORD:
+  }
+  case DATA_TYPE_WORD: {
     if (vm->stack.ptr < WORD_SIZE)
       // TODO: Error STACK_UNDERFLOW
       return DWORD(0);
-    word w = 0;
+    byte bytes[WORD_SIZE] = {0};
     for (size_t i = 0; i < WORD_SIZE; ++i)
     {
-      byte b = vm->stack.data[vm->stack.ptr - 1 - i];
-      w      = w | (((word)b) << (i * 8));
+      byte b                   = vm->stack.data[vm->stack.ptr - i - 1];
+      bytes[WORD_SIZE - 1 - i] = b;
     }
-    return DWORD(w);
+    return DWORD(convert_bytes_to_hword(bytes));
     break;
+  }
   default:
     return DBYTE(0);
     break;
@@ -317,10 +319,11 @@ void vm_push_hword(vm_t *vm, data_t f)
   if (vm->stack.ptr + HWORD_SIZE >= vm->stack.max)
     // TODO: Error STACK_OVERFLOW
     return;
-  for (size_t i = 32; i > 0; i -= 8)
+  byte bytes[HWORD_SIZE] = {0};
+  convert_hword_to_bytes(f.as_hword, bytes);
+  for (size_t i = 0; i < HWORD_SIZE; ++i)
   {
-    const word mask = ((word)0b11111111) << (i - 8);
-    byte b          = (f.as_hword & mask) >> (i - 8);
+    byte b = bytes[HWORD_SIZE - i - 1];
     vm_push_byte(vm, DBYTE(b));
   }
 }
@@ -330,11 +333,11 @@ void vm_push_word(vm_t *vm, data_t w)
   if (vm->stack.ptr + WORD_SIZE >= vm->stack.max)
     // TODO: Error STACK_OVERFLOW
     return;
-  // By default store in big endian
-  for (size_t i = 64; i > 0; i -= 8)
+  byte bytes[WORD_SIZE] = {0};
+  convert_word_to_bytes(w.as_word, bytes);
+  for (size_t i = 0; i < WORD_SIZE; ++i)
   {
-    const word mask = ((word)0b11111111) << (i - 8);
-    byte b          = (w.as_word & mask) >> (i - 8);
+    byte b = bytes[WORD_SIZE - i - 1];
     vm_push_byte(vm, DBYTE(b));
   }
 }
@@ -436,13 +439,13 @@ data_t vm_pop_hword(vm_t *vm)
   if (vm->stack.ptr < HWORD_SIZE)
     // TODO: Error STACK_UNDERFLOW
     return DHWORD(0);
-  hword h = 0;
+  byte bytes[HWORD_SIZE] = {0};
   for (size_t i = 0; i < HWORD_SIZE; ++i)
   {
-    data_t b = vm_pop_byte(vm);
-    h        = h | ((word)(b.as_byte) << (i * 8));
+    data_t b                  = vm_pop_byte(vm);
+    bytes[HWORD_SIZE - 1 - i] = b.as_byte;
   }
-  return DWORD(h);
+  return DWORD(convert_bytes_to_hword(bytes));
 }
 
 data_t vm_pop_word(vm_t *vm)
@@ -450,13 +453,13 @@ data_t vm_pop_word(vm_t *vm)
   if (vm->stack.ptr < WORD_SIZE)
     // TODO: Error STACK_UNDERFLOW
     return DWORD(0);
-  word w = 0;
+  byte bytes[WORD_SIZE] = {0};
   for (size_t i = 0; i < WORD_SIZE; ++i)
   {
-    data_t b = vm_pop_byte(vm);
-    w        = w | ((word)(b.as_byte) << (i * 8));
+    data_t b                 = vm_pop_byte(vm);
+    bytes[WORD_SIZE - 1 - i] = b.as_byte;
   }
-  return DWORD(w);
+  return DWORD(convert_bytes_to_word(bytes));
 }
 
 void vm_not_byte(vm_t *vm)
diff --git a/src/runtime.h b/src/runtime.h
index 3e4c295..5ee5f9b 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -83,6 +83,10 @@ static const push_reg_f PUSH_REG_ROUTINES[] = {
     [OP_PUSH_REGISTER_WORD]  = vm_push_word_register,
 };
 
+data_t vm_pop_byte(vm_t *);
+data_t vm_pop_hword(vm_t *);
+data_t vm_pop_word(vm_t *);
+
 data_t vm_mov_byte(vm_t *, byte);
 data_t vm_mov_hword(vm_t *, byte);
 data_t vm_mov_word(vm_t *, byte);
@@ -94,9 +98,6 @@ static const mov_f MOV_ROUTINES[] = {
     [OP_MOV_WORD]  = vm_mov_word,
 };
 
-data_t vm_pop_byte(vm_t *);
-data_t vm_pop_hword(vm_t *);
-data_t vm_pop_word(vm_t *);
 
 void vm_not_byte(vm_t *);
 void vm_not_hword(vm_t *);
-- 
cgit v1.2.3-13-gbd6f