refactor word header so only >NAME involves variable-length data
This commit is contained in:
parent
3009bc84e5
commit
70c87e3d7a
64
jumpforth.S
64
jumpforth.S
|
|
@ -110,14 +110,8 @@ DODOES:
|
||||||
PUSHRSP %esi
|
PUSHRSP %esi
|
||||||
/* Load address of DOES> body from DFA into %esi */
|
/* Load address of DOES> body from DFA into %esi */
|
||||||
movl 4(%eax),%esi
|
movl 4(%eax),%esi
|
||||||
/* Load name length byte into %eax and mask out flag bits */
|
/* Load address of word body (after DFA) onto stack */
|
||||||
xor %ebx,%ebx
|
add $8,%eax
|
||||||
movb 12(%eax),%bl
|
|
||||||
andb $F_LENMASK,%bl
|
|
||||||
/* Calculate %eax + 13 + %ebx and round up to next cell for address of body */
|
|
||||||
lea 16(%eax,%ebx),%eax
|
|
||||||
andl $-4,%eax
|
|
||||||
/* Push body address on the data stack */
|
|
||||||
push %eax
|
push %eax
|
||||||
/* Execute the DOES> code */
|
/* Execute the DOES> code */
|
||||||
NEXT
|
NEXT
|
||||||
|
|
@ -132,19 +126,19 @@ DODOES:
|
||||||
.macro defname label:req,codeword:req,dataword:req,name="",flags=0
|
.macro defname label:req,codeword:req,dataword:req,name="",flags=0
|
||||||
.section .data
|
.section .data
|
||||||
.align 4
|
.align 4
|
||||||
.globl \label
|
.skip (-(9f-8f+1) & 3),0
|
||||||
\label :
|
|
||||||
.int \codeword
|
|
||||||
.int \dataword
|
|
||||||
.int link
|
|
||||||
.set link,\label
|
|
||||||
.byte \flags+(9f-8f)
|
|
||||||
.ifeqs "\name",""
|
.ifeqs "\name",""
|
||||||
8: .ascii "\label"
|
8: .ascii "\label"
|
||||||
.else
|
.else
|
||||||
8: .ascii "\name"
|
8: .ascii "\name"
|
||||||
.endif
|
.endif
|
||||||
9: .align 4
|
9: .byte \flags+(9b-8b)
|
||||||
|
.int link
|
||||||
|
.globl \label
|
||||||
|
\label :
|
||||||
|
.set link,\label
|
||||||
|
.int \codeword
|
||||||
|
.int \dataword
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro defword label:req,name="",flags=0
|
.macro defword label:req,name="",flags=0
|
||||||
|
|
@ -1254,37 +1248,37 @@ defword STREQU,"=S",F_HIDDEN
|
||||||
1: .int TWODROP,DROP,FALSE,EXIT /* FALSE R: */
|
1: .int TWODROP,DROP,FALSE,EXIT /* FALSE R: */
|
||||||
2: .int TWODROP,DROP,TRUE,EXIT /* TRUE R: */
|
2: .int TWODROP,DROP,TRUE,EXIT /* TRUE R: */
|
||||||
|
|
||||||
/* ( xt -- cfa-addr ) Address of the codeword field */
|
/* ( xt -- a-addr ) Body a.k.a. data-field address (next cell after the dataword field) */
|
||||||
defword TCFA,">CFA",F_HIDDEN
|
defword TBODY,">BODY",F_HIDDEN
|
||||||
.int EXIT
|
.int LIT,8,ADD,EXIT
|
||||||
|
|
||||||
/* ( xt -- dfa-addr ) Address of the dataword field */
|
/* ( xt -- dfa-addr ) Address of the dataword field */
|
||||||
defword TDFA,">DFA",F_HIDDEN
|
defword TDFA,">DFA",F_HIDDEN
|
||||||
.int CELL,ADD,EXIT
|
.int CELL,ADD,EXIT
|
||||||
|
|
||||||
/* ( xt -- link-addr ) Address of the dataword field */
|
/* ( xt -- cfa-addr ) Address of the codeword field */
|
||||||
|
defword TCFA,">CFA",F_HIDDEN
|
||||||
|
.int EXIT
|
||||||
|
|
||||||
|
/* ( xt -- link-addr ) Address of the link field */
|
||||||
defword TLINK,">LINK",F_HIDDEN
|
defword TLINK,">LINK",F_HIDDEN
|
||||||
.int LIT,8,ADD,EXIT
|
.int LIT,4,SUB,EXIT
|
||||||
|
|
||||||
/* ( xt -- flags-addr ) Address of the flag/length byte */
|
/* ( xt -- flags-addr ) Address of the flag/length byte */
|
||||||
defword TFLAGS,">FLAGS",F_HIDDEN
|
defword TFLAGS,">FLAGS",F_HIDDEN
|
||||||
.int LIT,12,ADD,EXIT
|
.int LIT,5,SUB,EXIT
|
||||||
|
|
||||||
/* ( xt -- name-addr name-len ) Address and length of the name field */
|
/* ( xt -- name-addr name-len ) Address and length of the name field */
|
||||||
defword TNAME,">NAME",F_HIDDEN
|
defword TNAME,">NAME",F_HIDDEN
|
||||||
.int TFLAGS,DUP,ADD1,SWAP,FETCHBYTE,__F_LENMASK,AND,EXIT
|
.int TFLAGS,DUP,FETCHBYTE,__F_LENMASK,AND,TUCK,SUB,SWAP,EXIT ;
|
||||||
|
|
||||||
/* ( xt -- a-addr ) Data-field address (next cell after the name) */
|
|
||||||
defword TBODY,">BODY",F_HIDDEN
|
|
||||||
.int TNAME,ADD,ALIGNED,EXIT
|
|
||||||
|
|
||||||
/* ( xt -- flag ) Is the F_IMMED flag set? */
|
/* ( xt -- flag ) Is the F_IMMED flag set? */
|
||||||
defword ISIMMEDIATE,"IMMEDIATE?",F_HIDDEN
|
defword ISIMMEDIATE,"IMMEDIATE?",F_HIDDEN
|
||||||
.int LIT,12,ADD,FETCHBYTE,__F_IMMED,AND,LIT,0,NEQU,EXIT
|
.int TFLAGS,FETCHBYTE,__F_IMMED,AND,ZNEQU,EXIT
|
||||||
|
|
||||||
/* ( xt -- flag ) Is the F_HIDDEN flag set? */
|
/* ( xt -- flag ) Is the F_HIDDEN flag set? */
|
||||||
defword ISHIDDEN,"HIDDEN?",F_HIDDEN
|
defword ISHIDDEN,"HIDDEN?",F_HIDDEN
|
||||||
.int LIT,12,ADD,FETCHBYTE,__F_HIDDEN,AND,LIT,0,NEQU,EXIT
|
.int TFLAGS,FETCHBYTE,__F_HIDDEN,AND,ZNEQU,EXIT
|
||||||
|
|
||||||
/* ( xt -- flag ) Is the xt a non-primitive bootstrap word? */
|
/* ( xt -- flag ) Is the xt a non-primitive bootstrap word? */
|
||||||
defword ISBOOTSTRAP,"BOOTSTRAP?",F_HIDDEN
|
defword ISBOOTSTRAP,"BOOTSTRAP?",F_HIDDEN
|
||||||
|
|
@ -1418,13 +1412,15 @@ defword QUIT,,F_HIDDEN
|
||||||
defword LATEST,,F_HIDDEN
|
defword LATEST,,F_HIDDEN
|
||||||
.int CURRENT,FETCH,FETCH,EXIT
|
.int CURRENT,FETCH,FETCH,EXIT
|
||||||
|
|
||||||
|
defword COMMANAME,"NAME,",F_HIDDEN
|
||||||
|
.int TUCK,ALIGN,HERE,OVER,ADD,ADD1,NEGATE,CELL,SUB1,AND,BOOTSTRAP_ALLOT
|
||||||
|
.int HERE,OVER,BOOTSTRAP_ALLOT,SWAP,CMOVE,COMMABYTE,EXIT
|
||||||
|
|
||||||
/* CREATE depends on various bootstrap words */
|
/* CREATE depends on various bootstrap words */
|
||||||
defword CREATE
|
defword CREATE
|
||||||
.int ALIGN,HERE
|
.int PARSE_NAME,COMMANAME,LATEST,COMMA
|
||||||
.int LIT,DODATA,COMMA,LIT,0,COMMA,LATEST,COMMA
|
.int HERE,CURRENT,FETCH,STORE
|
||||||
.int PARSE_NAME,DUP,COMMABYTE,HERE,SWAP,DUP,BOOTSTRAP_ALLOT,CMOVE
|
.int __DODATA,COMMA,HERE,CELL,ADD,COMMA,EXIT
|
||||||
.int ALIGN,HERE,OVER,TDFA,STORE
|
|
||||||
.int CURRENT,FETCH,STORE,EXIT
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** These next few words aren't strictly necessary for bootstrapping but
|
** These next few words aren't strictly necessary for bootstrapping but
|
||||||
|
|
|
||||||
44
startup.4th
44
startup.4th
|
|
@ -59,12 +59,12 @@ SYSTEM-WORDLIST SET-CURRENT
|
||||||
>>UTILITY
|
>>UTILITY
|
||||||
|
|
||||||
\ Field accessors for execution tokens
|
\ Field accessors for execution tokens
|
||||||
: >CFA ( xt -- a-addr ) ;
|
: >BODY ( xt -- a-addr ) [ 2 CELLS ] LITERAL + ;
|
||||||
: >DFA ( xt -- a-addr ) CELL+ ;
|
: >DFA ( xt -- a-addr ) CELL+ ;
|
||||||
: >LINK ( xt -- a-addr ) 2 CELLS+ ;
|
: >CFA ( xt -- a-addr ) ;
|
||||||
: >FLAGS ( xt -- c-addr ) 3 CELLS+ ;
|
: >LINK ( xt -- a-addr ) CELL- ;
|
||||||
: >NAME ( xt -- c-addr u ) >FLAGS DUP 1+ SWAP C@ F_LENMASK AND ;
|
: >FLAGS ( xt -- c-addr ) [ CELL 1+ ] LITERAL - ;
|
||||||
: >BODY ( xt -- a-addr ) >NAME + ALIGNED ;
|
: >NAME ( xt -- c-addr u ) >FLAGS DUP C@ F_LENMASK AND TUCK - SWAP ;
|
||||||
|
|
||||||
>>SYSTEM
|
>>SYSTEM
|
||||||
|
|
||||||
|
|
@ -769,6 +769,13 @@ DEFER QUIT
|
||||||
\ Allocate bytes from the data area (less than one cell) to cell-align the address
|
\ Allocate bytes from the data area (less than one cell) to cell-align the address
|
||||||
: ALIGN ( -- ) CELL ALIGN-TO ;
|
: ALIGN ( -- ) CELL ALIGN-TO ;
|
||||||
|
|
||||||
|
\ Compile the name field of a word header, which is a counted string _right_ aligned
|
||||||
|
\ to a cell boundary, with the length at the _end_ of the string. Example:
|
||||||
|
\ [ x x x N ][ A M E 4 ]
|
||||||
|
: NAME, ( c-addr u -- )
|
||||||
|
TUCK ▪ ALIGN HERE OVER + 1+ ▪ NEGATE CELL 1- AND ALLOT
|
||||||
|
HERE ▪ OVER ALLOT ▪ SWAP CMOVE ▪ C, ;
|
||||||
|
|
||||||
\ Append the effect of the token on top of the stack to the current definition.
|
\ Append the effect of the token on top of the stack to the current definition.
|
||||||
\ Here it's equivalent to , since words are just arrays of execution tokens.
|
\ Here it's equivalent to , since words are just arrays of execution tokens.
|
||||||
\ Once COMPILE, has been defined we can use POSTPONE for non-immediate words.
|
\ Once COMPILE, has been defined we can use POSTPONE for non-immediate words.
|
||||||
|
|
@ -1194,7 +1201,7 @@ DEFER REFILL
|
||||||
\ The word is NOT added to the current compilation word list
|
\ The word is NOT added to the current compilation word list
|
||||||
\ The start and end of the header are both cell-aligned
|
\ The start and end of the header are both cell-aligned
|
||||||
: (CREATE-RAW) ( c-addr u link dfa cfa -- xt )
|
: (CREATE-RAW) ( c-addr u link dfa cfa -- xt )
|
||||||
ALIGN HERE >R , , , DUP F_LENMASK UMIN C, HERE SWAP DUP ALLOT CMOVE ALIGN R> ;
|
2>R >R ▪ F_LENMASK UMIN NAME, ▪ R> , ▪ 2R> , , ▪ HERE 2 CELLS- ;
|
||||||
|
|
||||||
\ Called when a word using DOES> is executed (not compiled) to set
|
\ Called when a word using DOES> is executed (not compiled) to set
|
||||||
\ the runtime behavior of the most recently defined word
|
\ the runtime behavior of the most recently defined word
|
||||||
|
|
@ -1651,15 +1658,16 @@ ENDSTRUCT MEMBLOCK%
|
||||||
\ the closure is no longer needed. When executed, the closure xt will place
|
\ the closure is no longer needed. When executed, the closure xt will place
|
||||||
\ xu ... x1 on the data stack and then execute the captured xt1.
|
\ xu ... x1 on the data stack and then execute the captured xt1.
|
||||||
: CLOSURE ( xu ... x1 xt1 u -- xt2 )
|
: CLOSURE ( xu ... x1 xt1 u -- xt2 )
|
||||||
1+ DUP 5 + CELLS ALLOCATE DUP >R
|
1+ DUP 5 + CELLS ALLOCATE DUP 2 CELLS+ >R
|
||||||
DODOES !(+) [[ ' (CLOSURE) >DFA @ ]] !(+) NULL !(+) 0 !(+) OVER !(+) N! R> ;
|
\ name(0) link(NULL) codeword dataword #words xt x1 x2 x3 …
|
||||||
|
0 !(+) NULL !(+) DODOES !(+) [[ ' (CLOSURE) >DFA @ ]] !(+) OVER !(+) N! R> ;
|
||||||
|
|
||||||
\ Return a closure which executes xt1 followed by xt2
|
\ Return a closure which executes xt1 followed by xt2
|
||||||
: COMPOSE ( xt1 xt2 -- xt3 )
|
: COMPOSE ( xt1 xt2 -- xt3 )
|
||||||
{ >R EXECUTE R> EXECUTE } 2 CLOSURE ;
|
{ >R EXECUTE R> EXECUTE } 2 CLOSURE ;
|
||||||
|
|
||||||
\ In the future the closure object and its xt may not share the same address
|
\ The xt points to the codeword, which is two cells above the base of the object
|
||||||
' FREE ALIAS FREE-CLOSURE
|
: FREE-CLOSURE ( closure-xt -- ) 2 CELLS- FREE ;
|
||||||
|
|
||||||
\ Reserve data or heap space for a data structure given alignment and size
|
\ Reserve data or heap space for a data structure given alignment and size
|
||||||
\ It is assumed that ALLOCATE (but not ALLOT) returns an address suitably
|
\ It is assumed that ALLOCATE (but not ALLOT) returns an address suitably
|
||||||
|
|
@ -2183,15 +2191,15 @@ HIDE (TRACE)
|
||||||
THEN
|
THEN
|
||||||
ENDCASE LOOP DROP ;
|
ENDCASE LOOP DROP ;
|
||||||
|
|
||||||
\ Recognize the pattern BRANCH a:{c-a} b:{word} {code…} c:LIT d:{b}
|
\ Recognize the pattern BRANCH a:{c-a} {name} {link} b:{codeword} {…} c:LIT d:{b}
|
||||||
\ This pattern is generated by the { … } inline :NONAME syntax
|
\ This pattern is generated by the { … } inline :NONAME syntax
|
||||||
: NONAME-LITERAL? ( a-addr -- flag )
|
: NONAME-LITERAL? ( a-addr -- flag )
|
||||||
@(+) [[ ' BRANCH ]] = AND-THEN
|
@(+) [[ ' BRANCH ]] = AND-THEN
|
||||||
@(+) DUP 0> AND-THEN
|
DUP @ DUP 5 CELLS >= AND-THEN
|
||||||
( S: addr-b offset-c-a )
|
( S: addr-a offset-c-a )
|
||||||
OVER CELL- + @(+) [[ ' LIT ]] = AND-THEN
|
OVER + @(+) [[ ' LIT ]] = AND-THEN
|
||||||
( S: addr-b addr-d )
|
( S: addr-a addr-d )
|
||||||
@ OVER = AND-THEN
|
@ SWAP 3 CELLS+ OVER = AND-THEN
|
||||||
DUP WORD?
|
DUP WORD?
|
||||||
THEN
|
THEN
|
||||||
ELSE NIP THEN
|
ELSE NIP THEN
|
||||||
|
|
@ -2222,11 +2230,11 @@ ALSO UTILITY
|
||||||
ENDOF
|
ENDOF
|
||||||
OVER CELL- NONAME-LITERAL? IF
|
OVER CELL- NONAME-LITERAL? IF
|
||||||
DROP DUP @ OVER + 2 CELLS+ DUP R> UMAX >R SWAP
|
DROP DUP @ OVER + 2 CELLS+ DUP R> UMAX >R SWAP
|
||||||
"{ " TYPE CELL+ >DFA @ UNTHREAD "} " TYPE
|
"{ " TYPE 3 CELLS+ >DFA @ UNTHREAD "} " TYPE
|
||||||
ELSE
|
ELSE
|
||||||
DUP [[ ' BRANCH ]] = OR-ELSE DUP [[ ' 0BRANCH ]] = THEN IF
|
DUP [[ ' BRANCH ]] = OR-ELSE DUP [[ ' 0BRANCH ]] = THEN IF
|
||||||
>NAME TYPE SPACE
|
>NAME TYPE SPACE
|
||||||
@(+) DUP "{" TYPE DUP 0> IF "+" TYPE THEN . "} " TYPE
|
@(+) DUP "{" TYPE DUP 0>= IF "+" TYPE THEN . "} " TYPE
|
||||||
OVER CELL- + R> UMAX >R
|
OVER CELL- + R> UMAX >R
|
||||||
ELSE
|
ELSE
|
||||||
DUP WORD? AND-THEN DUP IMMEDIATE? THEN IF
|
DUP WORD? AND-THEN DUP IMMEDIATE? THEN IF
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue