diff --git a/pkgs/racket-test-core/tests/racket/prompt-tests.rktl b/pkgs/racket-test-core/tests/racket/prompt-tests.rktl index cc2d0f1d1c..3b840f6209 100644 --- a/pkgs/racket-test-core/tests/racket/prompt-tests.rktl +++ b/pkgs/racket-test-core/tests/racket/prompt-tests.rktl @@ -1475,10 +1475,12 @@ [exit-k #f]) (let ([go (lambda (launch) - (let ([k (let/cc esc - (call-with-continuation-prompt - (lambda () - (dynamic-wind + (let ([k (call-with-continuation-barrier + (lambda () + (let/cc esc + (call-with-continuation-prompt + (lambda () + (dynamic-wind (lambda () (void)) (lambda () (with-handlers ([void (lambda (exn) @@ -1491,13 +1493,11 @@ (lambda () 10)) p1)) (set! output (cons 'post output))))) - p1))]) - (call-with-continuation-barrier + p1))))]) + (call-with-continuation-prompt (lambda () - (call-with-continuation-prompt - (lambda () - (exit-k (lambda () 'hi))) - p1)))))]) + (exit-k (lambda () 'hi))) + p1)))]) (err/rt-test (go (lambda (esc) (esc 'middle))) exn:fail:contract:continuation?) @@ -1513,48 +1513,53 @@ exn:fail:contract:continuation?)) (test '(post post post post) values output))) -;; Similar, but more checking of dropped d-ws: +;; Similar, but not a barrier error, because the jump +;; just escapes past a barrier instead of jumping into +;; one (let ([p1 (make-continuation-prompt-tag 'p1)] [output null] [exit-k #f] - [done? #f]) - ;; Capture a continuation w.r.t. the default prompt tag: - (call/cc - (lambda (esc) - (dynamic-wind - (lambda () (void)) - (lambda () - ;; Set a prompt for tag p1: - (call-with-continuation-prompt - (lambda () - (dynamic-wind - (lambda () (void)) - ;; inside d-w, jump out: - (lambda () (esc 'done)) - (lambda () - ;; As we jump out, capture a continuation - ;; w.r.t. p1: - ((call/cc - (lambda (k) - (set! exit-k k) - (lambda () 10)) - p1)) - (set! output (cons 'inner output))))) - p1)) - (lambda () - ;; This post thunk is not in the - ;; delimited continuation captured - ;; via tag p1: - (set! output (cons 'outer output)))))) - (unless done? - (set! done? #t) - ;; Now invoke the delimited continuation, which must - ;; somehow continue the jump to `esc': - (call-with-continuation-prompt - (lambda () - (exit-k (lambda () 10))) - p1)) - (test '(inner outer inner) values output)) + [count 3]) + (let ([go + (lambda (launch) + (let ([k (let/cc esc + (call-with-continuation-prompt + (lambda () + (dynamic-wind + (lambda () (void)) + (lambda () + (with-handlers ([void (lambda (exn) + (test #f "should not be used!" #t))]) + (launch esc))) + (lambda () + ((call/cc + (lambda (k) + (set! exit-k k) + (lambda () 10)) + p1)) + (set! output (cons 'post output))))) + p1))]) + (cond + [(zero? count) 'three] + [else + (set! count (sub1 count)) + (call-with-continuation-barrier + (lambda () + (call-with-continuation-prompt + (lambda () + (exit-k (lambda () 'hi))) + p1)))])))]) + (test 'three go (lambda (esc) (esc 'middle))) + (test '(post post post post) values output) + (let ([meta (call-with-continuation-prompt + (lambda () + ((call-with-composable-continuation + (lambda (k) (lambda () k))))))]) + (test 'three + go (lambda (esc) + (meta + (lambda () (esc 'ok)))))) + (test '(post post post post post) values output))) ;; Again, more checking of output (let ([p1 (make-continuation-prompt-tag 'p1)] @@ -2014,14 +2019,24 @@ (k (lambda () 17))) (test #t procedure? once-k) (test k values 17) - (err/rt-test (call-with-continuation-barrier - (lambda () - (once-k 18))) - exn:fail:contract:continuation?)) + (err/rt-test (call-with-continuation-prompt + (lambda () + (call-with-continuation-barrier + (lambda () + (once-k 18))))) + (lambda (x) + (and (exn:fail:contract? x) + (not (exn:fail:contract:continuation? x)))))) + (printf "Trying long chain under barrier...\n") + (let ([k (call-with-continuation-barrier + (lambda () + (long-loop (lambda () + ((let/cc k (lambda () k)))))))]) + (err/rt-test (k 18) exn:fail:contract:continuation?)) (printf "Trying long chain again...\n") (let ([k (call-with-continuation-prompt (lambda () - (long-loop (lambda () + (long-loop (lambda () ((call-with-composable-continuation (lambda (k) (lambda () k))))))))]) diff --git a/racket/src/racket/src/eval.c b/racket/src/racket/src/eval.c index c5f0ec74c0..c8fa62a2f0 100644 --- a/racket/src/racket/src/eval.c +++ b/racket/src/racket/src/eval.c @@ -1544,7 +1544,7 @@ static Scheme_Prompt *check_barrier(Scheme_Prompt *prompt, Scheme_Meta_Continuation *prompt_cont, MZ_MARK_POS_TYPE prompt_pos, Scheme_Cont *c) /* A continuation barrier is analogous to a dynamic-wind. A jump is - allowed if no dynamic-wind-like barriers would be executed for + allowed if no dynamic-wind-like pre-thunks would be executed for the jump. */ { Scheme_Prompt *barrier_prompt, *b1, *b2; @@ -1566,8 +1566,8 @@ static Scheme_Prompt *check_barrier(Scheme_Prompt *prompt, if (!b2->is_barrier) b2 = NULL; } - - if (b1 != b2) { + + if (b2 && (b1 != b2)) { scheme_raise_exn(MZEXN_FAIL_CONTRACT_CONTINUATION, "continuation application: attempt to cross a continuation barrier"); }