Will Rid Code of Outparams!
I resumed my outparam rewriting work last week. Having fixed the CPP induced architectural limitation that I ran into, it was quite straight-forward to factor out squash’s rewriting code into a new tool. Unlike squash, outparamdel (creatively named new tool), can rewrite code precisely and reliably. I still don’t have end-of-ast-node information in every Elsa AST member, but I think I have added position info to enough AST nodes to be able to do most of the Mozilla 2 rewrites.
Last time I was working on this, I was a little unhappy with the amount of code that had to be changed in the callee. I also wasn’t sure how to handle the complexity of callsites where control flow depends on the error code returned by the callee. This time I chose the path of least resistance.
In the callee two variables replace the out-parameter. The first holds the return value and the second points at the first and is declared in the same way as the out-parameter.
@@ -2358,6 +2358,5 @@
- nsStyleContext* aStyleContext,
- ImageFrameCreatorFunc aFunc,
- nsIFrame** aFrame)
+ nsStyleContext* aStyleContext,
+ ImageFrameCreatorFunc aFunc)
@@ -2364,1 +2364,3 @@
- *aFrame = nsnull;
+ nsIFrame* __aFrame = 0;
+ nsIFrame** aFrame = &__aFrame;
+ *aFrame = nsnull;
@@ -2371,1 +2371,1 @@
- return NS_ERROR_OUT_OF_MEMORY;
+ return nsnull;
@@ -2374,1 +2374,1 @@
- return NS_OK;
+ return __aFrame;
With a little more work one can get of one or even both local variables, but that will require more heuristics.
I also simplified call-site rewriting by wrapping the call to the callee function into a ternary expression when the error code is evaluated.
@@ -5290,2 +5290,1 @@
- rv = CreateHTMLImageFrame(aContent, aStyleContext, NS_NewImageFrame,
+ rv = ((newFrame = CreateHTMLImageFrame(aContent, aStyleContext, NS_NewImageFrame)) ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
Obviously this could be improved upon by getting rid of rv altogether, but the trick works in all cases and can be improved-upon incrementally.
Problems & Limitations
- Code within macros is detected, but not modified. Since macros are something that is easier to modify manually than with a tool, this isn’t a problem.
- Indentation isn’t updated. I think this is solvable with a few more heuristics in the patcher.
- Expression rewriting doesn’t work on Mac or Windows source-code. Mac is going to be relatively straight-forward to support. MCPP doesn’t understand all of the Mac strangeness yet and needs a loving and affectionate mac user to teach it the ways of Darwin. Windows is more work as it will require both updating the mingw Mozilla port and porting MCPP.
I wrote outparamdel and tested it on a convoluted manual testcase. Then I ran outparamdel mozilla-wide with the above input and the resulting code compiled! This was never the case prior to MCPP work since I found find new and exciting preprocessor madness to work-around and special case with every new rewrite.
Going to make this a little more challenging by rewriting QueryInterface to return result by a return value which should affect the majority of functions in Mozilla.