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.