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
46 ! Messages sent to walker thread
60 : status ( -- symbol )
61 walker-status tget value>> ;
63 : set-status ( symbol -- )
64 walker-status tget set-model ;
67 +running+ set-status ;
69 : walker-stopped ( -- )
70 +stopped+ set-status ;
72 : step-into-all-loop ( -- )
74 [ status +running+ eq? ] [
81 { step-into-all [ f ] }
83 { f [ +stopped+ set-status f ] }
85 [ walker-continuation tget set-model ]
86 [ continuation-step-into ] bi
92 : continuation-step-back ( continuation -- continuation' )
95 [ [ nip pop ] unless-empty ] bi ;
97 : walker-suspended ( continuation -- continuation' )
98 +suspended+ set-status
99 [ status +suspended+ eq? ] [
100 dup walker-history tget push
101 dup walker-continuation tget set-model
104 ! These are sent by the walker tool. We reply
106 { step [ continuation-step keep-running ] }
107 { step-out [ continuation-step-out keep-running ] }
108 { step-into [ continuation-step-into keep-running ] }
109 { step-all [ keep-running ] }
110 { step-into-all [ step-into-all-loop ] }
111 { abandon [ drop f keep-running ] }
112 ! Pass quotation to debugged thread
113 { call-in [ keep-running ] }
114 ! Pass previous continuation to debugged thread
115 { step-back [ continuation-step-back ] }
122 [ status +stopped+ eq? ] [
125 ! ignore these commands while the thread is
131 { step-into-all [ step-into-all-loop f ] }
134 { f [ walker-stopped f ] }
135 ! thread hit a breakpoint and sent us the
136 ! continuation, so we modify it and send it
143 : associate-thread ( walker -- )
145 [ f walker-thread tget send-synchronous drop ]
146 self (>>exit-handler) ;
148 : start-walker-thread ( status continuation -- thread' )
151 walker-continuation tset
153 V{ } clone walker-history tset
156 "Walker on " self name>> append spawn
157 [ associate-thread ] keep ;