Revisiting this old topic, (string-to-number (format-mode-line "%l") still holds up quite well against (line-number-at-position). I found it is also highly cached for "nearby" line positions. For example, operating on /usr/dict/words (236k lines here):
(let* ((buf (get-buffer "words"))
(win (get-buffer-window buf))
Do people still answer old questions? Anyway, I think the built-in help-function-arglist could be useful here.
It skips any advice in effect, but other than that it provides just what you'd see in the help buffer.
The Elisp manual (do C-h i g (elisp) RET i while-no-input RET for more details - learning to use Info and the Info manuals is a good investment of your time) suggests the following:
If you want to be able to distinguish all possible values computed
by BODY from both kinds of abort conditions, write the code like