Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[hl] hlopt rework try-catch control flow #11581

Merged
merged 7 commits into from Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 30 additions & 6 deletions src/generators/hlopt.ml
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 @@ -460,7 +464,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 @@ -474,11 +478,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 @@ -488,25 +493,44 @@ let code_graph (f:fundecl) =
end else match control (op i) with
| CNo ->
loop (i + 1)
| CRet | CThrow ->
| CRet ->
assert(b.btrap == []);
yuxiaomao marked this conversation as resolved.
Show resolved Hide resolved
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
15 changes: 15 additions & 0 deletions tests/unit/src/unit/issues/Issue11466.hx
@@ -0,0 +1,15 @@
package unit.issues;

class Issue11466 extends unit.Test {
var b = 10;
function test() {
var x = 0;
try {
x = b;
throw '';
} catch(_) {
x += 1;
}
eq(11, x);
}
}
18 changes: 18 additions & 0 deletions tests/unit/src/unit/issues/Issue9174.hx
@@ -0,0 +1,18 @@
package unit.issues;

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