| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | ! Copyright (C) 2008 Slava Pestov. | 
					
						
							|  |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							|  |  |  | USING: fry namespaces assocs kernel sequences words accessors | 
					
						
							| 
									
										
										
										
											2008-08-15 00:35:19 -04:00
										 |  |  | definitions math math.order effects classes arrays combinators | 
					
						
							|  |  |  | vectors arrays | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | stack-checker.state | 
					
						
							| 
									
										
										
										
											2008-11-13 01:07:45 -05:00
										 |  |  | stack-checker.errors | 
					
						
							|  |  |  | stack-checker.values | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | stack-checker.visitor | 
					
						
							|  |  |  | stack-checker.backend | 
					
						
							|  |  |  | stack-checker.branches | 
					
						
							| 
									
										
										
										
											2008-11-13 01:07:45 -05:00
										 |  |  | stack-checker.known-words | 
					
						
							|  |  |  | stack-checker.recursive-state ;
 | 
					
						
							| 
									
										
										
										
											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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-12 20:08:40 -05:00
										 |  |  | : infer-inline-word-def ( word label -- )
 | 
					
						
							| 
									
										
										
										
											2008-11-13 01:07:45 -05:00
										 |  |  |     [ drop 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 | 
					
						
							| 
									
										
										
										
											2008-08-07 02:08:11 -04:00
										 |  |  | word | 
					
						
							|  |  |  | enter-out enter-recursive | 
					
						
							|  |  |  | return calls | 
					
						
							|  |  |  | fixed-point | 
					
						
							| 
									
										
										
										
											2008-08-10 02:58:39 -04:00
										 |  |  | introductions | 
					
						
							|  |  |  | loop? ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: inline-recursive hashcode* id>> hashcode* ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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' )
 | 
					
						
							| 
									
										
										
										
											2008-08-15 05:09:23 -04:00
										 |  |  |     [ length cut* ] keep
 | 
					
						
							|  |  |  |     [ quotation-param? [ copy-value ] [ drop <value> ] if ] 2map
 | 
					
						
							| 
									
										
										
										
											2008-08-15 22:45:05 -04:00
										 |  |  |     [ 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 -- )
 | 
					
						
							| 
									
										
										
										
											2008-08-15 05:09:23 -04:00
										 |  |  |     required-stack-effect in>> | 
					
						
							|  |  |  |     [ length ensure-d drop ] [ | 
					
						
							|  |  |  |         meta-d get clone enter-in set
 | 
					
						
							|  |  |  |         meta-d get 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
										 |  |  | 
 | 
					
						
							|  |  |  | : check-return ( word label -- )
 | 
					
						
							|  |  |  |     2dup
 | 
					
						
							|  |  |  |     [ stack-effect effect-height ] | 
					
						
							|  |  |  |     [ entry-stack-height current-stack-height swap - ] | 
					
						
							|  |  |  |     bi*
 | 
					
						
							|  |  |  |     = [ 2drop ] [ | 
					
						
							| 
									
										
										
										
											2008-08-28 23:28:34 -04:00
										 |  |  |         terminated? get [ 2drop ] [ | 
					
						
							|  |  |  |             word>> current-stack-height | 
					
						
							|  |  |  |             unbalanced-recursion-error inference-error | 
					
						
							|  |  |  |         ] if
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : end-recursive-word ( word label -- )
 | 
					
						
							|  |  |  |     [ check-return ] | 
					
						
							| 
									
										
										
										
											2008-07-27 03:32:40 -04:00
										 |  |  |     [ meta-d get 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 d-in get + ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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> | 
					
						
							| 
									
										
										
										
											2008-11-12 20:08:40 -05:00
										 |  |  |         [ dup emit-enter-recursive infer-inline-word-def ] | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  |         [ end-recursive-word ] | 
					
						
							| 
									
										
										
										
											2008-08-15 05:09:23 -04:00
										 |  |  |         [ nip ] | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  |         2tri
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         check->r | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         dup recursive-word-inputs | 
					
						
							|  |  |  |         meta-d get
 | 
					
						
							| 
									
										
										
										
											2008-07-24 00:50:21 -04:00
										 |  |  |         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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-15 05:09:23 -04:00
										 |  |  | : check-call-height ( label -- )
 | 
					
						
							|  |  |  |     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-08-15 05:09:23 -04:00
										 |  |  |     meta-d get trim-stack ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : trimmed-enter-out ( label -- stack )
 | 
					
						
							|  |  |  |     dup enter-out>> trim-stack ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-15 05:09:23 -04:00
										 |  |  | : check-call-site-stack ( label -- )
 | 
					
						
							|  |  |  |     [ ] [ call-site-stack ] [ trimmed-enter-out ] tri
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  |     [ dup known [ [ known ] bi@ = ] [ 2drop t ] if ] 2all?
 | 
					
						
							|  |  |  |     [ drop ] [ word>> inconsistent-recursive-call-error inference-error ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-15 05:09:23 -04:00
										 |  |  | : 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-08-15 22:45:05 -04:00
										 |  |  |     meta-d get length pick length [-] | 
					
						
							| 
									
										
										
										
											2008-09-10 23:11:40 -04:00
										 |  |  |     object <repetition> '[ _ prepend ] bi@
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  |     <effect> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-11-12 20:08:40 -05:00
										 |  |  | : 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 ;
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : inline-word ( word -- )
 | 
					
						
							| 
									
										
										
										
											2008-08-30 03:31:27 -04:00
										 |  |  |     [ inlined-dependency depends-on ] | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  |     [ | 
					
						
							| 
									
										
										
										
											2008-11-12 20:08:40 -05:00
										 |  |  |         dup inline-recursive-label [ | 
					
						
							|  |  |  |             call-recursive-inline-word | 
					
						
							|  |  |  |         ] [ | 
					
						
							|  |  |  |             dup "recursive" word-prop | 
					
						
							|  |  |  |             [ inline-recursive-word ] | 
					
						
							|  |  |  |             [ dup infer-inline-word-def ] | 
					
						
							|  |  |  |             if
 | 
					
						
							|  |  |  |         ] if*
 | 
					
						
							| 
									
										
										
										
											2008-07-20 05:24:37 -04:00
										 |  |  |     ] bi ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: word apply-object | 
					
						
							|  |  |  |     dup inline? [ inline-word ] [ non-inline-word ] if ;
 |