[1] Because the execution of a function body always ends with a return, there is no need here for a mechanism like the return_undefined entry point from section 5.4.1.
[2] Elsewhere in the compiler, all saves and restores of registers are generated by preserving to preserve a register's value across a sequence of instructions by saving it before those instructions and restoring it after—for example over the evaluation of the predicate of a conditional. But this mechanism cannot generate instructions to save and restore continue for a function application and the corresponding return, because these are compiled separately and are not contiguous. Instead, these saves and restores must be explicitly generated by compile_fun_appl and compile_return_statement.
[3] Actually, we signal an error when the target is not val and the linkage is "return", since the only place we request a "return" linkage is in compiling return expressions, and our convention is that functions return their values in val.
[4] Making a compiler generate tail-recursive code is desirable, especially in the functional paradigm. However, compilers for common languages, including C and C++, do not always do this, and therefore these languages cannot represent iterative processes in terms of function call alone. The difficulty with tail recursion in these languages is that their implementations use the stack to store function arguments and local names as well as return addresses. The JavaScript implementations described in this book store arguments and names in memory to be garbage-collected. The reason for using the stack for names and arguments is that it avoids the need for garbage collection in languages that would not otherwise require it, and is generally believed to be more efficient. Sophisticated compilers can, in fact, use the stack for arguments without destroying tail recursion. (See Hanson 1990 for a description.) There is also some debate about whether stack allocation is actually more efficient than garbage collection in the first place, but the details seem to hinge on fine points of computer architecture. (See Appel 1987 and Miller and Rozas 1994 for opposing views on this issue.)
[5] The constant all_regs is bound to the list of names of all the registers:
const all_regs = list("env", "fun", "val", "argl", "continue");
5.5.3   Compiling Applications and Return Statements