... | ... | @@ -26,7 +26,7 @@ First, we need some terminology: |
|
|
|
|
|
- The function is bound at top level in this module; or,
|
|
|
- The function is bound at top level in another module, and optimisation is on, so we can see the details (notably arity) of the function in the module's interface file; or,
|
|
|
- The function is bound by an `let` binding that encloses the call.
|
|
|
- The function is bound by a `let` binding that encloses the call.
|
|
|
|
|
|
|
|
|
When compiling a call, there are several cases to consider, which are treated separately.
|
... | ... | @@ -52,7 +52,7 @@ When compiling a call that has an unknown function, we must generate code to |
|
|
|
|
|
- Exactly the right number of arguments: load them into the standard locations and tail-call the function's entry point
|
|
|
- Too few arguments: build a PAP
|
|
|
- Too many arguments: save the excess arguments, and tail call the function as for a saturated cal.
|
|
|
- Too many arguments: save the excess arguments, and tail call the function as for a saturated call.
|
|
|
|
|
|
|
|
|
All of this takes quite a lot of code, so we pre-generate a whole bunch of generic-apply code sequences, one for each combination of arguments. This code is generated by the tool [utils/genapply](https://gitlab.haskell.org/ghc/ghc/blob/master/utils/genapply), and the generated code appears in `rts/AutoApply.cmm`.
|
... | ... | |