|
| 1 | +# 3rd proposal formal spec overview |
| 2 | + |
| 3 | +This is an overview of the 3rd proposal's formal spec additions, to aid in discussions concerning the proposed semantics. |
| 4 | + |
| 5 | +## Abstract Syntax |
| 6 | + |
| 7 | +### Types |
| 8 | + |
| 9 | +Exception Types |
| 10 | + |
| 11 | +``` |
| 12 | +exntype ::= [t*] -> [] |
| 13 | +``` |
| 14 | + |
| 15 | +### Instructions |
| 16 | + |
| 17 | +``` |
| 18 | +instr ::= ... | throw x | rethrow l |
| 19 | + | try bt instr* (catch x instr*)+ end |
| 20 | + | try bt instr* (catch x instr*)* catch_all instr* end |
| 21 | + | try bt instr* delegate l |
| 22 | + | try bt instr* unwind instr* end |
| 23 | +``` |
| 24 | + |
| 25 | +### Modules |
| 26 | + |
| 27 | +Exceptions (definitions) |
| 28 | + |
| 29 | +``` |
| 30 | +exn ::= export* exception exntype | export* exception exntype import |
| 31 | +``` |
| 32 | + |
| 33 | +Modules |
| 34 | + |
| 35 | + |
| 36 | +``` |
| 37 | +mod ::= module ... exn* |
| 38 | +``` |
| 39 | + |
| 40 | +## Validation (Typing) |
| 41 | + |
| 42 | +To verify that a `try...delegate l` instruction refers to a label introduced by a try block (I'll call this a try-label), introduce a type attribute to labels in the validation context, which type attribute is set to `try` when the label is a try-label. The original notation `label [t*]` will then be a shortcut for `label {result [t*], type ε}`. |
| 43 | + |
| 44 | +Moreover, to verify that the `rethrow l` instruction refers to a label introduced by a catch block (call this a catch-label), we allow this type attribute of labels in the validation context to be set to `catch` when the label is a catch label. This addition is reflected in the execution rules, by the administrative instruction `caught` which introduces a label around the instructions of the catching try-block's catch instructions. |
| 45 | + |
| 46 | + |
| 47 | +### Instructions |
| 48 | + |
| 49 | + |
| 50 | +``` |
| 51 | +C_exn(x) = [t*] -> [] |
| 52 | +-------------------------------- |
| 53 | +C |- throw x : [t1* t*] -> [t2*] |
| 54 | +
|
| 55 | +
|
| 56 | +C_label(l).type = catch |
| 57 | +------------------------------- |
| 58 | +C |- rethrow l : [t1*] -> [t2*] |
| 59 | +
|
| 60 | +
|
| 61 | +bt = [t1*] -> [t2*] |
| 62 | +C, label {result [t2*], type try} |- instr* : [t1*] -> [t2*] |
| 63 | +(C_exn(x_i) = [t'_i*] -> [])^n |
| 64 | +(C, label {result [t2*], type catch} |- instr_i* : [t'_i*] -> [t2*])^n |
| 65 | +(C, label {result [t2*], type catch} |- instr'* : [] -> [t2*])? |
| 66 | +---------------------------------------------------------------------- |
| 67 | +try bt instr* (catch x_i instr_i*)^n (catch_all instr'*)? end : bt |
| 68 | +
|
| 69 | +
|
| 70 | +bt = [t1*] -> [t2*] |
| 71 | +C, label {result [t2*], type try} |- instr* : [t1*] -> [t2*] |
| 72 | +C_label(l).type = try |
| 73 | +------------------------------------------------------------ |
| 74 | +try bt instr* delegate l : bt |
| 75 | +
|
| 76 | +
|
| 77 | +bt = [t1*] -> [t2*] |
| 78 | +C, label {result [t2*], type try} |- instr_1* : [t1*] -> [t2*] |
| 79 | +C, label {result [t2*], type catch} |- instr_2* : [] -> [t2*] |
| 80 | +-------------------------------------------------------------- |
| 81 | +try bt instr_1* unwind instr_2* : bt |
| 82 | +``` |
| 83 | + |
| 84 | +## Execution (Reduction) |
| 85 | + |
| 86 | +### Runtime structure |
| 87 | + |
| 88 | +Stores |
| 89 | + |
| 90 | +``` |
| 91 | +S ::= {..., exn exninst*} |
| 92 | +``` |
| 93 | + |
| 94 | +Exception Instances |
| 95 | + |
| 96 | +``` |
| 97 | +exninst ::= {type exntype} |
| 98 | +``` |
| 99 | + |
| 100 | +Module Instances |
| 101 | + |
| 102 | +``` |
| 103 | +m ::= {..., (exn a)*} |
| 104 | +``` |
| 105 | + |
| 106 | +Administrative Instructions |
| 107 | + |
| 108 | +``` |
| 109 | +instr ::= ... | throw a | catch_n{a instr*}*{instr*} instr* end |
| 110 | + | delegate{l} instr* end | caught_m{a val^n} instr* end |
| 111 | +``` |
| 112 | + |
| 113 | +Throw Contexts |
| 114 | + |
| 115 | +``` |
| 116 | +T ::= v* [_] e* | label_n{e*} T end | caught_m{a val^n} T end | frame_n{F} T end |
| 117 | +``` |
| 118 | + |
| 119 | +### Instructions |
| 120 | + |
| 121 | +In the following reduction rules, note that `caught_m` introduces a label around the catching instructions. This corresponds to the label a `rethrow l` would target. |
| 122 | + |
| 123 | + |
| 124 | +``` |
| 125 | +F; throw x --> F; throw a (iff F_exn(x) = a) |
| 126 | +
|
| 127 | +caught_m{a val^n} label_m{} B^l[rethrow l] end end |
| 128 | + --> caught_m{a val^n} label_m{} B^l[val^n (throw a)] end end |
| 129 | +
|
| 130 | +caught_m{a val^n} val^m end --> val^m |
| 131 | +``` |
| 132 | + |
| 133 | +The requirements below involving `k` are to distinguish between a missing `catch_all` and an existing `catch_all` with no instructions (`nop` is added to the empty instruction set of an existing `catch_all`). |
| 134 | + |
| 135 | +``` |
| 136 | +F; val^n (try bt instr* (catch x_i instr_i*)* (catch_all instr'*)^k end) |
| 137 | + --> F; catch_m{a_i instr_i*}*{instr''*} (label_m{} val^n instr* end) end |
| 138 | + (iff bt = [t1^n] -> [t2^m] and (F_exn(x_i) = a_i)* and |
| 139 | + (if k=1 and instr'*=ε then instr''* = nop) |
| 140 | + and (if k=1 and inst'*=/=ε then instr''* = instr'*) and (if k=0 then instr''*=ε). |
| 141 | +
|
| 142 | +catch_m{a_i instr_i*}*{instr'*} val^m end --> val^m |
| 143 | +
|
| 144 | +S; F; catch_m{a_i instr_i*}*{instr'*} T[val^n (throw a)] end |
| 145 | + --> S; F; caught_m{a val^n} label_m{} val^n instr_i* end end |
| 146 | + (iff S_exn(a) = {type [t^n]->[]} and a_i = a) |
| 147 | +
|
| 148 | +S; F; catch_m{a_i instr_i*}*{instr*} T[val^n (throw a)] end |
| 149 | + --> S; F; caught_m{a val^n} label_m{} instr* end end |
| 150 | + (iff S_exn(a) = {type [t^n]->[]} and instr =/= ε and for every i, a_i =/= a) |
| 151 | +
|
| 152 | +S; F; catch_m{a_i instr_i*}*{ε} T[val^n (throw a)] end |
| 153 | + --> S; F; val^n (throw a) |
| 154 | + (iff for every i, a_i =/= a) |
| 155 | +
|
| 156 | +
|
| 157 | +val^n (try bt instr* delegate l) --> delegate{l} (label_m{} val^n instr* end) end |
| 158 | + (iff bt = [t^n] -> [t^m]) |
| 159 | +
|
| 160 | +catch_m{a_i instr_i*}*{instr*} (label_m{} B^l[ delegate{l} (T[val^n (throw a)]) end ] end) end |
| 161 | + --> catch_m{a_i instr_i*}*{instr*} label_m{} val^n (throw a) end end |
| 162 | +
|
| 163 | +
|
| 164 | +try bt instr* unwind instr'* end --> try bt instr* catch_all instr'* rethrow 0 end |
| 165 | +``` |
0 commit comments