Exceptions: Difference between revisions

557 bytes removed ,  21 December 2007
moved nothrow to end and shortened
(note about scoping to C++)
(moved nothrow to end and shortened)
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. In particular, this is about how to modify the call sites of methods so that the code uses exception handling and is exception safe.
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.
== nothrow methods ==
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.
We'll assume that any method implemented in JavaScript can fail and throw an exception, so the nothrow analysis is restricted to methods implemented in C++. The prime example is property retrieval methods.
[http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html#index-g_t_0040code_007bnothrow_007d-function-attribute-1735 GNU attribute syntax]
[http://msdn2.microsoft.com/en-us/library/49147z04(VS.80).aspx Microsoft C++ nothrow attribute syntax]
=== nothrow analysis ===
There are three ways a method can fail:
* By returning a non-zero (non-NS_OK) value,
* 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'''. [https://bugzilla.mozilla.org/show_bug.cgi?id=353144 new badness]
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();


== Call sites that ignore return values ==
== Call sites that ignore return values ==
Line 142: Line 98:


Above, we said we'd flag these for manual fix, but some of them, like the first two, are pretty common and we might want to fix them automatically. The first two cases seem fairly easy to handle, but we need more information on how they're being used.
Above, we said we'd flag these for manual fix, but some of them, like the first two, are pretty common and we might want to fix them automatically. The first two cases seem fairly easy to handle, but we need more information on how they're being used.
== nothrow methods ==
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. We can remove all exception handlers protecting nothrow call sites, making the code shorter and easier to read.
We'll assume that any method implemented in JavaScript can fail and throw an exception, so the nothrow analysis is restricted to methods implemented in C++. The prime example is property retrieval methods.
[http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html#index-g_t_0040code_007bnothrow_007d-function-attribute-1735 GNU attribute syntax]
[http://msdn2.microsoft.com/en-us/library/49147z04(VS.80).aspx Microsoft C++ nothrow attribute syntax]
=== nothrow analysis ===
There are three ways a method can fail:
* By returning a non-zero (non-NS_OK) value,
* 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'''. [https://bugzilla.mozilla.org/show_bug.cgi?id=353144 new badness]
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.
313

edits