Refactoring recursive-state alist; now its a mapping from words to local state triples, reduces searching by a bit

db4
Slava Pestov 2008-11-12 19:08:40 -06:00
parent 8f6f666a2a
commit 4a1bcacfd4
7 changed files with 71 additions and 47 deletions

View File

@ -12,12 +12,13 @@ IN: compiler.tree.builder
: build-tree ( quot -- nodes )
#! Not safe to call from inference transforms.
[ f infer-quot ] with-tree-builder nip ;
[ f initial-recursive-state infer-quot ] with-tree-builder nip ;
: build-tree-with ( in-stack quot -- nodes out-stack )
#! Not safe to call from inference transforms.
[
[ >vector meta-d set ] [ f infer-quot ] bi*
[ >vector meta-d set ]
[ f initial-recursive-state infer-quot ] bi*
] with-tree-builder nip
unclip-last in-d>> ;
@ -32,10 +33,10 @@ IN: compiler.tree.builder
dup
[ "inline" word-prop ]
[ "recursive" word-prop ] bi and [
1quotation f infer-quot
1quotation f initial-recursive-state infer-quot
] [
[ specialized-def ]
[ dup 2array 1array ] bi infer-quot
[ specialized-def ] [ initial-recursive-state ] bi
infer-quot
] if ;
: check-cannot-infer ( word -- )

View File

@ -82,9 +82,6 @@ M: object apply-object push-literal ;
infer-quot-here
] dip recursive-state set ;
: infer-quot-recursive ( quot word label -- )
2array recursive-state get swap prefix infer-quot ;
: time-bomb ( error -- )
'[ _ throw ] infer-quot-here ;
@ -97,7 +94,7 @@ M: object apply-object push-literal ;
] [
dup value>> callable? [
[ value>> ]
[ [ recursion>> ] keep f 2array prefix ]
[ [ recursion>> ] keep add-local-quotation ]
bi infer-quot
] [
drop bad-call
@ -126,6 +123,9 @@ M: object apply-object push-literal ;
terminated?>> [ terminate ] when
] 2bi ; inline
: infer-word-def ( word -- )
[ def>> ] [ add-recursive-state ] bi infer-quot ;
: check->r ( -- )
meta-r get empty? terminated? get or
[ \ too-many->r inference-error ] unless ;
@ -174,7 +174,7 @@ M: object apply-object push-literal ;
stack-visitor off
dependencies off
generic-dependencies off
[ [ def>> ] [ ] [ ] tri infer-quot-recursive end-infer ]
[ infer-word-def end-infer ]
[ finish-word current-effect ]
bi
] with-scope

View File

@ -2,11 +2,9 @@
! See http://factorcode.org/license.txt for BSD license.
USING: kernel generic sequences prettyprint io words arrays
summary effects debugger assocs accessors namespaces
compiler.errors ;
compiler.errors stack-checker.state ;
IN: stack-checker.errors
SYMBOL: recursive-state
TUPLE: inference-error error type rstate ;
M: inference-error compiler-error-type type>> ;
@ -35,6 +33,8 @@ TUPLE: literal-expected ;
M: literal-expected summary
drop "Literal value expected" ;
M: object (literal) \ literal-expected inference-warning ;
TUPLE: unbalanced-branches-error branches quots ;
: unbalanced-branches-error ( branches quots -- * )

View File

