transparent lambda
Peter Levart
peter.levart at marand.si
Mon Jan 4 03:33:14 PST 2010
On Monday 04 January 2010 11:07:45 Peter Levart wrote:
> Here's another example:
>
> #int() one = null;
> synchronized int sum(int n) {
> if (one == null) one = #() { return 1; };
> return n == 0 ? 0 : sum(n-1) + one();
> }
>
> The compiler could generate the following code for the above example:
>
Ops, not entirely correct.
So here's the first "refinement" that should make the generated code correct (changes to previous code are: try/catch wraps the whole method body not each lambda invocation):
#int() one = null;
synchronized int sum(int n) {
#int() $tmpLambda = null;
try {
if (one == null) {
$tmpLambda = new #int()() {
public int invoke() { throw new NonLocalReturnInt(this, 1); }
};
one = $tmpLambda;
}
return n == 0 ? 0 : sum(n-1) + one();
}
catch (NonLocalReturnInt $nlr) {
if ($tmlLambda == $nlr.lambda)
return $nlr.retval;
else
throw $nlr;
}
}
Each lambda expression that contains a non-local return statement and is specified in a method or constructor reserves a "$tmpLambda" slot on the stack which is filled-in with a reference to the lambda when the lambda expression is evaluated. The "NonLocalReturn" exception also contains a reference to the lambda that initiated the non-local transfer. The body of each method/constructor that contains lambda expressions with non-local returns is wrapped in a try/catch that catches the "NonLocalReturn" and checks it's "lambda" reference with all the "$tmpLambda" slots. If any of them matches, "NonLocalReturn" is translated into a return from the method/constructor else it is re-thrown.
Regards, Peter
More information about the closures-dev
mailing list