]> git.mdlowis.com Git - projs/onward.git/commitdiff
added underflow and overflow checking to arg and return stacks
authorMichael D. Lowis <mike@mdlowis.com>
Fri, 14 Nov 2014 02:19:41 +0000 (21:19 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Fri, 14 Nov 2014 02:19:41 +0000 (21:19 -0500)
Gemfile.lock
build.rb [changed mode: 0644->0755]
source/onward/onward.c
source/onward/onward.h

index 203fff5cd787827991b7c402fc17e350fa276544..ba072f961b42dea8a448f02791cc5e3a5a62c777 100755 (executable)
@@ -20,6 +20,7 @@ GEM
     rspec-support (3.1.2)
 
 PLATFORMS
+  ruby
   x86-mingw32
 
 DEPENDENCIES
old mode 100644 (file)
new mode 100755 (executable)
index a719734..802db8d
--- a/build.rb
+++ b/build.rb
@@ -6,6 +6,7 @@ require './modules/build-system/setup'
 #------------------------------------------------------------------------------
 # Define the default compiler environment
 base_env = BuildEnv.new do |env|
+  env.build_root = 'build/'
   # Compiler options
   env["CFLAGS"] += ['-DLEAK_DETECT_LEVEL=1', '--std=c99', '-Wall', '-Wextra']#, '-Werror']
   env["CPPPATH"] += Dir['source/**/']
@@ -13,11 +14,13 @@ end
 
 # Define the release environment
 main_env = base_env.clone do |env|
+  env.build_root = 'build/release/'
   env["CFLAGS"] += ['-O3']
 end
 
 # Define the test environment
 test_env = base_env.clone do |env|
+  env.build_root = 'build/test/'
   env["CPPPATH"] += Dir['modules/atf/source/**/']
   env['CFLAGS'] +=  ['-O0']
   if Opts[:profile].include? "coverage"
index 4e4a5c6c09b579204ff65f15f72455759589e913..f31b92e70abb2baea96ed5eecc0e97e1c7c2ad5d 100755 (executable)
@@ -2,6 +2,7 @@
 #include <string.h>
 
 static value_t char_oneof(char ch, char* chs);
+static void abort_on_error(value_t cond, value_t errcode);
 
 /** Version number of the implementation */
 defconst("VERSION", VERSION, 0, 0u);
@@ -27,6 +28,7 @@ defvar("pc", pc, 0, &F_IMMEDIATE_word);
 /** The address of the base of the argument stack */
 defvar("asb", asb, 0, &pc_word);
 
+/** The size of the argument stack in bytes */
 defvar("assz", assz, 0, &asb_word);
 
 /** The address of the top of the argument stack */
@@ -35,6 +37,7 @@ defvar("asp", asp, 0, &assz_word);
 /** The address of the base of the return stack */
 defvar("rsb", rsb, 0, &asp_word);
 
+/** The size of the return stack in bytes */
 defvar("rssz", rssz, 0, &rsb_word);
 
 /** The address of the top of the return stack */
@@ -145,8 +148,14 @@ defcode("find", find, &lit, 0u) {
     onward_aspush((value_t)curr);
 }
 
+defcode("abort", _abort, &find, 0u) {
+    asp = asb;
+    rsp = rsb;
+    pc  = 0u;
+}
+
 /** Execute a word */
-defcode("exec", exec, &find, 0u) {
+defcode("exec", exec, &_abort, 0u) {
     /* Load up the word to be executed, saving off the current state */
     value_t start = rsp;
     word_t* to_exec[] = { (word_t*)onward_aspop(), 0u };
@@ -167,7 +176,7 @@ defcode("exec", exec, &find, 0u) {
             onward_rspush(pc);
             pc = (value_t)current->code;
         }
-    } while(rsp != start);
+    } while(pc && rsp != start);
 }
 
 /** Create a new word definition with default attributes */
@@ -259,7 +268,7 @@ defcode("interp", interp, &zbr, 0u) {
                     comma_code();
                 }
             } else {
-                errno = 1;
+                errno = ERR_UNKNOWN_WORD;
                 (void)onward_aspop();
             }
         }
@@ -457,8 +466,10 @@ defcode("~", bnot, &bxor, 0u) {
 void onward_init(onward_init_t* init_data) {
     asb    = (value_t)(init_data->arg_stack - 1);
     asp    = (value_t)(init_data->arg_stack - 1);
+    assz   = (value_t)(init_data->arg_stack_sz * sizeof(value_t));
     rsb    = (value_t)(init_data->ret_stack - 1);
     rsp    = (value_t)(init_data->ret_stack - 1);
+    rssz   = (value_t)(init_data->ret_stack_sz * sizeof(value_t));
     here   = (value_t)(init_data->word_buf);
     latest = (value_t)(init_data->latest);
 }
@@ -471,28 +482,46 @@ value_t onward_pcfetch(void) {
 }
 
 void onward_aspush(value_t val) {
-    asp += sizeof(value_t);
-    *((value_t*)asp) = val;
+    #ifndef UNSAFE_MODE
+    if ((asp-asb) <= assz) {
+    #endif
+        asp += sizeof(value_t);
+        *((value_t*)asp) = val;
+    #ifndef UNSAFE_MODE
+    } else {
+        abort_on_error(1, ERR_ARG_STACK_OVRFLW);
+    }
+    #endif
 }
 
 value_t onward_aspeek(value_t val) {
-    return *((value_t*)(asp + (val* sizeof(value_t))));
+    return *((value_t*)(asp + (val * sizeof(value_t))));
 }
 
 value_t onward_aspop(void) {
     value_t val = *((value_t*)asp);
     asp -= sizeof(value_t);
+    abort_on_error(asp < asb, ERR_ARG_STACK_UNDRFLW);
     return val;
 }
 
 void onward_rspush(value_t val) {
-    rsp += sizeof(value_t);
-    *((value_t*)rsp) = val;
+    #ifndef UNSAFE_MODE
+    if ((rsp-rsb) <= rssz) {
+    #endif
+        rsp += sizeof(value_t);
+        *((value_t*)rsp) = val;
+    #ifndef UNSAFE_MODE
+    } else {
+        abort_on_error(1, ERR_RET_STACK_OVRFLW);
+    }
+    #endif
 }
 
 value_t onward_rspop(void) {
     value_t val = *((value_t*)rsp);
     rsp -= sizeof(value_t);
+    abort_on_error(rsp < rsb, ERR_RET_STACK_UNDRFLW);
     return val;
 }
 
@@ -508,3 +537,11 @@ static value_t char_oneof(char ch, char* chs) {
     return ret;
 }
 
+static void abort_on_error(value_t cond, value_t errcode) {
+    #ifndef UNSAFE_MODE
+    if(cond) {
+        errno = errcode;
+        _abort_code();
+    }
+    #endif
+}
index b630b11e9273474d81267c5cd146e66e9c5e91bc..a08c151b164923aab5c33100b99150d21739e206 100755 (executable)
@@ -98,6 +98,13 @@ typedef struct {
         onward_aspush(c_name);                   \
     }
 
+#define ERR_NONE              (0x00)
+#define ERR_UNKNOWN_WORD      (0x01)
+#define ERR_ARG_STACK_OVRFLW  (0x02)
+#define ERR_ARG_STACK_UNDRFLW (0x03)
+#define ERR_RET_STACK_OVRFLW  (0x04)
+#define ERR_RET_STACK_UNDRFLW (0x05)
+
 /** The number of bits that make up a stack cell */
 #define SYS_BITCOUNT ((value_t)(sizeof(value_t) * 8u))