370 likes | 566 Views
Continuation Marks. A john clements talk. What are Continuation Marks?. What are Continuation Marks?. What are Continuations?. What are Continuation Marks?. What are Continuations?. Continuations. Paren-hackers. Contexts. Stacks. Compiler-writers. Semanticists. Contexts. Stacks.
E N D
Continuation Marks A john clements talk
What are Continuation Marks? What are Continuations?
What are Continuation Marks? What are Continuations? Continuations Paren-hackers Contexts Stacks Compiler-writers Semanticists
Contexts Stacks Compiler-writers Semanticists (let*-2vals ([kept-vars (cond [(eq? tail-bound 'all) free-vars] [else (filter (lambda (varref) (ormap (lambda (binding) (bound-identifier=? binding varref)) tail-bound)) free-vars)])] [var-clauses (map (lambda (x) (list x (d->so `(quote-syntax ,x)))) kept-vars)] [let-bindings (filter (lambda (var) (case (syntax-property var 'stepper-binding-type) ((let-bound) #t) ((lambda-bound stepper-temp top-level) #f) (else (error 'make-debug-info "varref ~a's binding-type info \ was not recognized: ~a" (syntax-e var) (syntax-property var 'stepper-binding-type))))) kept-vars)] [lifter-syms (map get-lifted-var let-bindings)] [quoted-lifter-syms (map (lambda (b) (d->so `(quote-syntax ,b))) lifter-syms)] [let-clauses (map list lifter-syms quoted-lifter-syms)]) (make-full-mark source label (append var-clauses (if lifting? let-clauses null))))
Contexts Stacks Compiler-writers Semanticists (let*-2vals ([kept-vars (cond [(eq? tail-bound 'all) free-vars] [else (filter (lambda (varref) (ormap (lambda (binding) (bound-identifier=? binding varref)) tail-bound)) free-vars)])] [var-clauses (map (lambda (x) (list x (d->so `(quote-syntax ,x)))) kept-vars)] [let-bindings (filter (lambda (var) (case (syntax-property var 'stepper-binding-type) ((let-bound) #t) ((lambda-bound stepper-temp top-level) #f) (else (error 'make-debug-info "varref ~a's binding-type info \ was not recognized: ~a" (syntax-e var) (syntax-property var 'stepper-binding-type))))) kept-vars)] [lifter-syms (map get-lifted-var let-bindings)] [quoted-lifter-syms (map (lambda (b) (d->so `(quote-syntax ,b))) lifter-syms)] [let-clauses (map list lifter-syms quoted-lifter-syms)]) (make-full-mark source label (append var-clauses (if lifting? let-clauses null)))) mark mark mark
Closing the Loop Programming Language Marks
Closing the Loop Programming Language with marks
Closing the Loop oops! Programming Language with marks
Closing the Loop Programming Language with marks
Contexts Stacks Compiler-writers Semanticists (let*-2vals ([kept-vars (cond [(eq? tail-bound 'all) free-vars] [else (filter (lambda (varref) (ormap (lambda (binding) (bound-identifier=? binding varref)) tail-bound)) free-vars)])] [var-clauses (map (lambda (x) (list x (d->so `(quote-syntax ,x)))) kept-vars)] [let-bindings (filter (lambda (var) (case (syntax-property var 'stepper-binding-type) ((let-bound) #t) ((lambda-bound stepper-temp top-level) #f) (else (error 'make-debug-info "varref ~a's binding-type info \ was not recognized: ~a" (syntax-e var) (syntax-property var 'stepper-binding-type))))) kept-vars)] [lifter-syms (map get-lifted-var let-bindings)] [quoted-lifter-syms (map (lambda (b) (d->so `(quote-syntax ,b))) lifter-syms)] [let-clauses (map list lifter-syms quoted-lifter-syms)]) (make-full-mark source label (append var-clauses (if lifting? let-clauses null)))) mark mark mark
Contexts Stacks Compiler-writers Semanticists (let*-2vals ([kept-vars (cond [(eq? tail-bound 'all) free-vars] [else (filter (lambda (varref) (ormap (lambda (binding) (bound-identifier=? binding varref)) tail-bound)) free-vars)])] [var-clauses (map (lambda (x) (list x (d->so `(quote-syntax ,x)))) kept-vars)] [let-bindings (filter (lambda (var) (case (syntax-property var 'stepper-binding-type) ((let-bound) #t) ((lambda-bound stepper-temp top-level) #f) (else (error 'make-debug-info "varref ~a's binding-type info \ was not recognized: ~a" (syntax-e var) (syntax-property var 'stepper-binding-type))))) kept-vars)] [lifter-syms (map get-lifted-var let-bindings)] [quoted-lifter-syms (map (lambda (b) (d->so `(quote-syntax ,b))) lifter-syms)] [let-clauses (map list lifter-syms quoted-lifter-syms)]) (make-full-mark source label (append var-clauses (if lifting? let-clauses null))))
New Language Forms • Introducing marks: • Observing marks: (with-continuation-mark M M) mark value body (current-continuation-marks)
New Language Forms Synopsis of Reduction Semantics: New Contexts: E = [] | (E M) | (V E) | … | (w-c-m V E) * *With restrictions on successive w-c-m’s New Reductions: E[(w-c-m V V)] -> E[V] E[(w-c-m V (w-c-m M M))] -> E[(w-c-m M M)] E[(c-c-m)] -> E[X(E)]
New Language Forms (define (loop x) (w-c-m x (loop (+ x 1)))) (loop 0) -> (w-c-m 0 (loop (+ 0 1))) -> (w-c-m 0 (loop 1)) -> (w-c-m 0 (w-c-m 1 (loop (+ 1 1)))) -> (w-c-m 1 (loop (+ 1 1))) -> (w-c-m 1 (loop 2)) -> (w-c-m 1 (w-c-m 2 (loop (+ 2 1)))) -> ...
New Language Forms (define (f x) (w-c-m x (+ (f x) 1))) (loop 0) -> (w-c-m 0 (+ (f 0) 1)) -> (w-c-m 0 (+ (w-c-m 0 (+ (f 0) 1)) 1)) -> (w-c-m 0 (+ (w-c-m 0 (+ (w-c-m 0 (+ (f 0) 1)) 1)) 1)) -> (w-c-m 0 (+ (w-c-m 0 (+ (w-c-m 0 (+ (w-c-m 0 (+ (f 0) 1)) 1)) 1)) 1)) -> ...
Expressiveness • Conjecture: cannot be expressed in a “tail-call preserving way” by state, continuations, etc. • Difficult to state claim clearly
Using Continuation Marks (to build a stepper)
Building a Stepper (using continuation marks)
Building a Stepper • Why a Stepper? • A stepper is a sound debugger • A stepper is a complete debugger • … with a suitable proof • How to build a stepper? • Annotation with continuation marks • Non-invasive (well-defined) implementation
Building a Stepper • Annotation: • Marks must contain: • Source position • Values of free variables • Breakpoints • Where? Everywhere. • No, even more than that.
Building a Stepper Pragmatics
Pragmatics • Orthogonality of annotations • Add a ‘key’ to each mark: • Marks with different keys are orthogonal (with-continuation-mark M M M) key mark body (current-continuation-marks M)
Macro Reversal (cond [a b] [c d]) ?? R? R (if c d (error)) (if a b (if c d (error)))
“Needed” variables • Variables stored in each mark • Avoid duplication • Store all variables which are not guaranteed to occur in an enclosing mark.
“Needed” variables Variable “a” is not needed in these contexts (letrec ([a 13] [b (+ a 14)] [c (lambda () a)]) (g a) Variable “a” is needed in these contexts
Opaque Values • Closures: procedures, classes • Structures, Units • Put them in a table
Before & After Steps (+ 1 (if true 3 4)) -> (+ 1 3) Requires additional breakpoints for: • tail-position expressions • results of primitive applications
Unannotated Code • Libraries • Partial Annotation • Complete Reconstruction not possible • Detection necessary
Lifting & Renaming • Newly created closures go to top level • Names must be assigned at runtime • Extra binding created
Lightweight Inspection (what else can we do with continuation marks?)
Stack Inspection • Widely used security measure • Associate privileges with ‘principals’ • Inspect the stack to make guarantees about execution • Implemented in a variety of ways: • Stack Inspection • “Security-passing style” ...
Stack Inspection • … or using continuation marks • Preserves tail-call optimization • Place marks on the “bad” code T T G G OLD NEW
Aspect-Oriented Programming • Allows textual separation of program aspects. • May be implemented by a static annotation • … with certain run-time decisions • “cflow” rules in AspectJ • But what about tail-call optimization? • May be recovered with continuation marks
Lightweight Inspection • Other uses waiting to be found…
Lightweight Inspection • Other uses waiting to be found… • Tell me yours!