Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
erlang
2601-compiler-Document-exception-handling-at-th...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 2601-compiler-Document-exception-handling-at-the-BEAM-SSA.patch of Package erlang
From 476baa9b2ce73dbb7e56036b56935b0e17c9d346 Mon Sep 17 00:00:00 2001 From: Frej Drejhammar <frej.drejhammar@gmail.com> Date: Fri, 28 May 2021 10:43:53 +0200 Subject: [PATCH] compiler: Document exception handling at the BEAM SSA level MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document how exception handlers are structured at the the BEAM SSA level. The material in this patch is based on an email conversation between the author and Björn Gustavsson <bjorn@erlang.org>. --- lib/compiler/internal_doc/beam_ssa.md | 107 ++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/lib/compiler/internal_doc/beam_ssa.md b/lib/compiler/internal_doc/beam_ssa.md index 29ad019194..d32431ecff 100644 --- a/lib/compiler/internal_doc/beam_ssa.md +++ b/lib/compiler/internal_doc/beam_ssa.md @@ -1,6 +1,113 @@ Invariants on the Structure and Format of BEAM SSA ================================================== +Exception Handling +------------------ + +The translation of a `try`-`catch` expression into BEAM SSA has the +following structure: + + @tag = new_try_tag `try` + br @tag, ^protected_block0, ^landing_pad_block + + protected_block0: + @success0 = ... % Something that could raise an exception + br @success0, ^protected_block1, ^landing_pad_block + + ... + + protected_blockN: + % The end of the protected code + @ignored0 = kill_try_tag @tag + br ^after_try_catch + + landing_pad_block: + @aggregate = landingpad try, @tag + @class = extract @aggregate, `0` % The error class + @reason = extract @aggregate, `1` % The reason + @stk = extract @aggregate, `2` % The stack trace + @ignored1 = kill_try_tag @tag + %% Pattern matching on @class, @reason, and @stk is done here + %% to send control to the appropriate catch clause + br ^after_try_catch + + after_try_catch: + % Normal execution continues + +The following invariants must hold for the SSA: + + * All code that can cause an exception in one of the protected blocks + must have explicit control flow edges to the landing pad block. If + there are no edges to the landing pad block except from the block + containing the `new_try_tag`, the compiler will remove the + redundant exception handler. + * The extraction of the class, reason and stack trace from the result + of the `landingpad` instruction must be done in that + order. Omitting the extraction of elements which are unused is + allowed. + * Both the landing pad block and the final protected block must end + with a `kill_try_tag` instruction. Trying to share the + `kill_try_tag` epilogue between the last protected block and the + landing pad is unlikely to work. + +The translation of an old-style `catch` expression into BEAM SSA has +the following structure: + + @tag = new_try_tag `try` + br @tag, ^protected_block0, ^landing_pad_block + + protected_block0: + @success0 = ... % Something that could raise an exception + br @success0, ^protected_block1, ^landing_pad_block + + ... + + protected_blockN: + % The end of the protected code + @successful_result = .... % The result of a successful computation + br ^common_end_of_catch + + landing_pad_block: + @aggregate = landingpad catch, @tag + @catched_val = extract @ssa_agg, `0` + br ^common_end_of_catch + + common_end_of_catch: + @tmp = phi { @catched_val, ^landing_pad_block }, + { @successful_result, ^protected_blockN } + @result_of_catch_expr = catch_end @tag, @tmp + +Just as for a `try`-`catch` expression all code that can cause an +exception in one of the protected blocks must have explicit control +flow edges to the landing pad block. + +Exception Re-issuing +-------------------- + +A typical user-written `try`-`catch` expression will catch a subset of +all possible exception classes and reasons and leave unhandled +exceptions to a handler further up the call stack. Re-issuing an +exception is done with the `resume` instruction. The `resume` must +come after the `kill_try_tag` instruction in the program flow. For +example, if the [example in the Exception Handling Section](#exception-handling) +was to only handle user `throws`, the relevant blocks would look like this: + + landing_pad_block: + @aggregate = landingpad `try`, @tag + @class = extract @aggregate, `0` % The error class + @reason = extract @aggregate, `1` % The reason + @stk = extract @aggregate, `2` % The stack trace + @ignored1 = kill_try_tag @tag + @is_throw = bif:'=:=' @class, `throw` + br @is_throw ^first_block_of_throw_handler, ^reissue + + first_block_of_throw_handler: + %% Handle the user-defined throw + + reissue: + @tmp = resume @stk, @reason + ret @tmp + Function Calls -------------- -- 2.26.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor