]> code.bitgloo.com Git - bitgloo/alee-forth.git/commitdiff
move main execution to State; bring back verify() optimize
authorClyne Sullivan <clyne@bitgloo.com>
Thu, 9 Nov 2023 19:48:49 +0000 (14:48 -0500)
committerClyne Sullivan <clyne@bitgloo.com>
Thu, 9 Nov 2023 19:48:49 +0000 (14:48 -0500)
forth/core.fth
forth/fib.fth
libalee/corewords.cpp
libalee/corewords.hpp
libalee/state.cpp
libalee/state.hpp

index 8ec5b71972ed80d458c0a3e9d84b15abcdb8106f..e9fc1336592e36d30035e83d60d592a436863361 100644 (file)
@@ -51,8 +51,8 @@
 : else     ['] _jmp , here 0 , swap here swap ! ; imm
 
 : postpone _' dup 0 = if exit then
-           1 = swap ['] _lit , , if ['] execute ,
-           else ['] , , then ; imm
+           1 = swap ['] _lit , , if ['] execute
+           else ['] , then , ; imm
 
 : over     1 pick ;
 : rot      >r swap r> swap ;
index 671528a486519f33125851e51715d45bf68c2056..3efdd2c2e8760e3ffcda4afa889cb2a20e46710c 100644 (file)
@@ -9,10 +9,10 @@
   5 sys fib 5 sys >r 2drop r> ;
 
 variable avg 0 avg !
-2000 constant iters
+1000 constant iters
 
 : bench ( -- )
-  iters 0 do 100 fibbench avg +! loop
+  iters 0 do 1000 fibbench avg +! loop
   avg @ iters / avg ! ;
 
 bench ." avg time: " avg @ . ." us" cr
index 138ade4fb56e2c04c3c52bff0863ffdcd8a10d2e..b1775657b5cc46097aed0d240478202fcf029dca 100644 (file)
@@ -37,21 +37,12 @@ void find(State& state, Word word)
     state.push(imm);
 }
 
-void CoreWords::run(Cell ins, State& state)
+bool CoreWords::run(Cell ins, State& state)
 {
     DoubleCell dcell;
-    Addr index = ins;
     auto& ip = state.ip();
 
-execute:
-    if (index >= Dictionary::Begin) {
-        // must be calling a defined subroutine
-        state.pushr(ip);
-        ip = index;
-        return;
-    } else if (index >= WordCount) {
-        state.push(static_cast<Cell>(index - WordCount));
-    } else switch (index) {
+    switch (ins) {
     case 0: // _lit
         state.push(state.beyondip());
         break;
@@ -149,8 +140,7 @@ execute:
         find(state, state.dict.input());
         break;
     case 24: // execute
-        index = state.pop();
-        goto execute;
+        return true;
     case 25: // exit
         ip = state.popr();
         if (ip == 0)
@@ -180,8 +170,8 @@ execute:
         }
         [[fallthrough]];
     case 28: // _jmp
-        ip = state.beyondip();
-        return;
+        ip = static_cast<Addr>(state.beyondip() - sizeof(Cell));
+        break;
     case 29: // depth
         state.push(static_cast<Cell>(state.size()));
         break;
@@ -191,7 +181,7 @@ execute:
     case 31: // _in
         state.input();
         break;
-    case 32: // _ex
+    case 32: // _ev
         {
         const auto st = state.save();
         ip = 0;
@@ -235,7 +225,7 @@ execute:
         break;
     }
 
-    ip += sizeof(Cell);
+    return false;
 }
 
 Cell CoreWords::findi(State& state, Word word)
index 25f6a6ec2ab5a716283b836c98b07a0113f2a3ac..e56baa3d154b1f28b43c27e9aa9516fbe27e1bd9 100644 (file)
@@ -48,7 +48,7 @@ public:
     /**
      * Executes the given CoreWord execution token using the given state.
      */
-    static void run(Cell, State&);
+    static bool run(Cell, State&);
 
     constexpr static char wordsarr[] =
         "_lit\0drop\0dup\0swap\0pick\0sys\0"
index 6e129999af210c9330f872c559660fe6baf6cd50..34e4936c8834d585a6e8d77033feff21122a30ba 100644 (file)
@@ -42,17 +42,39 @@ void State::load(const State::Context& ctx)
     context = ctx;
 }
 
+void State::execute1(Addr ins)
+{
+repeat:
+    if (ins >= Dictionary::Begin) [[likely]] {
+        // Subroutine call
+        pushr(context.ip);
+        context.ip = ins;
+    } else {
+        if (ins < CoreWords::WordCount) {
+            if (CoreWords::run(ins, *this)) [[unlikely]] {
+                ins = pop();
+                goto repeat;
+            }
+        } else {
+            push(static_cast<Cell>(ins - CoreWords::WordCount));
+        }
+
+        context.ip += sizeof(Cell);
+    }
+}
+
 Error State::execute(Addr addr)
 {
     auto stat = static_cast<Error>(setjmp(context.jmpbuf));
 
     if (stat == Error::none) {
-        CoreWords::run(addr, *this);
+        context.ip = 0;
+        execute1(addr);
 
         if (context.ip >= Dictionary::Begin) {
             // longjmp will exit this loop.
             for (;;)
-                CoreWords::run(dict.read(context.ip), *this);
+                execute1(dict.read(context.ip));
         } else {
             // addr was a CoreWord, all done now.
             context.ip = 0;
index abf7a1e2944ef669be77ebb705ce4b88fa3f456d..529f118a3d33a5238832a83f66bf0d9f9afc87bc 100644 (file)
@@ -25,8 +25,6 @@
 #include <csetjmp>
 #include <cstddef>
 
-#define verify(C, E)
-
 constexpr unsigned DataStackSize = 64;
 constexpr unsigned ReturnStackSize = 64;
 
@@ -52,6 +50,7 @@ public:
      * Encountering an error will cause this function to exit immediately.
      */
     Error execute(Addr);
+    void execute1(Addr);
 
     /**
      * Clears the data and return stacks, sets ip to zero, and clears the
@@ -135,10 +134,10 @@ public:
         return dict.read(context.ip);
     }
 
-//    inline void verify(bool condition, Error error) {
-//        if (!condition)
-//            std::longjmp(context.jmpbuf, static_cast<int>(error));
-//    }
+    inline void verify(bool condition, Error error) {
+        if (!condition)
+            std::longjmp(context.jmpbuf, static_cast<int>(error));
+    }
 
 private:
     InputFunc inputfunc; // User-provided function to collect "stdin" input.