factor/library/bootstrap/image.factor

346 lines
8.0 KiB
Factor
Raw Normal View History

! Copyright (C) 2004, 2005 Slava Pestov.
! See http://factor.sf.net/license.txt for BSD license.
2004-07-16 02:26:21 -04:00
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
USING: errors generic hashtables kernel lists math namespaces
2005-04-02 02:39:33 -05:00
parser prettyprint sequences sequences stdio streams strings
vectors 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
2005-04-06 21:41:49 -04:00
: emit ( cell -- ) image get push ;
2004-11-26 22:23:57 -05:00
2005-04-06 21:41:49 -04:00
: fixup ( value offset -- ) image get set-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 ;
: cell "64-bits" get 8 4 ? ;
: char "64-bits" get 4 2 ? ;
2004-07-16 02:26:21 -04:00
2004-12-10 21:39:27 -05:00
: tag-mask BIN: 111 ; inline
: tag-bits 3 ; inline
2004-07-16 02:26:21 -04:00
: untag ( cell tag -- ) tag-mask bitnot bitand ;
: tag ( cell -- tag ) tag-mask bitand ;
: fixnum-tag BIN: 000 ; inline
: bignum-tag BIN: 001 ; inline
: cons-tag BIN: 010 ; inline
: object-tag BIN: 011 ; inline
2005-01-27 20:06:10 -05:00
: t-type 7 ; inline
: array-type 8 ; inline
: hashtable-type 10 ; inline
: vector-type 11 ; inline
: string-type 12 ; inline
: word-type 17 ; inline
2004-08-26 19:37:22 -04:00
: immediate ( x tag -- tagged ) swap tag-bits shift bitor ;
: >header ( id -- tagged ) object-tag immediate ;
2004-07-16 02:26:21 -04:00
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
#! some empty cells. This lets us differentiate an F pointer
2004-09-08 02:31:03 -04:00
#! (0/tag 3) from a pointer to the first object in the
#! image.
64 cell * ;
2004-09-08 02:31:03 -04:00
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 ;
GENERIC: ' ( obj -- ptr )
#! Write an object to the image.
2004-09-08 02:31:03 -04:00
( Allocator )
: here ( -- size )
image get 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-12-19 03:04:03 -05:00
: align-here ( -- )
2004-09-08 02:31:03 -04:00
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
2005-01-27 20:06:10 -05:00
: emit-fixnum ( n -- ) fixnum-tag immediate emit ;
M: fixnum ' ( n -- tagged ) fixnum-tag immediate ;
2004-07-16 02:26:21 -04:00
2004-08-06 02:51:32 -04:00
( Bignums )
M: bignum ' ( bignum -- tagged )
#! This can only emit 0, -1 and 1.
bignum-tag here-as >r
bignum-tag >header emit
[
[[ 0 [ 1 0 ] ]]
[[ -1 [ 2 1 1 ] ]]
[[ 1 [ 2 0 1 ] ]]
2005-01-27 20:06:10 -05:00
] assoc unswons emit-fixnum [ emit ] each align-here 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 ' emit ;
M: t ' ( obj -- ptr ) drop "t" get ;
M: f ' ( obj -- ptr )
#! f is #define F RETAG(0,OBJECT_TYPE)
drop object-tag ;
2004-07-16 02:26:21 -04:00
: 0, 0 >bignum ' drop ;
: 1, 1 >bignum ' drop ;
: -1, -1 >bignum ' drop ;
2004-08-29 01:04:42 -04:00
2004-07-24 15:11:55 -04:00
( Beginning of the image )
2005-01-27 20:06:10 -05:00
! The image 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
: word, ( word -- )
[
word-type >header ,
2004-12-27 22:58:43 -05:00
dup hashcode fixnum-tag immediate ,
0 ,
dup word-primitive ,
dup word-def ' ,
2005-01-28 23:55:22 -05:00
dup word-props ' ,
0 ,
0 ,
] make-list
swap object-tag here-as pool-object
[ emit ] each ;
: word-error ( word msg -- )
[
,
dup word-vocabulary ,
" " ,
word-name ,
] make-string throw ;
: transfer-word ( word -- word )
#! This is a hack. See doc/bootstrap.txt.
dup dup word-name swap word-vocabulary unit search
2005-03-21 14:39:46 -05:00
[ ] [ dup "Missing DEFER: " word-error ] ?ifte ;
2004-07-16 02:26:21 -04:00
2004-09-30 21:49:49 -04:00
: fixup-word ( word -- offset )
2005-03-21 14:39:46 -05:00
dup pooled-object [ ] [ "Not in image: " word-error ] ?ifte ;
2004-07-16 02:26:21 -04:00
: 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
2005-04-19 20:28:01 -04:00
] seq-map image set ;
2004-07-16 02:26:21 -04:00
M: word ' ( word -- pointer )
transfer-word 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
M: cons ' ( c -- tagged )
uncons ' swap '
cons-tag here-as
-rot emit emit ;
2004-07-16 02:26:21 -04:00
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 -- )
tuck length - CHAR: \0 fill cat2 ;
2004-07-16 02:26:21 -04:00
: emit-chars ( str -- )
2005-04-02 02:39:33 -05:00
>list "big-endian" get [ reverse ] unless
0 swap [ swap 16 shift + ] each emit ;
2004-07-16 02:26:21 -04:00
: (pack-string) ( n list -- )
#! Emit bytes for a string, with n characters per word.
[
2dup length > [ dupd align-string ] when
emit-chars
] each drop ;
2004-07-16 02:26:21 -04:00
: pack-string ( string -- )
char tuck swap split-n (pack-string) ;
2004-07-16 02:26:21 -04:00
: emit-string ( string -- )
2004-07-16 02:26:21 -04:00
object-tag here-as swap
2004-08-06 02:51:32 -04:00
string-type >header emit
dup length emit-fixnum
2005-01-27 20:06:10 -05:00
dup hashcode emit-fixnum
2005-02-09 19:58:53 -05:00
"\0" cat2 pack-string
2004-12-19 03:04:03 -05:00
align-here ;
2004-07-16 02:26:21 -04:00
M: string ' ( string -- pointer )
2004-07-16 02:26:21 -04:00
#! We pool strings so that each string is only written once
#! to the image
2005-03-21 14:39:46 -05:00
dup pooled-object [ ] [
2005-01-02 23:57:54 -05:00
dup emit-string dup >r pool-object r>
2005-03-21 14:39:46 -05:00
] ?ifte ;
2004-07-16 02:26:21 -04:00
2004-07-24 15:11:55 -04:00
( Arrays and vectors )
2004-07-16 02:26:21 -04:00
: emit-array ( list -- pointer )
2004-08-22 19:06:51 -04:00
[ ' ] map
object-tag here-as >r
2004-08-06 02:51:32 -04:00
array-type >header emit
2005-01-27 20:06:10 -05:00
dup length emit-fixnum
2004-07-16 02:26:21 -04:00
( elements -- ) [ emit ] each
2004-12-19 03:04:03 -05:00
align-here r> ;
2004-07-16 02:26:21 -04:00
2004-12-27 22:58:43 -05:00
: emit-vector ( vector -- pointer )
dup >list emit-array swap length
2004-07-16 02:26:21 -04:00
object-tag here-as >r
2004-08-06 02:51:32 -04:00
vector-type >header emit
2005-01-27 20:06:10 -05:00
emit-fixnum ( length )
2004-07-16 02:26:21 -04:00
emit ( array ptr )
2004-12-19 03:04:03 -05:00
align-here r> ;
2004-07-16 02:26:21 -04:00
2004-12-27 22:58:43 -05:00
M: vector ' ( vector -- pointer )
emit-vector ;
2005-01-27 20:06:10 -05:00
: emit-hashtable ( hash -- pointer )
2005-01-28 23:55:22 -05:00
dup buckets>list emit-array swap hash>alist length
2005-01-27 20:06:10 -05:00
object-tag here-as >r
hashtable-type >header emit
emit-fixnum ( length )
emit ( array ptr )
align-here r> ;
2004-12-27 22:58:43 -05:00
M: hashtable ' ( hashtable -- pointer )
#! Only hashtables are pooled, not vectors!
2005-03-21 14:39:46 -05:00
dup pooled-object [ ] [
2005-01-28 23:55:22 -05:00
dup emit-hashtable [ pool-object ] keep
2005-03-21 14:39:46 -05:00
] ?ifte ;
2004-12-27 22:58:43 -05:00
2004-07-24 15:11:55 -04:00
( End of the image )
2004-07-16 02:26:21 -04:00
: vocabularies, ( vocabularies -- )
2004-11-26 22:23:57 -05:00
[
2005-01-27 20:06:10 -05:00
cdr dup hashtable? [
[
cdr dup word? [ word, ] [ drop ] ifte
] hash-each
] [
drop
] ifte
] hash-each ;
2004-07-16 02:26:21 -04:00
: global, ( -- )
vocabularies get
dup vocabularies,
2005-03-07 22:11:36 -05:00
<namespace> [
vocabularies set
2005-04-10 18:58:30 -04:00
typemap [ ] change
builtins [ ] change
2005-03-07 22:11:36 -05:00
] extend '
global-offset fixup ;
2004-11-26 22:23:57 -05:00
: boot, ( quot -- )
2004-12-27 22:58:43 -05:00
boot-quot get swap append ' boot-quot-offset fixup ;
2004-07-16 02:26:21 -04:00
2004-12-27 22:58:43 -05:00
: end ( quot -- )
global,
2004-12-27 22:58:43 -05:00
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 -- )
"64-bits" get [
"big-endian" get [
write-big-endian-64
] [
write-little-endian-64
] ifte
2004-07-17 18:35:09 -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 -- )
2005-04-02 02:39:33 -05:00
<file-writer> [ [ write-word ] seq-each ] with-stream ;
2004-07-16 02:26:21 -04:00
: with-minimal-image ( quot -- image )
[
2004-11-26 22:23:57 -05:00
300000 <vector> image set
<namespace> "objects" set
call
2004-11-26 22:23:57 -05:00
image get
] with-scope ;
2004-07-16 02:26:21 -04:00
: with-image ( quot -- image )
2004-12-27 22:58:43 -05:00
#! The quotation leaves a boot quotation on the stack.
[ begin call end ] with-minimal-image ;
2005-04-02 02:39:33 -05:00
: test-image ( quot -- ) with-image >list . ;
: make-image ( name -- )
#! Make an image for the C interpreter.
[
2004-12-27 22:58:43 -05:00
boot-quot off
"/library/bootstrap/boot-stage1.factor" run-resource
] with-image
swap write-image ;
: make-images ( -- )
"64-bits" off
"big-endian" off "boot.image.le32" make-image
"big-endian" on "boot.image.be32" make-image
"64-bits" on
"big-endian" off "boot.image.le64" make-image
"big-endian" on "boot.image.be64" make-image
"64-bits" off ;