313
edits
m (Fix wiki links to outparamdel) |
|||
Line 21: | Line 21: | ||
=== Enabling Exceptions in the Compiler === | === Enabling Exceptions in the Compiler === | ||
An essential step is to enable exceptions in the compiler. By itself, this shouldn't do too much, but it may change the behavior of <code>operator new</code> in OOM conditions. | An essential step is to enable exceptions in the compiler. By itself, this shouldn't do too much, but it may change the behavior of <code>operator new</code> in OOM conditions to throw exceptions instead of returning a null pointer. We'll want to do that eventually, anyway. | ||
=== "Generic" Exceptions === | |||
There are several FF-specific issues with exceptions, which are discussed below. In this section, we discuss how to make FF use C++ exceptions for "generic" error conditions. | |||
<code>nsresult</code> return types will be changed to <code>void</code>. This affects the IDL header file generator, hand-written declarations, and implementation method signatures. | |||
An exception type hierarchy needs to be created to replace error codes. There is an opportunity here to include extra information in the exception object. | |||
Statements like <code>return NS_ERROR_FOO</code> will be replaced with throw statements. | |||
Call sites of <code>nsresult</code> methods need to be updated to handle exceptions instead of testing error codes. The key is to preserve current behavior. Call sites fall into a few categories: | |||
I'''gnore <code>nsresult</code>.''' Call sites that ignore the <code>nsresult</code> must be wrapped in <code>try { call() } catch {}</code>. If we can prove that the call will never throw an exception, which we can currently do for about 1/3 of this category, we could remove the wrapper. However, this is potentially dangerous for the future: the called method may someday throw or propagate exceptions. Thus, it is better to make the call site exception-safe before removing the wrapper. | |||
* Forward <code>nsresult</code>. This is when the method containing the call site simply propagates the error code to its caller without executing any other code (except destructors). The macro <code>NS_ENSURE_SUCCESS</code> does this. This category is very nice: with exceptions, there is no error handling code at all. To remove the existing error handling code, we can simply remove the assignment of the error code out of the call site and remove the return statement. This may create a dead <code>rv</code> variable, which can be deleted as a (conceptual) separate step. Note: we place call sites that log the error into this category as well: logging will be needed less with exceptions. | |||
* Compensate, then forward <code>nsresult</code>. This is when the method containing the call site propagates the error code, but only after running compensation code. Compensation code restores some invariant that would otherwise be lost. The prototypical example is releasing resources to avoid leaks. The preferred (by the designers of C++) pattern for this scenario is to create a stack object whose destructor maintains the invarant. | |||
Call sites that simply forward error codes to their caller need no error handling. | |||
Call sites that test for errors and run fixup code will need to be either (a) wrapped in a try block with a catch block containing the fixup code or (b) preceded by stack allocation of a http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization RAII] object in an appropriate scope. | |||
=== Exceptions for OOM === | === Exceptions for OOM === | ||
Line 35: | Line 57: | ||
=== Exceptions for nsresult rv != NS_OK === | === Exceptions for nsresult rv != NS_OK === | ||
XPConnect needs to be rewritten so that when JavaScript calls C++, the FFI catches C++ exceptions and generates JavaScript exceptions if necessary. Also, when C++ calls JavaScript, C++ exceptions should be generated in response to JavaScript exceptions. This is potentially a lot of work, because there are separate XPConnect implementations for every platform and compiler. | XPConnect needs to be rewritten so that when JavaScript calls C++, the FFI catches C++ exceptions and generates JavaScript exceptions if necessary. Also, when C++ calls JavaScript, C++ exceptions should be generated in response to JavaScript exceptions. This is potentially a lot of work, because there are separate XPConnect implementations for every platform and compiler. |
edits