@ -14,8 +14,8 @@ IN: stack-checker.inlining
! Code to handle inline words. Much of the complexity stems from
! having to handle recursive inline words.
: (inline-word) ( word label -- )
[ [ def>> ] keep ] dip infer-quot-recursive ;
: infer-inline-word-def ( word label -- )
[ drop def>> ] [ add-local-recursive-state ] 2bi infer-quot ;
TUPLE: inline-recursive < identity-tuple
id
@ -88,7 +88,7 @@ SYMBOL: enter-out
nest-visitor
dup <inline-recursive>
[ dup emit-enter-recursive (inline-word) ]
[ dup emit-enter-recursive infer-inline-word-def ]
[ end-recursive-word ]
[ nip ]
2tri
@ -133,20 +133,23 @@ SYMBOL: enter-out
object <repetition> '[ _ prepend ] bi@
<effect> ;
: call-recursive-inline-word ( word -- )
dup "recursive" word-prop [
[ required-stack-effect adjust-stack-effect ] [ ] [ recursive-label ] tri
[ 2nip check-call ] [ nip '[ _ #call-recursive, ] consume/produce ] 3bi
] [ undeclared-recursion-error inference-error ] if ;
: call-recursive-inline-word ( word label -- )
over "recursive" word-prop [
[ required-stack-effect adjust-stack-effect ] dip
[ check-call ] [ '[ _ #call-recursive, ] consume/produce ] bi
] [ drop undeclared-recursion-error inference-error ] if ;
: inline-word ( word -- )
[ inlined-dependency depends-on ]
[
{
{ [ dup inline-recursive-label ] [ call-recursive-inline-word ] }
{ [ dup "recursive" word-prop ] [ inline-recursive-word ] }
[ dup (inline-word) ]
} cond
dup inline-recursive-label [
call-recursive-inline-word
] [
dup "recursive" word-prop
[ inline-recursive-word ]
[ dup infer-inline-word-def ]
if
] if*
] bi ;
M: word apply-object

View File

@ -195,7 +195,7 @@ do-primitive alien-invoke alien-indirect alien-callback
{ [ dup local? ] [ infer-local-reader ] }
{ [ dup local-reader? ] [ infer-local-reader ] }
{ [ dup local-writer? ] [ infer-local-writer ] }
{ [ dup recursive-label ] [ call-recursive-word ] }
{ [ dup recursive-word? ] [ call-recursive-word ] }
[ dup infer-word apply-word/effect ]
} cond ;

View File

@ -1,10 +1,38 @@
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: assocs namespaces sequences kernel definitions math
effects accessors words fry classes.algebra stack-checker.errors
USING: assocs arrays namespaces sequences kernel definitions
math effects accessors words fry classes.algebra
compiler.units ;
IN: stack-checker.state
! Recursive state
SYMBOL: recursive-state
: initial-recursive-state ( word -- state )
{ } { } 3array 1array ; inline
f initial-recursive-state recursive-state set-global
: add-recursive-state ( word -- rstate )
[ recursive-state get ] dip { } { } 3array prefix ;
: add-local-quotation ( recursive-state quot -- rstate )
[ unclip first3 swap ] dip prefix swap 3array prefix ;
: add-local-recursive-state ( word label -- rstate )
[ recursive-state get ] 2dip
[ unclip first3 ] 2dip 2array prefix 3array prefix ;
: recursive-word? ( word -- ? )
recursive-state get key? ;
: inline-recursive-label ( word -- label/f )
recursive-state get first third at ;
: recursive-quotation? ( quot -- ? )
recursive-state get first second [ eq? ] with contains? ;
! Values
: <value> ( -- value ) \ <value> counter ;
SYMBOL: known-values
@ -29,9 +57,12 @@ TUPLE: literal < identity-tuple value recursion ;
: <literal> ( obj -- value )
recursive-state get \ literal boa ;
GENERIC: (literal) ( value -- literal )
M: literal (literal) ;
: literal ( value -- literal )
known dup literal?
[ \ literal-expected inference-warning ] unless ;
known (literal) ;
! Result of curry
TUPLE: curried obj quot ;
@ -71,20 +102,6 @@ SYMBOL: meta-r
: init-known-values ( -- )
H{ } clone known-values set ;
: recursive-label ( word -- label/f )
recursive-state get at ;
: local-recursive-state ( -- assoc )
recursive-state get dup
[ first dup word? [ inline? ] when not ] find drop
[ head-slice ] when* ;
: inline-recursive-label ( word -- label/f )
local-recursive-state at ;
: recursive-quotation? ( quot -- ? )
local-recursive-state [ first eq? ] with contains? ;
! Words that the current quotation depends on
SYMBOL: dependencies
@ -98,9 +115,12 @@ SYMBOL: dependencies
! Generic words that the current quotation depends on
SYMBOL: generic-dependencies
: ?class-or ( class/f class -- class' )
swap [ class-or ] when* ;
: depends-on-generic ( generic class -- )
generic-dependencies get dup
[ swap '[ null or _ class-or ] change-at ] [ 3drop ] if ;
[ swap '[ _ ?class-or ] change-at ] [ 3drop ] if ;
! Words we've inferred the stack effect of, for rollback
SYMBOL: recorded

View File

@ -9,7 +9,7 @@ stack-checker.errors ;
IN: stack-checker.transforms
: give-up-transform ( word -- )
dup recursive-label
dup recursive-word?
[ call-recursive-word ]
[ dup infer-word apply-word/effect ]
if ;