Exceptions: Difference between revisions

848 bytes added ,  20 December 2007
wikified and revised sec1
(first version, just a copy of an email with a new header.)
 
(wikified and revised sec1)
Line 1: Line 1:
This is a discussion document for ideas about how to use static analysis to help refactor Mozilla to use C++ exceptions instead of nsresults.  
This is a discussion document for ideas about how to use static analysis to help refactor Mozilla to use C++ exceptions instead of nsresults. In particular, this is about how to modify the call sites of methods so that the code uses exception handling and is exception safe.


=== Identifying nothrow methods ===


1. nothrow
Methods that never fail are the easiest to handle: exception safety at call sites is free. These are called '''nothrow''' methods following the ''Effective C++'' terminology. If we identify nothrow methods and annotate them, then we can easily refactor their sites.


The first step is to get the list of methods that never throw exceptions so that error handling can be removed entirely at their call sites.
== nothrow analysis ==


The basic analysis idea is that a nsresult-returning method is nothrow if it always returns NS_OK and never allocates memory. The main problem is that it's hard to analyze a method that calls other methods. It's easy to conservatively assume that any method that makes a call can throw, but that might miss too many nothrows. If so, we can try a conservative call graph approximation (i.e., one that doesn't need points-to analysis).
There are three ways a method can fail:


Once that analysis is in place, we know that the return value is 0 and we can do dead branch elimination on the call sites and make the call sites ignore the return value.
* By returning a non-zero (non-NS_OK) value,


We should probably also annotate nothrows in some way, which also gives us the opportunity to discover more of them manually later on.
* By calling another nsresult method that can fail (i.e., is not nothrow),
 
* By using a C++ feature that can throw an exception. The primary example is allocating memory with '''new'''.
 
The static analysis must be designed to detect any of these conditions. Because it's hard to know what method will be called in C++, a good starting point for the analysis would be to say that a method is nothrow if it can only return 0, does not invoke new, and does not call any other method. If this doesn't pick up enough nothrow methods, we can either do it by hand or augment the analysis with a simple call graph construction.
 
== Rewriting nothrow call sites ==
 
Some nothrow call sites may already ignore the return value. These call sites can be left alone (for exception rewriting--but [[outparamdel]] will rewrite many of them).
 
Otherwise, the call site should look like this:
 
  nsresult rv = callMethod();
  if (NS_FAILED(rv)) {
    stuff;
  }
 
Logically, this should be rewritten to:
 
  callMethod();
  nsresult rv = 0;
  if (NS_FAILED(rv)) {
    stuff;
  }
 
At this point, a standard branch folding and dead code elimination should be able to clean up the code to the desired:
 
  callMethod();


2. ignored nsresults
2. ignored nsresults
313

edits