Closures (unlike other methods) can be invoked with mismatched arguments, which
then should result in Object.noSuchMethod
invocation.
We implement it by tail-calling
to the CallClosureNoSuchMethod
stub if we discover
an arity mismatch or a unmatched named argument. The stub gets original arguments
and original argument descriptor and simply redirects to runtime function
InvokeClosureNoSuchMethod
which does all the heavy lifting related to
constructing Invocation
and invoking appropriate noSuchMethod
.
Given code like:
class Mock {
noSuchMethod(Invocation i) {
// ...
}
}
class A extends Mock {
void foo(...);
}
we should build (pseudo-code)
class A extends Mock {
void foo(...) {
tail-call RedirectToNoSuchMethodStub
}
}
The stub RedirectToNoSuchMethodStub
should be more or less the copy of
CallClosureNoSuchMethod
which then invokes RedirectToNoSuchMethod
runtime
function, which is also more or less a copy of InvokeClosureNoSuchMethod
just without any closure specific processing.
I think most of the code can be shared and reused - there is very little closure specific in these helpers.
Tail-calling NSM wont' work because we have to type-check the result of the NSM invocation.