Dynamic winder is always a headache. It doesn't matter in which situation. For the composable continuation, it's not an exception at all.
For example the below script
(define saved #f)
(define count 0)
(call/prompt
(lambda ()
(dynamic-wind
(lambda () (display "pre1\n"))
(lambda ()
(call/prompt
(lambda ()
(dynamic-wind
(lambda () (display "pre2\n"))
(lambda () #t)
(lambda ()
(call/comp (lambda (k) (set! saved k) ))
(display "post2\n"))))))
(lambda () (display "post1\n")))
(unless (= count 1)
(set! count (+ count 1))
(saved 'again))))
This results like this
pre1
pre2
post2
post1
post2
And if I swap call/comp with call/cc then it'd print this
pre1
pre2
post2
post1
pre1
post2
post1
The second post2 is wrapped with pre1 and post1 which are the
winders of the outer dynamic-wind.
If I see how it's written, it makes sense. The captured continuation is in the second prompt, so it shouldn't invoke the outer prompt winders. It makes sense, that doesn't mean it's easy to achieve.
Prompt as winder boundary
The winders are basically chains managed on VM. At the deepest location of the above example, the winder looks like this
[pre2 . post2] - [pre1 . post1] - [... system winders]
^^^
prompt
The prompt is in between the first and the second winders. So, when the composable continuation is captured, then it only considers the first winder.
Though, if I replace only the first winder but without the rest of
the [... system winders], then it'd cause a problem. So, it has to
have some sort of filtering.
Filtering winders
One of the easiest filtering is that if the captured continuation is partial a.k.a composable, then no before thunk is needed. I'm not entirely sure if this assumption is actually correct, but it seems working. So, keep it like that...
Then the next one is that comparing the current winders and capture winders.
Captured:
[pre2 . post2] - [pre1 . post1] - [... system winders]
^^^
prompt
Current:
[... system winders]
After exiting from the both dynamic-winds, then the current
winders contains only the [... system winders] for the above
example. So, it should take up until the prompt, then append
the current winder.
Again, I'm not sure if the current implementation is correct, but it's working. So, I'm fine for now until I find a bug...