Skip to content

Commit

Permalink
[hl] hlopt rework try-catch control flow (#11581)
Browse files Browse the repository at this point in the history
closes #11466, closes #9174
  • Loading branch information
yuxiaomao authored and kLabz committed Mar 4, 2024
1 parent 7517ebc commit 09d1bad
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 6 deletions.
36 changes: 30 additions & 6 deletions src/generators/hlopt.ml
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@ type block = {
mutable bneed : ISet.t;
mutable bneed_all : ISet.t option;
mutable bwrite : (int, int) PMap.t;
mutable btrap : int list;
}

type control =
| CNo
| CJCond of int
| CJAlways of int
| CTry of int
| CCatch
| CSwitch of int array
| CRet
| CThrow
Expand All @@ -75,6 +77,8 @@ let control = function
CSwitch cases
| OTrap (_,d) ->
CTry d
| OEndTrap _ ->
CCatch
| _ ->
CNo

Expand Down Expand Up @@ -444,7 +448,7 @@ let code_graph (f:fundecl) =
| CJAlways d | CJCond d -> Hashtbl.replace all_blocks (i + 1 + d) true
| _ -> ()
done;
let rec make_block pos =
let rec make_block trapl pos =
try
Hashtbl.find blocks_pos pos
with Not_found ->
Expand All @@ -458,11 +462,12 @@ let code_graph (f:fundecl) =
bneed = ISet.empty;
bwrite = PMap.empty;
bneed_all = None;
btrap = trapl;
} in
Hashtbl.add blocks_pos pos b;
let rec loop i =
let goto d =
let b2 = make_block (i + 1 + d) in
let goto ?(tl=b.btrap) d =
let b2 = make_block tl (i + 1 + d) in
b2.bprev <- b :: b2.bprev;
b2
in
Expand All @@ -472,25 +477,44 @@ let code_graph (f:fundecl) =
end else match control (op i) with
| CNo ->
loop (i + 1)
| CRet | CThrow ->
| CRet ->
assert(b.btrap = []);
b.bend <- i
| CJAlways d ->
b.bend <- i;
b.bnext <- [goto d];
| CSwitch pl ->
b.bend <- i;
b.bnext <- goto 0 :: Array.to_list (Array.map goto pl)
| CJCond d | CTry d ->
| CJCond d ->
b.bend <- i;
b.bnext <- [goto 0; goto d];
| CTry d ->
b.bend <- i;
b.bnext <- [goto ~tl:((i+1+d)::b.btrap) 0; goto d];
| CThrow ->
b.bend <- i;
match b.btrap with
| [] -> ()
| [p] -> b.bnext <- [goto ~tl:[] (p-1-i)];
| p :: pl -> b.bnext <- [goto ~tl:pl (p-1-i)];
;
| CCatch ->
let p, pl = match b.btrap with
| [] -> assert false;
| [p] -> p, []
| p :: pl -> p, pl
in
b.bend <- i;
b.bnext <- [goto ~tl:pl 0; goto ~tl:pl (p-1-i)];
| CLabel ->
b.bloop <- true;
loop (i + 1)
in
loop pos;
b
in
blocks_pos, make_block 0
blocks_pos, make_block [] 0

type rctx = {
r_root : block;
Expand Down
30 changes: 30 additions & 0 deletions tests/unit/src/unit/issues/Issue11466.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package unit.issues;

private function doThrow() {
throw "from doThrow";
}

class Issue11466 extends unit.Test {
var b = 10;
function test() {
var x = 0;
try {
x = b;
throw '';
} catch(_) {
x += 1;
}
eq(11, x);
}

function test2() {
var x = 0;
try {
x = b;
doThrow();
} catch(_) {
x += 1;
}
eq(11, x);
}
}
37 changes: 37 additions & 0 deletions tests/unit/src/unit/issues/Issue9174.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package unit.issues;

private function doThrow() {
throw "from doThrow";
}

class Issue9174 extends unit.Test {
function test() {
var value = "";
try {
try {
throw "from throw";
} catch (e:String) {
value += "inner catch";
throw e;
}
} catch (e:String) {
value += ", outer catch, " + e;
}
eq("inner catch, outer catch, from throw", value);
}

function test2() {
var value = "";
try {
try {
doThrow();
} catch (e:String) {
value += "inner catch";
throw e;
}
} catch (e:String) {
value += ", outer catch, " + e;
}
eq("inner catch, outer catch, from doThrow", value);
}
}

0 comments on commit 09d1bad

Please sign in to comment.