COMPILING EXCEPTIONS CORRECTLY Graham Hutton and Joel Wright University of Nottingham

  • View
    215

  • Download
    2

Embed Size (px)

Text of COMPILING EXCEPTIONS CORRECTLY Graham Hutton and Joel Wright University of Nottingham

  • What Is An Exception?Division by zero;Stack overflow;Null pointer.Examples:An event within a computation that causes termination in a non-standard way.

  • This TalkMost modern languages support programming with exceptions, e.g. using throw and catch;

    The compilation of such exception primitives is traditionally viewed as an advanced topic;

    We give a simple explanation and verification, using elementary functional techniques.

  • Step 1 - Arithmetic Expressionsdata Expr = Val Int | Add Expr Expreval :: Expr Inteval (Val n) = neval (Add x y) = eval x + eval ySyntax:Semantics:

  • type Stack = [Int]

    data Op = PUSH Int | ADD

    type Code = [Op]comp :: Expr Codecomp (Val n) = [PUSH n]comp (Add x y) = comp x ++ comp y ++ [ADD]Virtual machine:Compiler:

  • Compiler Correctnessexec s (comp e) = eval e : sTheorem:

  • Proof: by induction, using a distribution lemma:However, we can avoid this lemma and shorten the proof by 60% by generalising the theorem: exec s (comp e ++ ops)= exec (eval e : s) ops exec s (xs ++ ys)= exec (exec s xs) ys

  • Step 2 - Adding Exceptionseval :: Expr Maybe Inteval (Val n) = Just neval (Throw) = Nothingeval (Add x y) = eval x eval yeval (Catch x h) = eval x eval hdata Expr = | Throw | Catch Expr ExprSyntax:Semantics:

  • Add (Val 1) (Val 2)Add Throw (Val 2)Catch (Val 1) (Val 2)Catch Throw (Val 2)Just 3NothingJust 1Just 2evalevalevalevalExamples:

  • data Op = | THROW | MARK Code | UNMARK

    type Stack = [Item]

    data Item = VAL Int | HAN Codecomp (Throw) = [THROW]comp (Catch x h) = [MARK (comp h)] ++ comp x ++ [UNMARK]Virtual machine:Compiler:

  • How Is THROW Executed?Informally, we must:Unwind the stack seeking a handler;

    Execute the first handler found, if any;

    Skip to the next part of the computation.

  • skip :: Code Codeskip [] = []skip (UNMARK : ops) = opsskip (MARK h : ops) = skip (skip ops)skip (op : ops) = skip opsunwind :: Stack Code Stackunwind [] ops = []unwind (VAL n : s) ops = unwind s opsunwind (HAN h : s) ops = exec s (h ++ skip ops)Implementation:

  • Example1 + (catch (2 + throw) 3)StackCode

  • Example1 + (catch (2 + throw) 3)PUSH 1MARK [PUSH 3]PUSH 2THROWADDUNMARKADDStackCode

  • Example1 + (catch (2 + throw) 3)MARK [PUSH 3]PUSH 2THROWADDUNMARKADDStackCodeVAL 1

  • Example1 + (catch (2 + throw) 3)PUSH 2THROWADDUNMARKADDStackCodeHAN [PUSH 3]VAL 1

  • Example1 + (catch (2 + throw) 3)THROWADDUNMARKADDStackCodeVAL 2HAN [PUSH 3]VAL 1

  • Example1 + (catch (2 + throw) 3)THROWADDUNMARKADDStackCodeHAN [PUSH 3]VAL 1

  • Example1 + (catch (2 + throw) 3)PUSH 3THROW ADD UNMARK ADD StackCodeVAL 1

  • Example1 + (catch (2 + throw) 3)THROW ADD UNMARK ADD StackCodeVAL 3VAL 1

  • Example1 + (catch (2 + throw) 3)ADD UNMARK ADD StackCodeVAL 3VAL 1

  • Example1 + (catch (2 + throw) 3)UNMARK ADD StackCodeVAL 3VAL 1

  • Example1 + (catch (2 + throw) 3)ADD StackCodeVAL 3VAL 1

  • Example1 + (catch (2 + throw) 3)StackCodeVAL 4

  • Compiler CorrectnessExprMaybe IntCodeStackevalexec []compconvconv Nothing = []conv (Just n) = [VAL n]where

  • As previously, we generalise to an arbitrary initial stack and arbitrary additional code.

    Theorem: exec s (comp e ++ ops)= exec s (trans (eval e) : ops)trans :: Maybe Int Optrans Nothing = THROWtrans (Just n) = PUSH nwhere

  • Proof: by induction, using a skipping lemma:skip (comp e ++ ops) = skip opsNotes:The proof is 3.5 pages of simple calculation;

    The quickcheck tool was very useful as an aid to simplifying the definitions and results.

  • Step 3 - Adding Jumps MARK a code for x UNMARK JUMP ba: code for hb: remaining codeCatch x his now compiled toBasic idea:See the paper for further details.

  • SummaryExplanation and verification of the compilation of exceptions using stack unwinding.

    Stepwise development to aid understanding:1 - Arithmetic expressions;

    2 - Adding exceptions;

    3 - Adding jumps.

  • Further WorkMechanical verification;Modular compilers;Calculating the compiler;Generalising the language;Compiler optimisations.