%% -*- erlang-indent-level: 2 -*- %% %% %CopyrightBegin% %% %% Copyright Ericsson AB 2001-2009. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. %% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. %% %% %CopyrightEnd% %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Copyright (c) 2001 by Erik Johansson. All Rights Reserved %% ==================================================================== %% Filename : hipe_rtl_exceptions.erl %% Module : hipe_rtl_exceptions %% Purpose : %% Notes : %% History : * 2001-04-10 Erik Johansson (happi@it.uu.se): %% Created. %% CVS : %% $Id$ %% ==================================================================== %% Exports : %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -module(hipe_rtl_exceptions). -export([gen_fail/3, gen_begin_handler/3]). -include("../main/hipe.hrl"). -include("hipe_literals.hrl"). %% -------------------------------------------------------------------- %% Handle the Icode instruction %% FAIL %% gen_fail(Class, Args, L) -> case Args of [Reason] -> case Class of exit -> gen_exit(Reason, L); throw -> gen_throw(Reason, L); error -> gen_error(Reason, L) end; [Arg1,Arg2] -> case Class of error -> Reason = Arg1, ArgList = Arg2, gen_error(Reason, ArgList, L); rethrow -> Exception = Arg1, Reason = Arg2, gen_rethrow(Exception, Reason, L) end end. %% -------------------------------------------------------------------- %% Exception handler glue; interfaces between the runtime system's %% exception state and the Icode view of exception handling. gen_begin_handler(I, VarMap, ConstTab) -> Ds = hipe_icode:begin_handler_dstlist(I), {Vars, VarMap1} = hipe_rtl_varmap:ivs2rvs(Ds, VarMap), [FTagVar,FValueVar,FTraceVar] = Vars, {[hipe_rtl:mk_comment('begin_handler'), hipe_rtl_arch:pcb_load(FValueVar, ?P_FVALUE), hipe_rtl_arch:pcb_load(FTraceVar, ?P_FTRACE), %% synthesized from P->freason by hipe_handle_exception() hipe_rtl_arch:pcb_load(FTagVar, ?P_ARG0) ], VarMap1, ConstTab}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% Exceptions gen_exit(Reason, L) -> gen_fail_call({erlang,exit,1}, [Reason], L). gen_throw(Reason, L) -> gen_fail_call({erlang,throw,1}, [Reason], L). gen_error(Reason, L) -> gen_fail_call({erlang,error,1}, [Reason], L). gen_error(Reason, ArgList, L) -> gen_fail_call({erlang,error,2}, [Reason,ArgList], L). gen_rethrow(Exception, Reason, L) -> gen_fail_call(rethrow, [Exception,Reason], L). %% Generic fail. We can't use 'enter' with a fail label (there can be no %% stack descriptor info for an enter), so for a non-nil fail label we %% generate a call followed by a dummy return. %% %% Update: The runtime system now interprets the return address of %% the BIF call in order to list the invoking MFA in the stack trace. %% Generating tailcalls here defeats that purpose, so we no longer do that. %%gen_fail_call(Fun, Args, []) -> %% [hipe_rtl:mk_enter(Fun, Args, remote)]; gen_fail_call(Fun, Args, L) -> ContLbl = hipe_rtl:mk_new_label(), Cont = hipe_rtl:label_name(ContLbl), Zero = hipe_rtl:mk_imm(hipe_tagscheme:mk_fixnum(0)), [hipe_rtl:mk_call([], Fun, Args, Cont, L, remote), ContLbl, hipe_rtl:mk_return([Zero])].