Cleaning up and debugging corss-referencing
parent
460ce213af
commit
014d2ea31c
|
@ -35,7 +35,7 @@ IN: compiler
|
|||
[ swap save-effect ]
|
||||
[ compiled-unxref ]
|
||||
[
|
||||
dup compiled-crossref?
|
||||
dup crossref?
|
||||
[ dependencies get compiled-xref ] [ drop ] if
|
||||
] tri ;
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ GENERIC: definitions-changed ( assoc obj -- )
|
|||
|
||||
: compile ( words -- )
|
||||
recompile-hook get call
|
||||
dup [ drop compiled-crossref? ] assoc-contains?
|
||||
dup [ drop crossref? ] assoc-contains?
|
||||
modify-code-heap ;
|
||||
|
||||
SYMBOL: outdated-tuples
|
||||
|
@ -82,7 +82,7 @@ SYMBOL: update-tuples-hook
|
|||
: finish-compilation-unit ( -- )
|
||||
call-recompile-hook
|
||||
call-update-tuples-hook
|
||||
dup [ drop compiled-crossref? ] assoc-contains? modify-code-heap
|
||||
dup [ drop crossref? ] assoc-contains? modify-code-heap
|
||||
;
|
||||
|
||||
: with-nested-compilation-unit ( quot -- )
|
||||
|
|
|
@ -47,7 +47,17 @@ M: object uses drop f ;
|
|||
|
||||
: xref ( defspec -- ) dup uses crossref get add-vertex ;
|
||||
|
||||
: usage ( defspec -- seq ) \ f or crossref get at keys ;
|
||||
: usage ( defspec -- seq ) crossref get at keys ;
|
||||
|
||||
GENERIC: irrelevant? ( defspec -- ? )
|
||||
|
||||
M: object irrelevant? drop f ;
|
||||
|
||||
GENERIC: smart-usage ( defspec -- seq )
|
||||
|
||||
M: f smart-usage drop \ f smart-usage ;
|
||||
|
||||
M: object smart-usage usage [ irrelevant? not ] filter ;
|
||||
|
||||
: unxref ( defspec -- )
|
||||
dup uses crossref get remove-vertex ;
|
||||
|
|
|
@ -117,6 +117,9 @@ M: method-spec definition
|
|||
M: method-spec forget*
|
||||
first2 method forget* ;
|
||||
|
||||
M: method-spec smart-usage
|
||||
second smart-usage ;
|
||||
|
||||
M: method-body definer
|
||||
drop \ M: \ ; ;
|
||||
|
||||
|
@ -134,6 +137,9 @@ M: method-body forget*
|
|||
[ t "forgotten" set-word-prop ] bi
|
||||
] if ;
|
||||
|
||||
M: method-body smart-usage
|
||||
"method-generic" word-prop smart-usage ;
|
||||
|
||||
: implementors* ( classes -- words )
|
||||
all-words [
|
||||
"methods" word-prop keys
|
||||
|
|
|
@ -4,7 +4,7 @@ USING: kernel classes.tuple.private hashtables assocs sorting
|
|||
accessors combinators sequences slots.private math.parser words
|
||||
effects namespaces generic generic.standard.engines
|
||||
classes.algebra math math.private kernel.private
|
||||
quotations arrays ;
|
||||
quotations arrays definitions ;
|
||||
IN: generic.standard.engines.tuple
|
||||
|
||||
TUPLE: echelon-dispatch-engine n methods ;
|
||||
|
@ -64,8 +64,9 @@ M: engine-word stack-effect
|
|||
[ extra-values ] [ stack-effect ] bi
|
||||
dup [ clone [ length + ] change-in ] [ 2drop f ] if ;
|
||||
|
||||
M: engine-word compiled-crossref?
|
||||
drop t ;
|
||||
M: engine-word crossref? drop t ;
|
||||
|
||||
M: engine-word irrelevant? drop t ;
|
||||
|
||||
: remember-engine ( word -- )
|
||||
generic get "engines" word-prop push ;
|
||||
|
|
|
@ -3,7 +3,8 @@ USING: tools.test math math.functions math.constants
|
|||
generic.standard strings sequences arrays kernel accessors
|
||||
words float-arrays byte-arrays bit-arrays parser namespaces
|
||||
quotations inference vectors growable hashtables sbufs
|
||||
prettyprint byte-vectors bit-vectors float-vectors ;
|
||||
prettyprint byte-vectors bit-vectors float-vectors definitions
|
||||
generic sets graphs assocs ;
|
||||
|
||||
GENERIC: lo-tag-test
|
||||
|
||||
|
@ -287,3 +288,24 @@ M: sbuf no-stack-effect-decl ;
|
|||
[ ] [ \ no-stack-effect-decl see ] unit-test
|
||||
|
||||
[ ] [ \ no-stack-effect-decl word-def . ] unit-test
|
||||
|
||||
! Cross-referencing with generic words
|
||||
TUPLE: xref-tuple-1 ;
|
||||
TUPLE: xref-tuple-2 < xref-tuple-1 ;
|
||||
|
||||
: (xref-test) drop ;
|
||||
|
||||
GENERIC: xref-test ( obj -- )
|
||||
|
||||
M: xref-tuple-1 xref-test (xref-test) ;
|
||||
M: xref-tuple-2 xref-test (xref-test) ;
|
||||
|
||||
[ t ] [
|
||||
\ xref-test
|
||||
\ xref-tuple-1 \ xref-test method [ usage unique ] closure key?
|
||||
] unit-test
|
||||
|
||||
[ t ] [
|
||||
\ xref-test
|
||||
\ xref-tuple-2 \ xref-test method [ usage unique ] closure key?
|
||||
] unit-test
|
||||
|
|
|
@ -4,7 +4,7 @@ USING: inference.dataflow inference.state arrays generic io
|
|||
io.streams.string kernel math namespaces parser prettyprint
|
||||
sequences strings vectors words quotations effects classes
|
||||
continuations debugger assocs combinators compiler.errors
|
||||
generic.standard.engines.tuple accessors math.order ;
|
||||
generic.standard.engines.tuple accessors math.order definitions ;
|
||||
IN: inference.backend
|
||||
|
||||
: recursive-label ( word -- label/f )
|
||||
|
@ -21,6 +21,28 @@ M: engine-word inline?
|
|||
M: word inline?
|
||||
"inline" word-prop ;
|
||||
|
||||
SYMBOL: visited
|
||||
|
||||
: reset-on-redefine { "inferred-effect" "no-effect" } ; inline
|
||||
|
||||
: (redefined) ( word -- )
|
||||
dup visited get key? [ drop ] [
|
||||
[ reset-on-redefine reset-props ]
|
||||
[ dup visited get set-at ]
|
||||
[
|
||||
crossref get at keys
|
||||
[ word? ] filter
|
||||
[
|
||||
[ reset-on-redefine [ word-prop ] with contains? ]
|
||||
[ inline? ]
|
||||
bi or
|
||||
] filter
|
||||
[ (redefined) ] each
|
||||
] tri
|
||||
] if ;
|
||||
|
||||
M: word redefined H{ } clone visited [ (redefined) ] with-variable ;
|
||||
|
||||
: local-recursive-state ( -- assoc )
|
||||
recursive-state get dup keys
|
||||
[ dup word? [ inline? ] when not ] find drop
|
||||
|
|
|
@ -549,10 +549,34 @@ ERROR: custom-error ;
|
|||
{ 1 0 } [ [ ] map-children ] must-infer-as
|
||||
|
||||
! Corner case
|
||||
! [ [ [ f dup ] [ dup ] [ ] unfold ] infer ] must-fail
|
||||
[ [ [ f dup ] [ dup ] [ ] unfold ] infer ] must-fail
|
||||
|
||||
! [ [ [ f dup ] [ ] [ ] while ] infer ] must-fail
|
||||
[ [ [ f dup ] [ ] [ ] while ] infer ] must-fail
|
||||
|
||||
! : erg's-inference-bug ( -- ) f dup [ erg's-inference-bug ] when ; inline
|
||||
: erg's-inference-bug ( -- ) f dup [ erg's-inference-bug ] when ; inline
|
||||
|
||||
! [ [ erg's-inference-bug ] infer ] must-fail
|
||||
[ [ erg's-inference-bug ] infer ] must-fail
|
||||
|
||||
: inference-invalidation-a ;
|
||||
: inference-invalidation-b [ inference-invalidation-a ] dip call ; inline
|
||||
: inference-invalidation-c [ + ] inference-invalidation-b ;
|
||||
|
||||
[ 7 ] [ 4 3 inference-invalidation-c ] unit-test
|
||||
|
||||
{ 2 1 } [ inference-invalidation-c ] must-infer-as
|
||||
|
||||
[ ] [ "IN: inference.tests : inference-invalidation-a 1 2 ;" eval ] unit-test
|
||||
|
||||
[ 3 ] [ inference-invalidation-c ] unit-test
|
||||
|
||||
{ 0 1 } [ inference-invalidation-c ] must-infer-as
|
||||
|
||||
GENERIC: inference-invalidation-d ( obj -- )
|
||||
|
||||
M: object inference-invalidation-d inference-invalidation-c 2drop ;
|
||||
|
||||
\ inference-invalidation-d must-infer
|
||||
|
||||
[ ] [ "IN: inference.tests : inference-invalidation-a ;" eval ] unit-test
|
||||
|
||||
[ [ inference-invalidation-d ] infer ] must-fail
|
||||
|
|
|
@ -102,7 +102,7 @@ SYMBOL: compiled-crossref
|
|||
compiled-crossref global [ H{ } assoc-like ] change-at
|
||||
|
||||
: compiled-xref ( word dependencies -- )
|
||||
[ drop compiled-crossref? ] assoc-filter
|
||||
[ drop crossref? ] assoc-filter
|
||||
2dup "compiled-uses" set-word-prop
|
||||
compiled-crossref get add-vertex* ;
|
||||
|
||||
|
@ -125,28 +125,9 @@ SYMBOL: +called+
|
|||
compiled-usage [ nip +inlined+ eq? ] assoc-filter update
|
||||
] with each keys ;
|
||||
|
||||
<PRIVATE
|
||||
GENERIC: redefined ( word -- )
|
||||
|
||||
SYMBOL: visited
|
||||
|
||||
: reset-on-redefine { "inferred-effect" "no-effect" } ; inline
|
||||
|
||||
: (redefined) ( word -- )
|
||||
dup visited get key? [ drop ] [
|
||||
[ reset-on-redefine reset-props ]
|
||||
[ dup visited get set-at ]
|
||||
[
|
||||
crossref get at keys
|
||||
[ word? ] filter
|
||||
[ reset-on-redefine [ word-prop ] with contains? ] filter
|
||||
[ (redefined) ] each
|
||||
] tri
|
||||
] if ;
|
||||
|
||||
PRIVATE>
|
||||
|
||||
: redefined ( word -- )
|
||||
H{ } clone visited [ (redefined) ] with-variable ;
|
||||
M: object redefined drop ;
|
||||
|
||||
: define ( word def -- )
|
||||
[ ] like
|
||||
|
|
|
@ -53,7 +53,7 @@ M: object find-parse-error
|
|||
|
||||
: fix ( word -- )
|
||||
[ "Fixing " write pprint " and all usages..." print nl ]
|
||||
[ [ usage ] keep prefix ] bi
|
||||
[ [ smart-usage ] keep prefix ] bi
|
||||
[
|
||||
[ "Editing " write . ]
|
||||
[
|
||||
|
|
|
@ -7,7 +7,7 @@ sorting hashtables vocabs parser source-files ;
|
|||
IN: tools.crossref
|
||||
|
||||
: usage. ( word -- )
|
||||
usage sorted-definitions. ;
|
||||
smart-usage sorted-definitions. ;
|
||||
|
||||
: words-matching ( str -- seq )
|
||||
all-words [ dup word-name ] { } map>assoc completions ;
|
||||
|
|
|
@ -44,7 +44,7 @@ HELP: vocab-profile.
|
|||
HELP: usage-profile.
|
||||
{ $values { "word" word } }
|
||||
{ $description "Prints a table of call counts from the most recent invocation of " { $link profile } ", for words which directly call " { $snippet "word" } " only." }
|
||||
{ $notes "This word obtains the list of static usages with the " { $link usage } " word, and is not aware of dynamic call history. Consider the following scenario. A word " { $snippet "X" } " can execute word " { $snippet "Y" } " in a conditional branch, and " { $snippet "X" } " is executed many times during the profiling run, but this particular branch executing " { $snippet "Y" } " is never taken. However, some other word does execute " { $snippet "Y" } " multiple times. Then " { $snippet "\\ Y usage-profile." } " will list a number of calls to " { $snippet "X" } ", even though " { $snippet "Y" } " was never executed " { $emphasis "from" } " " { $snippet "X" } "." }
|
||||
{ $notes "This word obtains the list of static usages with the " { $link smart-usage } " word, and is not aware of dynamic call history. Consider the following scenario. A word " { $snippet "X" } " can execute word " { $snippet "Y" } " in a conditional branch, and " { $snippet "X" } " is executed many times during the profiling run, but this particular branch executing " { $snippet "Y" } " is never taken. However, some other word does execute " { $snippet "Y" } " multiple times. Then " { $snippet "\\ Y usage-profile." } " will list a number of calls to " { $snippet "X" } ", even though " { $snippet "Y" } " was never executed " { $emphasis "from" } " " { $snippet "X" } "." }
|
||||
{ $examples { $code "\\ + usage-profile." } } ;
|
||||
|
||||
HELP: vocabs-profile.
|
||||
|
|
|
@ -58,7 +58,7 @@ M: method-body (profile.)
|
|||
"Call counts for words which call " write
|
||||
dup pprint
|
||||
":" print
|
||||
usage [ word? ] filter counters counters. ;
|
||||
smart-usage [ word? ] filter counters counters. ;
|
||||
|
||||
: vocabs-profile. ( -- )
|
||||
"Call counts for all vocabularies:" print
|
||||
|
|
|
@ -94,7 +94,7 @@ M: live-search pref-dim* drop { 400 200 } ;
|
|||
"Words in " rot vocab-name append show-titled-popup ;
|
||||
|
||||
: show-word-usage ( workspace word -- )
|
||||
"" over usage f <definition-search>
|
||||
"" over smart-usage f <definition-search>
|
||||
"Words and methods using " rot word-name append
|
||||
show-titled-popup ;
|
||||
|
||||
|
|
Loading…
Reference in New Issue