Description
- Version: master
- Platform: Linux
- Subsystem: VM
While investigating #21573 I was interested in understanding why we are storing the importModuleDynamically
callback in a weak map, as that surely means that it can be GC'd if there is an indeterminate time before the import()
function in the module is called.
I may or may not have diagnosed the issue correctly, but the test case is a bug nonetheless:
main.js
const vm = require('vm');
var source = `
setTimeout(() => {
import('./test.mjs');
}, 1000)
gc();
`;
new vm.Script(source, {
importModuleDynamically (x) {
console.log('dynamic callback');
return import(x);
}
}).runInThisContext();
Where test.mjs
exists as an ES module.
Running with: node --experimental-modules --expose-gc main.js
I get the following output:
(node:12832) ExperimentalWarning: The ESM module loader is experimental.
dynamic callback
Segmentation fault (core dumped)
If I comment out the gc()
line or run the import()
call without a timeout the correct output is provided.
This makes me think we should reconsider the use of weak maps as the storage for the dynamic callback, and rather accept that the dynamic callback should always have a lifecycle that is directly tied to the lifecycle of the module(s) it is referenced by.