1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2 ;; UrForth level
1: self
-hosting
32-bit Forth compiler
3 ;; Copyright
(C
) 2020 Ketmar Dark
// Invisible Vector
5 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7 ;; temp debug buffer just stores dword line and dword PC
9 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
13 ;; dw itemcount
; files with more that
64kb lines?
'cmon!
14 ;; dw firstline ; files with more that 64kb lines? 'cmon
!
15 ;; dd filename
-c1strz
; this points
to special hidden buffer word
, or
0
18 ;; db pcoffs
; offset from the previous PC
(first
: from the CFA
)
19 ;; db lineofs
; offset from the previous line
21 ;; if lineofs is
255, next word is
16-bit line offset
22 ;; if pcofs is
255, next word is
16-bit line offset
24 ;; the compiler doesn
't store each PC, it only stores line changes
25 ;; that is, the range for the line lasts until the next item
26 ;; items should be sorted by PC (but the code should not fail on
28 $if URFORTH_DEBUG_INFO
30 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
31 $constant "(DBGBUF-MAXSIZE)" 1024*64
34 $value "(DBGINFO-ENABLED?)" 1
36 $value "(DBGINFO-ACTIVE?)" 0
39 $value "(DBGBUF-BASE-ADDR)" 0
41 $value "(DBGBUF-END-ADDR)" 0
44 $variable "(DBGBUF-CURR-ADDR)" 0
48 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
49 ;; list of known source files
52 ;; dd dpptr ;; in code area
54 $variable "(dbg-file-list-head)" 0
58 ;; also, list of know files is not stored in SAVEd binary
59 : (dbg-add-file) ( addr count -- straddr )
61 (dbg-file-list-head) @ over !
62 dup (dbg-file-list-head) ! cell+
66 2dup c! 1+ swap 0 max cmove
71 : (dbg-find-or-add-file) ( addr count -- straddr )
72 dp-temp @ if 0 exit endif ;; no file info for temp definitions
73 str-extract-name ?dup if
76 2dup r@ cell+ @ bcount s= if
86 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
87 : debug-info-off ( -- )
88 false to (dbginfo-enabled?)
89 false to (dbginfo-active?)
90 (dbgbuf-base-addr) ?dup if 0! endif
93 : debug-info-on ( -- )
94 (dbgbuf-base-addr) if true to (dbginfo-enabled?) else debug-info-off endif
98 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
99 : (DBGINFO-RESET) ( -- )
100 (dbgbuf-base-addr) (dbgbuf-curr-addr) !
101 false to (dbginfo-active?)
102 ;; set first line to 0 (to ease checks in "add-pc")
103 (dbgbuf-base-addr) ?dup if 0! endif
106 : (dbginfo-reset-activate) ( -- ) (dbginfo-reset) true to (dbginfo-active?) ; (hidden)
109 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
110 : (DBGINFO-ADD-PC) ( pc line -- )
111 ;; never put zero line
112 ?dup ifnot drop exit endif
113 ;; special? -1 items means "out of room"
114 (dbgbuf-curr-addr) @ ?dup ifnot 2drop exit endif
115 ( pc line dbgbufaddr )
116 ;; check if the line is the same (if we have no lines, there will be zero)
117 2dup @ = if drop 2drop exit endif
118 ;; check if we have enough room
119 dup 3 +cells (dbgbuf-end-addr) u> if
120 ;; out of buffer, abort debug info generation
121 drop 2drop (dbgbuf-curr-addr) 0!
125 ( pc line dbgbufaddr )
128 ;; put current line number to the next item (for equality check above)
129 dup 2 -cells @ over !
134 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
135 : (DBGINFO-ADD-HERE) ( -- )
137 dp-temp @ ifnot ;; no debug info for temporary words
138 (dbginfo-active?) (dbginfo-enabled?) logand if
139 here tib-curr-line (dbginfo-add-pc)
145 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
146 ;; create compressed debug info, set dfa
148 ;; let's use globals here
, because why not?
149 $value
"(dbginfo-cpbuf-start)" 0
150 $value
"(dbginfo-cpbuf-curpos)" 0
151 $value
"(dbginfo-cpbuf-currline)" 0
152 $value
"(dbginfo-cpbuf-currpc)" 0
154 : (dbginfo
-build
-byte
) ( b
-- )
155 (dbginfo
-cpbuf
-curpos
) c
!
156 (dbginfo
-cpbuf
-curpos
) 1+ to (dbginfo
-cpbuf
-curpos
)
159 : (dbginfo
-build
-word
) ( w
-- )
160 dup
0xff and
(dbginfo
-build
-byte
)
161 8 rshift
(dbginfo
-build
-byte
)
164 : (dbginfo
-build
-dword
) ( dw
-- )
165 dup
0xffff and
(dbginfo
-build
-word
)
166 16 rshift
(dbginfo
-build
-word
)
170 ;; prerequisite
: debug info must exist
, and must not be empty
171 : (dbginfo
-build
-compressed
) ( destbuf
-- destbuf size
)
172 ;; build file name
(do it here
, because it may allocate at here
)
173 (tib
-curr
-fname
) count
(dbg
-find
-or
-add
-file
) >r
175 dup
to (dbginfo
-cpbuf
-start
)
176 to (dbginfo
-cpbuf
-curpos
)
178 (dbgbuf
-base
-addr
) @
to (dbginfo
-cpbuf
-currline
)
180 latest
-cfa
to (dbginfo
-cpbuf
-currpc
)
182 ;; item count
(we know that in advance
)
183 (dbgbuf
-curr
-addr
) @
(dbgbuf
-base
-addr
) - 3 rshift
(dbginfo
-build
-word
)
185 (dbginfo
-cpbuf
-currline
) (dbginfo
-build
-word
)
187 r
> (dbginfo
-build
-dword
)
188 (dbgbuf
-curr
-addr
) @
(dbgbuf
-base
-addr
) do
189 ;; db pcoffs
; offset from the previous PC
(first
: from the CFA
)
190 ;; db lineofs
; offset from the previous line
192 ;; if lineofs is
255, next word is
16-bit line offset
193 ;; if pcofs is
255, next word is
16-bit line offset
195 i cell
+ @
(dbginfo
-cpbuf
-currpc
) - dup
255 < if
200 255 (dbginfo
-build
-byte
)
204 i cell
+ @
to (dbginfo
-cpbuf
-currpc
)
206 i @
(dbginfo
-cpbuf
-currline
) - dup
255 < if
211 255 (dbginfo
-build
-byte
)
214 ;; update current line
215 i @
to (dbginfo
-cpbuf
-currline
)
217 ;; return addr and size
218 (dbginfo
-cpbuf
-start
) (dbginfo
-cpbuf
-curpos
) over
-
221 : (dbginfo
-finalize
-and
-copy
) ( -- )
222 (dbginfo
-active?
) (dbginfo
-enabled?
) logand
if
223 (dbgbuf
-base
-addr
) ?dup
if
226 (dbgbuf
-curr
-addr
) @
0! (dbginfo
-add
-here
)
227 ;; compressed should never be bigger than the original
228 (dbgbuf
-curr
-addr
) @
(dbgbuf
-base
-addr
) - 4 +cells simple
-malloc throw dup
>r
229 (dbginfo
-build
-compressed
)
230 ;; save here
to debug info field
231 here latest
-nfa nfa
->dfa
!
232 dup n
-allot
( addr bytes rva
-newaddr
)
243 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
244 ..: (startup
-init
) ( -- )
245 (dbgbuf
-maxsize
) ?dup
if
247 dup
to (dbgbuf
-base
-addr
) (dbgbuf
-maxsize
) + 1- to (dbgbuf
-end-addr
)
248 (dbg
-file
-list
-head
) 0!
250 0 to (dbgbuf
-base
-addr
)
251 0 to (dbgbuf
-end-addr
)
252 false
to (dbginfo
-enabled?
)
253 false
to (dbginfo
-active?
)
255 (dbgbuf
-base
-addr
) ?dup
if 0! endif
260 \ this may be used by the
external tools
(assembler
, for example
)
261 : (dbginfo
-reset
) ; (hidden
) immediate
-noop
262 : (dbginfo
-reset
-activate
) ; (hidden
) immediate
-noop