factor/basis/stack-checker/inlining/inlining.factor

159 lines
4.4 KiB
Factor
Raw Normal View History

2010-01-14 10:10:13 -05:00
! Copyright (C) 2008, 2010 Slava Pestov.
2008-07-20 05:24:37 -04:00
! See http://factorcode.org/license.txt for BSD license.
2016-03-27 13:01:56 -04:00
USING: accessors arrays effects fry hints kernel locals math
math.order namespaces sequences stack-checker.backend
2015-07-31 23:41:46 -04:00
stack-checker.dependencies stack-checker.errors
stack-checker.known-words stack-checker.recursive-state
stack-checker.state stack-checker.values stack-checker.visitor
vectors words ;
2008-07-20 05:24:37 -04:00
IN: stack-checker.inlining
! Code to handle inline words. Much of the complexity stems from
! having to handle recursive inline words.
: infer-inline-word-def ( word label -- )
[ drop specialized-def ] [ add-inline-word ] 2bi infer-quot ;
2008-07-20 05:24:37 -04:00
2008-08-10 02:58:39 -04:00
TUPLE: inline-recursive < identity-tuple
id
word
enter-out enter-recursive
return calls
fixed-point
2008-08-10 02:58:39 -04:00
introductions
loop? ;
2008-08-12 00:30:18 -04:00
: inlined-block? ( word -- ? ) "inlined-block" word-prop ;
2008-07-20 05:24:37 -04:00
: <inline-recursive> ( word -- label )
2008-08-10 02:58:39 -04:00
inline-recursive new
2008-08-12 03:41:18 -04:00
gensym dup t "inlined-block" set-word-prop >>id
2008-08-10 02:58:39 -04:00
swap >>word ;
2008-07-20 05:24:37 -04:00
: quotation-param? ( obj -- ? )
dup pair? [ second effect? ] [ drop f ] if ;
: make-copies ( values effect-in -- values' )
[ length cut* ] keep
[ quotation-param? [ copy-value ] [ drop <value> ] if ] 2map
2010-01-14 10:10:13 -05:00
[ length make-values ] dip append ;
2008-07-20 05:24:37 -04:00
2008-07-27 03:32:40 -04:00
SYMBOL: enter-in
SYMBOL: enter-out
2008-07-20 05:24:37 -04:00
: prepare-stack ( word -- )
required-stack-effect in>>
[ length ensure-d drop ] [
2008-12-04 07:02:49 -05:00
meta-d clone enter-in set
meta-d swap make-copies enter-out set
] bi ;
2008-07-20 05:24:37 -04:00
2008-07-27 03:32:40 -04:00
: emit-enter-recursive ( label -- )
enter-out get >>enter-out
enter-in get enter-out get #enter-recursive,
enter-out get >vector (meta-d) set ;
2008-07-20 05:24:37 -04:00
: entry-stack-height ( label -- stack )
2008-07-27 03:32:40 -04:00
enter-out>> length ;
2008-07-20 05:24:37 -04:00
2016-03-27 13:01:56 -04:00
:: check-return ( word label -- )
word stack-height
current-stack-height label entry-stack-height -
= [
terminated? get [
label word>> current-stack-height
2008-08-28 23:28:34 -04:00
unbalanced-recursion-error inference-error
2016-03-27 13:01:56 -04:00
] unless
] unless ;
2008-07-20 05:24:37 -04:00
: end-recursive-word ( word label -- )
[ check-return ]
[ meta-d dup copy-values dup (meta-d) set #return-recursive, ]
2008-07-20 05:24:37 -04:00
bi ;
: recursive-word-inputs ( label -- n )
entry-stack-height input-count get + ;
2008-07-20 05:24:37 -04:00
2008-08-28 23:28:34 -04:00
: (inline-recursive-word) ( word -- label in out visitor terminated? )
2008-07-20 05:24:37 -04:00
dup prepare-stack
[
init-inference
nest-visitor
dup <inline-recursive>
[ dup emit-enter-recursive infer-inline-word-def ]
2008-07-20 05:24:37 -04:00
[ end-recursive-word ]
[ nip ]
2008-07-20 05:24:37 -04:00
2tri
dup recursive-word-inputs
2008-12-04 07:02:49 -05:00
meta-d
stack-visitor get
2008-08-28 23:28:34 -04:00
terminated? get
2008-07-20 05:24:37 -04:00
] with-scope ;
: inline-recursive-word ( word -- )
(inline-recursive-word)
2008-08-28 23:28:34 -04:00
[ [ consume-d ] [ output-d ] [ ] tri* #recursive, ] dip
[ terminate ] when ;
2008-07-20 05:24:37 -04:00
: check-call-height ( label -- )
2015-07-31 23:41:46 -04:00
dup entry-stack-height current-stack-height > [
word>> diverging-recursion-error inference-error
] [ drop ] if ;
: trim-stack ( label seq -- stack )
swap word>> required-stack-effect in>> length tail* ;
2008-07-20 05:24:37 -04:00
: call-site-stack ( label -- stack )
2008-12-04 07:02:49 -05:00
meta-d trim-stack ;
: trimmed-enter-out ( label -- stack )
dup enter-out>> trim-stack ;
2008-07-20 05:24:37 -04:00
GENERIC: (undeclared-known) ( value -- known )
M: object (undeclared-known) ;
M: declared-effect (undeclared-known) known>> (undeclared-known) ;
: undeclared-known ( value -- known ) known (undeclared-known) ;
: check-call-site-stack ( label -- )
[ ] [ call-site-stack ] [ trimmed-enter-out ] tri
2012-07-21 13:22:44 -04:00
[ dup undeclared-known [ [ undeclared-known ] same? ] [ 2drop t ] if ] 2all?
2008-07-20 05:24:37 -04:00
[ drop ] [ word>> inconsistent-recursive-call-error inference-error ] if ;
: check-call ( label -- )
[ check-call-height ] [ check-call-site-stack ] bi ;
2008-07-20 05:24:37 -04:00
: adjust-stack-effect ( effect -- effect' )
[ in>> ] [ out>> ] bi
2008-12-04 07:02:49 -05:00
meta-d length pick length [-]
2008-09-10 23:11:40 -04:00
object <repetition> '[ _ prepend ] bi@
2008-07-20 05:24:37 -04:00
<effect> ;
: call-recursive-inline-word ( word label -- )
2016-03-27 13:01:56 -04:00
over recursive? [
[ required-stack-effect adjust-stack-effect ] dip
[ check-call ] [ '[ _ #call-recursive, ] consume/produce ] bi
2016-03-27 13:01:56 -04:00
] [
drop undeclared-recursion-error inference-error
] if ;
2008-07-20 05:24:37 -04:00
: inline-word ( word -- )
2008-12-04 07:02:49 -05:00
commit-literals
[ +definition+ depends-on ]
[ declare-input-effects ]
2008-07-20 05:24:37 -04:00
[
dup inline-recursive-label [
call-recursive-inline-word
] [
2016-03-27 13:01:56 -04:00
dup recursive?
[ inline-recursive-word ]
[ dup infer-inline-word-def ]
if
] if*
] tri ;
2008-07-20 05:24:37 -04:00
M: word apply-object
dup inline? [ inline-word ] [ non-inline-word ] if ;