duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit f966805f2daffa8b6c7d5902a354125778090f1c
parent 532a1af32c49c58bfbdbab24b0eb6fb6010866b5
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Tue, 23 Aug 2022 21:11:58 -0400

Add local variables

Diffstat:
Mfs/doc/usage.txt | 34++++++++++++++++++++++++++++++++++
Mfs/tests/kernel.fs | 6++++++
Mfs/xcomp/bootlo.fs | 10++++++++--
Mfs/xcomp/i386.fs | 15+++++++++++----
Mposix/vm.c | 5++++-
5 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/fs/doc/usage.txt b/fs/doc/usage.txt @@ -83,6 +83,40 @@ Each metadata element has this structure: 4b type ID ( any other type-specific data ) +# Local variables + +It's a common pattern, to avoid PS juggling, to place an element on RS and +recall that element with r@. It works well, but unfortunately, this only works +with a single element. Another drawback is that this element can be "buried" by +a pattern (a "next" loop for example) that needs to place something on RS. + +A workaround to this is to declare a "private" value near the word and store +temporary values in there. It works too, but because those values are statically +allocated, this can't be done in words that require recursion. + +Local variables are there to the rescue! There are 4 of them: V1 V2 V3 V4. These +words do a simple thing: they reference an element on RS with "to" semantics. +They are also impervious to being "buried" because they remember their "slot" at +compile time and adjust their compilation accordingly. + +In other words, if RSTART is the address in memory of RSP when the word starts +executing and considering the fact that RSP grows "downwards" in memory, +V1=RSTART-4 and V4=RSTART-16. + +When using local variables, you are responsible with pushing and popping to/from +RS. All those variables give you are "to" semantics to a "RS slot". Example: + +: foo ( a b c -- ) >r >r >r V1 . spc> V2 . spc> V3 . rdrop rdrop rdrop ; + +1 2 3 foo \ prints "3 2 1" + +: inc ( a -- a+1 ) >r 1 to+ V1 V1 rdrop ; +42 inc . \ prints 43 + +\ this works too +: inc5 ( a -- a+5 ) >r 5 >r begin 1 to+ V1 next V1 rdrop ; +42 inc5 . \ prints 47 + # Structures Structures are an effective way to address offsets from base addresses while diff --git a/fs/tests/kernel.fs b/fs/tests/kernel.fs @@ -90,6 +90,12 @@ ll llcnt 3 #eq ' bar 'emeta lladd 42 , ( ll ) 42 ' bar emeta findemeta ( ll ) #eq +\ Local variables +: foo 54 >r 42 >r 1 to+ V1 2 to+ V2 V2 V1 rdrop rdrop ; +foo 55 #eq 44 #eq +: inc5 >r 5 >r begin 1 to+ V1 next V1 rdrop ; +42 inc5 47 #eq + \ Structures struct[ Foo sfield bar diff --git a/fs/xcomp/bootlo.fs b/fs/xcomp/bootlo.fs @@ -4,7 +4,7 @@ ' [ execute, ' exit, execute, exit, ," entry" 0 , sysdict @ , 5 c, here w>e sysdict ! ] dup 1+ swap c@ tuck move, nextmeta @ , over @ , c, - here w>e swap ! 0 nextmeta ! ; + here w>e swap ! 0 nextmeta ! 0 [rcnt] ! ; ," code" 0 , sysdict @ , 4 c, here w>e sysdict ! ] sysdict word entry ; code : ] code ] ; @@ -32,7 +32,7 @@ code : ] code ] ; : begin here ; immediate : again compile (br) , ; immediate : until compile (?br) , ; immediate -: next compile (next) , ; immediate +: next compile (next) , 4 [rcnt] +! ; immediate : leave 1 litn 0 r', compile ! ; immediate : = - not ; : \ begin in< $0a = until ; immediate @@ -185,6 +185,12 @@ alias noop [then] litn litn compile _ else swap _ then ; immediate +\ Local variables +: _varto ( a -- ) to? ?dup if execute else @ then ; +: var, ( off -- ) [rcnt] @ neg CELLSZ - -^ r', compile _varto ; +: V1 0 var, ; immediate : V2 4 var, ; immediate +: V3 8 var, ; immediate : V4 12 var, ; immediate + \ Structures 0 value _extends diff --git a/fs/xcomp/i386.fs b/fs/xcomp/i386.fs @@ -24,10 +24,10 @@ \ Constants and labels 0 to realmode : values ( n -- ) >r begin 0 value next ; -26 values L1 L2 lblmainalias lbltoptr lbltoexec lbltoexec2 lblbootptr lblin< +27 values L1 L2 lblmainalias lbltoptr lbltoexec lbltoexec2 lblbootptr lblin< lblcurword lblnextmeta lblret lblsysdict lblemit lblparsec lblparseh - lblparseud lblerrmsg lblrtype lblhere lblmovewrite lblwrite lblcwrite - lblfind lblcompiling lblareg lblidt + lblparseud lblerrmsg lblrtype lblhere lbl[rcnt] lblmovewrite lblwrite + lblcwrite lblfind lblcompiling lblareg lblidt $8000 const HERESTART \ TODO: find a better place $500 to binstart $2000 const STACKSZ @@ -459,13 +459,20 @@ xcode []= ( a1 a2 u -- f ) [ebp] ax mov, ret, +pc to lbl[rcnt] 0 , +xcode [rcnt] + lbl[rcnt] pspushN, + ret, + \ 83 c4 XX --> add esp, XX pc 2 nc, $83 $c4 xcode r+, ( n -- ) si ( pc ) i) mov, cx 2 i) mov, lblmovewrite abs>rel call, - xwordlbl c, abs>rel jmp, + AX pspop, + lbl[rcnt] m) ax add, + lblcwrite abs>rel jmp, \ 83 ed 04 --> sub ebp, 4 \ 89 45 00 --> mov [ebp], esp diff --git a/posix/vm.c b/posix/vm.c @@ -27,7 +27,8 @@ The VM is little endian. #define HERE SYSVARS #define SYSDICT (HERE+4) #define NEXTMETA (SYSDICT+4) -#define INRD (NEXTMETA+4) +#define _RCNT_ (NEXTMETA+4) +#define INRD (_RCNT_+4) #define EMIT (INRD+4) #define ABORT (EMIT+4) #define MAINLOOP (ABORT+4) @@ -334,6 +335,7 @@ static void RSADDWR() { // op: 21 dword n = ppop(); cwrite(0x20); // RSADD cwrite(n); + sd(_RCNT_, gd(_RCNT_)+n); } static void RSADDR() { // op: 22 @@ -1059,6 +1061,7 @@ static void buildsysdict() { sysconst("curword", CURWORD); sysconst("sysdict", SYSDICT); sysconst("nextmeta", NEXTMETA); + sysconst("[rcnt]", _RCNT_); entry("_fsinfobuf"); allot(0x112); // used in FINFO entry("mainloop"); sd(MAINLOOP, here());