diff options
-rw-r--r-- | lib/compiler/src/beam_validator.erl | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 9598970b86..4633bda2e0 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -516,20 +516,32 @@ valfun_1(I, Vst) -> init_try_catch_branch(Tag, Dst, Fail, Vst0) -> Vst1 = create_tag({Tag,[Fail]}, 'try_catch', [], Dst, Vst0), #vst{current=#st{ct=Fails}=St0} = Vst1, - CurrentSt = St0#st{ct=[[Fail]|Fails]}, - - %% Set the initial state at the try/catch label. - %% Assume that Y registers contain terms or try/catch - %% tags. - Yregs0 = map(fun({Y,uninitialized}) -> {Y,term}; - ({Y,initialized}) -> {Y,term}; - (E) -> E - end, gb_trees:to_list(CurrentSt#st.y)), - Yregs = gb_trees:from_orddict(Yregs0), - BranchSt = CurrentSt#st{y=Yregs}, - - Vst = branch_state(Fail, Vst1#vst{current=BranchSt}), - Vst#vst{current=CurrentSt}. + St = St0#st{ct=[[Fail]|Fails]}, + Vst = Vst0#vst{current=St}, + + complex_test(Fail, + fun(CatchVst) -> + #vst{current=#st{y=Ys}} = CatchVst, + init_catch_handler_1(gb_trees:keys(Ys), CatchVst) + end, + fun(SuccVst) -> + SuccVst + end, Vst). + +%% Set the initial state at the try/catch label. Assume that Y registers +%% contain terms or try/catch tags. +init_catch_handler_1([Reg | Regs], Vst0) -> + Vst = case get_raw_type(Reg, Vst0) of + initialized -> + create_term(term, 'catch_handler', [], Reg, Vst0); + uninitialized -> + create_term(term, 'catch_handler', [], Reg, Vst0); + _ -> + Vst0 + end, + init_catch_handler_1(Regs, Vst); +init_catch_handler_1([], Vst) -> + Vst. %% Update branched state if necessary and try next set of instructions. valfun_2(I, #vst{current=#st{ct=[]}}=Vst) -> |