From 4b50a9fafe793abf3c2c16e203072a98a0702814 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Thu, 9 Nov 2023 14:48:49 -0500 Subject: [PATCH] move main execution to State; bring back verify() --- forth/core.fth | 4 ++-- forth/fib.fth | 4 ++-- libalee/corewords.cpp | 24 +++++++----------------- libalee/corewords.hpp | 2 +- libalee/state.cpp | 26 ++++++++++++++++++++++++-- libalee/state.hpp | 11 +++++------ 6 files changed, 41 insertions(+), 30 deletions(-) diff --git a/forth/core.fth b/forth/core.fth index 8ec5b71..e9fc133 100644 --- a/forth/core.fth +++ b/forth/core.fth @@ -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 ; diff --git a/forth/fib.fth b/forth/fib.fth index 671528a..3efdd2c 100644 --- a/forth/fib.fth +++ b/forth/fib.fth @@ -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 diff --git a/libalee/corewords.cpp b/libalee/corewords.cpp index 138ade4..b177565 100644 --- a/libalee/corewords.cpp +++ b/libalee/corewords.cpp @@ -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(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(state.beyondip() - sizeof(Cell)); + break; case 29: // depth state.push(static_cast(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) diff --git a/libalee/corewords.hpp b/libalee/corewords.hpp index 25f6a6e..e56baa3 100644 --- a/libalee/corewords.hpp +++ b/libalee/corewords.hpp @@ -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" diff --git a/libalee/state.cpp b/libalee/state.cpp index 6e12999..34e4936 100644 --- a/libalee/state.cpp +++ b/libalee/state.cpp @@ -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(ins - CoreWords::WordCount)); + } + + context.ip += sizeof(Cell); + } +} + Error State::execute(Addr addr) { auto stat = static_cast(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; diff --git a/libalee/state.hpp b/libalee/state.hpp index abf7a1e..529f118 100644 --- a/libalee/state.hpp +++ b/libalee/state.hpp @@ -25,8 +25,6 @@ #include #include -#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(error)); -// } + inline void verify(bool condition, Error error) { + if (!condition) + std::longjmp(context.jmpbuf, static_cast(error)); + } private: InputFunc inputfunc; // User-provided function to collect "stdin" input.