2008-01-02 19:36:36 -05:00
|
|
|
! Copyright (C) 2004, 2008 Slava Pestov.
|
2007-09-20 18:09:08 -04:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
|
|
USING: alien arrays bit-arrays byte-arrays generic assocs
|
|
|
|
hashtables assocs hashtables.private io kernel kernel.private
|
|
|
|
math namespaces parser prettyprint sequences sequences.private
|
|
|
|
strings sbufs vectors words quotations assocs system layouts
|
2008-03-29 04:34:48 -04:00
|
|
|
splitting growable classes classes.tuple classes.tuple.private
|
|
|
|
words.private io.binary io.files vocabs vocabs.loader
|
|
|
|
source-files definitions debugger float-arrays
|
|
|
|
quotations.private sequences.private combinators
|
|
|
|
io.encodings.binary ;
|
2007-09-20 18:09:08 -04:00
|
|
|
IN: bootstrap.image
|
|
|
|
|
2008-02-07 18:55:31 -05:00
|
|
|
: my-arch ( -- arch )
|
|
|
|
cpu dup "ppc" = [ os "-" rot 3append ] when ;
|
|
|
|
|
|
|
|
: boot-image-name ( arch -- string )
|
|
|
|
"boot." swap ".image" 3append ;
|
|
|
|
|
|
|
|
: my-boot-image-name ( -- string )
|
|
|
|
my-arch boot-image-name ;
|
|
|
|
|
|
|
|
: images ( -- seq )
|
|
|
|
{
|
|
|
|
"x86.32"
|
|
|
|
"x86.64"
|
|
|
|
"linux-ppc" "macosx-ppc"
|
|
|
|
! "arm"
|
|
|
|
} ;
|
|
|
|
|
2007-09-20 18:09:08 -04:00
|
|
|
<PRIVATE
|
|
|
|
|
|
|
|
! Constants
|
|
|
|
|
|
|
|
: image-magic HEX: 0f0e0d0c ; inline
|
|
|
|
: image-version 4 ; inline
|
|
|
|
|
|
|
|
: data-base 1024 ; inline
|
|
|
|
|
2008-02-18 06:07:40 -05:00
|
|
|
: userenv-size 64 ; inline
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
: header-size 10 ; inline
|
|
|
|
|
|
|
|
: data-heap-size-offset 3 ; inline
|
|
|
|
: t-offset 6 ; inline
|
|
|
|
: 0-offset 7 ; inline
|
|
|
|
: 1-offset 8 ; inline
|
|
|
|
: -1-offset 9 ; inline
|
|
|
|
|
|
|
|
: array-start 2 bootstrap-cells object tag-number - ;
|
2007-09-22 02:28:49 -04:00
|
|
|
: scan@ array-start bootstrap-cell - ;
|
2007-09-20 18:09:08 -04:00
|
|
|
: wrapper@ bootstrap-cell object tag-number - ;
|
|
|
|
: word-xt@ 8 bootstrap-cells object tag-number - ;
|
|
|
|
: quot-array@ bootstrap-cell object tag-number - ;
|
2007-09-26 00:26:19 -04:00
|
|
|
: quot-xt@ 3 bootstrap-cells object tag-number - ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2007-12-25 23:40:36 -05:00
|
|
|
: jit-define ( quot rc rt offset name -- )
|
|
|
|
>r >r >r >r { } make r> r> r> 4array r> set ;
|
|
|
|
|
2007-09-20 18:09:08 -04:00
|
|
|
! The image being constructed; a vector of word-size integers
|
|
|
|
SYMBOL: image
|
|
|
|
|
|
|
|
! Object cache
|
|
|
|
SYMBOL: objects
|
|
|
|
|
|
|
|
! Image output format
|
|
|
|
SYMBOL: big-endian
|
|
|
|
|
|
|
|
! Bootstrap architecture name
|
|
|
|
SYMBOL: architecture
|
|
|
|
|
|
|
|
! Bootstrap global namesapce
|
|
|
|
SYMBOL: bootstrap-global
|
|
|
|
|
|
|
|
! Boot quotation, set in stage1.factor
|
|
|
|
SYMBOL: bootstrap-boot-quot
|
|
|
|
|
|
|
|
! JIT parameters
|
|
|
|
SYMBOL: jit-code-format
|
|
|
|
SYMBOL: jit-prolog
|
2008-01-02 19:36:36 -05:00
|
|
|
SYMBOL: jit-primitive-word
|
|
|
|
SYMBOL: jit-primitive
|
2007-09-20 18:09:08 -04:00
|
|
|
SYMBOL: jit-word-jump
|
|
|
|
SYMBOL: jit-word-call
|
|
|
|
SYMBOL: jit-push-literal
|
|
|
|
SYMBOL: jit-if-word
|
|
|
|
SYMBOL: jit-if-jump
|
|
|
|
SYMBOL: jit-dispatch-word
|
|
|
|
SYMBOL: jit-dispatch
|
|
|
|
SYMBOL: jit-epilog
|
|
|
|
SYMBOL: jit-return
|
2008-01-02 19:36:36 -05:00
|
|
|
SYMBOL: jit-profiling
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2007-12-26 20:40:46 -05:00
|
|
|
! Default definition for undefined words
|
|
|
|
SYMBOL: undefined-quot
|
|
|
|
|
2007-09-20 18:09:08 -04:00
|
|
|
: userenv-offset ( symbol -- n )
|
|
|
|
{
|
|
|
|
{ bootstrap-boot-quot 20 }
|
|
|
|
{ bootstrap-global 21 }
|
|
|
|
{ jit-code-format 22 }
|
2007-12-26 20:40:46 -05:00
|
|
|
{ jit-prolog 23 }
|
2008-01-02 19:36:36 -05:00
|
|
|
{ jit-primitive-word 24 }
|
|
|
|
{ jit-primitive 25 }
|
2007-12-26 20:40:46 -05:00
|
|
|
{ jit-word-jump 26 }
|
|
|
|
{ jit-word-call 27 }
|
|
|
|
{ jit-push-literal 28 }
|
|
|
|
{ jit-if-word 29 }
|
|
|
|
{ jit-if-jump 30 }
|
|
|
|
{ jit-dispatch-word 31 }
|
|
|
|
{ jit-dispatch 32 }
|
|
|
|
{ jit-epilog 33 }
|
|
|
|
{ jit-return 34 }
|
2008-01-02 19:36:36 -05:00
|
|
|
{ jit-profiling 35 }
|
2007-12-26 20:40:46 -05:00
|
|
|
{ undefined-quot 37 }
|
2007-09-20 18:09:08 -04:00
|
|
|
} at header-size + ;
|
|
|
|
|
|
|
|
: emit ( cell -- ) image get push ;
|
|
|
|
|
|
|
|
: emit-64 ( cell -- )
|
|
|
|
bootstrap-cell 8 = [
|
|
|
|
emit
|
|
|
|
] [
|
|
|
|
d>w/w big-endian get [ swap ] unless emit emit
|
|
|
|
] if ;
|
|
|
|
|
|
|
|
: emit-seq ( seq -- ) image get push-all ;
|
|
|
|
|
|
|
|
: fixup ( value offset -- ) image get set-nth ;
|
|
|
|
|
|
|
|
: heap-size ( -- size )
|
|
|
|
image get length header-size - userenv-size -
|
|
|
|
bootstrap-cells ;
|
|
|
|
|
|
|
|
: here ( -- size ) heap-size data-base + ;
|
|
|
|
|
|
|
|
: here-as ( tag -- pointer ) here swap bitor ;
|
|
|
|
|
|
|
|
: align-here ( -- )
|
2008-02-10 02:49:27 -05:00
|
|
|
here 8 mod 4 = [ heap-size drop 0 emit ] when ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-01-02 19:36:36 -05:00
|
|
|
: emit-fixnum ( n -- ) tag-fixnum emit ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
: emit-object ( header tag quot -- addr )
|
2008-01-02 19:36:36 -05:00
|
|
|
swap here-as >r swap tag-fixnum emit call align-here r> ;
|
2007-09-20 18:09:08 -04:00
|
|
|
inline
|
|
|
|
|
|
|
|
! Write an object to the image.
|
|
|
|
GENERIC: ' ( obj -- ptr )
|
|
|
|
|
|
|
|
! Image header
|
|
|
|
|
|
|
|
: emit-header ( -- )
|
|
|
|
image-magic emit
|
|
|
|
image-version emit
|
|
|
|
data-base emit ! relocation base at end of header
|
|
|
|
0 emit ! size of data heap set later
|
|
|
|
0 emit ! reloc base of code heap is 0
|
|
|
|
0 emit ! size of code heap is 0
|
|
|
|
0 emit ! pointer to t object
|
|
|
|
0 emit ! pointer to bignum 0
|
|
|
|
0 emit ! pointer to bignum 1
|
|
|
|
0 emit ! pointer to bignum -1
|
|
|
|
userenv-size [ f ' emit ] times ;
|
|
|
|
|
|
|
|
: emit-userenv ( symbol -- )
|
|
|
|
dup get ' swap userenv-offset fixup ;
|
|
|
|
|
|
|
|
! Bignums
|
|
|
|
|
|
|
|
: bignum-bits bootstrap-cell-bits 2 - ;
|
|
|
|
|
|
|
|
: bignum-radix bignum-bits 2^ 1- ;
|
|
|
|
|
|
|
|
: bignum>seq ( n -- seq )
|
|
|
|
#! n is positive or zero.
|
2007-10-16 04:15:16 -04:00
|
|
|
[ dup 0 > ]
|
|
|
|
[ dup bignum-bits neg shift swap bignum-radix bitand ]
|
2007-11-04 17:32:01 -05:00
|
|
|
[ ] unfold nip ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-02-10 02:34:16 -05:00
|
|
|
USE: continuations
|
2007-09-20 18:09:08 -04:00
|
|
|
: emit-bignum ( n -- )
|
2007-10-14 20:44:19 -04:00
|
|
|
dup 0 < [ 1 swap neg ] [ 0 swap ] if bignum>seq
|
2007-09-20 18:09:08 -04:00
|
|
|
dup length 1+ emit-fixnum
|
|
|
|
swap emit emit-seq ;
|
|
|
|
|
|
|
|
M: bignum '
|
|
|
|
bignum tag-number dup [ emit-bignum ] emit-object ;
|
|
|
|
|
|
|
|
! Fixnums
|
|
|
|
|
|
|
|
M: fixnum '
|
|
|
|
#! When generating a 32-bit image on a 64-bit system,
|
|
|
|
#! some fixnums should be bignums.
|
2008-03-12 02:54:29 -04:00
|
|
|
dup
|
|
|
|
bootstrap-most-negative-fixnum
|
|
|
|
bootstrap-most-positive-fixnum between?
|
2008-01-02 19:36:36 -05:00
|
|
|
[ tag-fixnum ] [ >bignum ' ] if ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
! Floats
|
|
|
|
|
|
|
|
M: float '
|
|
|
|
float tag-number dup [
|
|
|
|
align-here double>bits emit-64
|
|
|
|
] emit-object ;
|
|
|
|
|
|
|
|
! Special objects
|
|
|
|
|
|
|
|
! Padded with fixnums for 8-byte alignment
|
|
|
|
|
|
|
|
: t, t t-offset fixup ;
|
|
|
|
|
|
|
|
M: f '
|
|
|
|
#! f is #define F RETAG(0,F_TYPE)
|
|
|
|
drop \ f tag-number ;
|
|
|
|
|
|
|
|
: 0, 0 >bignum ' 0-offset fixup ;
|
|
|
|
: 1, 1 >bignum ' 1-offset fixup ;
|
|
|
|
: -1, -1 >bignum ' -1-offset fixup ;
|
|
|
|
|
|
|
|
! Words
|
|
|
|
|
|
|
|
: emit-word ( word -- )
|
2008-02-05 00:30:59 -05:00
|
|
|
dup subwords [ emit-word ] each
|
2007-09-20 18:09:08 -04:00
|
|
|
[
|
|
|
|
dup hashcode ' ,
|
|
|
|
dup word-name ' ,
|
|
|
|
dup word-vocabulary ' ,
|
|
|
|
dup word-def ' ,
|
|
|
|
dup word-props ' ,
|
|
|
|
f ' ,
|
2007-10-28 04:33:36 -04:00
|
|
|
0 , ! count
|
|
|
|
0 , ! xt
|
|
|
|
0 , ! code
|
2008-01-02 19:36:36 -05:00
|
|
|
0 , ! profiling
|
2007-09-20 18:09:08 -04:00
|
|
|
] { } make
|
|
|
|
\ word type-number object tag-number
|
|
|
|
[ emit-seq ] emit-object
|
|
|
|
swap objects get set-at ;
|
|
|
|
|
|
|
|
: word-error ( word msg -- * )
|
|
|
|
[ % dup word-vocabulary % " " % word-name % ] "" make throw ;
|
|
|
|
|
|
|
|
: transfer-word ( word -- word )
|
2008-02-04 17:20:07 -05:00
|
|
|
dup target-word swap or ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
: fixup-word ( word -- offset )
|
|
|
|
transfer-word dup objects get at
|
|
|
|
[ ] [ "Not in image: " word-error ] ?if ;
|
|
|
|
|
|
|
|
: fixup-words ( -- )
|
|
|
|
image get [ dup word? [ fixup-word ] when ] change-each ;
|
|
|
|
|
|
|
|
M: word ' ;
|
|
|
|
|
|
|
|
! Wrappers
|
|
|
|
|
|
|
|
M: wrapper '
|
|
|
|
wrapped ' wrapper type-number object tag-number
|
|
|
|
[ emit ] emit-object ;
|
|
|
|
|
|
|
|
! Strings
|
|
|
|
: emit-chars ( seq -- )
|
2008-02-01 00:00:08 -05:00
|
|
|
bootstrap-cell <groups>
|
|
|
|
big-endian get [ [ be> ] map ] [ [ le> ] map ] if
|
2007-09-20 18:09:08 -04:00
|
|
|
emit-seq ;
|
|
|
|
|
|
|
|
: pack-string ( string -- newstr )
|
2008-02-04 15:05:31 -05:00
|
|
|
dup length bootstrap-cell align 0 pad-right ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
: emit-string ( string -- ptr )
|
|
|
|
string type-number object tag-number [
|
|
|
|
dup length emit-fixnum
|
|
|
|
f ' emit
|
2008-01-31 21:11:46 -05:00
|
|
|
f ' emit
|
2007-09-20 18:09:08 -04:00
|
|
|
pack-string emit-chars
|
|
|
|
] emit-object ;
|
|
|
|
|
|
|
|
M: string '
|
|
|
|
#! We pool strings so that each string is only written once
|
|
|
|
#! to the image
|
|
|
|
objects get [ emit-string ] cache ;
|
|
|
|
|
|
|
|
: assert-empty ( seq -- )
|
|
|
|
length 0 assert= ;
|
|
|
|
|
|
|
|
: emit-dummy-array ( obj type -- ptr )
|
|
|
|
swap assert-empty
|
|
|
|
type-number object tag-number
|
|
|
|
[ 0 emit-fixnum ] emit-object ;
|
|
|
|
|
|
|
|
M: byte-array ' byte-array emit-dummy-array ;
|
|
|
|
|
|
|
|
M: bit-array ' bit-array emit-dummy-array ;
|
|
|
|
|
|
|
|
M: float-array ' float-array emit-dummy-array ;
|
|
|
|
|
2008-03-26 04:57:48 -04:00
|
|
|
! Tuples
|
|
|
|
: emit-tuple ( tuple -- pointer )
|
2008-02-04 17:20:07 -05:00
|
|
|
[
|
2008-03-26 04:57:48 -04:00
|
|
|
[
|
|
|
|
dup class transfer-word tuple-layout ' ,
|
|
|
|
tuple>array 1 tail-slice [ ' ] map %
|
|
|
|
] { } make
|
|
|
|
tuple type-number dup [ emit-seq ] emit-object
|
2008-02-04 17:20:07 -05:00
|
|
|
]
|
|
|
|
! Hack
|
|
|
|
over class word-name "tombstone" =
|
|
|
|
[ objects get swap cache ] [ call ] if ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
M: tuple ' emit-tuple ;
|
|
|
|
|
2008-03-26 04:57:48 -04:00
|
|
|
M: tuple-layout '
|
|
|
|
objects get [
|
|
|
|
[
|
|
|
|
dup layout-hashcode ' ,
|
|
|
|
dup layout-class ' ,
|
|
|
|
dup layout-size ' ,
|
|
|
|
dup layout-superclasses ' ,
|
|
|
|
layout-echelon ' ,
|
|
|
|
] { } make
|
|
|
|
\ tuple-layout type-number
|
|
|
|
object tag-number [ emit-seq ] emit-object
|
|
|
|
] cache ;
|
|
|
|
|
2007-09-20 18:09:08 -04:00
|
|
|
M: tombstone '
|
|
|
|
delegate
|
|
|
|
"((tombstone))" "((empty))" ? "hashtables.private" lookup
|
2008-02-04 17:20:07 -05:00
|
|
|
word-def first objects get [ emit-tuple ] cache ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-03-26 04:57:48 -04:00
|
|
|
! Arrays
|
|
|
|
: emit-array ( list type tag -- pointer )
|
|
|
|
>r >r [ ' ] map r> r> [
|
|
|
|
dup length emit-fixnum
|
|
|
|
emit-seq
|
|
|
|
] emit-object ;
|
|
|
|
|
2007-09-20 18:09:08 -04:00
|
|
|
M: array '
|
|
|
|
array type-number object tag-number emit-array ;
|
|
|
|
|
|
|
|
! Quotations
|
|
|
|
|
|
|
|
M: quotation '
|
|
|
|
objects get [
|
|
|
|
quotation-array '
|
|
|
|
quotation type-number object tag-number [
|
|
|
|
emit ! array
|
2007-09-26 00:26:19 -04:00
|
|
|
f ' emit ! compiled?
|
2007-10-28 04:33:36 -04:00
|
|
|
0 emit ! xt
|
|
|
|
0 emit ! code
|
2007-09-20 18:09:08 -04:00
|
|
|
] emit-object
|
|
|
|
] cache ;
|
|
|
|
|
|
|
|
! Curries
|
|
|
|
|
|
|
|
M: curry '
|
|
|
|
dup curry-quot ' swap curry-obj '
|
|
|
|
\ curry type-number object tag-number
|
|
|
|
[ emit emit ] emit-object ;
|
|
|
|
|
|
|
|
! End of the image
|
|
|
|
|
|
|
|
: emit-words ( -- )
|
|
|
|
all-words [ emit-word ] each ;
|
|
|
|
|
|
|
|
: emit-global ( -- )
|
|
|
|
[
|
|
|
|
{
|
2008-03-24 20:52:21 -04:00
|
|
|
dictionary source-files builtins
|
|
|
|
update-map class<-cache class-not-cache
|
|
|
|
classes-intersect-cache class-and-cache
|
|
|
|
class-or-cache
|
2007-12-24 19:40:09 -05:00
|
|
|
} [ dup get swap bootstrap-word set ] each
|
2007-09-20 18:09:08 -04:00
|
|
|
] H{ } make-assoc
|
|
|
|
bootstrap-global set
|
|
|
|
bootstrap-global emit-userenv ;
|
|
|
|
|
|
|
|
: emit-boot-quot ( -- )
|
|
|
|
bootstrap-boot-quot emit-userenv ;
|
|
|
|
|
|
|
|
: emit-jit-data ( -- )
|
|
|
|
\ if jit-if-word set
|
|
|
|
\ dispatch jit-dispatch-word set
|
2008-01-02 19:36:36 -05:00
|
|
|
\ do-primitive jit-primitive-word set
|
2007-12-26 20:40:46 -05:00
|
|
|
[ undefined ] undefined-quot set
|
2007-09-20 18:09:08 -04:00
|
|
|
{
|
|
|
|
jit-code-format
|
|
|
|
jit-prolog
|
2008-01-02 19:36:36 -05:00
|
|
|
jit-primitive-word
|
|
|
|
jit-primitive
|
2007-09-20 18:09:08 -04:00
|
|
|
jit-word-jump
|
|
|
|
jit-word-call
|
|
|
|
jit-push-literal
|
|
|
|
jit-if-word
|
|
|
|
jit-if-jump
|
|
|
|
jit-dispatch-word
|
|
|
|
jit-dispatch
|
|
|
|
jit-epilog
|
|
|
|
jit-return
|
2008-01-02 19:36:36 -05:00
|
|
|
jit-profiling
|
2007-12-26 20:40:46 -05:00
|
|
|
undefined-quot
|
2007-09-20 18:09:08 -04:00
|
|
|
} [ emit-userenv ] each ;
|
|
|
|
|
|
|
|
: fixup-header ( -- )
|
|
|
|
heap-size data-heap-size-offset fixup ;
|
|
|
|
|
2008-02-10 02:49:27 -05:00
|
|
|
: build-image ( -- image )
|
|
|
|
800000 <vector> image set
|
|
|
|
20000 <hashtable> objects set
|
|
|
|
emit-header t, 0, 1, -1,
|
2007-09-20 18:09:08 -04:00
|
|
|
"Serializing words..." print flush
|
|
|
|
emit-words
|
|
|
|
"Serializing JIT data..." print flush
|
|
|
|
emit-jit-data
|
|
|
|
"Serializing global namespace..." print flush
|
|
|
|
emit-global
|
|
|
|
"Serializing boot quotation..." print flush
|
|
|
|
emit-boot-quot
|
|
|
|
"Performing word fixups..." print flush
|
|
|
|
fixup-words
|
|
|
|
"Performing header fixups..." print flush
|
|
|
|
fixup-header
|
|
|
|
"Image length: " write image get length .
|
|
|
|
"Object cache size: " write objects get assoc-size .
|
2008-02-10 02:49:27 -05:00
|
|
|
\ word global delete-at
|
|
|
|
image get ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
! Image output
|
|
|
|
|
|
|
|
: (write-image) ( image -- )
|
|
|
|
bootstrap-cell big-endian get [
|
|
|
|
[ >be write ] curry each
|
|
|
|
] [
|
|
|
|
[ >le write ] curry each
|
|
|
|
] if ;
|
|
|
|
|
2008-02-10 02:49:27 -05:00
|
|
|
: write-image ( image -- )
|
|
|
|
"Writing image to " write
|
|
|
|
architecture get boot-image-name resource-path
|
|
|
|
dup write "..." print flush
|
2008-02-22 21:21:23 -05:00
|
|
|
binary <file-writer> [ (write-image) ] with-stream ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
PRIVATE>
|
|
|
|
|
2007-11-05 01:37:07 -05:00
|
|
|
: make-image ( arch -- )
|
2008-02-10 02:49:27 -05:00
|
|
|
[
|
|
|
|
architecture set
|
|
|
|
bootstrapping? on
|
|
|
|
load-help? off
|
2007-09-20 18:09:08 -04:00
|
|
|
"resource:/core/bootstrap/stage1.factor" run-file
|
2008-02-10 02:49:27 -05:00
|
|
|
build-image
|
2008-02-07 18:55:31 -05:00
|
|
|
write-image
|
2008-02-10 02:49:27 -05:00
|
|
|
] with-scope ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
: make-images ( -- )
|
2008-02-07 18:55:31 -05:00
|
|
|
images [ make-image ] each ;
|