2004-07-22 19:48:50 -04:00
|
|
|
! :folding=none:collapseFolds=1:
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
! $Id$
|
|
|
|
!
|
|
|
|
! Copyright (C) 2004 Slava Pestov.
|
|
|
|
!
|
|
|
|
! Redistribution and use in source and binary forms, with or without
|
|
|
|
! modification, are permitted provided that the following conditions are met:
|
|
|
|
!
|
|
|
|
! 1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
! this list of conditions and the following disclaimer.
|
|
|
|
!
|
|
|
|
! 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
! this list of conditions and the following disclaimer in the documentation
|
|
|
|
! and/or other materials provided with the distribution.
|
|
|
|
!
|
|
|
|
! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
|
|
! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
|
|
|
! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
|
|
! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
|
|
! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
|
|
! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
|
|
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
|
|
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
2004-10-27 23:13:00 -04:00
|
|
|
! This library allows one to generate a new set of bootstrap
|
|
|
|
! images (boot.image.{le32,le64,be32,be64}.
|
|
|
|
!
|
|
|
|
! It does this by parsing the set of source files needed to
|
|
|
|
! generate the minimal image, and writing the cons cells, words,
|
|
|
|
! strings etc to the image file in the CFactor object memory
|
|
|
|
! format.
|
|
|
|
!
|
|
|
|
! What is a bootstrap image? It basically contains enough code
|
|
|
|
! to parse a source file. See platform/native/boot.factor --
|
|
|
|
! It initializes the core interpreter services, and proceeds to
|
|
|
|
! run platform/native/boot-stage2.factor.
|
|
|
|
|
2004-09-11 15:26:24 -04:00
|
|
|
IN: image
|
2004-07-16 02:26:21 -04:00
|
|
|
USE: combinators
|
|
|
|
USE: errors
|
|
|
|
USE: hashtables
|
|
|
|
USE: kernel
|
|
|
|
USE: lists
|
|
|
|
USE: logic
|
2004-08-26 22:21:17 -04:00
|
|
|
USE: math
|
2004-07-16 02:26:21 -04:00
|
|
|
USE: namespaces
|
2004-07-21 19:26:41 -04:00
|
|
|
USE: prettyprint
|
2004-08-29 04:03:16 -04:00
|
|
|
USE: random
|
2004-07-16 02:26:21 -04:00
|
|
|
USE: stack
|
|
|
|
USE: stdio
|
|
|
|
USE: streams
|
|
|
|
USE: strings
|
|
|
|
USE: test
|
|
|
|
USE: vectors
|
|
|
|
USE: unparser
|
|
|
|
USE: words
|
|
|
|
|
2004-11-26 22:23:57 -05:00
|
|
|
! The image being constructed; a vector of word-size integers
|
|
|
|
SYMBOL: image
|
|
|
|
|
|
|
|
! Boot quotation, set by boot.factor
|
|
|
|
SYMBOL: boot-quot
|
2004-08-06 02:51:32 -04:00
|
|
|
|
2004-11-26 22:23:57 -05:00
|
|
|
: emit ( cell -- ) image get vector-push ;
|
|
|
|
|
|
|
|
: fixup ( value offset -- ) image get set-vector-nth ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-07-24 15:11:55 -04:00
|
|
|
( Object memory )
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
: image-magic HEX: 0f0e0d0c ;
|
|
|
|
: image-version 0 ;
|
|
|
|
|
2004-09-04 01:05:50 -04:00
|
|
|
: cell "64-bits" get 8 4 ? ;
|
|
|
|
: char "64-bits" get 4 2 ? ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
: tag-mask BIN: 111 ;
|
|
|
|
: tag-bits 3 ;
|
|
|
|
|
|
|
|
: untag ( cell tag -- ) tag-mask bitnot bitand ;
|
|
|
|
: tag ( cell -- tag ) tag-mask bitand ;
|
|
|
|
|
2004-08-06 18:40:44 -04:00
|
|
|
: fixnum-tag BIN: 000 ;
|
|
|
|
: word-tag BIN: 001 ;
|
|
|
|
: cons-tag BIN: 010 ;
|
|
|
|
: object-tag BIN: 011 ;
|
|
|
|
: ratio-tag BIN: 100 ;
|
|
|
|
: complex-tag BIN: 101 ;
|
|
|
|
: header-tag BIN: 110 ;
|
|
|
|
: gc-fwd-ptr BIN: 111 ; ( we don't output these )
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-08-06 02:51:32 -04:00
|
|
|
: f-type 6 ;
|
|
|
|
: t-type 7 ;
|
2004-08-12 17:36:36 -04:00
|
|
|
: array-type 8 ;
|
2004-10-31 14:36:42 -05:00
|
|
|
: bignum-type 9 ;
|
|
|
|
: float-type 10 ;
|
|
|
|
: vector-type 11 ;
|
|
|
|
: string-type 12 ;
|
2004-08-06 02:51:32 -04:00
|
|
|
|
2004-08-26 19:37:22 -04:00
|
|
|
: immediate ( x tag -- tagged ) swap tag-bits shift bitor ;
|
2004-07-16 02:26:21 -04:00
|
|
|
: >header ( id -- tagged ) header-tag immediate ;
|
|
|
|
|
2004-07-24 15:11:55 -04:00
|
|
|
( Image header )
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-09-08 02:31:03 -04:00
|
|
|
: base
|
|
|
|
#! We relocate the image to after the header, and leaving
|
|
|
|
#! two empty cells. This lets us differentiate an F pointer
|
|
|
|
#! (0/tag 3) from a pointer to the first object in the
|
|
|
|
#! image.
|
|
|
|
2 cell * ;
|
|
|
|
|
2004-07-16 02:26:21 -04:00
|
|
|
: header ( -- )
|
|
|
|
image-magic emit
|
|
|
|
image-version emit
|
2004-09-08 02:31:03 -04:00
|
|
|
( relocation base at end of header ) base emit
|
2004-07-16 02:26:21 -04:00
|
|
|
( bootstrap quotation set later ) 0 emit
|
|
|
|
( global namespace set later ) 0 emit
|
|
|
|
( size of heap set later ) 0 emit ;
|
|
|
|
|
|
|
|
: boot-quot-offset 3 ;
|
|
|
|
: global-offset 4 ;
|
|
|
|
: heap-size-offset 5 ;
|
|
|
|
: header-size 6 ;
|
|
|
|
|
2004-09-08 02:31:03 -04:00
|
|
|
( Allocator )
|
|
|
|
|
|
|
|
: here ( -- size )
|
2004-11-26 22:23:57 -05:00
|
|
|
image get vector-length header-size - cell * base + ;
|
2004-09-08 02:31:03 -04:00
|
|
|
|
|
|
|
: here-as ( tag -- pointer )
|
|
|
|
here swap bitor ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-09-08 02:31:03 -04:00
|
|
|
: pad ( -- )
|
|
|
|
here 8 mod 4 = [ 0 emit ] when ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-07-24 15:11:55 -04:00
|
|
|
( Remember what objects we've compiled )
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
: pooled-object ( object -- pointer )
|
|
|
|
"objects" get hash ;
|
|
|
|
|
|
|
|
: pool-object ( object pointer -- )
|
|
|
|
swap "objects" get set-hash ;
|
|
|
|
|
2004-07-24 15:11:55 -04:00
|
|
|
( Fixnums )
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
: 'fixnum ( n -- tagged ) fixnum-tag immediate ;
|
|
|
|
|
2004-08-06 02:51:32 -04:00
|
|
|
( Bignums )
|
|
|
|
|
|
|
|
: 'bignum ( bignum -- tagged )
|
2004-08-29 01:04:42 -04:00
|
|
|
object-tag here-as >r
|
|
|
|
bignum-type >header emit
|
|
|
|
dup 0 = 1 2 ? emit ( capacity )
|
2004-09-05 00:06:09 -04:00
|
|
|
[
|
|
|
|
[ 0 = ] [ emit pad ]
|
|
|
|
[ 0 < ] [ 1 emit neg emit ]
|
|
|
|
[ 0 > ] [ 0 emit emit ]
|
|
|
|
] cond r> ;
|
2004-08-06 02:51:32 -04:00
|
|
|
|
2004-07-24 15:11:55 -04:00
|
|
|
( Special objects )
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
! Padded with fixnums for 8-byte alignment
|
|
|
|
|
2004-09-08 02:31:03 -04:00
|
|
|
: t,
|
|
|
|
object-tag here-as "t" set
|
|
|
|
t-type >header emit
|
|
|
|
0 'fixnum emit ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-08-29 01:04:42 -04:00
|
|
|
: 0, 0 'bignum drop ;
|
|
|
|
: 1, 1 'bignum drop ;
|
|
|
|
: -1, -1 'bignum drop ;
|
|
|
|
|
2004-07-24 15:11:55 -04:00
|
|
|
( Beginning of the image )
|
2004-09-08 02:31:03 -04:00
|
|
|
! The image proper begins with the header, then T,
|
2004-08-29 01:04:42 -04:00
|
|
|
! and the bignums 0, 1, and -1.
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-09-08 02:31:03 -04:00
|
|
|
: begin ( -- ) header t, 0, 1, -1, ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-07-24 15:11:55 -04:00
|
|
|
( Words )
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-07-27 23:29:37 -04:00
|
|
|
: word, ( -- pointer )
|
2004-08-29 04:03:16 -04:00
|
|
|
word-tag here-as word-tag >header emit
|
|
|
|
0 HEX: fffffff random-int emit ( hashcode )
|
|
|
|
0 emit ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
! This is to handle mutually recursive words
|
|
|
|
|
2004-09-30 21:49:49 -04:00
|
|
|
: fixup-word ( word -- offset )
|
2004-07-16 02:26:21 -04:00
|
|
|
dup pooled-object dup [
|
2004-09-30 21:49:49 -04:00
|
|
|
nip
|
2004-07-16 02:26:21 -04:00
|
|
|
] [
|
2004-07-31 14:58:16 -04:00
|
|
|
drop "Not in image: " swap word-name cat2 throw
|
2004-07-16 02:26:21 -04:00
|
|
|
] ifte ;
|
|
|
|
|
|
|
|
: fixup-words ( -- )
|
2004-11-26 22:23:57 -05:00
|
|
|
image get [
|
2004-09-30 21:49:49 -04:00
|
|
|
dup word? [ fixup-word ] when
|
2004-11-26 22:23:57 -05:00
|
|
|
] vector-map image set ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
: 'word ( word -- pointer )
|
2004-09-30 21:49:49 -04:00
|
|
|
dup pooled-object dup [ nip ] [ drop ] ifte ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-07-24 15:11:55 -04:00
|
|
|
( Conses )
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
DEFER: '
|
|
|
|
|
|
|
|
: cons, ( -- pointer ) cons-tag here-as ;
|
|
|
|
: 'cons ( c -- tagged ) uncons ' swap ' cons, -rot emit emit ;
|
|
|
|
|
2004-07-24 15:11:55 -04:00
|
|
|
( Strings )
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-09-04 22:29:07 -04:00
|
|
|
: align-string ( n str -- )
|
2004-09-04 01:05:50 -04:00
|
|
|
tuck str-length - CHAR: \0 fill cat2 ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-09-04 01:05:50 -04:00
|
|
|
: emit-string ( str -- )
|
|
|
|
"big-endian" get [ str-reverse ] unless
|
|
|
|
0 swap [ swap 16 shift + ] str-each emit ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-09-04 01:05:50 -04:00
|
|
|
: (pack-string) ( n list -- )
|
|
|
|
#! Emit bytes for a string, with n characters per word.
|
|
|
|
[
|
2004-09-05 00:06:09 -04:00
|
|
|
2dup str-length > [ dupd align-string ] when
|
2004-09-04 01:05:50 -04:00
|
|
|
emit-string
|
|
|
|
] each drop ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-09-04 01:05:50 -04:00
|
|
|
: pack-string ( string -- )
|
|
|
|
char tuck swap split-n (pack-string) ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
: string, ( string -- )
|
|
|
|
object-tag here-as swap
|
2004-08-06 02:51:32 -04:00
|
|
|
string-type >header emit
|
2004-07-16 02:26:21 -04:00
|
|
|
dup str-length emit
|
2004-07-31 14:58:16 -04:00
|
|
|
dup hashcode emit
|
2004-07-16 02:26:21 -04:00
|
|
|
pack-string
|
|
|
|
pad ;
|
|
|
|
|
|
|
|
: 'string ( string -- pointer )
|
|
|
|
#! We pool strings so that each string is only written once
|
|
|
|
#! to the image
|
|
|
|
dup pooled-object dup [
|
|
|
|
nip
|
|
|
|
] [
|
|
|
|
drop dup string, dup >r pool-object r>
|
|
|
|
] ifte ;
|
|
|
|
|
2004-07-24 15:11:55 -04:00
|
|
|
( Word definitions )
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
: (vocabulary) ( name -- vocab )
|
|
|
|
#! Vocabulary for target image.
|
|
|
|
dup "vocabularies" get hash dup [
|
|
|
|
nip
|
|
|
|
] [
|
|
|
|
drop >r namespace-buckets <hashtable> dup r>
|
|
|
|
"vocabularies" get set-hash
|
|
|
|
] ifte ;
|
|
|
|
|
|
|
|
: (word+) ( word -- )
|
|
|
|
#! Add the word to a vocabulary in the target image.
|
|
|
|
dup word-name over word-vocabulary
|
|
|
|
(vocabulary) set-hash ;
|
|
|
|
|
|
|
|
: 'plist ( word -- plist )
|
2004-11-11 15:15:43 -05:00
|
|
|
[
|
|
|
|
dup word-name "name" swons ,
|
|
|
|
dup word-vocabulary "vocabulary" swons ,
|
|
|
|
"parsing" word-property [ t "parsing" swons , ] when
|
|
|
|
] make-list ' ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
: (worddef,) ( word primitive parameter -- )
|
|
|
|
' >r >r dup (word+) dup 'plist >r
|
|
|
|
word, pool-object
|
|
|
|
r> ( -- plist )
|
|
|
|
r> ( primitive -- ) emit
|
|
|
|
r> ( parameter -- ) emit
|
2004-07-27 23:29:37 -04:00
|
|
|
( plist -- ) emit
|
2004-08-29 03:20:19 -04:00
|
|
|
0 emit ( padding )
|
|
|
|
0 emit ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
: primitive, ( word primitive -- ) f (worddef,) ;
|
|
|
|
: compound, ( word definition -- ) 1 swap (worddef,) ;
|
|
|
|
|
2004-07-24 15:11:55 -04:00
|
|
|
( Arrays and vectors )
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
: 'array ( list -- untagged )
|
2004-08-22 19:06:51 -04:00
|
|
|
[ ' ] map
|
2004-07-16 02:26:21 -04:00
|
|
|
here >r
|
2004-08-06 02:51:32 -04:00
|
|
|
array-type >header emit
|
2004-07-16 02:26:21 -04:00
|
|
|
dup length emit
|
|
|
|
( elements -- ) [ emit ] each
|
|
|
|
pad r> ;
|
|
|
|
|
|
|
|
: 'vector ( vector -- pointer )
|
|
|
|
dup vector>list 'array swap vector-length
|
|
|
|
object-tag here-as >r
|
2004-08-06 02:51:32 -04:00
|
|
|
vector-type >header emit
|
2004-07-16 02:26:21 -04:00
|
|
|
emit ( length )
|
|
|
|
emit ( array ptr )
|
|
|
|
pad r> ;
|
|
|
|
|
2004-07-24 15:11:55 -04:00
|
|
|
( Cross-compile a reference to an object )
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
: ' ( obj -- pointer )
|
|
|
|
[
|
2004-08-06 18:40:44 -04:00
|
|
|
[ fixnum? ] [ 'fixnum ]
|
|
|
|
[ bignum? ] [ 'bignum ]
|
|
|
|
[ word? ] [ 'word ]
|
|
|
|
[ cons? ] [ 'cons ]
|
|
|
|
[ string? ] [ 'string ]
|
|
|
|
[ vector? ] [ 'vector ]
|
|
|
|
[ t = ] [ drop "t" get ]
|
2004-09-08 02:31:03 -04:00
|
|
|
! f is #define F RETAG(0,OBJECT_TYPE)
|
|
|
|
[ f = ] [ drop object-tag ]
|
2004-08-06 18:40:44 -04:00
|
|
|
[ drop t ] [ "Cannot cross-compile: " swap cat2 throw ]
|
2004-07-16 02:26:21 -04:00
|
|
|
] cond ;
|
|
|
|
|
2004-07-24 15:11:55 -04:00
|
|
|
( End of the image )
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-11-26 22:23:57 -05:00
|
|
|
: vocabularies, ( -- )
|
|
|
|
#! Produces code with stack effect ( -- vocabularies ).
|
|
|
|
#! This code sets up vocabulary hash tables.
|
|
|
|
\ <namespace> ,
|
|
|
|
[
|
|
|
|
"vocabularies" get [
|
|
|
|
uncons hash>alist , \ alist>hash , , \ set ,
|
|
|
|
] hash-each
|
|
|
|
] make-list ,
|
|
|
|
\ extend , ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
|
|
|
: global, ( -- )
|
2004-11-26 22:23:57 -05:00
|
|
|
#! Produces code with stack effect ( vocabularies -- ).
|
|
|
|
<namespace> ' global-offset fixup
|
|
|
|
"vocabularies" ,
|
|
|
|
\ global ,
|
|
|
|
\ set-hash , ;
|
|
|
|
|
|
|
|
: hash-quot ( -- quot )
|
|
|
|
#! Generate a quotation to generate vocabulary and global
|
|
|
|
#! namespace hashtables.
|
|
|
|
[ vocabularies, global, ] make-list ;
|
|
|
|
|
|
|
|
: boot, ( quot -- )
|
|
|
|
boot-quot get append ' boot-quot-offset fixup ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-09-08 02:31:03 -04:00
|
|
|
: end ( -- )
|
2004-11-26 22:23:57 -05:00
|
|
|
hash-quot
|
|
|
|
boot,
|
2004-09-08 02:31:03 -04:00
|
|
|
fixup-words
|
|
|
|
here base - heap-size-offset fixup ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-07-24 15:11:55 -04:00
|
|
|
( Image output )
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-07-17 18:35:09 -04:00
|
|
|
: write-word ( word -- )
|
2004-09-04 01:05:50 -04:00
|
|
|
"64-bits" get [
|
|
|
|
"big-endian" get [
|
|
|
|
write-big-endian-64
|
|
|
|
] [
|
|
|
|
write-little-endian-64
|
|
|
|
] ifte
|
2004-07-17 18:35:09 -04:00
|
|
|
] [
|
2004-09-04 01:05:50 -04:00
|
|
|
"big-endian" get [
|
|
|
|
write-big-endian-32
|
|
|
|
] [
|
|
|
|
write-little-endian-32
|
|
|
|
] ifte
|
2004-07-17 18:35:09 -04:00
|
|
|
] ifte ;
|
|
|
|
|
2004-07-16 02:26:21 -04:00
|
|
|
: write-image ( image file -- )
|
2004-07-17 18:35:09 -04:00
|
|
|
<filebw> [ [ write-word ] vector-each ] with-stream ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-08-06 18:40:44 -04:00
|
|
|
: with-minimal-image ( quot -- image )
|
2004-08-08 21:24:01 -04:00
|
|
|
[
|
2004-11-26 22:23:57 -05:00
|
|
|
300000 <vector> image set
|
2004-07-16 02:26:21 -04:00
|
|
|
521 <hashtable> "objects" set
|
|
|
|
namespace-buckets <hashtable> "vocabularies" set
|
2004-07-31 16:11:30 -04:00
|
|
|
! Note that this is a vector that we can side-effect,
|
|
|
|
! since ; ends up using this variable from nested
|
|
|
|
! parser namespaces.
|
|
|
|
1000 <vector> "word-fixups" set
|
2004-08-06 18:40:44 -04:00
|
|
|
call
|
2004-11-26 22:23:57 -05:00
|
|
|
image get
|
2004-08-08 21:24:01 -04:00
|
|
|
] with-scope ;
|
2004-07-16 02:26:21 -04:00
|
|
|
|
2004-08-06 18:40:44 -04:00
|
|
|
: with-image ( quot -- image )
|
|
|
|
[ begin call end ] with-minimal-image ;
|
|
|
|
|
2004-07-16 02:26:21 -04:00
|
|
|
: test-image ( quot -- ) with-image vector>list . ;
|