factor/library/bootstrap/image.factor

354 lines
8.1 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.
2005-12-13 18:16:37 -05:00
USING: alien arrays errors generic hashtables io kernel
kernel-internals lists math namespaces parser prettyprint
sequences sequences-internals strings vectors words ;
2005-12-02 02:25:44 -05:00
IN: image
2004-11-26 22:23:57 -05:00
! The image being constructed; a vector of word-size integers
SYMBOL: image
2005-08-07 00:00:57 -04:00
! Object cache
SYMBOL: objects
! Image output format
SYMBOL: big-endian
! Bootstrap architecture name
SYMBOL: architecture
2005-08-07 00:00:57 -04:00
2005-04-06 21:41:49 -04:00
: emit ( cell -- ) image get push ;
2004-11-26 22:23:57 -05:00
: d>w/w ( d -- w w )
2005-10-08 01:15:14 -04:00
dup HEX: ffffffff bitand swap -32 shift HEX: ffffffff bitand ;
2005-09-16 22:47:28 -04:00
: emit-64 ( cell -- )
cell get 8 = [
2005-09-16 22:47:28 -04:00
emit
] [
d>w/w big-endian get [ swap ] unless emit emit
2005-09-24 15:21:17 -04:00
] if ;
2005-09-16 22:47:28 -04:00
2005-07-31 23:38:33 -04:00
: emit-seq ( seq -- ) image get swap nappend ;
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 ;
: char cell get 2 /i ;
2004-07-16 02:26:21 -04:00
: untag ( cell tag -- ) tag-mask bitnot bitand ;
: tag ( cell -- tag ) tag-mask bitand ;
2005-01-27 20:06:10 -05:00
: array-type 8 ; inline
: hashtable-type 10 ; inline
: vector-type 11 ; inline
: string-type 12 ; inline
: wrapper-type 14 ; inline
2005-01-27 20:06:10 -05:00
: word-type 17 ; inline
: tuple-type 18 ; 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
2005-08-07 00:00:57 -04:00
: base 1024 ;
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
2005-05-10 22:30:58 -04:00
( pointer to t object ) 0 emit
( pointer to bignum 0 ) 0 emit
( pointer to bignum 1 ) 0 emit
( pointer to bignum -1 ) 0 emit
2004-07-16 02:26:21 -04:00
( size of heap set later ) 0 emit ;
: boot-quot-offset 3 ;
: global-offset 4 ;
2005-05-10 22:30:58 -04:00
: t-offset 5 ;
: 0-offset 6 ;
: 1-offset 7 ;
: -1-offset 8 ;
: heap-size-offset 9 ;
: header-size 10 ;
2004-07-16 02:26:21 -04:00
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 - cells 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
( 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 )
: bignum-bits cell-bits 2 - ;
2005-10-08 01:15:14 -04:00
: bignum-radix bignum-bits 1 swap shift 1- ;
: (bignum>seq) ( n -- )
dup 0 = [
drop
] [
dup bignum-radix bitand ,
bignum-bits neg shift (bignum>seq)
] if ;
: bignum>seq ( n -- seq )
#! n is positive or zero.
[ (bignum>seq) ] { } make ;
2005-10-08 01:15:14 -04:00
: emit-bignum ( n -- )
[ 0 < 1 0 ? ] keep abs bignum>seq
dup length 1+ emit-fixnum
swap emit emit-seq ;
M: bignum ' ( bignum -- tagged )
#! This can only emit 0, -1 and 1.
bignum-tag here-as >r
bignum-tag >header emit
2005-10-08 01:15:14 -04:00
emit-bignum align-here r> ;
2004-08-06 02:51:32 -04:00
2005-09-16 22:47:28 -04:00
( Floats )
M: float ' ( float -- tagged )
float-tag here-as >r
float-tag >header emit
align-here
double>bits emit-64
r> ;
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
2005-09-09 17:32:38 -04:00
: t, t t-offset fixup ;
M: f ' ( obj -- ptr )
#! f is #define F RETAG(0,OBJECT_TYPE)
drop object-tag ;
2004-07-16 02:26:21 -04:00
2005-05-10 22:30:58 -04:00
: 0, 0 >bignum ' 0-offset fixup ;
: 1, 1 >bignum ' 1-offset fixup ;
: -1, -1 >bignum ' -1-offset fixup ;
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
: begin-image ( -- ) 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
2005-07-31 23:38:33 -04:00
: emit-word ( word -- )
2005-08-07 00:00:57 -04:00
dup word-props ' >r
dup word-def ' >r
dup word-primitive ' >r
dup word-vocabulary ' >r
dup word-name ' >r
2005-08-07 00:00:57 -04:00
object-tag here-as over objects get set-hash
word-type >header emit
hashcode emit-fixnum
2005-08-07 00:00:57 -04:00
r> emit
r> emit
r> emit
r> emit
r> emit
0 emit ;
: word-error ( word msg -- )
2005-09-17 22:25:18 -04:00
[ % dup word-vocabulary % " " % word-name % ] "" make throw ;
: transfer-word ( word -- word )
#! This is a hack. See doc/bootstrap.txt.
2005-11-24 19:02:20 -05:00
dup target-word [ ] [ dup "Missing DEFER: " word-error ] ?if ;
2004-07-16 02:26:21 -04:00
2005-08-07 00:00:57 -04:00
: pooled-object ( object -- ptr ) objects get hash ;
2005-07-31 23:38:33 -04:00
2004-09-30 21:49:49 -04:00
: fixup-word ( word -- offset )
2005-08-07 00:00:57 -04:00
transfer-word dup pooled-object dup
2005-09-24 15:21:17 -04:00
[ nip ] [ "Not in image: " word-error ] if ;
2004-07-16 02:26:21 -04:00
: fixup-words ( -- )
image get [ dup word? [ fixup-word ] when ] inject ;
2004-07-16 02:26:21 -04:00
2005-08-07 00:00:57 -04:00
M: word ' ( word -- pointer ) ;
( Wrappers )
M: wrapper ' ( wrapper -- pointer )
wrapped '
object-tag here-as >r
wrapper-type >header emit
emit r> ;
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
2005-09-16 22:47:28 -04:00
: emit-cons ( first second tag -- pointer )
>r ' swap ' r> here-as -rot emit emit ;
M: cons ' ( c -- tagged ) uncons cons-tag emit-cons ;
M: ratio ' ( c -- tagged ) >fraction ratio-tag emit-cons ;
M: complex ' ( c -- tagged ) >rect complex-tag emit-cons ;
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
2005-07-31 23:38:33 -04:00
: emit-chars ( seq -- )
big-endian get [ [ reverse-slice ] map ] unless
2005-07-31 23:38:33 -04:00
[ 0 [ swap 16 shift + ] reduce emit ] each ;
2004-07-16 02:26:21 -04:00
2005-07-31 23:38:33 -04:00
: pack-string ( string -- seq )
2005-09-16 22:47:28 -04:00
dup length 1+ char align CHAR: \0 pad-right char swap group ;
2004-07-16 02:26:21 -04:00
2005-07-31 23:38:33 -04:00
: emit-string ( string -- ptr )
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-07-31 23:38:33 -04:00
pack-string emit-chars
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-08-07 00:00:57 -04:00
objects get [ emit-string ] cache ;
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 type -- pointer )
>r [ ' ] map r>
object-tag here-as >r
>header emit
2005-01-27 20:06:10 -05:00
dup length emit-fixnum
2005-07-31 23:38:33 -04:00
( elements -- ) emit-seq
2004-12-19 03:04:03 -05:00
align-here r> ;
2004-07-16 02:26:21 -04:00
2005-11-27 17:45:48 -05:00
: transfer-tuple ( tuple -- tuple )
tuple>array
dup first transfer-word 0 pick set-nth
array>tuple ;
M: tuple ' ( tuple -- pointer )
2005-11-27 17:45:48 -05:00
transfer-tuple
objects get [ tuple>array tuple-type emit-array ] cache ;
2005-09-11 21:18:19 -04:00
M: array ' ( array -- pointer )
array-type emit-array ;
2005-08-07 00:00:57 -04:00
M: vector ' ( vector -- pointer )
2005-11-27 17:45:48 -05:00
dup underlying ' 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
2005-08-07 00:00:57 -04:00
( Hashes )
2004-12-27 22:58:43 -05:00
2005-08-07 00:00:57 -04:00
M: hashtable ' ( hashtable -- pointer )
2005-11-27 17:45:48 -05:00
[ underlying ' ] keep
2005-01-27 20:06:10 -05:00
object-tag here-as >r
hashtable-type >header emit
2005-11-27 17:45:48 -05:00
dup hash-count emit-fixnum
hash-deleted emit-fixnum
2005-01-27 20:06:10 -05:00
emit ( array ptr )
align-here r> ;
2004-07-24 15:11:55 -04:00
( End of the image )
2004-07-16 02:26:21 -04:00
2005-07-31 23:38:33 -04:00
: words, ( -- )
all-words [ emit-word ] each ;
2004-07-16 02:26:21 -04:00
: global, ( -- )
[
2005-12-13 18:16:37 -05:00
{ vocabularies typemap builtins c-types crossref }
[ [ ] change ] each
] make-hash '
global-offset fixup ;
2004-11-26 22:23:57 -05:00
2005-08-22 16:01:13 -04:00
: boot, ( quot -- ) ' boot-quot-offset fixup ;
2004-07-16 02:26:21 -04:00
: heap-size image get length header-size - cells ;
2005-08-07 00:00:57 -04:00
: end-image ( quot -- )
2005-07-31 23:38:33 -04:00
"Generating words..." print
words,
"Generating global namespace..." print
global,
2005-07-31 23:38:33 -04:00
"Generating boot quotation..." print
2004-12-27 22:58:43 -05:00
boot,
2005-07-31 23:38:33 -04:00
"Performing some word fixups..." print
2004-09-08 02:31:03 -04:00
fixup-words
heap-size heap-size-offset fixup
"Image length: " write image get length .
"Object cache size: " write objects get hash-size .
\ word global remove-hash ;
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
2005-06-10 17:41:41 -04:00
: (write-image) ( image -- )
2005-12-14 20:29:32 -05:00
cell get swap big-endian get [
[ swap >be write ] each-with
2004-07-17 18:35:09 -04:00
] [
[ swap >le write ] each-with
2005-09-24 15:21:17 -04:00
] if ;
2004-07-17 18:35:09 -04:00
2005-12-14 20:29:32 -05:00
: image-name
"boot.image." architecture get append ;
: write-image ( image -- )
2005-07-31 23:38:33 -04:00
"Writing image to " write dup write "..." print
2005-06-10 17:41:41 -04:00
<file-writer> [ (write-image) ] with-stream ;
2004-07-16 02:26:21 -04:00
: prepare-profile ( arch -- )
"/library/bootstrap/profile-" swap ".factor" append3
run-resource ;
2004-07-16 02:26:21 -04:00
: prepare-image ( arch -- )
bootstrapping? on dup architecture set prepare-profile
800000 <vector> image set 20000 <hashtable> objects set ;
2005-12-14 20:29:32 -05:00
: make-image ( architecture -- )
#! Make a bootstrap image for the given architecture
#! (x86, ppc, or amd64).
[
prepare-image
begin-image
"/library/bootstrap/boot-stage1.factor" run-resource
end-image
2005-12-14 20:29:32 -05:00
image get image-name write-image
] with-scope ;
: make-images ( -- )
"x86" make-image "ppc" make-image "amd64" make-image ;