FFI rewrite part 7: compile callback bodies with the optimizing compiler
parent
5fc9aa05b0
commit
168dd1f825
|
@ -95,16 +95,8 @@ SYNTAX: CLASS:
|
||||||
[ [ make-local ] map ] H{ } make-assoc
|
[ [ make-local ] map ] H{ } make-assoc
|
||||||
(parse-lambda) <lambda> ?rewrite-closures first ;
|
(parse-lambda) <lambda> ?rewrite-closures first ;
|
||||||
|
|
||||||
: method-effect ( quadruple -- effect )
|
|
||||||
[ third ] [ second void? { } { "x" } ? ] bi <effect> ;
|
|
||||||
|
|
||||||
: check-method ( quadruple -- )
|
|
||||||
[ fourth infer ] [ method-effect ] bi
|
|
||||||
2dup effect<= [ 2drop ] [ effect-error ] if ;
|
|
||||||
|
|
||||||
SYNTAX: METHOD:
|
SYNTAX: METHOD:
|
||||||
scan-c-type
|
scan-c-type
|
||||||
parse-selector
|
parse-selector
|
||||||
parse-method-body [ swap ] 2dip 4array
|
parse-method-body [ swap ] 2dip 4array
|
||||||
dup check-method
|
|
||||||
suffix! ;
|
suffix! ;
|
||||||
|
|
|
@ -39,7 +39,6 @@ M: ##unary-float-function compute-stack-frame* drop vm-frame-required ;
|
||||||
M: ##binary-float-function compute-stack-frame* drop vm-frame-required ;
|
M: ##binary-float-function compute-stack-frame* drop vm-frame-required ;
|
||||||
|
|
||||||
M: ##call compute-stack-frame* drop frame-required ;
|
M: ##call compute-stack-frame* drop frame-required ;
|
||||||
M: ##alien-callback compute-stack-frame* drop frame-required ;
|
|
||||||
M: ##spill compute-stack-frame* drop frame-required ;
|
M: ##spill compute-stack-frame* drop frame-required ;
|
||||||
M: ##reload compute-stack-frame* drop frame-required ;
|
M: ##reload compute-stack-frame* drop frame-required ;
|
||||||
|
|
||||||
|
|
|
@ -173,24 +173,22 @@ M: #alien-assembly emit-node
|
||||||
: needs-frame-pointer ( -- )
|
: needs-frame-pointer ( -- )
|
||||||
cfg get t >>frame-pointer? drop ;
|
cfg get t >>frame-pointer? drop ;
|
||||||
|
|
||||||
|
: emit-callback-body ( nodes -- )
|
||||||
|
[ last #return? t assert= ] [ but-last emit-nodes ] bi ;
|
||||||
|
|
||||||
M: #alien-callback emit-node
|
M: #alien-callback emit-node
|
||||||
params>> dup xt>> dup
|
dup params>> xt>> dup
|
||||||
[
|
[
|
||||||
needs-frame-pointer
|
needs-frame-pointer
|
||||||
|
|
||||||
begin-word
|
begin-word
|
||||||
|
|
||||||
{
|
{
|
||||||
[ callee-parameters ##callback-inputs ]
|
[ params>> callee-parameters ##callback-inputs ]
|
||||||
[ box-parameters ]
|
[ params>> box-parameters ]
|
||||||
[
|
[ child>> emit-callback-body ]
|
||||||
[
|
[ params>> callee-return ##callback-outputs ]
|
||||||
make-kill-block
|
[ params>> callback-stack-cleanup ]
|
||||||
quot>> ##alien-callback
|
|
||||||
] emit-trivial-block
|
|
||||||
]
|
|
||||||
[ callee-return ##callback-outputs ]
|
|
||||||
[ callback-stack-cleanup ]
|
|
||||||
} cleave
|
} cleave
|
||||||
|
|
||||||
end-word
|
end-word
|
||||||
|
|
|
@ -99,6 +99,18 @@ M: ##write-barrier live-insn? src>> live-vreg? ;
|
||||||
|
|
||||||
M: ##write-barrier-imm live-insn? src>> live-vreg? ;
|
M: ##write-barrier-imm live-insn? src>> live-vreg? ;
|
||||||
|
|
||||||
|
: filter-alien-outputs ( triples -- triples' )
|
||||||
|
[ first live-vreg? ] filter ;
|
||||||
|
|
||||||
|
M: alien-call-insn live-insn?
|
||||||
|
[ filter-alien-outputs ] change-reg-outputs
|
||||||
|
drop t ;
|
||||||
|
|
||||||
|
M: ##callback-inputs live-insn?
|
||||||
|
[ filter-alien-outputs ] change-reg-outputs
|
||||||
|
[ filter-alien-outputs ] change-stack-outputs
|
||||||
|
drop t ;
|
||||||
|
|
||||||
M: flushable-insn live-insn? defs-vregs [ live-vreg? ] any? ;
|
M: flushable-insn live-insn? defs-vregs [ live-vreg? ] any? ;
|
||||||
|
|
||||||
M: insn live-insn? drop t ;
|
M: insn live-insn? drop t ;
|
||||||
|
|
|
@ -685,9 +685,6 @@ literal: reg-inputs stack-inputs reg-outputs cleanup stack-size quot gc-map ;
|
||||||
VREG-INSN: ##callback-inputs
|
VREG-INSN: ##callback-inputs
|
||||||
literal: reg-outputs stack-outputs ;
|
literal: reg-outputs stack-outputs ;
|
||||||
|
|
||||||
INSN: ##alien-callback
|
|
||||||
literal: quot ;
|
|
||||||
|
|
||||||
VREG-INSN: ##callback-outputs
|
VREG-INSN: ##callback-outputs
|
||||||
literal: reg-inputs ;
|
literal: reg-inputs ;
|
||||||
|
|
||||||
|
|
|
@ -293,5 +293,4 @@ CODEGEN: ##alien-invoke %alien-invoke
|
||||||
CODEGEN: ##alien-indirect %alien-indirect
|
CODEGEN: ##alien-indirect %alien-indirect
|
||||||
CODEGEN: ##alien-assembly %alien-assembly
|
CODEGEN: ##alien-assembly %alien-assembly
|
||||||
CODEGEN: ##callback-inputs %callback-inputs
|
CODEGEN: ##callback-inputs %callback-inputs
|
||||||
CODEGEN: ##alien-callback %alien-callback
|
|
||||||
CODEGEN: ##callback-outputs %callback-outputs
|
CODEGEN: ##callback-outputs %callback-outputs
|
||||||
|
|
|
@ -45,6 +45,8 @@ FUNCTION: void ffi_test_0 ;
|
||||||
FUNCTION: int ffi_test_1 ;
|
FUNCTION: int ffi_test_1 ;
|
||||||
[ 3 ] [ ffi_test_1 ] unit-test
|
[ 3 ] [ ffi_test_1 ] unit-test
|
||||||
|
|
||||||
|
[ ] [ \ ffi_test_1 def>> [ drop ] append compile-call ] unit-test
|
||||||
|
|
||||||
FUNCTION: int ffi_test_2 int x int y ;
|
FUNCTION: int ffi_test_2 int x int y ;
|
||||||
[ 5 ] [ 2 3 ffi_test_2 ] unit-test
|
[ 5 ] [ 2 3 ffi_test_2 ] unit-test
|
||||||
[ "hi" 3 ffi_test_2 ] must-fail
|
[ "hi" 3 ffi_test_2 ] must-fail
|
||||||
|
|
|
@ -20,10 +20,6 @@ M: callable (build-tree) infer-quot-here ;
|
||||||
: check-no-compile ( word -- )
|
: check-no-compile ( word -- )
|
||||||
dup "no-compile" word-prop [ do-not-compile ] [ drop ] if ;
|
dup "no-compile" word-prop [ do-not-compile ] [ drop ] if ;
|
||||||
|
|
||||||
: check-effect ( word effect -- )
|
|
||||||
swap required-stack-effect 2dup effect<=
|
|
||||||
[ 2drop ] [ effect-error ] if ;
|
|
||||||
|
|
||||||
: inline-recursive? ( word -- ? )
|
: inline-recursive? ( word -- ? )
|
||||||
[ "inline" word-prop ] [ "recursive" word-prop ] bi and ;
|
[ "inline" word-prop ] [ "recursive" word-prop ] bi and ;
|
||||||
|
|
||||||
|
@ -33,7 +29,7 @@ M: callable (build-tree) infer-quot-here ;
|
||||||
M: word (build-tree)
|
M: word (build-tree)
|
||||||
[ check-no-compile ]
|
[ check-no-compile ]
|
||||||
[ word-body infer-quot-here ]
|
[ word-body infer-quot-here ]
|
||||||
[ current-effect check-effect ] tri ;
|
[ required-stack-effect check-effect ] tri ;
|
||||||
|
|
||||||
: build-tree-with ( in-stack word/quot -- nodes )
|
: build-tree-with ( in-stack word/quot -- nodes )
|
||||||
[
|
[
|
||||||
|
|
|
@ -188,7 +188,7 @@ M: #copy check-stack-flow* [ check-in-d ] [ check-out-d ] bi ;
|
||||||
|
|
||||||
M: #alien-node check-stack-flow* [ check-in-d ] [ check-out-d ] bi ;
|
M: #alien-node check-stack-flow* [ check-in-d ] [ check-out-d ] bi ;
|
||||||
|
|
||||||
M: #alien-callback check-stack-flow* drop ;
|
M: #alien-callback check-stack-flow* child>> check-stack-flow ;
|
||||||
|
|
||||||
M: #declare check-stack-flow* drop ;
|
M: #declare check-stack-flow* drop ;
|
||||||
|
|
||||||
|
|
|
@ -519,3 +519,10 @@ cell-bits 32 = [
|
||||||
14 ndrop
|
14 ndrop
|
||||||
] cleaned-up-tree nodes>quot
|
] cleaned-up-tree nodes>quot
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
USING: alien alien.c-types ;
|
||||||
|
|
||||||
|
[ t ] [
|
||||||
|
[ int { } cdecl [ 2 2 + ] alien-callback ]
|
||||||
|
{ + } inlined?
|
||||||
|
] unit-test
|
||||||
|
|
|
@ -182,4 +182,7 @@ M: #recursive cleanup*
|
||||||
[ cleanup ] change-child
|
[ cleanup ] change-child
|
||||||
dup label>> calls>> empty? [ flatten-recursive ] when ;
|
dup label>> calls>> empty? [ flatten-recursive ] when ;
|
||||||
|
|
||||||
|
M: #alien-callback cleanup*
|
||||||
|
[ cleanup ] change-child ;
|
||||||
|
|
||||||
M: node cleanup* ;
|
M: node cleanup* ;
|
||||||
|
|
|
@ -1,46 +1,47 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
! Copyright (C) 2008, 2010 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: assocs fry kernel accessors sequences compiler.utilities
|
USING: assocs combinators combinators.short-circuit fry kernel
|
||||||
arrays stack-checker.inlining namespaces compiler.tree
|
locals accessors sequences compiler.utilities arrays
|
||||||
math.order ;
|
stack-checker.inlining namespaces compiler.tree math.order ;
|
||||||
IN: compiler.tree.combinators
|
IN: compiler.tree.combinators
|
||||||
|
|
||||||
: each-node ( ... nodes quot: ( ... node -- ... ) -- ... )
|
:: each-node ( ... nodes quot: ( ... node -- ... ) -- ... )
|
||||||
dup dup '[
|
nodes [
|
||||||
_ [
|
quot
|
||||||
dup #branch? [
|
[
|
||||||
children>> [ _ each-node ] each
|
{
|
||||||
] [
|
{ [ dup #branch? ] [ children>> [ quot each-node ] each ] }
|
||||||
dup #recursive? [
|
{ [ dup #recursive? ] [ child>> quot each-node ] }
|
||||||
child>> _ each-node
|
{ [ dup #alien-callback? ] [ child>> quot each-node ] }
|
||||||
] [ drop ] if
|
[ drop ]
|
||||||
] if
|
} cond
|
||||||
] bi
|
] bi
|
||||||
] each ; inline recursive
|
] each ; inline recursive
|
||||||
|
|
||||||
: map-nodes ( ... nodes quot: ( ... node -- ... node' ) -- ... nodes )
|
:: map-nodes ( ... nodes quot: ( ... node -- ... node' ) -- ... nodes )
|
||||||
dup dup '[
|
nodes [
|
||||||
@
|
quot call
|
||||||
dup #branch? [
|
{
|
||||||
[ [ _ map-nodes ] map ] change-children
|
{ [ dup #branch? ] [ [ [ quot map-nodes ] map ] change-children ] }
|
||||||
] [
|
{ [ dup #recursive? ] [ [ quot map-nodes ] change-child ] }
|
||||||
dup #recursive? [
|
{ [ dup #alien-callback? ] [ [ quot map-nodes ] change-child ] }
|
||||||
[ _ map-nodes ] change-child
|
[ ]
|
||||||
] when
|
} cond
|
||||||
] if
|
|
||||||
] map-flat ; inline recursive
|
] map-flat ; inline recursive
|
||||||
|
|
||||||
: contains-node? ( ... nodes quot: ( ... node -- ... ? ) -- ... ? )
|
:: contains-node? ( ... nodes quot: ( ... node -- ... ? ) -- ... ? )
|
||||||
dup dup '[
|
nodes [
|
||||||
_ keep swap [ drop t ] [
|
{
|
||||||
dup #branch? [
|
quot
|
||||||
children>> [ _ contains-node? ] any?
|
[
|
||||||
] [
|
{
|
||||||
dup #recursive? [
|
{ [ dup #branch? ] [ children>> [ quot contains-node? ] any? ] }
|
||||||
child>> _ contains-node?
|
{ [ dup #recursive? ] [ child>> quot contains-node? ] }
|
||||||
] [ drop f ] if
|
{ [ dup #alien-callback? ] [ child>> quot contains-node? ] }
|
||||||
] if
|
[ drop f ]
|
||||||
] if
|
} cond
|
||||||
|
]
|
||||||
|
} 1||
|
||||||
] any? ; inline recursive
|
] any? ; inline recursive
|
||||||
|
|
||||||
: select-children ( seq flags -- seq' )
|
: select-children ( seq flags -- seq' )
|
||||||
|
|
|
@ -117,3 +117,6 @@ M: #terminate remove-dead-code*
|
||||||
|
|
||||||
M: #alien-node remove-dead-code*
|
M: #alien-node remove-dead-code*
|
||||||
maybe-drop-dead-outputs ;
|
maybe-drop-dead-outputs ;
|
||||||
|
|
||||||
|
M: #alien-callback remove-dead-code*
|
||||||
|
[ (remove-dead-code) ] change-child ;
|
||||||
|
|
|
@ -4,7 +4,7 @@ USING: kernel assocs match fry accessors namespaces make effects
|
||||||
sequences sequences.private quotations generic macros arrays
|
sequences sequences.private quotations generic macros arrays
|
||||||
prettyprint prettyprint.backend prettyprint.custom
|
prettyprint prettyprint.backend prettyprint.custom
|
||||||
prettyprint.sections math words combinators
|
prettyprint.sections math words combinators
|
||||||
combinators.short-circuit io sorting hints
|
combinators.short-circuit io sorting hints sets
|
||||||
compiler.tree
|
compiler.tree
|
||||||
compiler.tree.recursive
|
compiler.tree.recursive
|
||||||
compiler.tree.normalization
|
compiler.tree.normalization
|
||||||
|
@ -22,6 +22,7 @@ compiler.tree.identities
|
||||||
compiler.tree.dead-code
|
compiler.tree.dead-code
|
||||||
compiler.tree.modular-arithmetic ;
|
compiler.tree.modular-arithmetic ;
|
||||||
FROM: fry => _ ;
|
FROM: fry => _ ;
|
||||||
|
FROM: namespaces => set ;
|
||||||
RENAME: _ match => __
|
RENAME: _ match => __
|
||||||
IN: compiler.tree.debugger
|
IN: compiler.tree.debugger
|
||||||
|
|
||||||
|
@ -128,7 +129,8 @@ M: #alien-indirect node>quot params>> , \ #alien-indirect , ;
|
||||||
|
|
||||||
M: #alien-assembly node>quot params>> , \ #alien-assembly , ;
|
M: #alien-assembly node>quot params>> , \ #alien-assembly , ;
|
||||||
|
|
||||||
M: #alien-callback node>quot params>> , \ #alien-callback , ;
|
M: #alien-callback node>quot
|
||||||
|
[ params>> , ] [ child>> nodes>quot , ] bi \ #alien-callback , ;
|
||||||
|
|
||||||
M: node node>quot drop ;
|
M: node node>quot drop ;
|
||||||
|
|
||||||
|
@ -222,7 +224,6 @@ SYMBOL: node-count
|
||||||
] with-scope ;
|
] with-scope ;
|
||||||
|
|
||||||
: inlined? ( quot seq/word -- ? )
|
: inlined? ( quot seq/word -- ? )
|
||||||
[ cleaned-up-tree ] dip
|
dup word? [ 1array ] when swap
|
||||||
dup word? [ 1array ] when
|
[ cleaned-up-tree [ dup #call? [ word>> , ] [ drop ] if ] each-node ] V{ } make
|
||||||
'[ dup #call? [ word>> _ member? ] [ drop f ] if ]
|
intersect empty? ;
|
||||||
contains-node? not ;
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ SYMBOL: next-node
|
||||||
: each-with-next ( ... seq quot: ( ... elt -- ... ) -- ... )
|
: each-with-next ( ... seq quot: ( ... elt -- ... ) -- ... )
|
||||||
dupd '[ 1 + _ ?nth next-node set @ ] each-index ; inline
|
dupd '[ 1 + _ ?nth next-node set @ ] each-index ; inline
|
||||||
|
|
||||||
: (escape-analysis) ( node -- )
|
: (escape-analysis) ( nodes -- )
|
||||||
[
|
[
|
||||||
[ node-defs-values introduce-values ]
|
[ node-defs-values introduce-values ]
|
||||||
[ escape-analysis* ]
|
[ escape-analysis* ]
|
||||||
|
|
|
@ -100,4 +100,5 @@ M: #alien-node escape-analysis*
|
||||||
[ out-d>> unknown-allocations ]
|
[ out-d>> unknown-allocations ]
|
||||||
bi ;
|
bi ;
|
||||||
|
|
||||||
M: #alien-callback escape-analysis* drop ;
|
M: #alien-callback escape-analysis*
|
||||||
|
child>> (escape-analysis) ;
|
||||||
|
|
|
@ -109,8 +109,13 @@ M: #call-recursive normalize*
|
||||||
M: node normalize* ;
|
M: node normalize* ;
|
||||||
|
|
||||||
: normalize ( nodes -- nodes' )
|
: normalize ( nodes -- nodes' )
|
||||||
dup count-introductions make-values
|
[
|
||||||
H{ } clone rename-map set
|
dup count-introductions make-values
|
||||||
[ (normalize) ] [ nip ] 2bi
|
H{ } clone rename-map set
|
||||||
[ #introduce prefix ] unless-empty
|
[ (normalize) ] [ nip ] 2bi
|
||||||
rename-node-values ;
|
[ #introduce prefix ] unless-empty
|
||||||
|
rename-node-values
|
||||||
|
] with-scope ;
|
||||||
|
|
||||||
|
M: #alien-callback normalize*
|
||||||
|
[ normalize ] change-child ;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
! Copyright (C) 2004, 2008 Slava Pestov.
|
! Copyright (C) 2004, 2010 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: sequences accessors kernel assocs
|
USING: sequences accessors kernel assocs
|
||||||
compiler.tree
|
compiler.tree
|
||||||
|
@ -16,7 +16,7 @@ GENERIC: annotate-node ( node -- )
|
||||||
|
|
||||||
GENERIC: propagate-around ( node -- )
|
GENERIC: propagate-around ( node -- )
|
||||||
|
|
||||||
: (propagate) ( node -- )
|
: (propagate) ( nodes -- )
|
||||||
[ [ compute-copy-equiv ] [ propagate-around ] bi ] each ;
|
[ [ compute-copy-equiv ] [ propagate-around ] bi ] each ;
|
||||||
|
|
||||||
: extract-value-info ( values -- assoc )
|
: extract-value-info ( values -- assoc )
|
||||||
|
|
|
@ -153,4 +153,6 @@ M: #call propagate-after
|
||||||
|
|
||||||
M: #alien-node propagate-before propagate-alien-invoke ;
|
M: #alien-node propagate-before propagate-alien-invoke ;
|
||||||
|
|
||||||
|
M: #alien-callback propagate-around child>> (propagate) ;
|
||||||
|
|
||||||
M: #return annotate-node dup in-d>> (annotate-node) ;
|
M: #return annotate-node dup in-d>> (annotate-node) ;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
USING: tools.test kernel combinators.short-circuit math sequences accessors
|
USING: tools.test kernel combinators.short-circuit math sequences accessors make
|
||||||
compiler.tree
|
compiler.tree
|
||||||
compiler.tree.builder
|
compiler.tree.builder
|
||||||
compiler.tree.combinators
|
compiler.tree.combinators
|
||||||
|
@ -12,22 +12,24 @@ IN: compiler.tree.recursive.tests
|
||||||
[ { f f f t } ] [ t { f f t f } (tail-calls) ] unit-test
|
[ { f f f t } ] [ t { f f t f } (tail-calls) ] unit-test
|
||||||
|
|
||||||
: label-is-loop? ( nodes word -- ? )
|
: label-is-loop? ( nodes word -- ? )
|
||||||
[
|
swap [
|
||||||
{
|
[
|
||||||
[ drop #recursive? ]
|
dup {
|
||||||
[ drop label>> loop?>> ]
|
[ #recursive? ]
|
||||||
[ swap label>> word>> eq? ]
|
[ label>> loop?>> ]
|
||||||
} 2&&
|
} 1&& [ label>> word>> , ] [ drop ] if
|
||||||
] curry contains-node? ;
|
] each-node
|
||||||
|
] V{ } make member? ;
|
||||||
|
|
||||||
: label-is-not-loop? ( nodes word -- ? )
|
: label-is-not-loop? ( nodes word -- ? )
|
||||||
[
|
swap [
|
||||||
{
|
[
|
||||||
[ drop #recursive? ]
|
dup {
|
||||||
[ drop label>> loop?>> not ]
|
[ #recursive? ]
|
||||||
[ swap label>> word>> eq? ]
|
[ label>> loop?>> not ]
|
||||||
} 2&&
|
} 1&& [ label>> word>> , ] [ drop ] if
|
||||||
] curry contains-node? ;
|
] each-node
|
||||||
|
] V{ } make member? ;
|
||||||
|
|
||||||
: loop-test-1 ( a -- )
|
: loop-test-1 ( a -- )
|
||||||
dup [ 1 + loop-test-1 ] [ drop ] if ; inline recursive
|
dup [ 1 + loop-test-1 ] [ drop ] if ; inline recursive
|
||||||
|
|
|
@ -61,6 +61,9 @@ M: #recursive node-call-graph
|
||||||
M: #branch node-call-graph
|
M: #branch node-call-graph
|
||||||
children>> [ (build-call-graph) ] with each ;
|
children>> [ (build-call-graph) ] with each ;
|
||||||
|
|
||||||
|
M: #alien-callback node-call-graph
|
||||||
|
child>> (build-call-graph) ;
|
||||||
|
|
||||||
M: node node-call-graph 2drop ;
|
M: node node-call-graph 2drop ;
|
||||||
|
|
||||||
SYMBOLS: not-loops recursive-nesting ;
|
SYMBOLS: not-loops recursive-nesting ;
|
||||||
|
|
|
@ -154,10 +154,11 @@ TUPLE: #alien-assembly < #alien-node in-d out-d ;
|
||||||
: #alien-assembly ( params -- node )
|
: #alien-assembly ( params -- node )
|
||||||
\ #alien-assembly new-alien-node ;
|
\ #alien-assembly new-alien-node ;
|
||||||
|
|
||||||
TUPLE: #alien-callback < node params ;
|
TUPLE: #alien-callback < node params child ;
|
||||||
|
|
||||||
: #alien-callback ( params -- node )
|
: #alien-callback ( params child -- node )
|
||||||
\ #alien-callback new
|
\ #alien-callback new
|
||||||
|
swap >>child
|
||||||
swap >>params ;
|
swap >>params ;
|
||||||
|
|
||||||
: node, ( node -- ) stack-visitor get push ;
|
: node, ( node -- ) stack-visitor get push ;
|
||||||
|
|
|
@ -5,7 +5,7 @@ compiler.tree.cleanup compiler.tree.escape-analysis
|
||||||
compiler.tree.tuple-unboxing compiler.tree.checker
|
compiler.tree.tuple-unboxing compiler.tree.checker
|
||||||
compiler.tree.def-use kernel accessors sequences math
|
compiler.tree.def-use kernel accessors sequences math
|
||||||
math.private sorting math.order binary-search sequences.private
|
math.private sorting math.order binary-search sequences.private
|
||||||
slots.private ;
|
slots.private alien alien.c-types ;
|
||||||
IN: compiler.tree.tuple-unboxing.tests
|
IN: compiler.tree.tuple-unboxing.tests
|
||||||
|
|
||||||
: test-unboxing ( quot -- )
|
: test-unboxing ( quot -- )
|
||||||
|
@ -35,6 +35,7 @@ TUPLE: empty-tuple ;
|
||||||
[ 1 cons boa over [ "A" throw ] when car>> ]
|
[ 1 cons boa over [ "A" throw ] when car>> ]
|
||||||
[ [ <=> ] sort ]
|
[ [ <=> ] sort ]
|
||||||
[ [ <=> ] with search ]
|
[ [ <=> ] with search ]
|
||||||
|
[ cons boa car>> void { } cdecl [ ] alien-callback ]
|
||||||
} [ [ ] swap [ test-unboxing ] curry unit-test ] each
|
} [ [ ] swap [ test-unboxing ] curry unit-test ] each
|
||||||
|
|
||||||
! A more complicated example
|
! A more complicated example
|
||||||
|
|
|
@ -610,8 +610,6 @@ HOOK: %alien-assembly cpu ( reg-inputs stack-inputs reg-outputs cleanup stack-si
|
||||||
|
|
||||||
HOOK: %callback-inputs cpu ( reg-outputs stack-outputs -- )
|
HOOK: %callback-inputs cpu ( reg-outputs stack-outputs -- )
|
||||||
|
|
||||||
HOOK: %alien-callback cpu ( quot -- )
|
|
||||||
|
|
||||||
HOOK: %callback-outputs cpu ( reg-inputs -- )
|
HOOK: %callback-outputs cpu ( reg-inputs -- )
|
||||||
|
|
||||||
HOOK: stack-cleanup cpu ( stack-size return abi -- n )
|
HOOK: stack-cleanup cpu ( stack-size return abi -- n )
|
||||||
|
|
|
@ -186,10 +186,6 @@ M: x86.32 %begin-callback ( -- )
|
||||||
4 stack@ 0 MOV
|
4 stack@ 0 MOV
|
||||||
"begin_callback" f f %c-invoke ;
|
"begin_callback" f f %c-invoke ;
|
||||||
|
|
||||||
M: x86.32 %alien-callback ( quot -- )
|
|
||||||
[ EAX ] dip %load-reference
|
|
||||||
EAX quot-entry-point-offset [+] CALL ;
|
|
||||||
|
|
||||||
M: x86.32 %end-callback ( -- )
|
M: x86.32 %end-callback ( -- )
|
||||||
0 save-vm-ptr
|
0 save-vm-ptr
|
||||||
"end_callback" f f %c-invoke ;
|
"end_callback" f f %c-invoke ;
|
||||||
|
|
|
@ -116,10 +116,6 @@ M: x86.64 %begin-callback ( -- )
|
||||||
param-reg-1 0 MOV
|
param-reg-1 0 MOV
|
||||||
"begin_callback" f f %c-invoke ;
|
"begin_callback" f f %c-invoke ;
|
||||||
|
|
||||||
M: x86.64 %alien-callback ( quot -- )
|
|
||||||
[ param-reg-0 ] dip %load-reference
|
|
||||||
param-reg-0 quot-entry-point-offset [+] CALL ;
|
|
||||||
|
|
||||||
M: x86.64 %end-callback ( -- )
|
M: x86.64 %end-callback ( -- )
|
||||||
param-reg-0 %mov-vm-ptr
|
param-reg-0 %mov-vm-ptr
|
||||||
"end_callback" f f %c-invoke ;
|
"end_callback" f f %c-invoke ;
|
||||||
|
|
|
@ -4,7 +4,8 @@ USING: kernel arrays sequences accessors combinators math
|
||||||
namespaces init sets words assocs alien.libraries alien
|
namespaces init sets words assocs alien.libraries alien
|
||||||
alien.private alien.c-types fry quotations strings
|
alien.private alien.c-types fry quotations strings
|
||||||
stack-checker.backend stack-checker.errors stack-checker.visitor
|
stack-checker.backend stack-checker.errors stack-checker.visitor
|
||||||
stack-checker.dependencies compiler.utilities ;
|
stack-checker.dependencies stack-checker.state
|
||||||
|
compiler.utilities effects ;
|
||||||
IN: stack-checker.alien
|
IN: stack-checker.alien
|
||||||
|
|
||||||
TUPLE: alien-node-params
|
TUPLE: alien-node-params
|
||||||
|
@ -19,7 +20,7 @@ TUPLE: alien-indirect-params < alien-node-params ;
|
||||||
|
|
||||||
TUPLE: alien-assembly-params < alien-node-params { quot callable } ;
|
TUPLE: alien-assembly-params < alien-node-params { quot callable } ;
|
||||||
|
|
||||||
TUPLE: alien-callback-params < alien-node-params { quot callable } xt ;
|
TUPLE: alien-callback-params < alien-node-params xt ;
|
||||||
|
|
||||||
: param-prep-quot ( params -- quot )
|
: param-prep-quot ( params -- quot )
|
||||||
parameters>> [ c-type c-type-unboxer-quot ] map spread>quot ;
|
parameters>> [ c-type c-type-unboxer-quot ] map spread>quot ;
|
||||||
|
@ -106,6 +107,7 @@ TUPLE: alien-callback-params < alien-node-params { quot callable } xt ;
|
||||||
callbacks get [ dup "stack-cleanup" word-prop <callback> ] cache ;
|
callbacks get [ dup "stack-cleanup" word-prop <callback> ] cache ;
|
||||||
|
|
||||||
: callback-bottom ( params -- )
|
: callback-bottom ( params -- )
|
||||||
|
"( callback )" <uninterned-word> >>xt
|
||||||
xt>> '[ _ callback-xt ] infer-quot-here ;
|
xt>> '[ _ callback-xt ] infer-quot-here ;
|
||||||
|
|
||||||
: callback-return-quot ( ctype -- quot )
|
: callback-return-quot ( ctype -- quot )
|
||||||
|
@ -114,19 +116,36 @@ TUPLE: alien-callback-params < alien-node-params { quot callable } xt ;
|
||||||
: callback-prep-quot ( params -- quot )
|
: callback-prep-quot ( params -- quot )
|
||||||
parameters>> [ c-type c-type-boxer-quot ] map spread>quot ;
|
parameters>> [ c-type c-type-boxer-quot ] map spread>quot ;
|
||||||
|
|
||||||
: wrap-callback-quot ( params -- quot )
|
GENERIC: wrap-callback-quot ( params quot -- quot' )
|
||||||
[ callback-prep-quot ] [ quot>> ] [ callback-return-quot ] tri 3append
|
|
||||||
yield-hook get
|
M: callable wrap-callback-quot
|
||||||
'[ _ _ do-callback ]
|
swap [ callback-prep-quot ] [ callback-return-quot ] bi surround
|
||||||
>quotation ;
|
yield-hook get
|
||||||
|
'[ _ _ do-callback ]
|
||||||
|
>quotation ;
|
||||||
|
|
||||||
|
: callback-effect ( params -- effect )
|
||||||
|
[ parameters>> length "x" <array> ] [ return>> void? { } { "x" } ? ] bi
|
||||||
|
<effect> ;
|
||||||
|
|
||||||
|
: infer-callback-quot ( params quot -- child )
|
||||||
|
[
|
||||||
|
init-inference
|
||||||
|
nest-visitor
|
||||||
|
infer-quot-here
|
||||||
|
end-infer
|
||||||
|
callback-effect check-effect
|
||||||
|
stack-visitor get
|
||||||
|
] with-scope ;
|
||||||
|
|
||||||
: infer-alien-callback ( -- )
|
: infer-alien-callback ( -- )
|
||||||
alien-callback-params new
|
pop-literal nip [
|
||||||
pop-quot
|
alien-callback-params new
|
||||||
pop-abi
|
pop-abi
|
||||||
pop-params
|
pop-params
|
||||||
pop-return
|
pop-return
|
||||||
"( callback )" <uninterned-word> >>xt
|
dup callback-bottom
|
||||||
dup wrap-callback-quot >>quot
|
dup
|
||||||
dup callback-bottom
|
dup
|
||||||
|
] dip wrap-callback-quot infer-callback-quot
|
||||||
#alien-callback, ;
|
#alien-callback, ;
|
||||||
|
|
|
@ -473,3 +473,31 @@ FROM: splitting.private => split, ;
|
||||||
! M\ declared-effect infer-call* didn't properly unify branches
|
! M\ declared-effect infer-call* didn't properly unify branches
|
||||||
{ 1 0 } [ [ 1 [ drop ] [ drop ] if ] each ] must-infer-as
|
{ 1 0 } [ [ 1 [ drop ] [ drop ] if ] each ] must-infer-as
|
||||||
|
|
||||||
|
! Make sure alien-callback effects are checked properly
|
||||||
|
USING: alien.c-types alien ;
|
||||||
|
|
||||||
|
[ void { } cdecl [ ] alien-callback ] must-infer
|
||||||
|
|
||||||
|
[ [ void { } cdecl [ f [ drop ] unless ] alien-callback ] infer ] [ unbalanced-branches-error? ] must-fail-with
|
||||||
|
|
||||||
|
[ [ void { } cdecl [ drop ] alien-callback ] infer ] [ effect-error? ] must-fail-with
|
||||||
|
|
||||||
|
[ [ int { } cdecl [ ] alien-callback ] infer ] [ effect-error? ] must-fail-with
|
||||||
|
|
||||||
|
[ int { } cdecl [ 5 ] alien-callback ] must-infer
|
||||||
|
|
||||||
|
[ int { int } cdecl [ ] alien-callback ] must-infer
|
||||||
|
|
||||||
|
[ int { int } cdecl [ 1 + ] alien-callback ] must-infer
|
||||||
|
|
||||||
|
[ void { int } cdecl [ . ] alien-callback ] must-infer
|
||||||
|
|
||||||
|
: recursive-callback-1 ( -- x )
|
||||||
|
void { } cdecl [ recursive-callback-1 drop ] alien-callback ;
|
||||||
|
|
||||||
|
\ recursive-callback-1 def>> must-infer
|
||||||
|
|
||||||
|
: recursive-callback-2 ( -- x )
|
||||||
|
void { } cdecl [ recursive-callback-2 drop ] alien-callback ; inline recursive
|
||||||
|
|
||||||
|
[ recursive-callback-2 ] must-infer
|
||||||
|
|
|
@ -43,6 +43,9 @@ SYMBOL: literals
|
||||||
meta-d length "x" <array>
|
meta-d length "x" <array>
|
||||||
terminated? get <terminated-effect> ;
|
terminated? get <terminated-effect> ;
|
||||||
|
|
||||||
|
: check-effect ( required-effect -- )
|
||||||
|
[ current-effect ] dip 2dup effect<= [ 2drop ] [ effect-error ] if ;
|
||||||
|
|
||||||
: init-inference ( -- )
|
: init-inference ( -- )
|
||||||
terminated? off
|
terminated? off
|
||||||
V{ } clone \ meta-d set
|
V{ } clone \ meta-d set
|
||||||
|
|
|
@ -25,4 +25,4 @@ M: f #drop, drop ;
|
||||||
M: f #alien-invoke, drop ;
|
M: f #alien-invoke, drop ;
|
||||||
M: f #alien-indirect, drop ;
|
M: f #alien-indirect, drop ;
|
||||||
M: f #alien-assembly, drop ;
|
M: f #alien-assembly, drop ;
|
||||||
M: f #alien-callback, drop ;
|
M: f #alien-callback, 2drop ;
|
||||||
|
|
|
@ -30,4 +30,4 @@ HOOK: #copy, stack-visitor ( inputs outputs -- )
|
||||||
HOOK: #alien-invoke, stack-visitor ( params -- )
|
HOOK: #alien-invoke, stack-visitor ( params -- )
|
||||||
HOOK: #alien-indirect, stack-visitor ( params -- )
|
HOOK: #alien-indirect, stack-visitor ( params -- )
|
||||||
HOOK: #alien-assembly, stack-visitor ( params -- )
|
HOOK: #alien-assembly, stack-visitor ( params -- )
|
||||||
HOOK: #alien-callback, stack-visitor ( params -- )
|
HOOK: #alien-callback, stack-visitor ( params child -- )
|
||||||
|
|
|
@ -106,12 +106,12 @@ SYMBOL: callbacks
|
||||||
! returning from it, to avoid a bad interaction between threads
|
! returning from it, to avoid a bad interaction between threads
|
||||||
! and callbacks. See basis/compiler/tests/alien.factor for a
|
! and callbacks. See basis/compiler/tests/alien.factor for a
|
||||||
! test case.
|
! test case.
|
||||||
: wait-to-return ( yield-quot callback-id -- )
|
: wait-to-return ( yield-quot: ( -- ) callback-id -- )
|
||||||
dup current-callback eq?
|
dup current-callback eq?
|
||||||
[ 2drop ] [ over call( -- ) wait-to-return ] if ;
|
[ 2drop ] [ over call wait-to-return ] if ; inline recursive
|
||||||
|
|
||||||
! Used by compiler.codegen to wrap callback bodies
|
! Used by compiler.codegen to wrap callback bodies
|
||||||
: do-callback ( callback-quot yield-quot -- )
|
: do-callback ( callback-quot yield-quot: ( -- ) -- )
|
||||||
init-namespaces
|
init-namespaces
|
||||||
init-catchstack
|
init-catchstack
|
||||||
current-callback
|
current-callback
|
||||||
|
|
Loading…
Reference in New Issue