1 ! :folding=none:collapseFolds=1:
5 ! Copyright (C) 2004 Slava Pestov.
7 ! Redistribution and use in source and binary forms, with or without
8 ! modification, are permitted provided that the following conditions are met:
10 ! 1. Redistributions of source code must retain the above copyright notice,
11 ! this list of conditions and the following disclaimer.
13 ! 2. Redistributions in binary form must reproduce the above copyright notice,
14 ! this list of conditions and the following disclaimer in the documentation
15 ! and/or other materials provided with the distribution.
17 ! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 ! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19 ! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 ! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 ! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 ! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 ! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 ! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 : emit ( cell -- ) image vector-push ;
51 : fixup ( value offset -- ) image set-vector-nth ;
55 : image-magic HEX: 0f0e0d0c ;
58 : cell ( we're compiling for a 32-bit system ) 4 ;
63 : untag ( cell tag -- ) tag-mask bitnot bitand ;
64 : tag ( cell -- tag ) tag-mask bitand ;
66 : fixnum-tag BIN: 000 ;
69 : object-tag BIN: 011 ;
70 : header-tag BIN: 100 ;
72 : immediate ( x tag -- tagged ) swap tag-bits shift< bitor ;
73 : >header ( id -- tagged ) header-tag immediate ;
80 ( relocation base at end of header ) 0 emit
81 ( bootstrap quotation set later ) 0 emit
82 ( global namespace set later ) 0 emit
83 ( size of heap set later ) 0 emit ;
85 : boot-quot-offset 3 ;
87 : heap-size-offset 5 ;
90 ( Top of heap pointer )
92 : here ( -- size ) image vector-length header-size - cell * ;
93 : here-as ( tag -- pointer ) here swap bitor ;
94 : pad ( -- ) here 8 mod 4 = [ 0 emit ] when ;
96 ( Remember what objects we've compiled )
98 : pooled-object ( object -- pointer )
101 : pool-object ( object pointer -- )
102 swap "objects" get set-hash ;
106 : 'fixnum ( n -- tagged ) fixnum-tag immediate ;
110 ! Padded with fixnums for 8-byte alignment
112 : f, object-tag here-as "f" set 6 >header emit 0 'fixnum emit ;
113 : t, object-tag here-as "t" set 7 >header emit 0 'fixnum emit ;
114 : empty, 8 >header emit 0 'fixnum emit ;
116 ( Beginning of the image )
117 ! The image proper begins with the header, then EMPTY, F, T
119 : begin ( -- ) header empty, f, t, ;
123 : word, ( -- pointer )
124 word-tag here-as word-tag >header emit 0 emit ;
126 ! This is to handle mutually recursive words
127 ! It is a hack. A recursive word in the cdr of a
128 ! cons doesn't work! This never happends though.
130 ! Eg : foo [ 5 | foo ] ;
132 : fixup-word-later ( word -- )
133 image vector-length cons "word-fixups" cons@ ;
135 : fixup-word ( where word -- )
136 dup pooled-object dup [
139 drop "Not in image: " swap cat2 throw
143 "word-fixups" get [ unswons fixup-word ] each ;
145 : 'word ( word -- pointer )
146 dup pooled-object dup [
150 ! Remember where we are, and add the reference later
158 : cons, ( -- pointer ) cons-tag here-as ;
159 : 'cons ( c -- tagged ) uncons ' swap ' cons, -rot emit emit ;
163 : pack ( n n -- ) 16 shift< bitor emit ;
165 : pack-at ( n str -- )
166 2dup str-nth rot succ rot str-nth pack ;
168 : (pack-string) ( n str -- )
172 2dup str-length pred = [
176 ] ifte >r 2 + r> (pack-string)
179 : pack-string ( str -- ) 0 swap (pack-string) ;
181 : string, ( string -- )
182 object-tag here-as swap
189 : 'string ( string -- pointer )
190 #! We pool strings so that each string is only written once
192 dup pooled-object dup [
195 drop dup string, dup >r pool-object r>
202 : namespace-buckets 23 ;
206 : (vocabulary) ( name -- vocab )
207 #! Vocabulary for target image.
208 dup "vocabularies" get hash dup [
211 drop >r namespace-buckets <hashtable> dup r>
212 "vocabularies" get set-hash
215 : (word+) ( word -- )
216 #! Add the word to a vocabulary in the target image.
217 dup word-name over word-vocabulary
218 (vocabulary) set-hash ;
220 : 'plist ( word -- plist )
223 dup word-name "name" swons ,
224 dup word-vocabulary "vocabulary" swons ,
225 [ "parsing" get >boolean ] bind "parsing" swons ,
229 : (worddef,) ( word primitive parameter -- )
230 ' >r >r dup (word+) dup 'plist >r
233 r> ( primitive -- ) emit
234 r> ( parameter -- ) emit
238 : primitive, ( word primitive -- ) f (worddef,) ;
239 : compound, ( word definition -- ) 1 swap (worddef,) ;
241 ( Arrays and vectors )
243 : 'array ( list -- untagged )
248 ( elements -- ) [ emit ] each
251 : 'vector ( vector -- pointer )
252 dup vector>list 'array swap vector-length
253 object-tag here-as >r
259 ( Cross-compile a reference to an object )
261 : ' ( obj -- pointer )
263 [ fixnum? ] [ 'fixnum ]
266 [ char? ] [ 'fixnum ]
267 [ string? ] [ 'string ]
268 [ vector? ] [ 'vector ]
269 [ t = ] [ drop "t" get ]
270 [ f = ] [ drop "f" get ]
271 [ drop t ] [ "Cannot cross-compile: " swap cat2 throw ]
276 : (set-boot) ( quot -- ) ' boot-quot-offset fixup ;
277 : (set-global) ( namespace -- ) ' global-offset fixup ;
280 "vocabularies" get "vocabularies"
281 namespace-buckets <hashtable>
282 dup >r set-hash r> (set-global) ;
284 : end ( -- ) global, fixup-words here heap-size-offset fixup ;
288 : byte0 ( num -- byte ) 24 shift> HEX: ff bitand ;
289 : byte1 ( num -- byte ) 16 shift> HEX: ff bitand ;
290 : byte2 ( num -- byte ) 8 shift> HEX: ff bitand ;
291 : byte3 ( num -- byte ) HEX: ff bitand ;
293 : write-little-endian ( word -- )
294 dup byte3 >char write
295 dup byte2 >char write
296 dup byte1 >char write
299 : write-big-endian ( word -- )
300 dup byte0 >char write
301 dup byte1 >char write
302 dup byte2 >char write
305 : write-word ( word -- )
312 : write-image ( image file -- )
313 <filebw> [ [ write-word ] vector-each ] with-stream ;
315 : with-image ( quot -- image )
317 300000 <vector> "image" set
318 521 <hashtable> "objects" set
319 namespace-buckets <hashtable> "vocabularies" set
324 : test-image ( quot -- ) with-image vector>list . ;