Open juj opened 11 hours ago
Yup, I agree this seems wrong.
Its a shame we can't attached these symbols to the "current context", since JS has no way to access that.
We could consider simply dropping these features (at least in MODULARIZE
mode), or we could emit these functions as regular symbols in the namespace.
At Unity we support a feature to unload the game engine from a web page. This enables sites to hot-swap between multiple Unity builds on a single web page.
To enable seamless integration with site content, this unloading support has been requested to be possible without needing to use iframes, and we build it on top of Emscripten's
-sMODULARIZE
feature.It looks like since our last Emscripten update, this feature has regressed in debug builds, due to the use of the
globalThis
object in runtime_debug.js.The functions
missingGlobal()
andmissingLibrarySymbol()
both call toObject.defineProperty(globalThis, ...);
, which has the effect of leaking symbol definitions into the global scope of the JS context, even when the code is being built with-sMODULARIZE=1
where symbol definitions would be expected to be local to the MODULARIZEd function.The defined functions contain closures that hold on to the loaded Wasm page.
Then even if one deletes all the traces of the loaded Module, these polluted global symbols have function scopes that keep the page alive.
Here is an example:
shell_unload.html
Then run the page, click on Unload and take a Chrome heap snapshot:
This snapshot shows that the Wasm program is still in memory:
and it is being held in memory by functions
missingGlobal()
andmissingLibrarySymbol()
.It is noted that this appears only in debug builds, although in our case, we provide developers debug tooling especially in debug builds so that they would be able to examine how this plays out. So we would prefer for this symbol pollution to not occur in debug builds either.
I am not sure however what would be a good way to rearchitect
unexportedRuntimeSymbol()
andmissingGlobal()
to fix the leakage, except to have the compiler python script statically list out the missing runtime symbols. Maybe that is what it'd take, if no better ideas?