M fs/doc/arch.txt => fs/doc/arch.txt +7 -1
@@ 21,10 21,12 @@ Dictionaries are a form of linked list.
The structure of each entry is:
+Xb of padding to align the structure to 4b
Xb name
+1b name length + immediate
4b pointer to metadata
4b pointer to previous entry --> this is where we link
-1b name length + immediate
+... payload ...
The "previous entry" field in an entry refers to this same place.
@@ 33,6 35,10 @@ The link to "metadata" is a linked list, initialized to 0.
The "name length" field is a 7 bit length with the 8th bit reserved for the
"immediate" flag (1=immediate).
+The whole structure is aligned to 4 bytes, with zero padding in front of the
+name to enforce that alignment. This means that the payload is also always
+aligned to 4b.
+
When we refer to a "word" in Dusk OS, we always refer to its first executable
byte, right after the name length field. When what you have is a word, you can
call it.
M fs/lib/meta.fs => fs/lib/meta.fs +1 -1
@@ 2,7 2,7 @@
\ Dictionary
9 const ENTRYSZ
-: wordlen ( w -- len ) 1- c@ $3f and ;
+: wordlen ( w -- len ) w>e e>wlen c@ $3f and ;
: wordname[] ( w -- sa sl )
bi wordlen | 9 - over - ( sl sa ) swap ;
: .word ( w -- ) wordname[] rtype ;
M fs/xcomp/bootlo.fs => fs/xcomp/bootlo.fs +5 -4
@@ 57,12 57,13 @@ code8b W>A, drop, A) 8b) [!], 1 A) [+n], drop, exit,
code + PSP) +, nip, exit,
code - -W, PSP) +, nip, exit,
: -^ swap - ;
-: e>w 5 + ;
-: w>e 5 - ;
+: e>w 4 + ;
+: e>wlen 5 - ;
+: w>e 4 - ;
: current sysdict @ e>w ;
code 1+ 1 W+n, exit,
code 1- -1 W+n, exit,
-: immediate current 1- dup c@ $80 or swap c! ;
+: immediate sysdict @ e>wlen dup c@ $80 or swap c! ;
: EMETA_16B $11 ; : EMETA_8B $10 ;
: 16b EMETA_16B MOD ! ; immediate
: 8b EMETA_8B MOD ! ; immediate
@@ 329,7 330,7 @@ code move ( src dst u -- )
word" SZ" code _cur e>w structsz' litn W) @, exit,
does> ( 'struct )
_structfind
- dup 1- c@ $80 and not compiling and \ compile only if not immediate
+ dup w>e e>wlen c@ $80 and not compiling and \ compile only if not immediate
if execute, else execute then ;
: ]struct
\ break the chain at the root of the struct
M fs/xcomp/i386/kernel.fs => fs/xcomp/i386/kernel.fs +6 -6
@@ 492,20 492,20 @@ pc to lblfind \ ax=str dx='dict
ax inc,
di push, si push,
pc ( loop )
- bl dx 4 d) mov, \ entry len
+ bl dx -5 d) mov, \ entry len
bl $3f i) and, \ 3f instead of 7f? we reserve space for another flag.
bl cl cmp,
forward jnz, to L1 ( skip1 )
\ same length
di dx mov,
- di 4 i) sub,
+ di 5 i) sub,
di cx sub, \ beginning of name range
si ax mov,
repz, cmpsb,
forward jnz, to L2 ( skip2 )
\ same contents
si pop, di pop,
- dx 5 i) add, \ word
+ dx 4 i) add, \ word
ax dx mov,
ret,
L2 forward! ( skip2 )
@@ 643,7 643,7 @@ xcode findmod ( w -- w )
lblmod m) -1 i) test,
lblret abs>rel jz,
dx ax mov,
- ax ax -9 d) mov,
+ ax ax -8 d) mov,
bx lblmod m) mov,
L1 abscall, \ findmeta
ax ax test,
@@ 675,7 675,7 @@ xcode compword ( str -- )
xwordlbl litn abs>rel jnz, \ literal: jump to litn
\ not a literal, find and compile
L2 abscall, \ ax=w
- ax -1 d) 8b) $80 i) test,
+ ax -9 d) 8b) $80 i) test,
L1 abs>rel jnz, \ immediate? execute
\ compile word
wcall, findmod
@@ 711,13 711,13 @@ xcode entry ( 'dict s -- )
ax inc,
wcall, align4 \ ( 'dict -- )
cx push, lblwriterange abscall, cx pop,
+ cl cwrite,
bx lblnextmeta m) mov, bx dwrite,
lblnextmeta m) 0 i) mov,
bx ax 0 d) mov, \ ax='dict bx=dict
dx lblhere m) mov,
ax 0 d) dx mov, xdrop, ( -- )
bx dwrite,
- cl cwrite,
lbl[rcnt] m) 0 i) mov,
ret,
M fs/xcomp/tools.fs => fs/xcomp/tools.fs +1 -1
@@ 10,7 10,7 @@ create xbindict 0 ,
: xoffset binstart org - ;
: xcode xbindict word entry ;
-: ximm xbindict @ e>w 1- dup c@ $80 or swap c! ;
+: ximm xbindict @ e>wlen dup c@ $80 or swap c! ;
\ Usage: xwordlbl foo call, "foo" being a word name in xbindict
: xwordlbl ( "name" -- pc )
M posix/vm.c => posix/vm.c +14 -15
@@ 168,9 168,9 @@ static dword _find(dword dict, byte *name, byte slen) {
dword a = dict;
byte len;
while (memchk(a)) {
- len = gb(a+4) & 0x3f;
- if ((len == slen) && (memcmp(name, &vm.mem[a-4-len], len)==0)) {
- return a+5;
+ len = gb(a-5) & 0x3f;
+ if ((len == slen) && (memcmp(name, &vm.mem[a-5-len], len)==0)) {
+ return a+4;
}
a = gd(a);
}
@@ 227,13 227,18 @@ static void compbinopwr(byte binopidx) { litwr(binopidx); cwrite(0x45); }
static void storewr() { cwrite(0x0e); dropwr(); wstorewr(OPA); dropwr(); }
static void callword(dword addr); // forward declaration
+static void align4(dword n) {
+ n = (here() + n) % 4;
+ if (n) { allot(4-n); }
+}
static void _entry(dword dict, byte *name, byte slen) {
+ align4(slen+1);
memcpy(&vm.mem[here()], name, slen);
allot(slen);
+ cwrite(slen);
dwrite(gd(NEXTMETA));
dwrite(gd(dict));
- cwrite(slen);
- sd(dict, here()-5);
+ sd(dict, here()-4);
sd(NEXTMETA, 0);
}
static void entry(char *name) {
@@ 470,7 475,7 @@ static void WNF() {
static void FINDMOD() {
dword a;
if (gd(MOD)) {
- if ((a = findmeta(gd(MOD), gd(vm.W-9)))) {
+ if ((a = findmeta(gd(MOD), gd(vm.W-8)))) {
vm.W = a + 8;
sd(MOD, 0);
}
@@ 493,7 498,7 @@ static void COMPWORD() {
ppush(sysdict());
FIND();
if (!vm.W) { WNF(); return; }
- if ((gb(vm.W-1) & 0x80) /* immediate */) {
+ if ((gb(vm.W-9) & 0x80) /* immediate */) {
FINDMOD();
callword(ppop());
STACKCHK();
@@ 532,18 537,12 @@ static void RSADDWR() {
static void COMPOP() {
dword opcode = ppop(); dword operand = ppop(); wopwr(opcode, operand); }
-static void ALIGN4() { // 0x40
- dword n = ppop();
- n = (here() + n) % 4;
- if (n) { allot(4-n); }
-}
+static void ALIGN4() { align4(ppop()); } // 0x40
// ( 'dict s -- )
static void ENTRY() {
dword s = ppop();
dword dict = ppop();
byte len = gb(s++);
- ppush(len+1);
- ALIGN4();
_entry(dict, &vm.mem[s], len);
sd(_RCNT_, 0);
}
@@ 935,7 934,7 @@ static void callword(dword addr) {
static void wentry(char *name, byte op) { entry(name); cwrite(op); retwr(); }
static void sysconst(char *name, dword val) { entry(name); litwr(val); retwr(); }
static void sysalias(char *name, char *target) { entry(name); brwr(find(target)); }
-static void makeimm() { dword a = sysdict()+4; sb(a, gb(a)|0x80); }
+static void makeimm() { dword a = sysdict()-5; sb(a, gb(a)|0x80); }
static void compileop(byte op) { litwr(op); cwritewr(); }
// Names for simple word-to-code mappings