Overhaul passing of globals and lifted loops

The main change in this PR is to pass an environment object to generated functions, which can gather various runtime data such as globals, the dispatchers for lifted loops... In the future, we can imagine having actual Python closures too (i.e. with mutable values, not frozen at compile-time). This replaces the previous mechanisms using MetadataKeyStore (for globals) and specially-named module globals (for nested loops).

This has brought a bunch of related changes as well as minor cleanups (and some added comments in some places).

Note that a NULL environment is passed to nested nopython functions. They don't need it, so it's ok, but in the future we may need to find a way to pass a proper env.