I believe we have tests for this, so one option is to look there (grepping for `getenv()` in tests/, etc.).
But it is possible there is a bug here. So also worth doing is trying to make a small testcase showing where preRun fails to work as you expect. That might either show a bug, or help understand what you're doing differently than the test suite. I think there is indeed a "window" of time - first ENV needs to exist at all, as some JS creates it. That happens when the JS is evaluated. Then when the program starts to run and we execute main(), one of the global constructors will I believe copy the ENV data from JS into memory that C can access. That is done once. And a preRun should occur exactly in between those, as it's defined as running after the JS is evaluated (it has to, as the JS has to be evaluated for anything to happen) and before running the compiled code. On Sun, Jul 19, 2020 at 2:26 PM Hostile Fork <[email protected]> wrote: > I noticed that getenv() stopped working for me after switching to > MODULARIZE=1. There is a related thread here about it: > > https://github.com/emscripten-core/emscripten/issues/9827 > > It seems that snippets from that resolved it for some people, but not for > me. Here's what I'm seeing: > > * If I do not export the ENV variable, then `modularized_module.ENV` will > be a function that tells you that you have to export ENV. If you do that, > then anything you put as ENV in the options object passed to your > modularize factory function (e.g. opts.ENV.X = '1') will be overwritten > with an empty object. > > * Advice from the documentation on "Interacting with Code" says "Care must > be taken to ensure that the ENV variable has been initialised by Emscripten > before it is modified -- using Module.preRun is a convenient way to do > this." We might assume this empty object is that initialized object. Okay. > > * I can add things to this object with `opts.preRun = (mod) => { mod.ENV.X > = "1"}` or in `factory(opts).then((mod) => {mod.ENV.X = "1"})`. Neither > method seems to have getenv() return anything but null for what is added. > > To try and get a better understanding, I exported _getenv() and call it > directly from JavaScript with a stringToUTF8() of the variable. As far as > I can tell from stepping into the compiled wasm, it is this implementation > from musl: > > > https://github.com/emscripten-core/emscripten/blob/master/system/lib/libc/musl/src/env/getenv.c > > This doesn't call any functions for consulting a JavaScript object's > state. That is to say: it seems that the environment is captured at some > early point, and cannot be changed except through calls to setenv(). This > would imply that JavaScript setting of an "ENV" variable can only influence > the environment *before* that first capture--it is not sync'd after that. > And the documentation say it can only work *after* an object has been > initialized. So it's some kind of time window. > > I'm not sure when this moment of capture would be. But as the thread > suggests using preRun() as the place to set it...I gather waiting until the > factory function gives you a completed module may be too late. > > That still doesn't explain why setting options on the created-for-me ENV > object during preRun() isn't working. I can see that the assignment > happened, because the module I get back from the factory function has its > ENV set to what I added. (There are no other variables in the enviroment > object added by the system.) > > Any ideas on where I might look next? :-/ > > -- > > (Note: If I'm right about this "ENV is captured to the wasm heap and then > after that point there is no interaction with JS", then it seems it would > be good if after that point the ENV variable were turned to an erroring > function--at least in debug builds--that says the environment is no longer > up to date. Perhaps the object in configuration could be moved to > something like ENV_STALE if you wanted to know what the environment was > before the capture.) > > -- > You received this message because you are subscribed to the Google Groups > "emscripten-discuss" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > To view this discussion on the web visit > https://groups.google.com/d/msgid/emscripten-discuss/0d62ed76-0fe8-44e4-a35b-01dce19d359co%40googlegroups.com > <https://groups.google.com/d/msgid/emscripten-discuss/0d62ed76-0fe8-44e4-a35b-01dce19d359co%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "emscripten-discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/emscripten-discuss/CAEX4NpTra0sEZfcZ-BHNCOoUb5z7Ge%2BkryG_bifPgY2nLFsgHw%40mail.gmail.com.
