diff options
Diffstat (limited to 'docs/ExceptionHandling.html')
-rw-r--r-- | docs/ExceptionHandling.html | 296 |
1 files changed, 177 insertions, 119 deletions
diff --git a/docs/ExceptionHandling.html b/docs/ExceptionHandling.html index d597ffb..247448d 100644 --- a/docs/ExceptionHandling.html +++ b/docs/ExceptionHandling.html @@ -11,7 +11,7 @@ <body> -<div class="doc_title">Exception Handling in LLVM</div> +<h1>Exception Handling in LLVM</h1> <table class="layout" style="width:100%"> <tr class="layout"> @@ -35,6 +35,7 @@ <ol> <li><a href="#llvm_eh_exception"><tt>llvm.eh.exception</tt></a></li> <li><a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a></li> + <li><a href="#llvm_eh_resume"><tt>llvm.eh.resume</tt></a></li> <li><a href="#llvm_eh_typeid_for"><tt>llvm.eh.typeid.for</tt></a></li> <li><a href="#llvm_eh_sjlj_setjmp"><tt>llvm.eh.sjlj.setjmp</tt></a></li> <li><a href="#llvm_eh_sjlj_longjmp"><tt>llvm.eh.sjlj.longjmp</tt></a></li> @@ -58,10 +59,10 @@ <!-- *********************************************************************** --> -<div class="doc_section"><a name="introduction">Introduction</a></div> +<h2><a name="introduction">Introduction</a></h2> <!-- *********************************************************************** --> -<div class="doc_text"> +<div> <p>This document is the central repository for all information pertaining to exception handling in LLVM. It describes the format that LLVM exception @@ -70,14 +71,12 @@ provides specific examples of what exception handling information is used for in C/C++.</p> -</div> - <!-- ======================================================================= --> -<div class="doc_subsection"> +<h3> <a name="itanium">Itanium ABI Zero-cost Exception Handling</a> -</div> +</h3> -<div class="doc_text"> +<div> <p>Exception handling for most programming languages is designed to recover from conditions that rarely occur during general use of an application. To that @@ -106,11 +105,11 @@ </div> <!-- ======================================================================= --> -<div class="doc_subsection"> +<h3> <a name="sjlj">Setjmp/Longjmp Exception Handling</a> -</div> +</h3> -<div class="doc_text"> +<div> <p>Setjmp/Longjmp (SJLJ) based exception handling uses LLVM intrinsics <a href="#llvm_eh_sjlj_setjmp"><tt>llvm.eh.sjlj.setjmp</tt></a> and @@ -138,11 +137,11 @@ </div> <!-- ======================================================================= --> -<div class="doc_subsection"> +<h3> <a name="overview">Overview</a> -</div> +</h3> -<div class="doc_text"> +<div> <p>When an exception is thrown in LLVM code, the runtime does its best to find a handler suited to processing the circumstance.</p> @@ -185,12 +184,14 @@ </div> +</div> + <!-- ======================================================================= --> -<div class="doc_section"> +<h2> <a name="codegen">LLVM Code Generation</a> -</div> +</h2> -<div class="doc_text"> +<div> <p>At the time of this writing, only C++ exception handling support is available in LLVM. So the remainder of this document will be somewhat C++-centric.</p> @@ -200,14 +201,12 @@ we will describe the implementation of LLVM exception handling in terms of C++ examples.</p> -</div> - <!-- ======================================================================= --> -<div class="doc_subsection"> +<h3> <a name="throw">Throw</a> -</div> +</h3> -<div class="doc_text"> +<div> <p>Languages that support exception handling typically provide a <tt>throw</tt> operation to initiate the exception process. Internally, a throw operation @@ -225,11 +224,11 @@ </div> <!-- ======================================================================= --> -<div class="doc_subsection"> +<h3> <a name="try_catch">Try/Catch</a> -</div> +</h3> -<div class="doc_text"> +<div> <p>A call within the scope of a <i>try</i> statement can potentially raise an exception. In those circumstances, the LLVM C++ front-end replaces the call @@ -313,30 +312,43 @@ </div> <!-- ======================================================================= --> -<div class="doc_subsection"> +<h3> <a name="cleanups">Cleanups</a> -</div> +</h3> + +<div> -<div class="doc_text"> +<p>A cleanup is extra code which needs to be run as part of unwinding + a scope. C++ destructors are a prominent example, but other + languages and language extensions provide a variety of different + kinds of cleanup. In general, a landing pad may need to run + arbitrary amounts of cleanup code before actually entering a catch + block. To indicate the presence of cleanups, a landing pad's call + to <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> should + end with the argument <tt>i32 0</tt>; otherwise, the unwinder will + not stop at the landing pad if there are no catches or filters that + require it to.</p> -<p>To handle destructors and cleanups in <tt>try</tt> code, control may not run - directly from a landing pad to the first catch. Control may actually flow - from the landing pad to clean up code and then to the first catch. Since the - required clean up for each <tt>invoke</tt> in a <tt>try</tt> may be different - (e.g. intervening constructor), there may be several landing pads for a given - try. If cleanups need to be run, an <tt>i32 0</tt> should be passed as the - last <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> argument. - However, when using DWARF exception handling with C++, a <tt>i8* null</tt> - <a href="#restrictions">must</a> be passed instead.</p> +<p>Do not allow a new exception to propagate out of the execution of a + cleanup. This can corrupt the internal state of the unwinder. + Different languages describe different high-level semantics for + these situations: for example, C++ requires that the process be + terminated, whereas Ada cancels both exceptions and throws a third.</p> + +<p>When all cleanups have completed, if the exception is not handled + by the current function, resume unwinding by calling the + <a href="#llvm_eh_resume"><tt>llvm.eh.resume</tt></a> intrinsic, + passing in the results of <tt>llvm.eh.exception</tt> and + <tt>llvm.eh.selector</tt> for the original landing pad.</p> </div> <!-- ======================================================================= --> -<div class="doc_subsection"> +<h3> <a name="throw_filters">Throw Filters</a> -</div> +</h3> -<div class="doc_text"> +<div> <p>C++ allows the specification of which exception types can be thrown from a function. To represent this a top level landing pad may exist to filter out @@ -359,50 +371,57 @@ </div> <!-- ======================================================================= --> -<div class="doc_subsection"> +<h3> <a name="restrictions">Restrictions</a> -</div> +</h3> + +<div> -<div class="doc_text"> - -<p>The semantics of the invoke instruction require that any exception that - unwinds through an invoke call should result in a branch to the invoke's - unwind label. However such a branch will only happen if the - <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> matches. Thus in - order to ensure correct operation, the front-end must only generate - <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> calls that are - guaranteed to always match whatever exception unwinds through the invoke. - For most languages it is enough to pass zero, indicating the presence of - a <a href="#cleanups">cleanup</a>, as the - last <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> argument. - However for C++ this is not sufficient, because the C++ personality function - will terminate the program if it detects that unwinding the exception only - results in matches with cleanups. For C++ a <tt>null i8*</tt> should be - passed as the last <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> - argument instead. This is interpreted as a catch-all by the C++ personality - function, and will always match.</p> +<p>The unwinder delegates the decision of whether to stop in a call + frame to that call frame's language-specific personality function. + Not all personalities functions guarantee that they will stop to + perform cleanups: for example, the GNU C++ personality doesn't do + so unless the exception is actually caught somewhere further up the + stack. When using this personality to implement EH for a language + that guarantees that cleanups will always be run, be sure to + indicate a catch-all in the + <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> call + rather than just cleanups.</p> + +<p>In order for inlining to behave correctly, landing pads must be + prepared to handle selector results that they did not originally + advertise. Suppose that a function catches exceptions of + type <tt>A</tt>, and it's inlined into a function that catches + exceptions of type <tt>B</tt>. The inliner will update the + selector for the inlined landing pad to include the fact + that <tt>B</tt> is caught. If that landing pad assumes that it + will only be entered to catch an <tt>A</tt>, it's in for a rude + surprise. Consequently, landing pads must test for the selector + results they understand and then resume exception propagation + with the <a href="#llvm_eh_resume"><tt>llvm.eh.resume</tt></a> + intrinsic if none of the conditions match.</p> + +</div> </div> <!-- ======================================================================= --> -<div class="doc_section"> +<h2> <a name="format_common_intrinsics">Exception Handling Intrinsics</a> -</div> +</h2> -<div class="doc_text"> +<div> <p>LLVM uses several intrinsic functions (name prefixed with "llvm.eh") to provide exception handling information at various points in generated code.</p> -</div> - <!-- ======================================================================= --> -<div class="doc_subsubsection"> +<h4> <a name="llvm_eh_exception">llvm.eh.exception</a> -</div> +</h4> -<div class="doc_text"> +<div> <pre> i8* %<a href="#llvm_eh_exception">llvm.eh.exception</a>() @@ -413,11 +432,11 @@ </div> <!-- ======================================================================= --> -<div class="doc_subsubsection"> +<h4> <a name="llvm_eh_selector">llvm.eh.selector</a> -</div> +</h4> -<div class="doc_text"> +<div> <pre> i32 %<a href="#llvm_eh_selector">llvm.eh.selector</a>(i8*, i8*, ...) @@ -426,30 +445,40 @@ <p>This intrinsic is used to compare the exception with the given type infos, filters and cleanups.</p> -<p><a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> takes a minimum of - three arguments. The first argument is the reference to the exception - structure. The second argument is a reference to the personality function to - be used for this try catch sequence. Each of the remaining arguments is - either a reference to the type info for a catch statement, - a <a href="#throw_filters">filter</a> expression, or the number zero - representing a <a href="#cleanups">cleanup</a>. The exception is tested - against the arguments sequentially from first to last. The result of - the <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> is a positive - number if the exception matched a type info, a negative number if it matched - a filter, and zero if it matched a cleanup. If nothing is matched, the - behaviour of the program is <a href="#restrictions">undefined</a>. If a type - info matched then the selector value is the index of the type info in the - exception table, which can be obtained using the +<p><a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> takes a + minimum of three arguments. The first argument is the reference to + the exception structure. The second argument is a reference to the + personality function to be used for this try catch sequence. Each + of the remaining arguments is either a reference to the type info + for a catch statement, a <a href="#throw_filters">filter</a> + expression, or the number zero representing + a <a href="#cleanups">cleanup</a>. The exception is tested against + the arguments sequentially from first to last. The result of + the <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> is a + positive number if the exception matched a type info, a negative + number if it matched a filter, and zero if it matched a cleanup. + If nothing is matched, or if only a cleanup is matched, different + personality functions may or may not cause control to stop at the + landing pad; see <a href="#restrictions">the restrictions</a> for + more information. If a type info matched then the selector value + is the index of the type info in the exception table, which can be + obtained using the <a href="#llvm_eh_typeid_for"><tt>llvm.eh.typeid.for</tt></a> intrinsic.</p> +<p>If a landing pad containing a call to <tt>llvm.eh.selector</tt> is + inlined into an <tt>invoke</tt> instruction, the selector arguments + for the outer landing pad are appended to those of the inlined + landing pad. Consequently, landing pads must be written to ignore + selector values that they did not originally advertise.</p> + </div> <!-- ======================================================================= --> -<div class="doc_subsubsection"> +<h4> <a name="llvm_eh_typeid_for">llvm.eh.typeid.for</a> -</div> +</h4> -<div class="doc_text"> +<div> <pre> i32 %<a href="#llvm_eh_typeid_for">llvm.eh.typeid.for</a>(i8*) @@ -463,11 +492,38 @@ </div> <!-- ======================================================================= --> -<div class="doc_subsubsection"> - <a name="llvm_eh_sjlj_setjmp">llvm.eh.sjlj.setjmp</a> +<h4> + <a name="llvm_eh_resume">llvm.eh.resume</a> +</h4> + +<div> + +<pre> + void %<a href="#llvm_eh_resume">llvm.eh.resume</a>(i8*, i32) noreturn +</pre> + +<p>This intrinsic is used to resume propagation of an exception after + landing at a landing pad. The first argument should be the result + of <a href="#llvm_eh_exception">llvm.eh.exception</a> for that + landing pad, and the second argument should be the result of + <a href="#llvm_eh_selector">llvm.eh.selector</a>. When a call to + this intrinsic is inlined into an invoke, the call is transformed + into a branch to the invoke's unwind destination, using its + arguments in place of the calls + to <a href="#llvm_eh_exception">llvm.eh.exception</a> and + <a href="#llvm_eh_selector">llvm.eh.selector</a> there.</p> + +<p>This intrinsic is not implicitly <tt>nounwind</tt>; calls to it + will always throw. It may not be invoked.</p> + </div> -<div class="doc_text"> +<!-- ======================================================================= --> +<h4> + <a name="llvm_eh_sjlj_setjmp">llvm.eh.sjlj.setjmp</a> +</h4> + +<div> <pre> i32 %<a href="#llvm_eh_sjlj_setjmp">llvm.eh.sjlj.setjmp</a>(i8*) @@ -492,11 +548,11 @@ </div> <!-- ======================================================================= --> -<div class="doc_subsubsection"> +<h4> <a name="llvm_eh_sjlj_longjmp">llvm.eh.sjlj.longjmp</a> -</div> +</h4> -<div class="doc_text"> +<div> <pre> void %<a href="#llvm_eh_sjlj_longjmp">llvm.eh.sjlj.setjmp</a>(i8*) @@ -507,16 +563,16 @@ style exception handling. The single parameter is a pointer to a buffer populated by <a href="#llvm_eh_sjlj_setjmp"> <tt>llvm.eh.sjlj.setjmp</tt></a>. The frame pointer and stack pointer - are restored from the buffer, then control is transfered to the + are restored from the buffer, then control is transferred to the destination address.</p> </div> <!-- ======================================================================= --> -<div class="doc_subsubsection"> +<h4> <a name="llvm_eh_sjlj_lsda">llvm.eh.sjlj.lsda</a> -</div> +</h4> -<div class="doc_text"> +<div> <pre> i8* %<a href="#llvm_eh_sjlj_lsda">llvm.eh.sjlj.lsda</a>() @@ -531,11 +587,11 @@ </div> <!-- ======================================================================= --> -<div class="doc_subsubsection"> +<h4> <a name="llvm_eh_sjlj_callsite">llvm.eh.sjlj.callsite</a> -</div> +</h4> -<div class="doc_text"> +<div> <pre> void %<a href="#llvm_eh_sjlj_callsite">llvm.eh.sjlj.callsite</a>(i32) @@ -549,11 +605,11 @@ </div> <!-- ======================================================================= --> -<div class="doc_subsubsection"> +<h4> <a name="llvm_eh_sjlj_dispatchsetup">llvm.eh.sjlj.dispatchsetup</a> -</div> +</h4> -<div class="doc_text"> +<div> <pre> void %<a href="#llvm_eh_sjlj_dispatchsetup">llvm.eh.sjlj.dispatchsetup</a>(i32) @@ -565,24 +621,24 @@ </div> +</div> + <!-- ======================================================================= --> -<div class="doc_section"> +<h2> <a name="asm">Asm Table Formats</a> -</div> +</h2> -<div class="doc_text"> +<div> <p>There are two tables that are used by the exception handling runtime to determine which actions should take place when an exception is thrown.</p> -</div> - <!-- ======================================================================= --> -<div class="doc_subsection"> +<h3> <a name="unwind_tables">Exception Handling Frame</a> -</div> +</h3> -<div class="doc_text"> +<div> <p>An exception handling frame <tt>eh_frame</tt> is very similar to the unwind frame used by dwarf debug info. The frame contains all the information @@ -596,11 +652,11 @@ </div> <!-- ======================================================================= --> -<div class="doc_subsection"> +<h3> <a name="exception_tables">Exception Tables</a> -</div> +</h3> -<div class="doc_text"> +<div> <p>An exception table contains information about what actions to take when an exception is thrown in a particular part of a function's code. There is one @@ -611,12 +667,14 @@ </div> +</div> + <!-- ======================================================================= --> -<div class="doc_section"> +<h2> <a name="todo">ToDo</a> -</div> +</h2> -<div class="doc_text"> +<div> <ol> @@ -636,7 +694,7 @@ src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a> <a href="mailto:sabre@nondot.org">Chris Lattner</a><br> - <a href="http://llvm.org">LLVM Compiler Infrastructure</a><br> + <a href="http://llvm.org/">LLVM Compiler Infrastructure</a><br> Last modified: $Date$ </address> |