| # Exceptions Implementation | 
 |  | 
 | This page describes how exceptions throwing and catching is implemented in the | 
 | VM. | 
 |  | 
 | ## Intermediate Language | 
 |  | 
 | Dart VM's IL **does not** explicitly represent exceptional control flow in its | 
 | flow graph, there are **no** explicit exceptional edges connecting potentially | 
 | throwing instructions (e.g. calls) with corresponding catch blocks. Instead this | 
 | connection is defined at the block level: all exceptions that occur in any block | 
 | with the given `try_index` will be caught by `CatchBlockEntry` with the equal | 
 | `catch_try_index`. | 
 |  | 
 |  | 
 |  | 
 | For optimized code this means that data flow associated with exceptional control | 
 | flow is also represented implicitly: due to the absence of explicit exceptional | 
 | edges the data flow can't be represented using explicit phi-functions. Instead | 
 | in optimized code each `CatchBlockEntry` is treated almost as if it was an | 
 | independent entry into the function: for each variable `v` `CatchBlockEntry` | 
 | will contain a `Parameter(...)` instruction restoring variable state at catch | 
 | entry from a fixed location on the stack. When an exception is thrown runtime | 
 | system takes care of populating these stack slots with right values - current | 
 | state of corresponding local variables. It's easy to see a parallel between | 
 | these `Parameter(...)` instructions and `Phi(...)` instructions that would be | 
 | used if exception control flow would be explicit. | 
 |  | 
 |  | 
 |  | 
 | How does runtime system populate stack slots corresponding to these | 
 | `Parameter(...)` instructions? During compilation necessary information is | 
 | available in _deoptimization environment_ attached to the instruction. This | 
 | environment encodes the state of local variables in terms of SSA values i.e. if | 
 | we need to reconstruct unoptimized frame which SSA value should be stored into | 
 | the given local variable (see [Optimized | 
 | IL](compiler-pipeline-overview.md#optimized-il) for | 
 | an overview). However the way we use these information for exception handling is | 
 | slightly different in JIT and AOT modes. | 
 |  | 
 | ### AOT mode | 
 |  | 
 | AOT mode does not support deoptimization and thus AOT compiler does not | 
 | associate any deoptimization metadata with generated code. Instead | 
 | deoptimization environments associated with instructions that can throw are | 
 | converted into `CatchEntryMoves` metadata during code generation and resulting | 
 | metadata is stored `RawCode::catch_entry_moves_maps_` in a compressed form. | 
 |  | 
 | `CatchEntryMoves` is essentially a sequence of moves which runtime needs to | 
 | perform to create the state that catch entry expects. There are three types of | 
 | moves: | 
 |  | 
 | * `*(FP + Dst) <- ObjectPool[PoolIndex]` - a move of a constant from an object | 
 | pool; | 
 | * `*(FP + Dst) <- *(FP + Src)` - a move of a tagged value; | 
 | * `*(FP + Dst) <- Box<Rep>(*(FP + Src))` - a boxing operation for an untagged | 
 | value; | 
 |  | 
 | When an exception is caught runtime decompresses the metadata associated with the | 
 | call site which has thrown an exception and uses it to prepare the state of the | 
 | stack for the catch block entry. See | 
 | `ExceptionHandlerFinder::{ReadCompressedCatchEntryMoves, ExecuteCatchEntryMoves}`. | 
 |  | 
 | NOTE: See [this | 
 | design/motivation](https://docs.google.com/a/google.com/document/d/1_vX8VkvHVA1Om7jjONiWLA325k_JmSZuvVClet-x-xM/edit?usp=sharing) | 
 | document for `CatchEntryMoves` metadata | 
 |  | 
 | ### JIT mode | 
 |  | 
 | JIT mode heavily relies on deoptimization and all call instructions have (lazy) | 
 | deoptimization environments associated with them. These environments are | 
 | converted to [deoptimization | 
 | instructions](deoptimization.md#in-optimized-code) | 
 | during code generation and stored on the `Code` object. | 
 |  | 
 | When an exception is caught the runtime system converts deoptimization | 
 | environment associated with the call site that threw an exception into | 
 | `CatchEntryMoves` and then uses it to prepare the state of the stack for the | 
 | catch block entry. See `ExceptionHandlerFinder::{GetCatchEntryMovesFromDeopt, ExecuteCatchEntryMoves}`. | 
 |  | 
 | Constructing `CatchEntryMoves` dynamically from deoptimization instructions | 
 | allows to avoid unnecessary duplication of the metadata and save memory: as | 
 | deoptimization environments contain all information necessary for constructing | 
 | correct stack state. |