1 ! Copyright (C) 2004, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: threads kernel namespaces continuations combinators
4 sequences math namespaces.private continuations.private
5 concurrency.messaging quotations kernel.private words
6 sequences.private assocs models models.arrow arrays accessors
7 generic generic.standard definitions make sbufs
11 SYMBOL: show-walker-hook ! ( status continuation thread -- )
13 ! Thread local in thread being walked
16 ! Thread local in walker thread
17 SYMBOL: walking-thread
19 SYMBOL: walker-continuation
20 SYMBOL: walker-history
22 DEFER: start-walker-thread
24 : get-walker-thread ( -- status continuation thread )
26 [ variables>> walker-status swap at ]
27 [ variables>> walker-continuation swap at ]
32 2dup start-walker-thread
35 : walk ( quot -- quot' )
36 \ break prefix [ break rethrow ] recover ;
41 [ show-walker-hook get call ] keep
54 (step-into-continuation)
55 (step-into-call-next-method)
56 } [ t "no-compile" set-word-prop ] each >>
58 ! Messages sent to walker thread
72 : status ( -- symbol )
73 walker-status tget value>> ;
75 : set-status ( symbol -- )
76 walker-status tget set-model ;
79 +running+ set-status ;
81 : walker-stopped ( -- )
82 +stopped+ set-status ;
84 : step-into-all-loop ( -- )
86 [ status +running+ eq? ] [
93 { step-into-all [ f ] }
95 { f [ +stopped+ set-status f ] }
97 [ walker-continuation tget set-model ]
98 [ continuation-step-into ] bi
104 : continuation-step-back ( continuation -- continuation' )
107 [ [ nip pop ] unless-empty ] bi ;
109 : walker-suspended ( continuation -- continuation' )
110 +suspended+ set-status
111 [ status +suspended+ eq? ] [
112 dup walker-history tget push
113 dup walker-continuation tget set-model
116 ! These are sent by the walker tool. We reply
118 { step [ continuation-step keep-running ] }
119 { step-out [ continuation-step-out keep-running ] }
120 { step-into [ continuation-step-into keep-running ] }
121 { step-all [ keep-running ] }
122 { step-into-all [ step-into-all-loop ] }
123 { abandon [ drop f keep-running ] }
124 ! Pass quotation to debugged thread
125 { call-in [ keep-running ] }
126 ! Pass previous continuation to debugged thread
127 { step-back [ continuation-step-back ] }
134 [ status +stopped+ eq? ] [
137 ! ignore these commands while the thread is
143 { step-into-all [ step-into-all-loop f ] }
146 { f [ walker-stopped f ] }
147 ! thread hit a breakpoint and sent us the
148 ! continuation, so we modify it and send it
155 : associate-thread ( walker -- )
157 [ f walker-thread tget send-synchronous drop ]
158 self (>>exit-handler) ;
160 : start-walker-thread ( status continuation -- thread' )
163 walker-continuation tset
165 V{ } clone walker-history tset
168 "Walker on " self name>> append spawn
169 [ associate-thread ] keep ;