Merge branch 'master' of git://factorcode.org/git/factor
commit
a88b176ba2
|
@ -85,8 +85,16 @@ SYMBOL: objects
|
||||||
: 1-offset 8 ; inline
|
: 1-offset 8 ; inline
|
||||||
: -1-offset 9 ; inline
|
: -1-offset 9 ; inline
|
||||||
|
|
||||||
|
SYMBOL: sub-primitives
|
||||||
|
|
||||||
|
: make-jit ( quot rc rt offset -- quad )
|
||||||
|
{ [ { } make ] [ ] [ ] [ ] } spread 4array ; inline
|
||||||
|
|
||||||
: jit-define ( quot rc rt offset name -- )
|
: jit-define ( quot rc rt offset name -- )
|
||||||
>r { [ { } make ] [ ] [ ] [ ] } spread 4array r> set ;
|
>r make-jit r> set ; inline
|
||||||
|
|
||||||
|
: define-sub-primitive ( quot rc rt offset word -- )
|
||||||
|
>r make-jit r> sub-primitives get set-at ;
|
||||||
|
|
||||||
! The image being constructed; a vector of word-size integers
|
! The image being constructed; a vector of word-size integers
|
||||||
SYMBOL: image
|
SYMBOL: image
|
||||||
|
@ -118,29 +126,7 @@ SYMBOL: jit-dispatch
|
||||||
SYMBOL: jit-epilog
|
SYMBOL: jit-epilog
|
||||||
SYMBOL: jit-return
|
SYMBOL: jit-return
|
||||||
SYMBOL: jit-profiling
|
SYMBOL: jit-profiling
|
||||||
SYMBOL: jit-tag
|
|
||||||
SYMBOL: jit-tag-word
|
|
||||||
SYMBOL: jit-eq?
|
|
||||||
SYMBOL: jit-eq?-word
|
|
||||||
SYMBOL: jit-slot
|
|
||||||
SYMBOL: jit-slot-word
|
|
||||||
SYMBOL: jit-declare-word
|
SYMBOL: jit-declare-word
|
||||||
SYMBOL: jit-drop
|
|
||||||
SYMBOL: jit-drop-word
|
|
||||||
SYMBOL: jit-dup
|
|
||||||
SYMBOL: jit-dup-word
|
|
||||||
SYMBOL: jit->r
|
|
||||||
SYMBOL: jit->r-word
|
|
||||||
SYMBOL: jit-r>
|
|
||||||
SYMBOL: jit-r>-word
|
|
||||||
SYMBOL: jit-swap
|
|
||||||
SYMBOL: jit-swap-word
|
|
||||||
SYMBOL: jit-over
|
|
||||||
SYMBOL: jit-over-word
|
|
||||||
SYMBOL: jit-fixnum-fast
|
|
||||||
SYMBOL: jit-fixnum-fast-word
|
|
||||||
SYMBOL: jit-fixnum>=
|
|
||||||
SYMBOL: jit-fixnum>=-word
|
|
||||||
|
|
||||||
! Default definition for undefined words
|
! Default definition for undefined words
|
||||||
SYMBOL: undefined-quot
|
SYMBOL: undefined-quot
|
||||||
|
@ -163,29 +149,7 @@ SYMBOL: undefined-quot
|
||||||
{ jit-epilog 33 }
|
{ jit-epilog 33 }
|
||||||
{ jit-return 34 }
|
{ jit-return 34 }
|
||||||
{ jit-profiling 35 }
|
{ jit-profiling 35 }
|
||||||
{ jit-tag 36 }
|
|
||||||
{ jit-tag-word 37 }
|
|
||||||
{ jit-eq? 38 }
|
|
||||||
{ jit-eq?-word 39 }
|
|
||||||
{ jit-slot 40 }
|
|
||||||
{ jit-slot-word 41 }
|
|
||||||
{ jit-declare-word 42 }
|
{ jit-declare-word 42 }
|
||||||
{ jit-drop 43 }
|
|
||||||
{ jit-drop-word 44 }
|
|
||||||
{ jit-dup 45 }
|
|
||||||
{ jit-dup-word 46 }
|
|
||||||
{ jit->r 47 }
|
|
||||||
{ jit->r-word 48 }
|
|
||||||
{ jit-r> 49 }
|
|
||||||
{ jit-r>-word 50 }
|
|
||||||
{ jit-swap 51 }
|
|
||||||
{ jit-swap-word 52 }
|
|
||||||
{ jit-over 53 }
|
|
||||||
{ jit-over-word 54 }
|
|
||||||
{ jit-fixnum-fast 55 }
|
|
||||||
{ jit-fixnum-fast-word 56 }
|
|
||||||
{ jit-fixnum>= 57 }
|
|
||||||
{ jit-fixnum>=-word 58 }
|
|
||||||
{ undefined-quot 60 }
|
{ undefined-quot 60 }
|
||||||
} at header-size + ;
|
} at header-size + ;
|
||||||
|
|
||||||
|
@ -305,6 +269,9 @@ M: f '
|
||||||
|
|
||||||
! Words
|
! Words
|
||||||
|
|
||||||
|
: word-sub-primitive ( word -- obj )
|
||||||
|
global [ target-word ] bind sub-primitives get at ;
|
||||||
|
|
||||||
: emit-word ( word -- )
|
: emit-word ( word -- )
|
||||||
[
|
[
|
||||||
[ subwords [ emit-word ] each ]
|
[ subwords [ emit-word ] each ]
|
||||||
|
@ -316,12 +283,13 @@ M: f '
|
||||||
[ vocabulary>> , ]
|
[ vocabulary>> , ]
|
||||||
[ def>> , ]
|
[ def>> , ]
|
||||||
[ props>> , ]
|
[ props>> , ]
|
||||||
|
[ drop f , ]
|
||||||
|
[ drop 0 , ] ! count
|
||||||
|
[ word-sub-primitive , ]
|
||||||
|
[ drop 0 , ] ! xt
|
||||||
|
[ drop 0 , ] ! code
|
||||||
|
[ drop 0 , ] ! profiling
|
||||||
} cleave
|
} cleave
|
||||||
f ,
|
|
||||||
0 , ! count
|
|
||||||
0 , ! xt
|
|
||||||
0 , ! code
|
|
||||||
0 , ! profiling
|
|
||||||
] { } make [ ' ] map
|
] { } make [ ' ] map
|
||||||
] bi
|
] bi
|
||||||
\ word type-number object tag-number
|
\ word type-number object tag-number
|
||||||
|
@ -460,18 +428,7 @@ M: quotation '
|
||||||
\ if jit-if-word set
|
\ if jit-if-word set
|
||||||
\ dispatch jit-dispatch-word set
|
\ dispatch jit-dispatch-word set
|
||||||
\ do-primitive jit-primitive-word set
|
\ do-primitive jit-primitive-word set
|
||||||
\ tag jit-tag-word set
|
|
||||||
\ eq? jit-eq?-word set
|
|
||||||
\ slot jit-slot-word set
|
|
||||||
\ declare jit-declare-word set
|
\ declare jit-declare-word set
|
||||||
\ drop jit-drop-word set
|
|
||||||
\ dup jit-dup-word set
|
|
||||||
\ >r jit->r-word set
|
|
||||||
\ r> jit-r>-word set
|
|
||||||
\ swap jit-swap-word set
|
|
||||||
\ over jit-over-word set
|
|
||||||
\ fixnum-fast jit-fixnum-fast-word set
|
|
||||||
\ fixnum>= jit-fixnum>=-word set
|
|
||||||
[ undefined ] undefined-quot set
|
[ undefined ] undefined-quot set
|
||||||
{
|
{
|
||||||
jit-code-format
|
jit-code-format
|
||||||
|
@ -488,29 +445,7 @@ M: quotation '
|
||||||
jit-epilog
|
jit-epilog
|
||||||
jit-return
|
jit-return
|
||||||
jit-profiling
|
jit-profiling
|
||||||
jit-tag
|
|
||||||
jit-tag-word
|
|
||||||
jit-eq?
|
|
||||||
jit-eq?-word
|
|
||||||
jit-slot
|
|
||||||
jit-slot-word
|
|
||||||
jit-declare-word
|
jit-declare-word
|
||||||
jit-drop
|
|
||||||
jit-drop-word
|
|
||||||
jit-dup
|
|
||||||
jit-dup-word
|
|
||||||
jit->r
|
|
||||||
jit->r-word
|
|
||||||
jit-r>
|
|
||||||
jit-r>-word
|
|
||||||
jit-swap
|
|
||||||
jit-swap-word
|
|
||||||
jit-over
|
|
||||||
jit-over-word
|
|
||||||
jit-fixnum-fast
|
|
||||||
jit-fixnum-fast-word
|
|
||||||
jit-fixnum>=
|
|
||||||
jit-fixnum>=-word
|
|
||||||
undefined-quot
|
undefined-quot
|
||||||
} [ emit-userenv ] each ;
|
} [ emit-userenv ] each ;
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,8 @@ IN: bootstrap.primitives
|
||||||
|
|
||||||
crossref off
|
crossref off
|
||||||
|
|
||||||
|
H{ } clone sub-primitives set
|
||||||
|
|
||||||
"resource:core/bootstrap/syntax.factor" parse-file
|
"resource:core/bootstrap/syntax.factor" parse-file
|
||||||
|
|
||||||
"resource:core/cpu/" architecture get {
|
"resource:core/cpu/" architecture get {
|
||||||
|
@ -256,6 +258,7 @@ bi
|
||||||
"props"
|
"props"
|
||||||
{ "compiled" read-only }
|
{ "compiled" read-only }
|
||||||
{ "counter" { "fixnum" "math" } }
|
{ "counter" { "fixnum" "math" } }
|
||||||
|
{ "sub-primitive" read-only }
|
||||||
} define-builtin
|
} define-builtin
|
||||||
|
|
||||||
"byte-array" "byte-arrays" create { } define-builtin
|
"byte-array" "byte-arrays" create { } define-builtin
|
||||||
|
@ -323,14 +326,55 @@ tuple
|
||||||
[ tuple-layout [ <tuple-boa> ] curry ] tri
|
[ tuple-layout [ <tuple-boa> ] curry ] tri
|
||||||
(( quot1 quot2 -- compose )) define-declared
|
(( quot1 quot2 -- compose )) define-declared
|
||||||
|
|
||||||
|
! Sub-primitive words
|
||||||
|
: make-sub-primitive ( word vocab -- )
|
||||||
|
create
|
||||||
|
dup reset-word
|
||||||
|
dup 1quotation define ;
|
||||||
|
|
||||||
|
{
|
||||||
|
{ "(execute)" "words.private" }
|
||||||
|
{ "(call)" "kernel.private" }
|
||||||
|
{ "fixnum+fast" "math.private" }
|
||||||
|
{ "fixnum-fast" "math.private" }
|
||||||
|
{ "fixnum*fast" "math.private" }
|
||||||
|
{ "fixnum-bitand" "math.private" }
|
||||||
|
{ "fixnum-bitor" "math.private" }
|
||||||
|
{ "fixnum-bitxor" "math.private" }
|
||||||
|
{ "fixnum-bitnot" "math.private" }
|
||||||
|
{ "fixnum<" "math.private" }
|
||||||
|
{ "fixnum<=" "math.private" }
|
||||||
|
{ "fixnum>" "math.private" }
|
||||||
|
{ "fixnum>=" "math.private" }
|
||||||
|
{ "drop" "kernel" }
|
||||||
|
{ "2drop" "kernel" }
|
||||||
|
{ "3drop" "kernel" }
|
||||||
|
{ "dup" "kernel" }
|
||||||
|
{ "2dup" "kernel" }
|
||||||
|
{ "3dup" "kernel" }
|
||||||
|
{ "rot" "kernel" }
|
||||||
|
{ "-rot" "kernel" }
|
||||||
|
{ "dupd" "kernel" }
|
||||||
|
{ "swapd" "kernel" }
|
||||||
|
{ "nip" "kernel" }
|
||||||
|
{ "2nip" "kernel" }
|
||||||
|
{ "tuck" "kernel" }
|
||||||
|
{ "over" "kernel" }
|
||||||
|
{ "pick" "kernel" }
|
||||||
|
{ "swap" "kernel" }
|
||||||
|
{ ">r" "kernel" }
|
||||||
|
{ "r>" "kernel" }
|
||||||
|
{ "eq?" "kernel" }
|
||||||
|
{ "tag" "kernel.private" }
|
||||||
|
{ "slot" "slots.private" }
|
||||||
|
} [ make-sub-primitive ] assoc-each
|
||||||
|
|
||||||
! Primitive words
|
! Primitive words
|
||||||
: make-primitive ( word vocab n -- )
|
: make-primitive ( word vocab n -- )
|
||||||
>r create dup reset-word r>
|
>r create dup reset-word r>
|
||||||
[ do-primitive ] curry [ ] like define ;
|
[ do-primitive ] curry [ ] like define ;
|
||||||
|
|
||||||
{
|
{
|
||||||
{ "(execute)" "words.private" }
|
|
||||||
{ "(call)" "kernel.private" }
|
|
||||||
{ "bignum>fixnum" "math.private" }
|
{ "bignum>fixnum" "math.private" }
|
||||||
{ "float>fixnum" "math.private" }
|
{ "float>fixnum" "math.private" }
|
||||||
{ "fixnum>bignum" "math.private" }
|
{ "fixnum>bignum" "math.private" }
|
||||||
|
@ -346,24 +390,13 @@ tuple
|
||||||
{ "bits>double" "math" }
|
{ "bits>double" "math" }
|
||||||
{ "<complex>" "math.private" }
|
{ "<complex>" "math.private" }
|
||||||
{ "fixnum+" "math.private" }
|
{ "fixnum+" "math.private" }
|
||||||
{ "fixnum+fast" "math.private" }
|
|
||||||
{ "fixnum-" "math.private" }
|
{ "fixnum-" "math.private" }
|
||||||
{ "fixnum-fast" "math.private" }
|
|
||||||
{ "fixnum*" "math.private" }
|
{ "fixnum*" "math.private" }
|
||||||
{ "fixnum*fast" "math.private" }
|
|
||||||
{ "fixnum/i" "math.private" }
|
{ "fixnum/i" "math.private" }
|
||||||
{ "fixnum-mod" "math.private" }
|
{ "fixnum-mod" "math.private" }
|
||||||
{ "fixnum/mod" "math.private" }
|
{ "fixnum/mod" "math.private" }
|
||||||
{ "fixnum-bitand" "math.private" }
|
|
||||||
{ "fixnum-bitor" "math.private" }
|
|
||||||
{ "fixnum-bitxor" "math.private" }
|
|
||||||
{ "fixnum-bitnot" "math.private" }
|
|
||||||
{ "fixnum-shift" "math.private" }
|
{ "fixnum-shift" "math.private" }
|
||||||
{ "fixnum-shift-fast" "math.private" }
|
{ "fixnum-shift-fast" "math.private" }
|
||||||
{ "fixnum<" "math.private" }
|
|
||||||
{ "fixnum<=" "math.private" }
|
|
||||||
{ "fixnum>" "math.private" }
|
|
||||||
{ "fixnum>=" "math.private" }
|
|
||||||
{ "bignum=" "math.private" }
|
{ "bignum=" "math.private" }
|
||||||
{ "bignum+" "math.private" }
|
{ "bignum+" "math.private" }
|
||||||
{ "bignum-" "math.private" }
|
{ "bignum-" "math.private" }
|
||||||
|
@ -395,25 +428,6 @@ tuple
|
||||||
{ "float>=" "math.private" }
|
{ "float>=" "math.private" }
|
||||||
{ "<word>" "words" }
|
{ "<word>" "words" }
|
||||||
{ "word-xt" "words" }
|
{ "word-xt" "words" }
|
||||||
{ "drop" "kernel" }
|
|
||||||
{ "2drop" "kernel" }
|
|
||||||
{ "3drop" "kernel" }
|
|
||||||
{ "dup" "kernel" }
|
|
||||||
{ "2dup" "kernel" }
|
|
||||||
{ "3dup" "kernel" }
|
|
||||||
{ "rot" "kernel" }
|
|
||||||
{ "-rot" "kernel" }
|
|
||||||
{ "dupd" "kernel" }
|
|
||||||
{ "swapd" "kernel" }
|
|
||||||
{ "nip" "kernel" }
|
|
||||||
{ "2nip" "kernel" }
|
|
||||||
{ "tuck" "kernel" }
|
|
||||||
{ "over" "kernel" }
|
|
||||||
{ "pick" "kernel" }
|
|
||||||
{ "swap" "kernel" }
|
|
||||||
{ ">r" "kernel" }
|
|
||||||
{ "r>" "kernel" }
|
|
||||||
{ "eq?" "kernel" }
|
|
||||||
{ "getenv" "kernel.private" }
|
{ "getenv" "kernel.private" }
|
||||||
{ "setenv" "kernel.private" }
|
{ "setenv" "kernel.private" }
|
||||||
{ "(exists?)" "io.files.private" }
|
{ "(exists?)" "io.files.private" }
|
||||||
|
@ -433,7 +447,6 @@ tuple
|
||||||
{ "code-room" "memory" }
|
{ "code-room" "memory" }
|
||||||
{ "os-env" "system" }
|
{ "os-env" "system" }
|
||||||
{ "millis" "system" }
|
{ "millis" "system" }
|
||||||
{ "tag" "kernel.private" }
|
|
||||||
{ "modify-code-heap" "compiler.units" }
|
{ "modify-code-heap" "compiler.units" }
|
||||||
{ "dlopen" "alien" }
|
{ "dlopen" "alien" }
|
||||||
{ "dlsym" "alien" }
|
{ "dlsym" "alien" }
|
||||||
|
@ -468,7 +481,6 @@ tuple
|
||||||
{ "set-alien-cell" "alien.accessors" }
|
{ "set-alien-cell" "alien.accessors" }
|
||||||
{ "(throw)" "kernel.private" }
|
{ "(throw)" "kernel.private" }
|
||||||
{ "alien-address" "alien" }
|
{ "alien-address" "alien" }
|
||||||
{ "slot" "slots.private" }
|
|
||||||
{ "set-slot" "slots.private" }
|
{ "set-slot" "slots.private" }
|
||||||
{ "string-nth" "strings.private" }
|
{ "string-nth" "strings.private" }
|
||||||
{ "set-string-nth" "strings.private" }
|
{ "set-string-nth" "strings.private" }
|
||||||
|
|
|
@ -18,8 +18,8 @@ IN: compiler.constants
|
||||||
: underlying-alien-offset ( -- n ) bootstrap-cell object tag-number - ;
|
: underlying-alien-offset ( -- n ) bootstrap-cell object tag-number - ;
|
||||||
: tuple-class-offset ( -- n ) bootstrap-cell tuple tag-number - ;
|
: tuple-class-offset ( -- n ) bootstrap-cell tuple tag-number - ;
|
||||||
: class-hash-offset ( -- n ) bootstrap-cell object tag-number - ;
|
: class-hash-offset ( -- n ) bootstrap-cell object tag-number - ;
|
||||||
: word-xt-offset ( -- n ) 8 bootstrap-cells object tag-number - ;
|
: word-xt-offset ( -- n ) 9 bootstrap-cells object tag-number - ;
|
||||||
: quot-xt-offset ( -- n ) 3 bootstrap-cells object tag-number - ;
|
: quot-xt-offset ( -- n ) 3 bootstrap-cells object tag-number - ;
|
||||||
: word-code-offset ( -- n ) 9 bootstrap-cells object tag-number - ;
|
: word-code-offset ( -- n ) 10 bootstrap-cells object tag-number - ;
|
||||||
: array-start-offset ( -- n ) 2 bootstrap-cells object tag-number - ;
|
: array-start-offset ( -- n ) 2 bootstrap-cells object tag-number - ;
|
||||||
: compiled-header-size ( -- n ) 4 bootstrap-cells ;
|
: compiled-header-size ( -- n ) 4 bootstrap-cells ;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
! Copyright (C) 2007, 2008 Slava Pestov.
|
! Copyright (C) 2007, 2008 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: bootstrap.image.private kernel namespaces system
|
USING: bootstrap.image.private kernel kernel.private namespaces
|
||||||
cpu.x86.assembler layouts compiler.units math generator.fixup
|
system cpu.x86.assembler layouts compiler.units math math.private
|
||||||
compiler.constants vocabs ;
|
generator.fixup compiler.constants vocabs slots.private words
|
||||||
|
words.private ;
|
||||||
IN: bootstrap.x86
|
IN: bootstrap.x86
|
||||||
|
|
||||||
big-endian off
|
big-endian off
|
||||||
|
@ -74,27 +75,34 @@ big-endian off
|
||||||
arg0 quot-xt-offset [+] JMP ! execute branch
|
arg0 quot-xt-offset [+] JMP ! execute branch
|
||||||
] rc-absolute-cell rt-literal 1 rex-length + jit-dispatch jit-define
|
] rc-absolute-cell rt-literal 1 rex-length + jit-dispatch jit-define
|
||||||
|
|
||||||
|
[
|
||||||
|
stack-reg stack-frame-size bootstrap-cell - ADD ! unwind stack frame
|
||||||
|
] f f f jit-epilog jit-define
|
||||||
|
|
||||||
|
[ 0 RET ] f f f jit-return jit-define
|
||||||
|
|
||||||
|
! Sub-primitives
|
||||||
|
|
||||||
|
! Quotations and words
|
||||||
|
[
|
||||||
|
arg0 ds-reg [] MOV ! load from stack
|
||||||
|
ds-reg bootstrap-cell SUB ! pop stack
|
||||||
|
arg0 quot-xt-offset [+] JMP ! call quotation
|
||||||
|
] f f f \ (call) define-sub-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
arg0 ds-reg [] MOV ! load from stack
|
||||||
|
ds-reg bootstrap-cell SUB ! pop stack
|
||||||
|
arg0 word-xt-offset [+] JMP ! execute word
|
||||||
|
] f f f \ (execute) define-sub-primitive
|
||||||
|
|
||||||
|
! Objects
|
||||||
[
|
[
|
||||||
arg1 ds-reg [] MOV ! load from stack
|
arg1 ds-reg [] MOV ! load from stack
|
||||||
arg1 tag-mask get AND ! compute tag
|
arg1 tag-mask get AND ! compute tag
|
||||||
arg1 tag-bits get SHL ! tag the tag
|
arg1 tag-bits get SHL ! tag the tag
|
||||||
ds-reg [] arg1 MOV ! push to stack
|
ds-reg [] arg1 MOV ! push to stack
|
||||||
] f f f jit-tag jit-define
|
] f f f \ tag define-sub-primitive
|
||||||
|
|
||||||
: jit-compare ( -- )
|
|
||||||
arg1 0 MOV ! load t
|
|
||||||
arg1 dup [] MOV
|
|
||||||
temp-reg \ f tag-number MOV ! load f
|
|
||||||
arg0 ds-reg [] MOV ! load first value
|
|
||||||
ds-reg bootstrap-cell SUB ! adjust stack pointer
|
|
||||||
ds-reg [] arg0 CMP ! compare with second value
|
|
||||||
;
|
|
||||||
|
|
||||||
[
|
|
||||||
jit-compare
|
|
||||||
arg1 temp-reg CMOVNE ! not equal?
|
|
||||||
ds-reg [] arg1 MOV ! store
|
|
||||||
] rc-absolute-cell rt-literal 1 rex-length + jit-eq? jit-define
|
|
||||||
|
|
||||||
[
|
[
|
||||||
arg0 ds-reg [] MOV ! load slot number
|
arg0 ds-reg [] MOV ! load slot number
|
||||||
|
@ -105,63 +113,187 @@ big-endian off
|
||||||
arg1 tag-bits get SHL
|
arg1 tag-bits get SHL
|
||||||
arg0 arg1 arg0 [+] MOV ! load slot value
|
arg0 arg1 arg0 [+] MOV ! load slot value
|
||||||
ds-reg [] arg0 MOV ! push to stack
|
ds-reg [] arg0 MOV ! push to stack
|
||||||
] f f f jit-slot jit-define
|
] f f f \ slot define-sub-primitive
|
||||||
|
|
||||||
|
! Shufflers
|
||||||
[
|
[
|
||||||
ds-reg bootstrap-cell SUB
|
ds-reg bootstrap-cell SUB
|
||||||
] f f f jit-drop jit-define
|
] f f f \ drop define-sub-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
ds-reg 2 bootstrap-cells SUB
|
||||||
|
] f f f \ 2drop define-sub-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
ds-reg 3 bootstrap-cells SUB
|
||||||
|
] f f f \ 3drop define-sub-primitive
|
||||||
|
|
||||||
[
|
[
|
||||||
arg0 ds-reg [] MOV
|
arg0 ds-reg [] MOV
|
||||||
ds-reg bootstrap-cell ADD
|
ds-reg bootstrap-cell ADD
|
||||||
ds-reg [] arg0 MOV
|
ds-reg [] arg0 MOV
|
||||||
] f f f jit-dup jit-define
|
] f f f \ dup define-sub-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
arg0 ds-reg [] MOV
|
||||||
|
arg1 ds-reg bootstrap-cell neg [+] MOV
|
||||||
|
ds-reg 2 bootstrap-cells ADD
|
||||||
|
ds-reg [] arg0 MOV
|
||||||
|
ds-reg bootstrap-cell neg [+] arg1 MOV
|
||||||
|
] f f f \ 2dup define-sub-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
arg0 ds-reg [] MOV
|
||||||
|
arg1 ds-reg -1 bootstrap-cells [+] MOV
|
||||||
|
temp-reg ds-reg -2 bootstrap-cells [+] MOV
|
||||||
|
ds-reg 3 bootstrap-cells ADD
|
||||||
|
ds-reg [] arg0 MOV
|
||||||
|
ds-reg -1 bootstrap-cells [+] arg1 MOV
|
||||||
|
ds-reg -2 bootstrap-cells [+] temp-reg MOV
|
||||||
|
] f f f \ 3dup define-sub-primitive
|
||||||
|
|
||||||
[
|
[
|
||||||
rs-reg bootstrap-cell ADD
|
|
||||||
arg0 ds-reg [] MOV
|
arg0 ds-reg [] MOV
|
||||||
ds-reg bootstrap-cell SUB
|
ds-reg bootstrap-cell SUB
|
||||||
rs-reg [] arg0 MOV
|
ds-reg [] arg0 MOV
|
||||||
] f f f jit->r jit-define
|
] f f f \ nip define-sub-primitive
|
||||||
|
|
||||||
[
|
[
|
||||||
ds-reg bootstrap-cell ADD
|
arg0 ds-reg [] MOV
|
||||||
arg0 rs-reg [] MOV
|
ds-reg 2 bootstrap-cells SUB
|
||||||
rs-reg bootstrap-cell SUB
|
|
||||||
ds-reg [] arg0 MOV
|
ds-reg [] arg0 MOV
|
||||||
] f f f jit-r> jit-define
|
] f f f \ 2nip define-sub-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
arg0 ds-reg -1 bootstrap-cells [+] MOV
|
||||||
|
ds-reg bootstrap-cell ADD
|
||||||
|
ds-reg [] arg0 MOV
|
||||||
|
] f f f \ over define-sub-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
arg0 ds-reg -2 bootstrap-cells [+] MOV
|
||||||
|
ds-reg bootstrap-cell ADD
|
||||||
|
ds-reg [] arg0 MOV
|
||||||
|
] f f f \ pick define-sub-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
arg0 ds-reg [] MOV
|
||||||
|
arg1 ds-reg -1 bootstrap-cells [+] MOV
|
||||||
|
ds-reg [] arg1 MOV
|
||||||
|
ds-reg bootstrap-cell ADD
|
||||||
|
ds-reg [] arg0 MOV
|
||||||
|
] f f f \ dupd define-sub-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
arg0 ds-reg [] MOV
|
||||||
|
arg1 ds-reg -1 bootstrap-cells [+] MOV
|
||||||
|
ds-reg bootstrap-cell ADD
|
||||||
|
ds-reg [] arg0 MOV
|
||||||
|
ds-reg -1 bootstrap-cells [+] arg1 MOV
|
||||||
|
ds-reg -2 bootstrap-cells [+] arg0 MOV
|
||||||
|
] f f f \ tuck define-sub-primitive
|
||||||
|
|
||||||
[
|
[
|
||||||
arg0 ds-reg [] MOV
|
arg0 ds-reg [] MOV
|
||||||
arg1 ds-reg bootstrap-cell neg [+] MOV
|
arg1 ds-reg bootstrap-cell neg [+] MOV
|
||||||
ds-reg bootstrap-cell neg [+] arg0 MOV
|
ds-reg bootstrap-cell neg [+] arg0 MOV
|
||||||
ds-reg [] arg1 MOV
|
ds-reg [] arg1 MOV
|
||||||
] f f f jit-swap jit-define
|
] f f f \ swap define-sub-primitive
|
||||||
|
|
||||||
[
|
[
|
||||||
arg0 ds-reg bootstrap-cell neg [+] MOV
|
arg0 ds-reg -1 bootstrap-cells [+] MOV
|
||||||
ds-reg bootstrap-cell ADD
|
arg1 ds-reg -2 bootstrap-cells [+] MOV
|
||||||
ds-reg [] arg0 MOV
|
ds-reg -2 bootstrap-cells [+] arg0 MOV
|
||||||
] f f f jit-over jit-define
|
ds-reg -1 bootstrap-cells [+] arg1 MOV
|
||||||
|
] f f f \ swapd define-sub-primitive
|
||||||
|
|
||||||
[
|
[
|
||||||
arg0 ds-reg [] MOV
|
arg0 ds-reg [] MOV
|
||||||
ds-reg bootstrap-cell SUB
|
arg1 ds-reg -1 bootstrap-cells [+] MOV
|
||||||
arg1 ds-reg [] MOV
|
temp-reg ds-reg -2 bootstrap-cells [+] MOV
|
||||||
arg1 arg0 SUB
|
ds-reg -2 bootstrap-cells [+] arg1 MOV
|
||||||
|
ds-reg -1 bootstrap-cells [+] arg0 MOV
|
||||||
|
ds-reg [] temp-reg MOV
|
||||||
|
] f f f \ rot define-sub-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
arg0 ds-reg [] MOV
|
||||||
|
arg1 ds-reg -1 bootstrap-cells [+] MOV
|
||||||
|
temp-reg ds-reg -2 bootstrap-cells [+] MOV
|
||||||
|
ds-reg -2 bootstrap-cells [+] arg0 MOV
|
||||||
|
ds-reg -1 bootstrap-cells [+] temp-reg MOV
|
||||||
ds-reg [] arg1 MOV
|
ds-reg [] arg1 MOV
|
||||||
] f f f jit-fixnum-fast jit-define
|
] f f f \ -rot define-sub-primitive
|
||||||
|
|
||||||
[
|
[
|
||||||
jit-compare
|
rs-reg bootstrap-cell ADD
|
||||||
arg1 temp-reg CMOVL ! not equal?
|
arg0 ds-reg [] MOV
|
||||||
|
ds-reg bootstrap-cell SUB
|
||||||
|
rs-reg [] arg0 MOV
|
||||||
|
] f f f \ >r define-sub-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
ds-reg bootstrap-cell ADD
|
||||||
|
arg0 rs-reg [] MOV
|
||||||
|
rs-reg bootstrap-cell SUB
|
||||||
|
ds-reg [] arg0 MOV
|
||||||
|
] f f f \ r> define-sub-primitive
|
||||||
|
|
||||||
|
! Comparisons
|
||||||
|
: jit-compare ( insn -- )
|
||||||
|
arg1 0 MOV ! load t
|
||||||
|
arg1 dup [] MOV
|
||||||
|
temp-reg \ f tag-number MOV ! load f
|
||||||
|
arg0 ds-reg [] MOV ! load first value
|
||||||
|
ds-reg bootstrap-cell SUB ! adjust stack pointer
|
||||||
|
ds-reg [] arg0 CMP ! compare with second value
|
||||||
|
[ arg1 temp-reg ] dip execute ! move t if true
|
||||||
ds-reg [] arg1 MOV ! store
|
ds-reg [] arg1 MOV ! store
|
||||||
] rc-absolute-cell rt-literal 1 rex-length + jit-fixnum>= jit-define
|
;
|
||||||
|
|
||||||
|
: define-jit-compare ( insn word -- )
|
||||||
|
[ [ jit-compare ] curry rc-absolute-cell rt-literal 1 rex-length + ] dip
|
||||||
|
define-sub-primitive ;
|
||||||
|
|
||||||
|
\ CMOVNE \ eq? define-jit-compare
|
||||||
|
\ CMOVL \ fixnum>= define-jit-compare
|
||||||
|
\ CMOVG \ fixnum<= define-jit-compare
|
||||||
|
\ CMOVLE \ fixnum> define-jit-compare
|
||||||
|
\ CMOVGE \ fixnum< define-jit-compare
|
||||||
|
|
||||||
|
! Math
|
||||||
|
: jit-math ( insn -- )
|
||||||
|
arg0 ds-reg [] MOV ! load second input
|
||||||
|
ds-reg bootstrap-cell SUB ! pop stack
|
||||||
|
arg1 ds-reg [] MOV ! load first input
|
||||||
|
[ arg1 arg0 ] dip execute ! compute result
|
||||||
|
ds-reg [] arg1 MOV ! push result
|
||||||
|
;
|
||||||
|
|
||||||
|
[ \ ADD jit-math ] f f f \ fixnum+fast define-sub-primitive
|
||||||
|
|
||||||
|
[ \ SUB jit-math ] f f f \ fixnum-fast define-sub-primitive
|
||||||
|
|
||||||
[
|
[
|
||||||
stack-reg stack-frame-size bootstrap-cell - ADD ! unwind stack frame
|
arg0 ds-reg [] MOV ! load second input
|
||||||
] f f f jit-epilog jit-define
|
ds-reg bootstrap-cell SUB ! pop stack
|
||||||
|
arg1 ds-reg [] MOV ! load first input
|
||||||
|
arg0 tag-bits get SAR ! untag second input
|
||||||
|
arg0 arg1 IMUL2 ! multiply
|
||||||
|
ds-reg [] arg1 MOV ! push result
|
||||||
|
] f f f \ fixnum*fast define-sub-primitive
|
||||||
|
|
||||||
[ 0 RET ] f f f jit-return jit-define
|
[ \ AND jit-math ] f f f \ fixnum-bitand define-sub-primitive
|
||||||
|
|
||||||
|
[ \ OR jit-math ] f f f \ fixnum-bitor define-sub-primitive
|
||||||
|
|
||||||
|
[ \ XOR jit-math ] f f f \ fixnum-bitxor define-sub-primitive
|
||||||
|
|
||||||
|
[
|
||||||
|
arg0 ds-reg [] MOV ! load input input
|
||||||
|
arg0 NOT ! complement
|
||||||
|
arg0 tag-mask get XOR ! clear tag bits
|
||||||
|
ds-reg [] arg0 MOV ! save
|
||||||
|
] f f f \ fixnum-bitnot define-sub-primitive
|
||||||
|
|
||||||
[ "bootstrap.x86" forget-vocab ] with-compilation-unit
|
[ "bootstrap.x86" forget-vocab ] with-compilation-unit
|
||||||
|
|
|
@ -104,6 +104,8 @@ M: object infer-call
|
||||||
] if
|
] if
|
||||||
] "infer" set-word-prop
|
] "infer" set-word-prop
|
||||||
|
|
||||||
|
\ execute t "no-compile" set-word-prop
|
||||||
|
|
||||||
\ if [
|
\ if [
|
||||||
3 ensure-values
|
3 ensure-values
|
||||||
2 d-tail [ special? ] contains? [
|
2 d-tail [ special? ] contains? [
|
||||||
|
@ -123,6 +125,8 @@ M: object infer-call
|
||||||
[ #dispatch ] infer-branches
|
[ #dispatch ] infer-branches
|
||||||
] "infer" set-word-prop
|
] "infer" set-word-prop
|
||||||
|
|
||||||
|
\ dispatch t "no-compile" set-word-prop
|
||||||
|
|
||||||
\ curry [
|
\ curry [
|
||||||
2 ensure-values
|
2 ensure-values
|
||||||
pop-d pop-d swap <curried> push-d
|
pop-d pop-d swap <curried> push-d
|
||||||
|
|
|
@ -34,7 +34,9 @@ M: symbol definer drop \ SYMBOL: f ;
|
||||||
M: symbol definition drop f ;
|
M: symbol definition drop f ;
|
||||||
|
|
||||||
PREDICATE: primitive < word ( obj -- ? )
|
PREDICATE: primitive < word ( obj -- ? )
|
||||||
def>> [ do-primitive ] tail? ;
|
[ def>> [ do-primitive ] tail? ]
|
||||||
|
[ sub-primitive>> >boolean ]
|
||||||
|
bi or ;
|
||||||
M: primitive definer drop \ PRIMITIVE: f ;
|
M: primitive definer drop \ PRIMITIVE: f ;
|
||||||
M: primitive definition drop f ;
|
M: primitive definition drop f ;
|
||||||
|
|
||||||
|
|
|
@ -82,10 +82,10 @@ M: irc-message write-irc
|
||||||
<scrolling-pane>
|
<scrolling-pane>
|
||||||
[ <pane-stream> swap display ] keep ;
|
[ <pane-stream> swap display ] keep ;
|
||||||
|
|
||||||
TUPLE: irc-editor outstream listener client ;
|
TUPLE: irc-editor < editor outstream listener client ;
|
||||||
|
|
||||||
: <irc-editor> ( pane listener client -- editor )
|
: <irc-editor> ( pane listener client -- editor )
|
||||||
[ <editor> irc-editor construct-editor
|
[ irc-editor new-editor
|
||||||
swap >>listener swap <pane-stream> >>outstream
|
swap >>listener swap <pane-stream> >>outstream
|
||||||
] dip client>> >>client ;
|
] dip client>> >>client ;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2007, 2008 Chris Double.
|
! Copyright (C) 2007, 2008 Chris Double.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel sequences strings fry namespaces math assocs shuffle debugger io
|
USING: kernel sequences strings fry namespaces math assocs shuffle debugger io
|
||||||
vectors arrays math.parser math.order vectors combinators combinators.lib
|
vectors arrays math.parser math.order vectors combinators
|
||||||
classes sets unicode.categories compiler.units parser
|
classes sets unicode.categories compiler.units parser
|
||||||
words quotations effects memoize accessors locals effects splitting
|
words quotations effects memoize accessors locals effects splitting
|
||||||
combinators.short-circuit combinators.short-circuit.smart ;
|
combinators.short-circuit combinators.short-circuit.smart ;
|
||||||
|
|
|
@ -6,7 +6,7 @@ TUPLE: foo bar ;
|
||||||
C: <foo> foo
|
C: <foo> foo
|
||||||
[ 2 ] [ 2 T{ foo } <tuple-array> dup mat set length ] unit-test
|
[ 2 ] [ 2 T{ foo } <tuple-array> dup mat set length ] unit-test
|
||||||
[ T{ foo } ] [ mat get first ] unit-test
|
[ T{ foo } ] [ mat get first ] unit-test
|
||||||
[ T{ foo f 1 } ] [ T{ foo 2 1 } 0 mat get [ set-nth ] keep first ] unit-test
|
[ T{ foo 2 1 } ] [ T{ foo 2 1 } 0 mat get [ set-nth ] keep first ] unit-test
|
||||||
[ t ] [ { T{ foo f 1 } T{ foo f 2 } } >tuple-array dup mat set tuple-array? ] unit-test
|
[ t ] [ { T{ foo f 1 } T{ foo f 2 } } >tuple-array dup mat set tuple-array? ] unit-test
|
||||||
[ T{ foo f 3 } t ]
|
[ T{ foo f 3 } t ]
|
||||||
[ mat get [ foo-bar 2 + <foo> ] map [ first ] keep tuple-array? ] unit-test
|
[ mat get [ foo-bar 2 + <foo> ] map [ first ] keep tuple-array? ] unit-test
|
||||||
|
|
|
@ -1,35 +1,26 @@
|
||||||
! Copyright (C) 2007 Daniel Ehrenberg.
|
! Copyright (C) 2007 Daniel Ehrenberg.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: splitting grouping classes.tuple classes math kernel
|
USING: splitting grouping classes.tuple classes math kernel
|
||||||
sequences arrays ;
|
sequences arrays accessors ;
|
||||||
IN: tuple-arrays
|
IN: tuple-arrays
|
||||||
|
|
||||||
TUPLE: tuple-array example ;
|
TUPLE: tuple-array seq class ;
|
||||||
|
|
||||||
: prepare-example ( tuple -- seq n )
|
|
||||||
dup class over delegate [ 1array ] [ f 2array ] if
|
|
||||||
swap tuple>array length over length - ;
|
|
||||||
|
|
||||||
: <tuple-array> ( length example -- tuple-array )
|
: <tuple-array> ( length example -- tuple-array )
|
||||||
prepare-example [ rot * { } new-sequence ] keep
|
[ tuple>array length 1- [ * { } new-sequence ] keep <sliced-groups> ]
|
||||||
<sliced-groups> tuple-array construct-delegate
|
[ class ] bi tuple-array boa ;
|
||||||
[ set-tuple-array-example ] keep ;
|
|
||||||
|
|
||||||
: reconstruct ( seq example -- tuple )
|
|
||||||
prepend >tuple ;
|
|
||||||
|
|
||||||
M: tuple-array nth
|
M: tuple-array nth
|
||||||
[ delegate nth ] keep
|
[ seq>> nth ] [ class>> ] bi prefix >tuple ;
|
||||||
tuple-array-example reconstruct ;
|
|
||||||
|
|
||||||
: deconstruct ( tuple example -- seq )
|
: deconstruct ( tuple -- seq )
|
||||||
>r tuple>array r> length tail-slice ;
|
tuple>array 1 tail ;
|
||||||
|
|
||||||
M: tuple-array set-nth ( elt n seq -- )
|
M: tuple-array set-nth ( elt n seq -- )
|
||||||
tuck >r >r tuple-array-example deconstruct r> r>
|
>r >r deconstruct r> r> seq>> set-nth ;
|
||||||
delegate set-nth ;
|
|
||||||
|
|
||||||
M: tuple-array new-sequence tuple-array-example >tuple <tuple-array> ;
|
M: tuple-array new-sequence
|
||||||
|
class>> new <tuple-array> ;
|
||||||
|
|
||||||
: >tuple-array ( seq -- tuple-array/seq )
|
: >tuple-array ( seq -- tuple-array/seq )
|
||||||
dup empty? [
|
dup empty? [
|
||||||
|
@ -39,4 +30,6 @@ M: tuple-array new-sequence tuple-array-example >tuple <tuple-array> ;
|
||||||
M: tuple-array like
|
M: tuple-array like
|
||||||
drop dup tuple-array? [ >tuple-array ] unless ;
|
drop dup tuple-array? [ >tuple-array ] unless ;
|
||||||
|
|
||||||
|
M: tuple-array length seq>> length ;
|
||||||
|
|
||||||
INSTANCE: tuple-array sequence
|
INSTANCE: tuple-array sequence
|
||||||
|
|
|
@ -51,6 +51,6 @@ DEFER: (del-page)
|
||||||
tabbed new-frame
|
tabbed new-frame
|
||||||
[ g 0 <model> >>model
|
[ g 0 <model> >>model
|
||||||
<pile> 1 >>fill [ >>toggler ] keep swap @left grid-add
|
<pile> 1 >>fill [ >>toggler ] keep swap @left grid-add
|
||||||
[ keys g swap >>names ]
|
[ keys >vector g swap >>names ]
|
||||||
[ values g model>> <book> [ >>content ] keep swap @center grid-add ] bi
|
[ values g model>> <book> [ >>content ] keep swap @center grid-add ] bi
|
||||||
g redo-toggler g ] with-gadget ;
|
g redo-toggler g ] with-gadget ;
|
||||||
|
|
|
@ -6,7 +6,6 @@ and the callstack top is passed in EDX */
|
||||||
|
|
||||||
#define ARG0 %eax
|
#define ARG0 %eax
|
||||||
#define ARG1 %edx
|
#define ARG1 %edx
|
||||||
#define XT_REG %ecx
|
|
||||||
#define STACK_REG %esp
|
#define STACK_REG %esp
|
||||||
#define DS_REG %esi
|
#define DS_REG %esi
|
||||||
#define RETURN_REG %eax
|
#define RETURN_REG %eax
|
||||||
|
@ -22,9 +21,6 @@ and the callstack top is passed in EDX */
|
||||||
pop %ebx
|
pop %ebx
|
||||||
|
|
||||||
#define QUOT_XT_OFFSET 9
|
#define QUOT_XT_OFFSET 9
|
||||||
#define PROFILING_OFFSET 25
|
|
||||||
#define WORD_DEF_OFFSET 13
|
|
||||||
#define WORD_XT_OFFSET 29
|
|
||||||
|
|
||||||
/* We pass a function pointer to memcpy to work around a Mac OS X
|
/* We pass a function pointer to memcpy to work around a Mac OS X
|
||||||
ABI limitation which would otherwise require us to do a bizzaro PC-relative
|
ABI limitation which would otherwise require us to do a bizzaro PC-relative
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#define ARG0 %rdi
|
#define ARG0 %rdi
|
||||||
#define ARG1 %rsi
|
#define ARG1 %rsi
|
||||||
#define XT_REG %rcx
|
|
||||||
#define STACK_REG %rsp
|
#define STACK_REG %rsp
|
||||||
#define DS_REG %r14
|
#define DS_REG %r14
|
||||||
#define RETURN_REG %rax
|
#define RETURN_REG %rax
|
||||||
|
@ -22,9 +21,6 @@
|
||||||
pop %rbx
|
pop %rbx
|
||||||
|
|
||||||
#define QUOT_XT_OFFSET 21
|
#define QUOT_XT_OFFSET 21
|
||||||
#define PROFILING_OFFSET 53
|
|
||||||
#define WORD_DEF_OFFSET 29
|
|
||||||
#define WORD_XT_OFFSET 61
|
|
||||||
|
|
||||||
/* We pass a function pointer to memcpy to work around a Mac OS X
|
/* We pass a function pointer to memcpy to work around a Mac OS X
|
||||||
ABI limitation which would otherwise require us to do a bizzaro PC-relative
|
ABI limitation which would otherwise require us to do a bizzaro PC-relative
|
||||||
|
|
17
vm/cpu-x86.S
17
vm/cpu-x86.S
|
@ -1,5 +1,3 @@
|
||||||
#define JUMP_QUOT jmp *QUOT_XT_OFFSET(ARG0)
|
|
||||||
|
|
||||||
DEF(F_FASTCALL void,c_to_factor,(CELL quot)):
|
DEF(F_FASTCALL void,c_to_factor,(CELL quot)):
|
||||||
PUSH_NONVOLATILE
|
PUSH_NONVOLATILE
|
||||||
push ARG0 /* Save quot */
|
push ARG0 /* Save quot */
|
||||||
|
@ -14,20 +12,9 @@ DEF(F_FASTCALL void,c_to_factor,(CELL quot)):
|
||||||
POP_NONVOLATILE
|
POP_NONVOLATILE
|
||||||
ret
|
ret
|
||||||
|
|
||||||
DEF(F_FASTCALL void,primitive_call,(void)):
|
|
||||||
mov (DS_REG),ARG0 /* Load quotation from data stack */
|
|
||||||
sub $CELL_SIZE,DS_REG /* Pop data stack */
|
|
||||||
JUMP_QUOT
|
|
||||||
|
|
||||||
/* Don't mess up EDX, it's the callstack top parameter to primitives. */
|
|
||||||
DEF(F_FASTCALL void,primitive_execute,(void)):
|
|
||||||
mov (DS_REG),ARG0 /* Load word from data stack */
|
|
||||||
sub $CELL_SIZE,DS_REG /* Pop data stack */
|
|
||||||
jmp *WORD_XT_OFFSET(ARG0) /* Load word-xt slot */
|
|
||||||
|
|
||||||
DEF(F_FASTCALL void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to)):
|
DEF(F_FASTCALL void,throw_impl,(CELL quot, F_STACK_FRAME *rewind_to)):
|
||||||
mov ARG1,STACK_REG /* rewind_to */
|
mov ARG1,STACK_REG /* rewind_to */
|
||||||
JUMP_QUOT
|
jmp *QUOT_XT_OFFSET(ARG0)
|
||||||
|
|
||||||
DEF(FASTCALL void,lazy_jit_compile,(CELL quot)):
|
DEF(FASTCALL void,lazy_jit_compile,(CELL quot)):
|
||||||
mov STACK_REG,ARG1 /* Save stack pointer */
|
mov STACK_REG,ARG1 /* Save stack pointer */
|
||||||
|
@ -39,7 +26,7 @@ DEF(FASTCALL void,lazy_jit_compile,(CELL quot)):
|
||||||
pop ARG1 /* OK to clobber ARG1 here */
|
pop ARG1 /* OK to clobber ARG1 here */
|
||||||
pop ARG1
|
pop ARG1
|
||||||
pop ARG1
|
pop ARG1
|
||||||
JUMP_QUOT /* Call the quotation */
|
jmp *QUOT_XT_OFFSET(ARG0) /* Call the quotation */
|
||||||
|
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
.section .drectve
|
.section .drectve
|
||||||
|
|
|
@ -129,6 +129,8 @@ typedef struct {
|
||||||
CELL compiledp;
|
CELL compiledp;
|
||||||
/* TAGGED call count for profiling */
|
/* TAGGED call count for profiling */
|
||||||
CELL counter;
|
CELL counter;
|
||||||
|
/* TAGGED machine code for sub-primitive */
|
||||||
|
CELL subprimitive;
|
||||||
/* UNTAGGED execution token: jump here to execute word */
|
/* UNTAGGED execution token: jump here to execute word */
|
||||||
XT xt;
|
XT xt;
|
||||||
/* UNTAGGED compiled code block */
|
/* UNTAGGED compiled code block */
|
||||||
|
|
68
vm/math.c
68
vm/math.c
|
@ -35,33 +35,18 @@ DEFINE_PRIMITIVE(float_to_fixnum)
|
||||||
F_FIXNUM y = untag_fixnum_fast(dpop()); \
|
F_FIXNUM y = untag_fixnum_fast(dpop()); \
|
||||||
F_FIXNUM x = untag_fixnum_fast(dpop());
|
F_FIXNUM x = untag_fixnum_fast(dpop());
|
||||||
|
|
||||||
/* The fixnum arithmetic operations defined in C are relatively slow.
|
|
||||||
The Factor compiler has optimized assembly intrinsics for some of these
|
|
||||||
operations. */
|
|
||||||
DEFINE_PRIMITIVE(fixnum_add)
|
DEFINE_PRIMITIVE(fixnum_add)
|
||||||
{
|
{
|
||||||
POP_FIXNUMS(x,y)
|
POP_FIXNUMS(x,y)
|
||||||
box_signed_cell(x + y);
|
box_signed_cell(x + y);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(fixnum_add_fast)
|
|
||||||
{
|
|
||||||
POP_FIXNUMS(x,y)
|
|
||||||
dpush(tag_fixnum(x + y));
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(fixnum_subtract)
|
DEFINE_PRIMITIVE(fixnum_subtract)
|
||||||
{
|
{
|
||||||
POP_FIXNUMS(x,y)
|
POP_FIXNUMS(x,y)
|
||||||
box_signed_cell(x - y);
|
box_signed_cell(x - y);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(fixnum_subtract_fast)
|
|
||||||
{
|
|
||||||
POP_FIXNUMS(x,y)
|
|
||||||
dpush(tag_fixnum(x - y));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Multiply two integers, and trap overflow.
|
/* Multiply two integers, and trap overflow.
|
||||||
Thanks to David Blaikie (The_Vulture from freenode #java) for the hint. */
|
Thanks to David Blaikie (The_Vulture from freenode #java) for the hint. */
|
||||||
DEFINE_PRIMITIVE(fixnum_multiply)
|
DEFINE_PRIMITIVE(fixnum_multiply)
|
||||||
|
@ -87,12 +72,6 @@ DEFINE_PRIMITIVE(fixnum_multiply)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(fixnum_multiply_fast)
|
|
||||||
{
|
|
||||||
POP_FIXNUMS(x,y)
|
|
||||||
dpush(tag_fixnum(x * y));
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(fixnum_divint)
|
DEFINE_PRIMITIVE(fixnum_divint)
|
||||||
{
|
{
|
||||||
POP_FIXNUMS(x,y)
|
POP_FIXNUMS(x,y)
|
||||||
|
@ -112,24 +91,6 @@ DEFINE_PRIMITIVE(fixnum_mod)
|
||||||
dpush(tag_fixnum(x % y));
|
dpush(tag_fixnum(x % y));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(fixnum_and)
|
|
||||||
{
|
|
||||||
POP_FIXNUMS(x,y)
|
|
||||||
dpush(tag_fixnum(x & y));
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(fixnum_or)
|
|
||||||
{
|
|
||||||
POP_FIXNUMS(x,y)
|
|
||||||
dpush(tag_fixnum(x | y));
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(fixnum_xor)
|
|
||||||
{
|
|
||||||
POP_FIXNUMS(x,y)
|
|
||||||
dpush(tag_fixnum(x ^ y));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note the hairy overflow check.
|
* Note the hairy overflow check.
|
||||||
* If we're shifting right by n bits, we won't overflow as long as none of the
|
* If we're shifting right by n bits, we won't overflow as long as none of the
|
||||||
|
@ -172,35 +133,6 @@ DEFINE_PRIMITIVE(fixnum_shift_fast)
|
||||||
dpush(tag_fixnum(y < 0 ? (x >> -y) : (x << y)));
|
dpush(tag_fixnum(y < 0 ? (x >> -y) : (x << y)));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(fixnum_less)
|
|
||||||
{
|
|
||||||
POP_FIXNUMS(x,y)
|
|
||||||
box_boolean(x < y);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(fixnum_lesseq)
|
|
||||||
{
|
|
||||||
POP_FIXNUMS(x,y)
|
|
||||||
box_boolean(x <= y);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(fixnum_greater)
|
|
||||||
{
|
|
||||||
POP_FIXNUMS(x,y)
|
|
||||||
box_boolean(x > y);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(fixnum_greatereq)
|
|
||||||
{
|
|
||||||
POP_FIXNUMS(x,y)
|
|
||||||
box_boolean(x >= y);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(fixnum_not)
|
|
||||||
{
|
|
||||||
drepl(tag_fixnum(~untag_fixnum_fast(dpeek())));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bignums */
|
/* Bignums */
|
||||||
DEFINE_PRIMITIVE(fixnum_to_bignum)
|
DEFINE_PRIMITIVE(fixnum_to_bignum)
|
||||||
{
|
{
|
||||||
|
|
11
vm/math.h
11
vm/math.h
|
@ -11,23 +11,12 @@ DECLARE_PRIMITIVE(float_to_fixnum);
|
||||||
|
|
||||||
DECLARE_PRIMITIVE(fixnum_add);
|
DECLARE_PRIMITIVE(fixnum_add);
|
||||||
DECLARE_PRIMITIVE(fixnum_subtract);
|
DECLARE_PRIMITIVE(fixnum_subtract);
|
||||||
DECLARE_PRIMITIVE(fixnum_add_fast);
|
|
||||||
DECLARE_PRIMITIVE(fixnum_subtract_fast);
|
|
||||||
DECLARE_PRIMITIVE(fixnum_multiply);
|
DECLARE_PRIMITIVE(fixnum_multiply);
|
||||||
DECLARE_PRIMITIVE(fixnum_multiply_fast);
|
|
||||||
DECLARE_PRIMITIVE(fixnum_divint);
|
DECLARE_PRIMITIVE(fixnum_divint);
|
||||||
DECLARE_PRIMITIVE(fixnum_divmod);
|
DECLARE_PRIMITIVE(fixnum_divmod);
|
||||||
DECLARE_PRIMITIVE(fixnum_mod);
|
DECLARE_PRIMITIVE(fixnum_mod);
|
||||||
DECLARE_PRIMITIVE(fixnum_and);
|
|
||||||
DECLARE_PRIMITIVE(fixnum_or);
|
|
||||||
DECLARE_PRIMITIVE(fixnum_xor);
|
|
||||||
DECLARE_PRIMITIVE(fixnum_shift);
|
DECLARE_PRIMITIVE(fixnum_shift);
|
||||||
DECLARE_PRIMITIVE(fixnum_shift_fast);
|
DECLARE_PRIMITIVE(fixnum_shift_fast);
|
||||||
DECLARE_PRIMITIVE(fixnum_less);
|
|
||||||
DECLARE_PRIMITIVE(fixnum_lesseq);
|
|
||||||
DECLARE_PRIMITIVE(fixnum_greater);
|
|
||||||
DECLARE_PRIMITIVE(fixnum_greatereq);
|
|
||||||
DECLARE_PRIMITIVE(fixnum_not);
|
|
||||||
|
|
||||||
CELL bignum_zero;
|
CELL bignum_zero;
|
||||||
CELL bignum_pos_one;
|
CELL bignum_pos_one;
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#include "master.h"
|
#include "master.h"
|
||||||
|
|
||||||
void *primitives[] = {
|
void *primitives[] = {
|
||||||
primitive_execute,
|
|
||||||
primitive_call,
|
|
||||||
primitive_bignum_to_fixnum,
|
primitive_bignum_to_fixnum,
|
||||||
primitive_float_to_fixnum,
|
primitive_float_to_fixnum,
|
||||||
primitive_fixnum_to_bignum,
|
primitive_fixnum_to_bignum,
|
||||||
|
@ -18,24 +16,13 @@ void *primitives[] = {
|
||||||
primitive_bits_double,
|
primitive_bits_double,
|
||||||
primitive_from_rect,
|
primitive_from_rect,
|
||||||
primitive_fixnum_add,
|
primitive_fixnum_add,
|
||||||
primitive_fixnum_add_fast,
|
|
||||||
primitive_fixnum_subtract,
|
primitive_fixnum_subtract,
|
||||||
primitive_fixnum_subtract_fast,
|
|
||||||
primitive_fixnum_multiply,
|
primitive_fixnum_multiply,
|
||||||
primitive_fixnum_multiply_fast,
|
|
||||||
primitive_fixnum_divint,
|
primitive_fixnum_divint,
|
||||||
primitive_fixnum_mod,
|
primitive_fixnum_mod,
|
||||||
primitive_fixnum_divmod,
|
primitive_fixnum_divmod,
|
||||||
primitive_fixnum_and,
|
|
||||||
primitive_fixnum_or,
|
|
||||||
primitive_fixnum_xor,
|
|
||||||
primitive_fixnum_not,
|
|
||||||
primitive_fixnum_shift,
|
primitive_fixnum_shift,
|
||||||
primitive_fixnum_shift_fast,
|
primitive_fixnum_shift_fast,
|
||||||
primitive_fixnum_less,
|
|
||||||
primitive_fixnum_lesseq,
|
|
||||||
primitive_fixnum_greater,
|
|
||||||
primitive_fixnum_greatereq,
|
|
||||||
primitive_bignum_eq,
|
primitive_bignum_eq,
|
||||||
primitive_bignum_add,
|
primitive_bignum_add,
|
||||||
primitive_bignum_subtract,
|
primitive_bignum_subtract,
|
||||||
|
@ -67,25 +54,6 @@ void *primitives[] = {
|
||||||
primitive_float_greatereq,
|
primitive_float_greatereq,
|
||||||
primitive_word,
|
primitive_word,
|
||||||
primitive_word_xt,
|
primitive_word_xt,
|
||||||
primitive_drop,
|
|
||||||
primitive_2drop,
|
|
||||||
primitive_3drop,
|
|
||||||
primitive_dup,
|
|
||||||
primitive_2dup,
|
|
||||||
primitive_3dup,
|
|
||||||
primitive_rot,
|
|
||||||
primitive__rot,
|
|
||||||
primitive_dupd,
|
|
||||||
primitive_swapd,
|
|
||||||
primitive_nip,
|
|
||||||
primitive_2nip,
|
|
||||||
primitive_tuck,
|
|
||||||
primitive_over,
|
|
||||||
primitive_pick,
|
|
||||||
primitive_swap,
|
|
||||||
primitive_to_r,
|
|
||||||
primitive_from_r,
|
|
||||||
primitive_eq,
|
|
||||||
primitive_getenv,
|
primitive_getenv,
|
||||||
primitive_setenv,
|
primitive_setenv,
|
||||||
primitive_existsp,
|
primitive_existsp,
|
||||||
|
@ -105,7 +73,6 @@ void *primitives[] = {
|
||||||
primitive_code_room,
|
primitive_code_room,
|
||||||
primitive_os_env,
|
primitive_os_env,
|
||||||
primitive_millis,
|
primitive_millis,
|
||||||
primitive_tag,
|
|
||||||
primitive_modify_code_heap,
|
primitive_modify_code_heap,
|
||||||
primitive_dlopen,
|
primitive_dlopen,
|
||||||
primitive_dlsym,
|
primitive_dlsym,
|
||||||
|
@ -140,7 +107,6 @@ void *primitives[] = {
|
||||||
primitive_set_alien_cell,
|
primitive_set_alien_cell,
|
||||||
primitive_throw,
|
primitive_throw,
|
||||||
primitive_alien_address,
|
primitive_alien_address,
|
||||||
primitive_slot,
|
|
||||||
primitive_set_slot,
|
primitive_set_slot,
|
||||||
primitive_string_nth,
|
primitive_string_nth,
|
||||||
primitive_set_string_nth,
|
primitive_set_string_nth,
|
||||||
|
|
194
vm/quotations.c
194
vm/quotations.c
|
@ -1,8 +1,38 @@
|
||||||
#include "master.h"
|
#include "master.h"
|
||||||
|
|
||||||
/* Simple JIT compiler. This is one of the two compilers implementing Factor;
|
/* Simple non-optimizing compiler.
|
||||||
the second one is written in Factor and performs a lot of optimizations.
|
|
||||||
See core/compiler/compiler.factor */
|
This is one of the two compilers implementing Factor; the second one is written
|
||||||
|
in Factor and performs advanced optimizations. See core/compiler/compiler.factor.
|
||||||
|
|
||||||
|
The non-optimizing compiler compiles a quotation at a time by concatenating
|
||||||
|
machine code chunks; prolog, epilog, call word, jump to word, etc. These machine
|
||||||
|
code chunks are generated from Factor code in core/cpu/.../bootstrap.factor.
|
||||||
|
|
||||||
|
It actually does do a little bit of very simple optimization:
|
||||||
|
|
||||||
|
1) Tail call optimization.
|
||||||
|
|
||||||
|
2) If a quotation is determined to not call any other words (except for a few
|
||||||
|
special words which are open-coded, see below), then no prolog/epilog is
|
||||||
|
generated.
|
||||||
|
|
||||||
|
3) When in tail position and immediately preceded by literal arguments, the
|
||||||
|
'if' and 'dispatch' conditionals are generated inline, instead of as a call to
|
||||||
|
the 'if' word.
|
||||||
|
|
||||||
|
4) When preceded by an array, calls to the 'declare' word are optimized out
|
||||||
|
entirely. This word is only used by the optimizing compiler, and with the
|
||||||
|
non-optimizing compiler it would otherwise just decrease performance to have to
|
||||||
|
push the array and immediately drop it after.
|
||||||
|
|
||||||
|
5) Sub-primitives are primitive words which are implemented in assembly and not
|
||||||
|
in the VM. They are open-coded and no subroutine call is generated. This
|
||||||
|
includes stack shufflers, some fixnum arithmetic words, and words such as tag,
|
||||||
|
slot and eq?. A primitive call is relatively expensive (two subroutine calls)
|
||||||
|
so this results in a big speedup for relatively little effort.
|
||||||
|
|
||||||
|
*/
|
||||||
bool jit_primitive_call_p(F_ARRAY *array, CELL i)
|
bool jit_primitive_call_p(F_ARRAY *array, CELL i)
|
||||||
{
|
{
|
||||||
return (i + 2) == array_capacity(array)
|
return (i + 2) == array_capacity(array)
|
||||||
|
@ -32,15 +62,15 @@ bool jit_ignore_declare_p(F_ARRAY *array, CELL i)
|
||||||
&& array_nth(array,i + 1) == userenv[JIT_DECLARE_WORD];
|
&& array_nth(array,i + 1) == userenv[JIT_DECLARE_WORD];
|
||||||
}
|
}
|
||||||
|
|
||||||
F_ARRAY *code_to_emit(CELL name)
|
F_ARRAY *code_to_emit(CELL code)
|
||||||
{
|
{
|
||||||
return untag_object(array_nth(untag_object(userenv[name]),0));
|
return untag_object(array_nth(untag_object(code),0));
|
||||||
}
|
}
|
||||||
|
|
||||||
F_REL rel_to_emit(CELL name, CELL code_format, CELL code_length,
|
F_REL rel_to_emit(CELL code, CELL code_format, CELL code_length,
|
||||||
CELL rel_argument, bool *rel_p)
|
CELL rel_argument, bool *rel_p)
|
||||||
{
|
{
|
||||||
F_ARRAY *quadruple = untag_object(userenv[name]);
|
F_ARRAY *quadruple = untag_object(code);
|
||||||
CELL rel_class = array_nth(quadruple,1);
|
CELL rel_class = array_nth(quadruple,1);
|
||||||
CELL rel_type = array_nth(quadruple,2);
|
CELL rel_type = array_nth(quadruple,2);
|
||||||
CELL offset = array_nth(quadruple,3);
|
CELL offset = array_nth(quadruple,3);
|
||||||
|
@ -82,22 +112,11 @@ bool jit_stack_frame_p(F_ARRAY *array)
|
||||||
CELL obj = array_nth(array,i);
|
CELL obj = array_nth(array,i);
|
||||||
if(type_of(obj) == WORD_TYPE)
|
if(type_of(obj) == WORD_TYPE)
|
||||||
{
|
{
|
||||||
if(obj != userenv[JIT_TAG_WORD]
|
F_WORD *word = untag_object(obj);
|
||||||
&& obj != userenv[JIT_EQP_WORD]
|
if(word->subprimitive == F && obj != userenv[JIT_DECLARE_WORD])
|
||||||
&& obj != userenv[JIT_SLOT_WORD]
|
|
||||||
&& obj != userenv[JIT_DROP_WORD]
|
|
||||||
&& obj != userenv[JIT_DUP_WORD]
|
|
||||||
&& obj != userenv[JIT_TO_R_WORD]
|
|
||||||
&& obj != userenv[JIT_FROM_R_WORD]
|
|
||||||
&& obj != userenv[JIT_SWAP_WORD]
|
|
||||||
&& obj != userenv[JIT_OVER_WORD]
|
|
||||||
&& obj != userenv[JIT_FIXNUM_MINUS_WORD]
|
|
||||||
&& obj != userenv[JIT_FIXNUM_GE_WORD])
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -139,7 +158,7 @@ void jit_compile(CELL quot, bool relocate)
|
||||||
bool stack_frame = jit_stack_frame_p(untag_object(array));
|
bool stack_frame = jit_stack_frame_p(untag_object(array));
|
||||||
|
|
||||||
if(stack_frame)
|
if(stack_frame)
|
||||||
EMIT(JIT_PROLOG,0);
|
EMIT(userenv[JIT_PROLOG],0);
|
||||||
|
|
||||||
CELL i;
|
CELL i;
|
||||||
CELL length = array_capacity(untag_object(array));
|
CELL length = array_capacity(untag_object(array));
|
||||||
|
@ -154,84 +173,44 @@ void jit_compile(CELL quot, bool relocate)
|
||||||
switch(type_of(obj))
|
switch(type_of(obj))
|
||||||
{
|
{
|
||||||
case WORD_TYPE:
|
case WORD_TYPE:
|
||||||
|
word = untag_object(obj);
|
||||||
|
|
||||||
/* Intrinsics */
|
/* Intrinsics */
|
||||||
if(obj == userenv[JIT_TAG_WORD])
|
if(word->subprimitive != F)
|
||||||
{
|
{
|
||||||
EMIT(JIT_TAG,0);
|
if(array_nth(untag_object(word->subprimitive),1) != F)
|
||||||
}
|
|
||||||
else if(obj == userenv[JIT_EQP_WORD])
|
|
||||||
{
|
{
|
||||||
GROWABLE_ARRAY_ADD(literals,T);
|
GROWABLE_ARRAY_ADD(literals,T);
|
||||||
EMIT(JIT_EQP,literals_count - 1);
|
|
||||||
}
|
}
|
||||||
else if(obj == userenv[JIT_SLOT_WORD])
|
|
||||||
{
|
EMIT(word->subprimitive,literals_count - 1);
|
||||||
EMIT(JIT_SLOT,0);
|
|
||||||
}
|
|
||||||
else if(obj == userenv[JIT_DROP_WORD])
|
|
||||||
{
|
|
||||||
EMIT(JIT_DROP,0);
|
|
||||||
}
|
|
||||||
else if(obj == userenv[JIT_DUP_WORD])
|
|
||||||
{
|
|
||||||
EMIT(JIT_DUP,0);
|
|
||||||
}
|
|
||||||
else if(obj == userenv[JIT_TO_R_WORD])
|
|
||||||
{
|
|
||||||
EMIT(JIT_TO_R,0);
|
|
||||||
}
|
|
||||||
else if(obj == userenv[JIT_FROM_R_WORD])
|
|
||||||
{
|
|
||||||
EMIT(JIT_FROM_R,0);
|
|
||||||
}
|
|
||||||
else if(obj == userenv[JIT_SWAP_WORD])
|
|
||||||
{
|
|
||||||
EMIT(JIT_SWAP,0);
|
|
||||||
}
|
|
||||||
else if(obj == userenv[JIT_OVER_WORD])
|
|
||||||
{
|
|
||||||
EMIT(JIT_OVER,0);
|
|
||||||
}
|
|
||||||
else if(obj == userenv[JIT_FIXNUM_MINUS_WORD])
|
|
||||||
{
|
|
||||||
EMIT(JIT_FIXNUM_MINUS,0);
|
|
||||||
}
|
|
||||||
else if(obj == userenv[JIT_FIXNUM_GE_WORD])
|
|
||||||
{
|
|
||||||
GROWABLE_ARRAY_ADD(literals,T);
|
|
||||||
EMIT(JIT_FIXNUM_GE,literals_count - 1);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Emit the epilog before the primitive call gate
|
|
||||||
so that we save the C stack pointer minus the
|
|
||||||
current stack frame. */
|
|
||||||
word = untag_object(obj);
|
|
||||||
|
|
||||||
GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
|
GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
|
||||||
|
|
||||||
if(i == length - 1)
|
if(i == length - 1)
|
||||||
{
|
{
|
||||||
if(stack_frame)
|
if(stack_frame)
|
||||||
EMIT(JIT_EPILOG,0);
|
EMIT(userenv[JIT_EPILOG],0);
|
||||||
|
|
||||||
EMIT(JIT_WORD_JUMP,literals_count - 1);
|
EMIT(userenv[JIT_WORD_JUMP],literals_count - 1);
|
||||||
|
|
||||||
tail_call = true;
|
tail_call = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
EMIT(JIT_WORD_CALL,literals_count - 1);
|
EMIT(userenv[JIT_WORD_CALL],literals_count - 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WRAPPER_TYPE:
|
case WRAPPER_TYPE:
|
||||||
wrapper = untag_object(obj);
|
wrapper = untag_object(obj);
|
||||||
GROWABLE_ARRAY_ADD(literals,wrapper->object);
|
GROWABLE_ARRAY_ADD(literals,wrapper->object);
|
||||||
EMIT(JIT_PUSH_LITERAL,literals_count - 1);
|
EMIT(userenv[JIT_PUSH_LITERAL],literals_count - 1);
|
||||||
break;
|
break;
|
||||||
case FIXNUM_TYPE:
|
case FIXNUM_TYPE:
|
||||||
if(jit_primitive_call_p(untag_object(array),i))
|
if(jit_primitive_call_p(untag_object(array),i))
|
||||||
{
|
{
|
||||||
EMIT(JIT_PRIMITIVE,to_fixnum(obj));
|
EMIT(userenv[JIT_PRIMITIVE],to_fixnum(obj));
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
@ -242,11 +221,11 @@ void jit_compile(CELL quot, bool relocate)
|
||||||
if(jit_fast_if_p(untag_object(array),i))
|
if(jit_fast_if_p(untag_object(array),i))
|
||||||
{
|
{
|
||||||
if(stack_frame)
|
if(stack_frame)
|
||||||
EMIT(JIT_EPILOG,0);
|
EMIT(userenv[JIT_EPILOG],0);
|
||||||
|
|
||||||
GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
|
GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
|
||||||
GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i + 1));
|
GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i + 1));
|
||||||
EMIT(JIT_IF_JUMP,literals_count - 2);
|
EMIT(userenv[JIT_IF_JUMP],literals_count - 2);
|
||||||
|
|
||||||
i += 2;
|
i += 2;
|
||||||
|
|
||||||
|
@ -257,10 +236,10 @@ void jit_compile(CELL quot, bool relocate)
|
||||||
if(jit_fast_dispatch_p(untag_object(array),i))
|
if(jit_fast_dispatch_p(untag_object(array),i))
|
||||||
{
|
{
|
||||||
if(stack_frame)
|
if(stack_frame)
|
||||||
EMIT(JIT_EPILOG,0);
|
EMIT(userenv[JIT_EPILOG],0);
|
||||||
|
|
||||||
GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
|
GROWABLE_ARRAY_ADD(literals,array_nth(untag_object(array),i));
|
||||||
EMIT(JIT_DISPATCH,literals_count - 1);
|
EMIT(userenv[JIT_DISPATCH],literals_count - 1);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
@ -274,7 +253,7 @@ void jit_compile(CELL quot, bool relocate)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
GROWABLE_ARRAY_ADD(literals,obj);
|
GROWABLE_ARRAY_ADD(literals,obj);
|
||||||
EMIT(JIT_PUSH_LITERAL,literals_count - 1);
|
EMIT(userenv[JIT_PUSH_LITERAL],literals_count - 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,9 +261,9 @@ void jit_compile(CELL quot, bool relocate)
|
||||||
if(!tail_call)
|
if(!tail_call)
|
||||||
{
|
{
|
||||||
if(stack_frame)
|
if(stack_frame)
|
||||||
EMIT(JIT_EPILOG,0);
|
EMIT(userenv[JIT_EPILOG],0);
|
||||||
|
|
||||||
EMIT(JIT_RETURN,0);
|
EMIT(userenv[JIT_RETURN],0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GROWABLE_ARRAY_TRIM(code);
|
GROWABLE_ARRAY_TRIM(code);
|
||||||
|
@ -330,7 +309,7 @@ F_FIXNUM quot_code_offset_to_scan(CELL quot, F_FIXNUM offset)
|
||||||
bool stack_frame = jit_stack_frame_p(untag_object(array));
|
bool stack_frame = jit_stack_frame_p(untag_object(array));
|
||||||
|
|
||||||
if(stack_frame)
|
if(stack_frame)
|
||||||
COUNT(JIT_PROLOG,0)
|
COUNT(userenv[JIT_PROLOG],0)
|
||||||
|
|
||||||
CELL i;
|
CELL i;
|
||||||
CELL length = array_capacity(untag_object(array));
|
CELL length = array_capacity(untag_object(array));
|
||||||
|
@ -339,55 +318,34 @@ F_FIXNUM quot_code_offset_to_scan(CELL quot, F_FIXNUM offset)
|
||||||
for(i = 0; i < length; i++)
|
for(i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
CELL obj = array_nth(untag_object(array),i);
|
CELL obj = array_nth(untag_object(array),i);
|
||||||
|
F_WORD *word;
|
||||||
|
|
||||||
switch(type_of(obj))
|
switch(type_of(obj))
|
||||||
{
|
{
|
||||||
case WORD_TYPE:
|
case WORD_TYPE:
|
||||||
/* Intrinsics */
|
/* Intrinsics */
|
||||||
if(obj == userenv[JIT_TAG_WORD])
|
word = untag_object(obj);
|
||||||
COUNT(JIT_TAG,i)
|
if(word->subprimitive != F)
|
||||||
else if(obj == userenv[JIT_EQP_WORD])
|
COUNT(word->subprimitive,i)
|
||||||
COUNT(JIT_EQP,i)
|
else if(i == length - 1)
|
||||||
else if(obj == userenv[JIT_SLOT_WORD])
|
|
||||||
COUNT(JIT_SLOT,i)
|
|
||||||
else if(obj == userenv[JIT_DROP_WORD])
|
|
||||||
COUNT(JIT_DROP,i)
|
|
||||||
else if(obj == userenv[JIT_DUP_WORD])
|
|
||||||
COUNT(JIT_DUP,i)
|
|
||||||
else if(obj == userenv[JIT_TO_R_WORD])
|
|
||||||
COUNT(JIT_TO_R,i)
|
|
||||||
else if(obj == userenv[JIT_FROM_R_WORD])
|
|
||||||
COUNT(JIT_FROM_R,i)
|
|
||||||
else if(obj == userenv[JIT_SWAP_WORD])
|
|
||||||
COUNT(JIT_SWAP,i)
|
|
||||||
else if(obj == userenv[JIT_OVER_WORD])
|
|
||||||
COUNT(JIT_OVER,i)
|
|
||||||
else if(obj == userenv[JIT_FIXNUM_MINUS_WORD])
|
|
||||||
COUNT(JIT_FIXNUM_MINUS,i)
|
|
||||||
else if(obj == userenv[JIT_FIXNUM_GE_WORD])
|
|
||||||
COUNT(JIT_FIXNUM_GE,i)
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(i == length - 1)
|
|
||||||
{
|
{
|
||||||
if(stack_frame)
|
if(stack_frame)
|
||||||
COUNT(JIT_EPILOG,i);
|
COUNT(userenv[JIT_EPILOG],i);
|
||||||
|
|
||||||
COUNT(JIT_WORD_JUMP,i)
|
COUNT(userenv[JIT_WORD_JUMP],i)
|
||||||
|
|
||||||
tail_call = true;
|
tail_call = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
COUNT(JIT_WORD_CALL,i)
|
COUNT(userenv[JIT_WORD_CALL],i)
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case WRAPPER_TYPE:
|
case WRAPPER_TYPE:
|
||||||
COUNT(JIT_PUSH_LITERAL,i)
|
COUNT(userenv[JIT_PUSH_LITERAL],i)
|
||||||
break;
|
break;
|
||||||
case FIXNUM_TYPE:
|
case FIXNUM_TYPE:
|
||||||
if(jit_primitive_call_p(untag_object(array),i))
|
if(jit_primitive_call_p(untag_object(array),i))
|
||||||
{
|
{
|
||||||
COUNT(JIT_PRIMITIVE,i);
|
COUNT(userenv[JIT_PRIMITIVE],i);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
@ -398,11 +356,11 @@ F_FIXNUM quot_code_offset_to_scan(CELL quot, F_FIXNUM offset)
|
||||||
if(jit_fast_if_p(untag_object(array),i))
|
if(jit_fast_if_p(untag_object(array),i))
|
||||||
{
|
{
|
||||||
if(stack_frame)
|
if(stack_frame)
|
||||||
COUNT(JIT_EPILOG,i)
|
COUNT(userenv[JIT_EPILOG],i)
|
||||||
|
|
||||||
i += 2;
|
i += 2;
|
||||||
|
|
||||||
COUNT(JIT_IF_JUMP,i)
|
COUNT(userenv[JIT_IF_JUMP],i)
|
||||||
|
|
||||||
tail_call = true;
|
tail_call = true;
|
||||||
break;
|
break;
|
||||||
|
@ -411,11 +369,11 @@ F_FIXNUM quot_code_offset_to_scan(CELL quot, F_FIXNUM offset)
|
||||||
if(jit_fast_dispatch_p(untag_object(array),i))
|
if(jit_fast_dispatch_p(untag_object(array),i))
|
||||||
{
|
{
|
||||||
if(stack_frame)
|
if(stack_frame)
|
||||||
COUNT(JIT_EPILOG,i)
|
COUNT(userenv[JIT_EPILOG],i)
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
COUNT(JIT_DISPATCH,i)
|
COUNT(userenv[JIT_DISPATCH],i)
|
||||||
|
|
||||||
tail_call = true;
|
tail_call = true;
|
||||||
break;
|
break;
|
||||||
|
@ -429,7 +387,7 @@ F_FIXNUM quot_code_offset_to_scan(CELL quot, F_FIXNUM offset)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
COUNT(JIT_PUSH_LITERAL,i)
|
COUNT(userenv[JIT_PUSH_LITERAL],i)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,9 +395,9 @@ F_FIXNUM quot_code_offset_to_scan(CELL quot, F_FIXNUM offset)
|
||||||
if(!tail_call)
|
if(!tail_call)
|
||||||
{
|
{
|
||||||
if(stack_frame)
|
if(stack_frame)
|
||||||
COUNT(JIT_EPILOG,length)
|
COUNT(userenv[JIT_EPILOG],length)
|
||||||
|
|
||||||
COUNT(JIT_RETURN,length)
|
COUNT(userenv[JIT_RETURN],length)
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
146
vm/run.c
146
vm/run.c
|
@ -90,133 +90,6 @@ void init_stacks(CELL ds_size_, CELL rs_size_)
|
||||||
stack_chain = NULL;
|
stack_chain = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(drop)
|
|
||||||
{
|
|
||||||
dpop();
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(2drop)
|
|
||||||
{
|
|
||||||
ds -= 2 * CELLS;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(3drop)
|
|
||||||
{
|
|
||||||
ds -= 3 * CELLS;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(dup)
|
|
||||||
{
|
|
||||||
dpush(dpeek());
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(2dup)
|
|
||||||
{
|
|
||||||
CELL top = dpeek();
|
|
||||||
CELL next = get(ds - CELLS);
|
|
||||||
ds += CELLS * 2;
|
|
||||||
put(ds - CELLS,next);
|
|
||||||
put(ds,top);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(3dup)
|
|
||||||
{
|
|
||||||
CELL c1 = dpeek();
|
|
||||||
CELL c2 = get(ds - CELLS);
|
|
||||||
CELL c3 = get(ds - CELLS * 2);
|
|
||||||
ds += CELLS * 3;
|
|
||||||
put (ds,c1);
|
|
||||||
put (ds - CELLS,c2);
|
|
||||||
put (ds - CELLS * 2,c3);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(rot)
|
|
||||||
{
|
|
||||||
CELL c1 = dpeek();
|
|
||||||
CELL c2 = get(ds - CELLS);
|
|
||||||
CELL c3 = get(ds - CELLS * 2);
|
|
||||||
put(ds,c3);
|
|
||||||
put(ds - CELLS,c1);
|
|
||||||
put(ds - CELLS * 2,c2);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(_rot)
|
|
||||||
{
|
|
||||||
CELL c1 = dpeek();
|
|
||||||
CELL c2 = get(ds - CELLS);
|
|
||||||
CELL c3 = get(ds - CELLS * 2);
|
|
||||||
put(ds,c2);
|
|
||||||
put(ds - CELLS,c3);
|
|
||||||
put(ds - CELLS * 2,c1);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(dupd)
|
|
||||||
{
|
|
||||||
CELL top = dpeek();
|
|
||||||
CELL next = get(ds - CELLS);
|
|
||||||
put(ds,next);
|
|
||||||
put(ds - CELLS,next);
|
|
||||||
dpush(top);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(swapd)
|
|
||||||
{
|
|
||||||
CELL top = get(ds - CELLS);
|
|
||||||
CELL next = get(ds - CELLS * 2);
|
|
||||||
put(ds - CELLS,next);
|
|
||||||
put(ds - CELLS * 2,top);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(nip)
|
|
||||||
{
|
|
||||||
CELL top = dpop();
|
|
||||||
drepl(top);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(2nip)
|
|
||||||
{
|
|
||||||
CELL top = dpeek();
|
|
||||||
ds -= CELLS * 2;
|
|
||||||
drepl(top);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(tuck)
|
|
||||||
{
|
|
||||||
CELL top = dpeek();
|
|
||||||
CELL next = get(ds - CELLS);
|
|
||||||
put(ds,next);
|
|
||||||
put(ds - CELLS,top);
|
|
||||||
dpush(top);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(over)
|
|
||||||
{
|
|
||||||
dpush(get(ds - CELLS));
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(pick)
|
|
||||||
{
|
|
||||||
dpush(get(ds - CELLS * 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(swap)
|
|
||||||
{
|
|
||||||
CELL top = dpeek();
|
|
||||||
CELL next = get(ds - CELLS);
|
|
||||||
put(ds,next);
|
|
||||||
put(ds - CELLS,top);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(to_r)
|
|
||||||
{
|
|
||||||
rpush(dpop());
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(from_r)
|
|
||||||
{
|
|
||||||
dpush(rpop());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool stack_to_array(CELL bottom, CELL top)
|
bool stack_to_array(CELL bottom, CELL top)
|
||||||
{
|
{
|
||||||
F_FIXNUM depth = (F_FIXNUM)(top - bottom + CELLS);
|
F_FIXNUM depth = (F_FIXNUM)(top - bottom + CELLS);
|
||||||
|
@ -280,13 +153,6 @@ DEFINE_PRIMITIVE(exit)
|
||||||
exit(to_fixnum(dpop()));
|
exit(to_fixnum(dpop()));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(eq)
|
|
||||||
{
|
|
||||||
CELL lhs = dpop();
|
|
||||||
CELL rhs = dpeek();
|
|
||||||
drepl((lhs == rhs) ? T : F);
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(millis)
|
DEFINE_PRIMITIVE(millis)
|
||||||
{
|
{
|
||||||
box_unsigned_8(current_millis());
|
box_unsigned_8(current_millis());
|
||||||
|
@ -297,18 +163,6 @@ DEFINE_PRIMITIVE(sleep)
|
||||||
sleep_millis(to_cell(dpop()));
|
sleep_millis(to_cell(dpop()));
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(tag)
|
|
||||||
{
|
|
||||||
drepl(tag_fixnum(TAG(dpeek())));
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(slot)
|
|
||||||
{
|
|
||||||
F_FIXNUM slot = untag_fixnum_fast(dpop());
|
|
||||||
CELL obj = dpop();
|
|
||||||
dpush(get(SLOT(obj,slot)));
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(set_slot)
|
DEFINE_PRIMITIVE(set_slot)
|
||||||
{
|
{
|
||||||
F_FIXNUM slot = untag_fixnum_fast(dpop());
|
F_FIXNUM slot = untag_fixnum_fast(dpop());
|
||||||
|
|
24
vm/run.h
24
vm/run.h
|
@ -245,28 +245,9 @@ DLLEXPORT void save_stacks(void);
|
||||||
DLLEXPORT void nest_stacks(void);
|
DLLEXPORT void nest_stacks(void);
|
||||||
DLLEXPORT void unnest_stacks(void);
|
DLLEXPORT void unnest_stacks(void);
|
||||||
void init_stacks(CELL ds_size, CELL rs_size);
|
void init_stacks(CELL ds_size, CELL rs_size);
|
||||||
DECLARE_PRIMITIVE(drop);
|
|
||||||
DECLARE_PRIMITIVE(2drop);
|
|
||||||
DECLARE_PRIMITIVE(3drop);
|
|
||||||
DECLARE_PRIMITIVE(dup);
|
|
||||||
DECLARE_PRIMITIVE(2dup);
|
|
||||||
DECLARE_PRIMITIVE(3dup);
|
|
||||||
DECLARE_PRIMITIVE(rot);
|
|
||||||
DECLARE_PRIMITIVE(_rot);
|
|
||||||
DECLARE_PRIMITIVE(dupd);
|
|
||||||
DECLARE_PRIMITIVE(swapd);
|
|
||||||
DECLARE_PRIMITIVE(nip);
|
|
||||||
DECLARE_PRIMITIVE(2nip);
|
|
||||||
DECLARE_PRIMITIVE(tuck);
|
|
||||||
DECLARE_PRIMITIVE(over);
|
|
||||||
DECLARE_PRIMITIVE(pick);
|
|
||||||
DECLARE_PRIMITIVE(swap);
|
|
||||||
DECLARE_PRIMITIVE(to_r);
|
|
||||||
DECLARE_PRIMITIVE(from_r);
|
|
||||||
DECLARE_PRIMITIVE(datastack);
|
DECLARE_PRIMITIVE(datastack);
|
||||||
DECLARE_PRIMITIVE(retainstack);
|
DECLARE_PRIMITIVE(retainstack);
|
||||||
DECLARE_PRIMITIVE(execute);
|
|
||||||
DECLARE_PRIMITIVE(call);
|
|
||||||
DECLARE_PRIMITIVE(getenv);
|
DECLARE_PRIMITIVE(getenv);
|
||||||
DECLARE_PRIMITIVE(setenv);
|
DECLARE_PRIMITIVE(setenv);
|
||||||
DECLARE_PRIMITIVE(exit);
|
DECLARE_PRIMITIVE(exit);
|
||||||
|
@ -275,11 +256,8 @@ DECLARE_PRIMITIVE(os_envs);
|
||||||
DECLARE_PRIMITIVE(set_os_env);
|
DECLARE_PRIMITIVE(set_os_env);
|
||||||
DECLARE_PRIMITIVE(unset_os_env);
|
DECLARE_PRIMITIVE(unset_os_env);
|
||||||
DECLARE_PRIMITIVE(set_os_envs);
|
DECLARE_PRIMITIVE(set_os_envs);
|
||||||
DECLARE_PRIMITIVE(eq);
|
|
||||||
DECLARE_PRIMITIVE(millis);
|
DECLARE_PRIMITIVE(millis);
|
||||||
DECLARE_PRIMITIVE(sleep);
|
DECLARE_PRIMITIVE(sleep);
|
||||||
DECLARE_PRIMITIVE(tag);
|
|
||||||
DECLARE_PRIMITIVE(slot);
|
|
||||||
DECLARE_PRIMITIVE(set_slot);
|
DECLARE_PRIMITIVE(set_slot);
|
||||||
|
|
||||||
bool stage2;
|
bool stage2;
|
||||||
|
|
|
@ -49,6 +49,7 @@ F_WORD *allot_word(CELL vocab, CELL name)
|
||||||
word->props = F;
|
word->props = F;
|
||||||
word->counter = tag_fixnum(0);
|
word->counter = tag_fixnum(0);
|
||||||
word->compiledp = F;
|
word->compiledp = F;
|
||||||
|
word->subprimitive = F;
|
||||||
word->profiling = NULL;
|
word->profiling = NULL;
|
||||||
word->code = NULL;
|
word->code = NULL;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue