| == t1 == |
| fun t1() { |
| try { |
| 1 |
| } finally { |
| 2 |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| 2 mark({ try { 1 } finally { 2 } }) |
| mark(try { 1 } finally { 2 }) |
| jmp?(L2) NEXT:[mark({ 2 }), mark({ 1 })] |
| 3 mark({ 1 }) |
| r(1) -> <v0> |
| 2 jmp?(L2) NEXT:[mark({ 2 }), jmp(L3)] |
| jmp(L3) NEXT:[mark({ 2 })] |
| L2 [onExceptionToFinallyBlock]: |
| L4 [start finally]: |
| 3 mark({ 2 }) PREV:[jmp?(L2), jmp?(L2)] |
| r(2) -> <v1> |
| L5 [finish finally]: |
| 2 jmp(error) NEXT:[<ERROR>] |
| L3 [skipFinallyToErrorBlock]: |
| L6 [copy of L2, onExceptionToFinallyBlock]: |
| 3 mark({ 2 }) PREV:[jmp(L3)] |
| r(2) -> <v1> |
| 2 merge(try { 1 } finally { 2 }|<v0>) -> <v2> |
| L1: |
| 1 <END> NEXT:[<SINK>] |
| error: |
| <ERROR> PREV:[jmp(error)] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == t2 == |
| fun t2() { |
| try { |
| 1 |
| if (2 > 3) { |
| return |
| } |
| } finally { |
| 2 |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| 2 mark({ try { 1 if (2 > 3) { return } } finally { 2 } }) |
| mark(try { 1 if (2 > 3) { return } } finally { 2 }) |
| jmp?(L2) NEXT:[mark({ 2 }), mark({ 1 if (2 > 3) { return } })] |
| 3 mark({ 1 if (2 > 3) { return } }) |
| r(1) -> <v0> |
| mark(if (2 > 3) { return }) |
| r(2) -> <v1> |
| r(3) -> <v2> |
| mark(2 > 3) |
| call(2 > 3, compareTo|<v1>, <v2>) -> <v3> |
| jf(L3|<v3>) NEXT:[read (Unit), mark({ return })] |
| 4 mark({ return }) |
| jmp?(L2) NEXT:[mark({ 2 }), mark({ 2 })] |
| L4 [start finally]: |
| 5 mark({ 2 }) |
| r(2) -> <v4> |
| L5 [finish finally]: |
| 4 ret L1 NEXT:[<END>] |
| - 3 jmp(L6) NEXT:[merge(if (2 > 3) { return }|!<v5>) -> <v6>] PREV:[] |
| L3 [else branch]: |
| read (Unit) PREV:[jf(L3|<v3>)] |
| L6 ['if' expression result]: |
| merge(if (2 > 3) { return }|!<v5>) -> <v6> |
| 2 jmp?(L2) NEXT:[mark({ 2 }), jmp(L7)] |
| jmp(L7) NEXT:[mark({ 2 })] |
| L2 [onExceptionToFinallyBlock]: |
| 5 mark({ 2 }) PREV:[jmp?(L2), jmp?(L2), jmp?(L2)] |
| r(2) -> <v4> |
| 2 jmp(error) NEXT:[<ERROR>] |
| L7 [skipFinallyToErrorBlock]: |
| 5 mark({ 2 }) PREV:[jmp(L7)] |
| r(2) -> <v4> |
| 2 merge(try { 1 if (2 > 3) { return } } finally { 2 }|<v6>) -> <v7> |
| L1: |
| 1 <END> NEXT:[<SINK>] PREV:[ret L1, merge(try { 1 if (2 > 3) { return } } finally { 2 }|<v6>) -> <v7>] |
| error: |
| <ERROR> PREV:[jmp(error)] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == t3 == |
| fun t3() { |
| try { |
| 1 |
| l@{ -> |
| if (2 > 3) { |
| return@l |
| } |
| } |
| } finally { |
| 2 |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| 2 mark({ try { 1 l@{ -> if (2 > 3) { return@l } } } finally { 2 } }) |
| mark(try { 1 l@{ -> if (2 > 3) { return@l } } } finally { 2 }) |
| jmp?(L2) NEXT:[mark({ 2 }), mark({ 1 l@{ -> if (2 > 3) { return@l } } })] |
| 3 mark({ 1 l@{ -> if (2 > 3) { return@l } } }) |
| r(1) -> <v0> |
| mark(l@{ -> if (2 > 3) { return@l } }) |
| mark({ -> if (2 > 3) { return@l } }) |
| jmp?(L3) NEXT:[r({ -> if (2 > 3) { return@l } }) -> <v1>, d({ -> if (2 > 3) { return@l } })] |
| d({ -> if (2 > 3) { return@l } }) NEXT:[<SINK>] |
| L3 [after local declaration]: |
| r({ -> if (2 > 3) { return@l } }) -> <v1> PREV:[jmp?(L3)] |
| 2 jmp?(L2) NEXT:[mark({ 2 }), jmp(L8)] |
| jmp(L8) NEXT:[mark({ 2 })] |
| L2 [onExceptionToFinallyBlock]: |
| L9 [start finally]: |
| 3 mark({ 2 }) PREV:[jmp?(L2), jmp?(L2)] |
| r(2) -> <v2> |
| L10 [finish finally]: |
| 2 jmp(error) NEXT:[<ERROR>] |
| L8 [skipFinallyToErrorBlock]: |
| L11 [copy of L2, onExceptionToFinallyBlock]: |
| 3 mark({ 2 }) PREV:[jmp(L8)] |
| r(2) -> <v2> |
| 2 merge(try { 1 l@{ -> if (2 > 3) { return@l } } } finally { 2 }|<v1>) -> <v3> |
| L1: |
| 1 <END> NEXT:[<SINK>] |
| error: |
| <ERROR> PREV:[jmp(error)] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>, d({ -> if (2 > 3) { return@l } })] |
| ===================== |
| == anonymous_0 == |
| { -> |
| if (2 > 3) { |
| return@l |
| } |
| } |
| --------------------- |
| L4: |
| 4 <START> |
| 5 mark(if (2 > 3) { return@l }) |
| mark(if (2 > 3) { return@l }) |
| r(2) -> <v0> |
| r(3) -> <v1> |
| mark(2 > 3) |
| call(2 > 3, compareTo|<v0>, <v1>) -> <v2> |
| jf(L6|<v2>) NEXT:[read (Unit), mark({ return@l })] |
| 6 mark({ return@l }) |
| ret L5 NEXT:[<END>] |
| - 5 jmp(L7) NEXT:[merge(if (2 > 3) { return@l }|!<v3>) -> <v4>] PREV:[] |
| L6 [else branch]: |
| read (Unit) PREV:[jf(L6|<v2>)] |
| L7 ['if' expression result]: |
| merge(if (2 > 3) { return@l }|!<v3>) -> <v4> |
| L5: |
| 4 <END> NEXT:[<SINK>] PREV:[ret L5, merge(if (2 > 3) { return@l }|!<v3>) -> <v4>] |
| error: |
| <ERROR> PREV:[] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == t4 == |
| fun t4() { |
| l@{ -> |
| try { |
| 1 |
| if (2 > 3) { |
| return@l |
| } |
| } finally { |
| 2 |
| } |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| 2 mark({ l@{ -> try { 1 if (2 > 3) { return@l } } finally { 2 } } }) |
| mark(l@{ -> try { 1 if (2 > 3) { return@l } } finally { 2 } }) |
| mark({ -> try { 1 if (2 > 3) { return@l } } finally { 2 } }) |
| jmp?(L2) NEXT:[r({ -> try { 1 if (2 > 3) { return@l } } finally { 2 } }) -> <v0>, d({ -> try { 1 if (2 > 3) { return@l } } finally { 2 } })] |
| d({ -> try { 1 if (2 > 3) { return@l } } finally { 2 } }) NEXT:[<SINK>] |
| L2 [after local declaration]: |
| r({ -> try { 1 if (2 > 3) { return@l } } finally { 2 } }) -> <v0> PREV:[jmp?(L2)] |
| L1: |
| 1 <END> NEXT:[<SINK>] |
| error: |
| <ERROR> PREV:[] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>, d({ -> try { 1 if (2 > 3) { return@l } } finally { 2 } })] |
| ===================== |
| == anonymous_1 == |
| { -> |
| try { |
| 1 |
| if (2 > 3) { |
| return@l |
| } |
| } finally { |
| 2 |
| } |
| } |
| --------------------- |
| L3: |
| 3 <START> |
| 4 mark(try { 1 if (2 > 3) { return@l } } finally { 2 }) |
| mark(try { 1 if (2 > 3) { return@l } } finally { 2 }) |
| jmp?(L5) NEXT:[mark({ 2 }), mark({ 1 if (2 > 3) { return@l } })] |
| 5 mark({ 1 if (2 > 3) { return@l } }) |
| r(1) -> <v0> |
| mark(if (2 > 3) { return@l }) |
| r(2) -> <v1> |
| r(3) -> <v2> |
| mark(2 > 3) |
| call(2 > 3, compareTo|<v1>, <v2>) -> <v3> |
| jf(L6|<v3>) NEXT:[read (Unit), mark({ return@l })] |
| 6 mark({ return@l }) |
| jmp?(L5) NEXT:[mark({ 2 }), mark({ 2 })] |
| L7 [start finally]: |
| 7 mark({ 2 }) |
| r(2) -> <v4> |
| L8 [finish finally]: |
| 6 ret L4 NEXT:[<END>] |
| - 5 jmp(L9) NEXT:[merge(if (2 > 3) { return@l }|!<v5>) -> <v6>] PREV:[] |
| L6 [else branch]: |
| read (Unit) PREV:[jf(L6|<v3>)] |
| L9 ['if' expression result]: |
| merge(if (2 > 3) { return@l }|!<v5>) -> <v6> |
| 4 jmp?(L5) NEXT:[mark({ 2 }), jmp(L10)] |
| jmp(L10) NEXT:[mark({ 2 })] |
| L5 [onExceptionToFinallyBlock]: |
| 7 mark({ 2 }) PREV:[jmp?(L5), jmp?(L5), jmp?(L5)] |
| r(2) -> <v4> |
| 4 jmp(error) NEXT:[<ERROR>] |
| L10 [skipFinallyToErrorBlock]: |
| 7 mark({ 2 }) PREV:[jmp(L10)] |
| r(2) -> <v4> |
| 4 merge(try { 1 if (2 > 3) { return@l } } finally { 2 }|<v6>) -> <v7> |
| L4: |
| 3 <END> NEXT:[<SINK>] PREV:[ret L4, merge(try { 1 if (2 > 3) { return@l } } finally { 2 }|<v6>) -> <v7>] |
| error: |
| <ERROR> PREV:[jmp(error)] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == t5 == |
| fun t5() { |
| l@ while(true) { |
| try { |
| 1 |
| if (2 > 3) { |
| break@l |
| } |
| } finally { |
| 2 |
| } |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| 2 mark({ l@ while(true) { try { 1 if (2 > 3) { break@l } } finally { 2 } } }) |
| mark(l@ while(true) { try { 1 if (2 > 3) { break@l } } finally { 2 } }) |
| L2 [loop entry point]: |
| L6 [condition entry point]: |
| r(true) -> <v0> PREV:[mark(l@ while(true) { try { 1 if (2 > 3) { break@l } } finally { 2 } }), jmp(L2)] |
| mark(while(true) { try { 1 if (2 > 3) { break@l } } finally { 2 } }) |
| magic[VALUE_CONSUMER](true|<v0>) -> <v1> |
| L4 [body entry point]: |
| 3 mark({ try { 1 if (2 > 3) { break@l } } finally { 2 } }) |
| mark(try { 1 if (2 > 3) { break@l } } finally { 2 }) |
| jmp?(L7) NEXT:[mark({ 2 }), mark({ 1 if (2 > 3) { break@l } })] |
| 4 mark({ 1 if (2 > 3) { break@l } }) |
| r(1) -> <v2> |
| mark(if (2 > 3) { break@l }) |
| r(2) -> <v3> |
| r(3) -> <v4> |
| mark(2 > 3) |
| call(2 > 3, compareTo|<v3>, <v4>) -> <v5> |
| jf(L8|<v5>) NEXT:[read (Unit), mark({ break@l })] |
| 5 mark({ break@l }) |
| jmp?(L7) NEXT:[mark({ 2 }), mark({ 2 })] |
| L9 [start finally]: |
| 6 mark({ 2 }) |
| r(2) -> <v6> |
| L10 [finish finally]: |
| 5 jmp(L3) NEXT:[read (Unit)] |
| - 4 jmp(L11) NEXT:[merge(if (2 > 3) { break@l }|!<v7>) -> <v8>] PREV:[] |
| L8 [else branch]: |
| read (Unit) PREV:[jf(L8|<v5>)] |
| L11 ['if' expression result]: |
| merge(if (2 > 3) { break@l }|!<v7>) -> <v8> |
| 3 jmp?(L7) NEXT:[mark({ 2 }), jmp(L12)] |
| jmp(L12) NEXT:[mark({ 2 })] |
| L7 [onExceptionToFinallyBlock]: |
| 6 mark({ 2 }) PREV:[jmp?(L7), jmp?(L7), jmp?(L7)] |
| r(2) -> <v6> |
| 3 jmp(error) NEXT:[<ERROR>] |
| L12 [skipFinallyToErrorBlock]: |
| 6 mark({ 2 }) PREV:[jmp(L12)] |
| r(2) -> <v6> |
| 3 merge(try { 1 if (2 > 3) { break@l } } finally { 2 }|<v8>) -> <v9> |
| 2 jmp(L2) NEXT:[r(true) -> <v0>] |
| L3 [loop exit point]: |
| L5 [body exit point]: |
| read (Unit) PREV:[jmp(L3)] |
| L1: |
| 1 <END> NEXT:[<SINK>] |
| error: |
| <ERROR> PREV:[jmp(error)] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == t6 == |
| fun t6() { |
| try { |
| l@ while(true) { |
| 1 |
| if (2 > 3) { |
| break@l |
| } |
| } |
| 5 |
| } finally { |
| 2 |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| 2 mark({ try { l@ while(true) { 1 if (2 > 3) { break@l } } 5 } finally { 2 } }) |
| mark(try { l@ while(true) { 1 if (2 > 3) { break@l } } 5 } finally { 2 }) |
| jmp?(L2) NEXT:[mark({ 2 }), mark({ l@ while(true) { 1 if (2 > 3) { break@l } } 5 })] |
| 3 mark({ l@ while(true) { 1 if (2 > 3) { break@l } } 5 }) |
| mark(l@ while(true) { 1 if (2 > 3) { break@l } }) |
| L3 [loop entry point]: |
| L7 [condition entry point]: |
| r(true) -> <v0> PREV:[mark(l@ while(true) { 1 if (2 > 3) { break@l } }), jmp(L3)] |
| mark(while(true) { 1 if (2 > 3) { break@l } }) |
| magic[VALUE_CONSUMER](true|<v0>) -> <v1> |
| L5 [body entry point]: |
| 4 mark({ 1 if (2 > 3) { break@l } }) |
| r(1) -> <v2> |
| mark(if (2 > 3) { break@l }) |
| r(2) -> <v3> |
| r(3) -> <v4> |
| mark(2 > 3) |
| call(2 > 3, compareTo|<v3>, <v4>) -> <v5> |
| jf(L8|<v5>) NEXT:[read (Unit), mark({ break@l })] |
| 5 mark({ break@l }) |
| jmp(L4) NEXT:[read (Unit)] |
| - 4 jmp(L9) NEXT:[merge(if (2 > 3) { break@l }|!<v6>) -> <v7>] PREV:[] |
| L8 [else branch]: |
| read (Unit) PREV:[jf(L8|<v5>)] |
| L9 ['if' expression result]: |
| merge(if (2 > 3) { break@l }|!<v6>) -> <v7> |
| 3 jmp(L3) NEXT:[r(true) -> <v0>] |
| L4 [loop exit point]: |
| L6 [body exit point]: |
| read (Unit) PREV:[jmp(L4)] |
| r(5) -> <v9> |
| 2 jmp?(L2) NEXT:[mark({ 2 }), jmp(L10)] |
| jmp(L10) NEXT:[mark({ 2 })] |
| L2 [onExceptionToFinallyBlock]: |
| L11 [start finally]: |
| 3 mark({ 2 }) PREV:[jmp?(L2), jmp?(L2)] |
| r(2) -> <v10> |
| L12 [finish finally]: |
| 2 jmp(error) NEXT:[<ERROR>] |
| L10 [skipFinallyToErrorBlock]: |
| L13 [copy of L2, onExceptionToFinallyBlock]: |
| 3 mark({ 2 }) PREV:[jmp(L10)] |
| r(2) -> <v10> |
| 2 merge(try { l@ while(true) { 1 if (2 > 3) { break@l } } 5 } finally { 2 }|<v9>) -> <v11> |
| L1: |
| 1 <END> NEXT:[<SINK>] |
| error: |
| <ERROR> PREV:[jmp(error)] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == t7 == |
| fun t7() { |
| try { |
| l@ while(true) { |
| 1 |
| if (2 > 3) { |
| break@l |
| } |
| } |
| } finally { |
| 2 |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| 2 mark({ try { l@ while(true) { 1 if (2 > 3) { break@l } } } finally { 2 } }) |
| mark(try { l@ while(true) { 1 if (2 > 3) { break@l } } } finally { 2 }) |
| jmp?(L2) NEXT:[mark({ 2 }), mark({ l@ while(true) { 1 if (2 > 3) { break@l } } })] |
| 3 mark({ l@ while(true) { 1 if (2 > 3) { break@l } } }) |
| mark(l@ while(true) { 1 if (2 > 3) { break@l } }) |
| L3 [loop entry point]: |
| L7 [condition entry point]: |
| r(true) -> <v0> PREV:[mark(l@ while(true) { 1 if (2 > 3) { break@l } }), jmp(L3)] |
| mark(while(true) { 1 if (2 > 3) { break@l } }) |
| magic[VALUE_CONSUMER](true|<v0>) -> <v1> |
| L5 [body entry point]: |
| 4 mark({ 1 if (2 > 3) { break@l } }) |
| r(1) -> <v2> |
| mark(if (2 > 3) { break@l }) |
| r(2) -> <v3> |
| r(3) -> <v4> |
| mark(2 > 3) |
| call(2 > 3, compareTo|<v3>, <v4>) -> <v5> |
| jf(L8|<v5>) NEXT:[read (Unit), mark({ break@l })] |
| 5 mark({ break@l }) |
| jmp(L4) NEXT:[read (Unit)] |
| - 4 jmp(L9) NEXT:[merge(if (2 > 3) { break@l }|!<v6>) -> <v7>] PREV:[] |
| L8 [else branch]: |
| read (Unit) PREV:[jf(L8|<v5>)] |
| L9 ['if' expression result]: |
| merge(if (2 > 3) { break@l }|!<v6>) -> <v7> |
| 3 jmp(L3) NEXT:[r(true) -> <v0>] |
| L4 [loop exit point]: |
| L6 [body exit point]: |
| read (Unit) PREV:[jmp(L4)] |
| 2 jmp?(L2) NEXT:[mark({ 2 }), jmp(L10)] |
| jmp(L10) NEXT:[mark({ 2 })] |
| L2 [onExceptionToFinallyBlock]: |
| L11 [start finally]: |
| 3 mark({ 2 }) PREV:[jmp?(L2), jmp?(L2)] |
| r(2) -> <v9> |
| L12 [finish finally]: |
| 2 jmp(error) NEXT:[<ERROR>] |
| L10 [skipFinallyToErrorBlock]: |
| L13 [copy of L2, onExceptionToFinallyBlock]: |
| 3 mark({ 2 }) PREV:[jmp(L10)] |
| r(2) -> <v9> |
| 2 merge(try { l@ while(true) { 1 if (2 > 3) { break@l } } } finally { 2 }|!<v8>) -> <v10> |
| L1: |
| 1 <END> NEXT:[<SINK>] |
| error: |
| <ERROR> PREV:[jmp(error)] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == t8 == |
| fun t8(a : Int) { |
| l@ for (i in 1..a) { |
| try { |
| 1 |
| if (2 > 3) { |
| continue@l |
| } |
| } finally { |
| 2 |
| } |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| v(a : Int) |
| magic[FAKE_INITIALIZER](a : Int) -> <v0> |
| w(a|<v0>) |
| 2 mark({ l@ for (i in 1..a) { try { 1 if (2 > 3) { continue@l } } finally { 2 } } }) |
| mark(l@ for (i in 1..a) { try { 1 if (2 > 3) { continue@l } } finally { 2 } }) |
| 3 r(1) -> <v1> |
| r(a) -> <v2> |
| mark(1..a) |
| call(1..a, rangeTo|<v1>, <v2>) -> <v3> |
| mark(1..a) |
| call(1..a, iterator|<v3>) -> <v4> |
| v(i) |
| L2 [loop entry point]: |
| L6 [condition entry point]: |
| mark(1..a) PREV:[v(i), jmp(L6), jmp(L2)] |
| call(1..a, hasNext) -> <v5> |
| jmp?(L3) NEXT:[read (Unit), mark(1..a)] |
| mark(1..a) |
| call(1..a, next) -> <v6> |
| magic[LOOP_RANGE_ITERATION](1..a|<v6>) -> <v7> |
| w(i|<v7>) |
| mark(for (i in 1..a) { try { 1 if (2 > 3) { continue@l } } finally { 2 } }) |
| L4 [body entry point]: |
| 4 mark({ try { 1 if (2 > 3) { continue@l } } finally { 2 } }) |
| mark(try { 1 if (2 > 3) { continue@l } } finally { 2 }) |
| jmp?(L7) NEXT:[mark({ 2 }), mark({ 1 if (2 > 3) { continue@l } })] |
| 5 mark({ 1 if (2 > 3) { continue@l } }) |
| r(1) -> <v8> |
| mark(if (2 > 3) { continue@l }) |
| r(2) -> <v9> |
| r(3) -> <v10> |
| mark(2 > 3) |
| call(2 > 3, compareTo|<v9>, <v10>) -> <v11> |
| jf(L8|<v11>) NEXT:[read (Unit), mark({ continue@l })] |
| 6 mark({ continue@l }) |
| jmp?(L7) NEXT:[mark({ 2 }), mark({ 2 })] |
| L9 [start finally]: |
| 7 mark({ 2 }) |
| r(2) -> <v12> |
| L10 [finish finally]: |
| 6 jmp(L6) NEXT:[mark(1..a)] |
| - 5 jmp(L11) NEXT:[merge(if (2 > 3) { continue@l }|!<v13>) -> <v14>] PREV:[] |
| L8 [else branch]: |
| read (Unit) PREV:[jf(L8|<v11>)] |
| L11 ['if' expression result]: |
| merge(if (2 > 3) { continue@l }|!<v13>) -> <v14> |
| 4 jmp?(L7) NEXT:[mark({ 2 }), jmp(L12)] |
| jmp(L12) NEXT:[mark({ 2 })] |
| L7 [onExceptionToFinallyBlock]: |
| 7 mark({ 2 }) PREV:[jmp?(L7), jmp?(L7), jmp?(L7)] |
| r(2) -> <v12> |
| 4 jmp(error) NEXT:[<ERROR>] |
| L12 [skipFinallyToErrorBlock]: |
| 7 mark({ 2 }) PREV:[jmp(L12)] |
| r(2) -> <v12> |
| 4 merge(try { 1 if (2 > 3) { continue@l } } finally { 2 }|<v14>) -> <v15> |
| 3 jmp(L2) NEXT:[mark(1..a)] |
| L3 [loop exit point]: |
| L5 [body exit point]: |
| read (Unit) PREV:[jmp?(L3)] |
| L1: |
| 1 <END> NEXT:[<SINK>] |
| error: |
| <ERROR> PREV:[jmp(error)] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == t9 == |
| fun t9(a : Int) { |
| try { |
| l@ for (i in 1..a) { |
| 1 |
| if (2 > 3) { |
| continue@l |
| } |
| } |
| 5 |
| } finally { |
| 2 |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| v(a : Int) |
| magic[FAKE_INITIALIZER](a : Int) -> <v0> |
| w(a|<v0>) |
| 2 mark({ try { l@ for (i in 1..a) { 1 if (2 > 3) { continue@l } } 5 } finally { 2 } }) |
| mark(try { l@ for (i in 1..a) { 1 if (2 > 3) { continue@l } } 5 } finally { 2 }) |
| jmp?(L2) NEXT:[mark({ 2 }), mark({ l@ for (i in 1..a) { 1 if (2 > 3) { continue@l } } 5 })] |
| 3 mark({ l@ for (i in 1..a) { 1 if (2 > 3) { continue@l } } 5 }) |
| mark(l@ for (i in 1..a) { 1 if (2 > 3) { continue@l } }) |
| 4 r(1) -> <v1> |
| r(a) -> <v2> |
| mark(1..a) |
| call(1..a, rangeTo|<v1>, <v2>) -> <v3> |
| mark(1..a) |
| call(1..a, iterator|<v3>) -> <v4> |
| v(i) |
| L3 [loop entry point]: |
| L7 [condition entry point]: |
| mark(1..a) PREV:[v(i), jmp(L7), jmp(L3)] |
| call(1..a, hasNext) -> <v5> |
| jmp?(L4) NEXT:[read (Unit), mark(1..a)] |
| mark(1..a) |
| call(1..a, next) -> <v6> |
| magic[LOOP_RANGE_ITERATION](1..a|<v6>) -> <v7> |
| w(i|<v7>) |
| mark(for (i in 1..a) { 1 if (2 > 3) { continue@l } }) |
| L5 [body entry point]: |
| 5 mark({ 1 if (2 > 3) { continue@l } }) |
| r(1) -> <v8> |
| mark(if (2 > 3) { continue@l }) |
| r(2) -> <v9> |
| r(3) -> <v10> |
| mark(2 > 3) |
| call(2 > 3, compareTo|<v9>, <v10>) -> <v11> |
| jf(L8|<v11>) NEXT:[read (Unit), mark({ continue@l })] |
| 6 mark({ continue@l }) |
| jmp(L7) NEXT:[mark(1..a)] |
| - 5 jmp(L9) NEXT:[merge(if (2 > 3) { continue@l }|!<v12>) -> <v13>] PREV:[] |
| L8 [else branch]: |
| read (Unit) PREV:[jf(L8|<v11>)] |
| L9 ['if' expression result]: |
| merge(if (2 > 3) { continue@l }|!<v12>) -> <v13> |
| 4 jmp(L3) NEXT:[mark(1..a)] |
| L4 [loop exit point]: |
| L6 [body exit point]: |
| read (Unit) PREV:[jmp?(L4)] |
| 3 r(5) -> <v15> |
| 2 jmp?(L2) NEXT:[mark({ 2 }), jmp(L10)] |
| jmp(L10) NEXT:[mark({ 2 })] |
| L2 [onExceptionToFinallyBlock]: |
| L11 [start finally]: |
| 3 mark({ 2 }) PREV:[jmp?(L2), jmp?(L2)] |
| r(2) -> <v16> |
| L12 [finish finally]: |
| 2 jmp(error) NEXT:[<ERROR>] |
| L10 [skipFinallyToErrorBlock]: |
| L13 [copy of L2, onExceptionToFinallyBlock]: |
| 3 mark({ 2 }) PREV:[jmp(L10)] |
| r(2) -> <v16> |
| 2 merge(try { l@ for (i in 1..a) { 1 if (2 > 3) { continue@l } } 5 } finally { 2 }|<v15>) -> <v17> |
| L1: |
| 1 <END> NEXT:[<SINK>] |
| error: |
| <ERROR> PREV:[jmp(error)] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == t10 == |
| fun t10(a : Int) { |
| try { |
| l@ for (i in 1..a) { |
| 1 |
| if (2 > 3) { |
| continue@l |
| } |
| } |
| } finally { |
| 2 |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| v(a : Int) |
| magic[FAKE_INITIALIZER](a : Int) -> <v0> |
| w(a|<v0>) |
| 2 mark({ try { l@ for (i in 1..a) { 1 if (2 > 3) { continue@l } } } finally { 2 } }) |
| mark(try { l@ for (i in 1..a) { 1 if (2 > 3) { continue@l } } } finally { 2 }) |
| jmp?(L2) NEXT:[mark({ 2 }), mark({ l@ for (i in 1..a) { 1 if (2 > 3) { continue@l } } })] |
| 3 mark({ l@ for (i in 1..a) { 1 if (2 > 3) { continue@l } } }) |
| mark(l@ for (i in 1..a) { 1 if (2 > 3) { continue@l } }) |
| 4 r(1) -> <v1> |
| r(a) -> <v2> |
| mark(1..a) |
| call(1..a, rangeTo|<v1>, <v2>) -> <v3> |
| mark(1..a) |
| call(1..a, iterator|<v3>) -> <v4> |
| v(i) |
| L3 [loop entry point]: |
| L7 [condition entry point]: |
| mark(1..a) PREV:[v(i), jmp(L7), jmp(L3)] |
| call(1..a, hasNext) -> <v5> |
| jmp?(L4) NEXT:[read (Unit), mark(1..a)] |
| mark(1..a) |
| call(1..a, next) -> <v6> |
| magic[LOOP_RANGE_ITERATION](1..a|<v6>) -> <v7> |
| w(i|<v7>) |
| mark(for (i in 1..a) { 1 if (2 > 3) { continue@l } }) |
| L5 [body entry point]: |
| 5 mark({ 1 if (2 > 3) { continue@l } }) |
| r(1) -> <v8> |
| mark(if (2 > 3) { continue@l }) |
| r(2) -> <v9> |
| r(3) -> <v10> |
| mark(2 > 3) |
| call(2 > 3, compareTo|<v9>, <v10>) -> <v11> |
| jf(L8|<v11>) NEXT:[read (Unit), mark({ continue@l })] |
| 6 mark({ continue@l }) |
| jmp(L7) NEXT:[mark(1..a)] |
| - 5 jmp(L9) NEXT:[merge(if (2 > 3) { continue@l }|!<v12>) -> <v13>] PREV:[] |
| L8 [else branch]: |
| read (Unit) PREV:[jf(L8|<v11>)] |
| L9 ['if' expression result]: |
| merge(if (2 > 3) { continue@l }|!<v12>) -> <v13> |
| 4 jmp(L3) NEXT:[mark(1..a)] |
| L4 [loop exit point]: |
| L6 [body exit point]: |
| read (Unit) PREV:[jmp?(L4)] |
| 2 jmp?(L2) NEXT:[mark({ 2 }), jmp(L10)] |
| jmp(L10) NEXT:[mark({ 2 })] |
| L2 [onExceptionToFinallyBlock]: |
| L11 [start finally]: |
| 3 mark({ 2 }) PREV:[jmp?(L2), jmp?(L2)] |
| r(2) -> <v15> |
| L12 [finish finally]: |
| 2 jmp(error) NEXT:[<ERROR>] |
| L10 [skipFinallyToErrorBlock]: |
| L13 [copy of L2, onExceptionToFinallyBlock]: |
| 3 mark({ 2 }) PREV:[jmp(L10)] |
| r(2) -> <v15> |
| 2 merge(try { l@ for (i in 1..a) { 1 if (2 > 3) { continue@l } } } finally { 2 }|!<v14>) -> <v16> |
| L1: |
| 1 <END> NEXT:[<SINK>] |
| error: |
| <ERROR> PREV:[jmp(error)] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == t11 == |
| fun t11() { |
| try { |
| return 1 |
| } |
| finally { |
| return 2 |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| 2 mark({ try { return 1 } finally { return 2 } }) |
| mark(try { return 1 } finally { return 2 }) |
| jmp?(L2) NEXT:[mark({ return 2 }), mark({ return 1 })] |
| 3 mark({ return 1 }) |
| jmp?(L2) NEXT:[mark({ return 2 }), r(1) -> <v0>] |
| r(1) -> <v0> |
| L3 [start finally]: |
| 4 mark({ return 2 }) |
| r(2) -> <v1> |
| ret(*|<v1>) L1 NEXT:[<END>] |
| L4 [finish finally]: |
| - 3 ret(*|<v0>) L1 NEXT:[<END>] PREV:[] |
| - 2 jmp?(L2) NEXT:[mark({ return 2 }), jmp(L5)] PREV:[] |
| - jmp(L5) NEXT:[mark({ return 2 })] PREV:[] |
| L2 [onExceptionToFinallyBlock]: |
| 4 mark({ return 2 }) PREV:[jmp?(L2), jmp?(L2)] |
| r(2) -> <v1> |
| ret(*|<v1>) L1 NEXT:[<END>] |
| - 2 jmp(error) NEXT:[<ERROR>] PREV:[] |
| L5 [skipFinallyToErrorBlock]: |
| - 4 mark({ return 2 }) PREV:[] |
| - r(2) -> <v1> PREV:[] |
| - ret(*|<v1>) L1 NEXT:[<END>] PREV:[] |
| - 2 merge(try { return 1 } finally { return 2 }|!<v3>) -> <v4> PREV:[] |
| L1: |
| 1 <END> NEXT:[<SINK>] PREV:[ret(*|<v1>) L1, ret(*|<v1>) L1] |
| error: |
| <ERROR> PREV:[] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == t12 == |
| fun t12() : Int { |
| try { |
| return 1 |
| } |
| finally { |
| doSmth(3) |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| 2 mark({ try { return 1 } finally { doSmth(3) } }) |
| mark(try { return 1 } finally { doSmth(3) }) |
| jmp?(L2) NEXT:[mark({ doSmth(3) }), mark({ return 1 })] |
| 3 mark({ return 1 }) |
| jmp?(L2) NEXT:[mark({ doSmth(3) }), r(1) -> <v0>] |
| r(1) -> <v0> |
| L3 [start finally]: |
| 4 mark({ doSmth(3) }) |
| r(3) -> <v1> |
| mark(doSmth(3)) |
| call(doSmth(3), doSmth|<v1>) -> <v2> |
| L4 [finish finally]: |
| 3 ret(*|<v0>) L1 NEXT:[<END>] |
| - 2 jmp?(L2) NEXT:[mark({ doSmth(3) }), jmp(L5)] PREV:[] |
| - jmp(L5) NEXT:[mark({ doSmth(3) })] PREV:[] |
| L2 [onExceptionToFinallyBlock]: |
| 4 mark({ doSmth(3) }) PREV:[jmp?(L2), jmp?(L2)] |
| r(3) -> <v1> |
| mark(doSmth(3)) |
| call(doSmth(3), doSmth|<v1>) -> <v2> |
| 2 jmp(error) NEXT:[<ERROR>] |
| L5 [skipFinallyToErrorBlock]: |
| - 4 mark({ doSmth(3) }) PREV:[] |
| - r(3) -> <v1> PREV:[] |
| - mark(doSmth(3)) PREV:[] |
| - call(doSmth(3), doSmth|<v1>) -> <v2> PREV:[] |
| - 2 merge(try { return 1 } finally { doSmth(3) }|!<v3>) -> <v4> PREV:[] |
| L1: |
| 1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1] |
| error: |
| <ERROR> PREV:[jmp(error)] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == t13 == |
| fun t13() : Int { |
| try { |
| return 1 |
| } |
| catch (e: UnsupportedOperationException) { |
| doSmth(2) |
| } |
| finally { |
| doSmth(3) |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| 2 mark({ try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } finally { doSmth(3) } }) |
| mark(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } finally { doSmth(3) }) |
| jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp?(L3)] |
| jmp?(L3) NEXT:[mark({ doSmth(3) }), mark({ return 1 })] |
| 3 mark({ return 1 }) |
| jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp?(L3)] |
| jmp?(L3) NEXT:[mark({ doSmth(3) }), r(1) -> <v0>] |
| r(1) -> <v0> |
| L4 [start finally]: |
| 4 mark({ doSmth(3) }) |
| r(3) -> <v1> |
| mark(doSmth(3)) |
| call(doSmth(3), doSmth|<v1>) -> <v2> |
| L5 [finish finally]: |
| 3 ret(*|<v0>) L1 NEXT:[<END>] |
| - 2 jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp?(L3)] PREV:[] |
| - jmp?(L3) NEXT:[mark({ doSmth(3) }), jmp(L6)] PREV:[] |
| - jmp(L6) NEXT:[jmp(L7)] PREV:[] |
| L2 [onException]: |
| 3 v(e: UnsupportedOperationException) PREV:[jmp?(L2), jmp?(L2)] |
| magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v4> |
| w(e|<v4>) |
| 4 mark({ doSmth(2) }) |
| r(2) -> <v5> |
| mark(doSmth(2)) |
| call(doSmth(2), doSmth|<v5>) -> <v6> |
| 3 jmp(L6) |
| L6 [afterCatches]: |
| 2 jmp(L7) NEXT:[mark({ doSmth(3) })] |
| L3 [onExceptionToFinallyBlock]: |
| 4 mark({ doSmth(3) }) PREV:[jmp?(L3), jmp?(L3)] |
| r(3) -> <v1> |
| mark(doSmth(3)) |
| call(doSmth(3), doSmth|<v1>) -> <v2> |
| 2 jmp(error) NEXT:[<ERROR>] |
| L7 [skipFinallyToErrorBlock]: |
| 4 mark({ doSmth(3) }) PREV:[jmp(L7)] |
| r(3) -> <v1> |
| mark(doSmth(3)) |
| call(doSmth(3), doSmth|<v1>) -> <v2> |
| 2 merge(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } finally { doSmth(3) }|!<v3>, <v6>) -> <v7> |
| L1: |
| 1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, merge(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } finally { doSmth(3) }|!<v3>, <v6>) -> <v7>] |
| error: |
| <ERROR> PREV:[jmp(error)] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == t14 == |
| fun t14() : Int { |
| try { |
| return 1 |
| } |
| catch (e: UnsupportedOperationException) { |
| doSmth(2) |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| 2 mark({ try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) } }) |
| mark(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) }) |
| jmp?(L2) NEXT:[v(e: UnsupportedOperationException), mark({ return 1 })] |
| 3 mark({ return 1 }) |
| jmp?(L2) NEXT:[v(e: UnsupportedOperationException), r(1) -> <v0>] |
| r(1) -> <v0> |
| ret(*|<v0>) L1 NEXT:[<END>] |
| - 2 jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp(L3)] PREV:[] |
| - jmp(L3) NEXT:[merge(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) }|!<v1>, <v4>) -> <v5>] PREV:[] |
| L2 [onException]: |
| 3 v(e: UnsupportedOperationException) PREV:[jmp?(L2), jmp?(L2)] |
| magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v2> |
| w(e|<v2>) |
| 4 mark({ doSmth(2) }) |
| r(2) -> <v3> |
| mark(doSmth(2)) |
| call(doSmth(2), doSmth|<v3>) -> <v4> |
| 3 jmp(L3) |
| L3 [afterCatches]: |
| 2 merge(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) }|!<v1>, <v4>) -> <v5> |
| L1: |
| 1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, merge(try { return 1 } catch (e: UnsupportedOperationException) { doSmth(2) }|!<v1>, <v4>) -> <v5>] |
| error: |
| <ERROR> PREV:[] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == t15 == |
| fun t15() : Int { |
| try { |
| return 1 |
| } |
| catch (e: UnsupportedOperationException) { |
| return 2 |
| } |
| finally { |
| doSmth(3) |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| 2 mark({ try { return 1 } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) } }) |
| mark(try { return 1 } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) }) |
| jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp?(L3)] |
| jmp?(L3) NEXT:[mark({ doSmth(3) }), mark({ return 1 })] |
| 3 mark({ return 1 }) |
| jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp?(L3)] |
| jmp?(L3) NEXT:[mark({ doSmth(3) }), r(1) -> <v0>] |
| r(1) -> <v0> |
| L4 [start finally]: |
| 4 mark({ doSmth(3) }) |
| r(3) -> <v1> |
| mark(doSmth(3)) |
| call(doSmth(3), doSmth|<v1>) -> <v2> |
| L5 [finish finally]: |
| 3 ret(*|<v0>) L1 NEXT:[<END>] |
| - 2 jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp?(L3)] PREV:[] |
| - jmp?(L3) NEXT:[mark({ doSmth(3) }), jmp(L6)] PREV:[] |
| - jmp(L6) NEXT:[jmp(L7)] PREV:[] |
| L2 [onException]: |
| 3 v(e: UnsupportedOperationException) PREV:[jmp?(L2), jmp?(L2)] |
| magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v4> |
| w(e|<v4>) |
| 4 mark({ return 2 }) |
| r(2) -> <v5> |
| mark({ doSmth(3) }) |
| r(3) -> <v1> |
| mark(doSmth(3)) |
| call(doSmth(3), doSmth|<v1>) -> <v2> |
| ret(*|<v5>) L1 NEXT:[<END>] |
| - 3 jmp(L6) PREV:[] |
| L6 [afterCatches]: |
| - 2 jmp(L7) NEXT:[mark({ doSmth(3) })] PREV:[] |
| L3 [onExceptionToFinallyBlock]: |
| 4 mark({ doSmth(3) }) PREV:[jmp?(L3), jmp?(L3)] |
| r(3) -> <v1> |
| mark(doSmth(3)) |
| call(doSmth(3), doSmth|<v1>) -> <v2> |
| 2 jmp(error) NEXT:[<ERROR>] |
| L7 [skipFinallyToErrorBlock]: |
| - 4 mark({ doSmth(3) }) PREV:[] |
| - r(3) -> <v1> PREV:[] |
| - mark(doSmth(3)) PREV:[] |
| - call(doSmth(3), doSmth|<v1>) -> <v2> PREV:[] |
| - 2 merge(try { return 1 } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) }|!<v3>, !<v6>) -> <v7> PREV:[] |
| L1: |
| 1 <END> NEXT:[<SINK>] PREV:[ret(*|<v0>) L1, ret(*|<v5>) L1] |
| error: |
| <ERROR> PREV:[jmp(error)] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == t16 == |
| fun t16() : Int { |
| try { |
| doSmth(1) |
| } |
| catch (e: UnsupportedOperationException) { |
| return 2 |
| } |
| finally { |
| doSmth(3) |
| } |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| 2 mark({ try { doSmth(1) } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) } }) |
| mark(try { doSmth(1) } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) }) |
| jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp?(L3)] |
| jmp?(L3) NEXT:[mark({ doSmth(3) }), mark({ doSmth(1) })] |
| 3 mark({ doSmth(1) }) |
| r(1) -> <v0> |
| mark(doSmth(1)) |
| call(doSmth(1), doSmth|<v0>) -> <v1> |
| 2 jmp?(L2) NEXT:[v(e: UnsupportedOperationException), jmp?(L3)] |
| jmp?(L3) NEXT:[mark({ doSmth(3) }), jmp(L4)] |
| jmp(L4) NEXT:[jmp(L7)] |
| L2 [onException]: |
| 3 v(e: UnsupportedOperationException) PREV:[jmp?(L2), jmp?(L2)] |
| magic[FAKE_INITIALIZER](e: UnsupportedOperationException) -> <v2> |
| w(e|<v2>) |
| 4 mark({ return 2 }) |
| r(2) -> <v3> |
| L5 [start finally]: |
| 5 mark({ doSmth(3) }) |
| r(3) -> <v4> |
| mark(doSmth(3)) |
| call(doSmth(3), doSmth|<v4>) -> <v5> |
| L6 [finish finally]: |
| 4 ret(*|<v3>) L1 NEXT:[<END>] |
| - 3 jmp(L4) PREV:[] |
| L4 [afterCatches]: |
| 2 jmp(L7) NEXT:[mark({ doSmth(3) })] PREV:[jmp(L4)] |
| L3 [onExceptionToFinallyBlock]: |
| 5 mark({ doSmth(3) }) PREV:[jmp?(L3), jmp?(L3)] |
| r(3) -> <v4> |
| mark(doSmth(3)) |
| call(doSmth(3), doSmth|<v4>) -> <v5> |
| 2 jmp(error) NEXT:[<ERROR>] |
| L7 [skipFinallyToErrorBlock]: |
| 5 mark({ doSmth(3) }) PREV:[jmp(L7)] |
| r(3) -> <v4> |
| mark(doSmth(3)) |
| call(doSmth(3), doSmth|<v4>) -> <v5> |
| 2 merge(try { doSmth(1) } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) }|<v1>, !<v6>) -> <v7> |
| L1: |
| 1 <END> NEXT:[<SINK>] PREV:[ret(*|<v3>) L1, merge(try { doSmth(1) } catch (e: UnsupportedOperationException) { return 2 } finally { doSmth(3) }|<v1>, !<v6>) -> <v7>] |
| error: |
| <ERROR> PREV:[jmp(error)] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |
| == doSmth == |
| fun doSmth(i: Int) { |
| } |
| --------------------- |
| L0: |
| 1 <START> |
| v(i: Int) |
| magic[FAKE_INITIALIZER](i: Int) -> <v0> |
| w(i|<v0>) |
| 2 mark({ }) |
| read (Unit) |
| L1: |
| 1 <END> NEXT:[<SINK>] |
| error: |
| <ERROR> PREV:[] |
| sink: |
| <SINK> PREV:[<ERROR>, <END>] |
| ===================== |