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

COMPILING EXCEPTIONS CORRECTLY Graham Hutton and Joel Wright University of Nottingham

Embed Size (px)

Citation preview

COMPILING EXCEPTIONSCORRECTLY

Graham Hutton and Joel WrightUniversity of Nottingham

2

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.

3

This Talk

Most 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.

4

Step 1 - Arithmetic Expressions

data Expr = Val Int | Add Expr Expr

eval :: Expr Inteval (Val n) = neval (Add x y) = eval x + eval y

Syntax:

Semantics:

5

type Stack = [Int]

data Op = PUSH Int | ADD

type Code = [Op]

comp :: Expr Code

comp (Val n) = [PUSH n]

comp (Add x y) = comp x ++ comp y ++ [ADD]

Virtual machine:

Compiler:

6

Compiler Correctness

Expr Int

Code Stack

eval

exec []

comp []

exec s (comp e) = eval e : s

Theorem:

7

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

8

eval :: Expr Maybe Inteval (Val n) = Just neval (Throw) = Nothingeval (Add x y) = eval x eval yeval (Catch x h) = eval x eval h

Step 2 - Adding Exceptions

data Expr = ••• | Throw | Catch Expr Expr

Syntax:

Semantics:

9

Add (Val 1) (Val 2)

Add Throw (Val 2)

Catch (Val 1) (Val 2)

Catch Throw (Val 2)

Just 3

Nothing

Just 1

Just 2

eval

eval

eval

eval

Examples:

10

data Op = ••• | THROW | MARK Code | UNMARK

type Stack = [Item]

data Item = VAL Int | HAN Code

comp (Throw) = [THROW]

comp (Catch x h) =

[MARK (comp h)] ++ comp x ++ [UNMARK]

Virtual machine:

Compiler:

11

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.

12

skip :: Code Codeskip [] = []skip (UNMARK : ops) = opsskip (MARK h : ops) = skip (skip ops)skip (op : ops) = skip ops

unwind :: Stack Code Stackunwind [] ops = []unwind (VAL n : s) ops = unwind s opsunwind (HAN h : s) ops = exec s (h ++ skip ops)

Implementation:

13

1 + (catch (2 + throw) 3)

Example

Stack

Code

14

1 + (catch (2 + throw) 3)

Example

PUSH 1MARK [PUSH 3]PUSH 2THROWADDUNMARKADD

Stack

Code

15

1 + (catch (2 + throw) 3)

Example

MARK [PUSH 3]PUSH 2THROWADDUNMARKADD

Stack

Code

VAL 1

16

1 + (catch (2 + throw) 3)

Example

PUSH 2THROWADDUNMARKADD

Stack

Code

HAN [PUSH 3]VAL 1

17

1 + (catch (2 + throw) 3)

Example

THROWADDUNMARKADD

Stack

Code

VAL 2HAN [PUSH 3]VAL 1

18

1 + (catch (2 + throw) 3)

Example

THROWADDUNMARKADD

Stack

Code

HAN [PUSH 3]VAL 1

19

1 + (catch (2 + throw) 3)

Example

PUSH 3THROW ADD UNMARK ADD

Stack

Code

VAL 1

20

1 + (catch (2 + throw) 3)

Example

THROW ADD UNMARK ADD

Stack

Code

VAL 3VAL 1

21

1 + (catch (2 + throw) 3)

Example

ADD UNMARK ADD

Stack

Code

VAL 3VAL 1

22

1 + (catch (2 + throw) 3)

Example

UNMARK ADD

Stack

Code

VAL 3VAL 1

23

1 + (catch (2 + throw) 3)

Example

ADD

Stack

Code

VAL 3VAL 1

24

1 + (catch (2 + throw) 3)

Example

Stack

Code

VAL 4

25

Compiler Correctness

Expr Maybe Int

Code Stack

eval

exec []

comp conv

conv Nothing = []conv (Just n) = [VAL n]

where

26

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 n

where

27

Proof: by induction, using a skipping lemma:

skip (comp e ++ ops) = skip ops

Notes:

The proof is 3.5 pages of simple calculation;

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

28

Step 3 - Adding Jumps

MARK a code for x UNMARK JUMP ba: code for hb: remaining code

Catch x h

is now compiled to

Basic idea:

See the paper for further

details.

29

Summary

Explanation and verification of the compilation of exceptions using stack unwinding.

Stepwise development to aid understanding:

1 - Arithmetic expressions;

2 - Adding exceptions;

3 - Adding jumps.

30

Further Work

Mechanical verification;

Modular compilers;

Calculating the compiler;

Generalising the language;

Compiler optimisations.