@@ -14,8 +14,6 @@ const {
1414 ObjectDefineProperty,
1515 ObjectFreeze,
1616 String,
17- StringPrototypeIndexOf,
18- StringPrototypeSlice,
1917 globalThis,
2018} = primordials ;
2119
@@ -216,98 +214,58 @@ function setupVmModules() {
216214let vfsMounted = false ;
217215let vfsLoadRoot ;
218216
219- // --vfs-mount and --vfs-load append to one list, so `mounts` is already in the
220- // order the command line gave, and the entry point comes from whichever of them
221- // --vfs-load contributed. The parser stores plain strings and cannot record
222- // which flag produced an entry, so its position is recovered from execArgv -
223- // the command line's own node options, in order. NODE_OPTIONS may add mounts
224- // but not a --vfs-load, so anything it contributed sits ahead of these.
225- // Returns -1 when no --vfs-load was given.
226- //
227- // A worker does not run the --vfs-load entry (see node_worker.cc), but it must
228- // still recognize which source that entry is, so as to give it the reserved
229- // layer its mount point has on every other thread.
230- function getVfsLoadIndex ( mountCount ) {
231- const execArgv = process . execArgv ;
232- let seen = 0 ;
233- let found = - 1 ;
234- for ( let i = 0 ; i < execArgv . length ; i ++ ) {
235- const arg = execArgv [ i ] ;
236- let name = arg ;
237- const eq = StringPrototypeIndexOf ( arg , '=' ) ;
238- let spaced = false ;
239- if ( eq !== - 1 ) {
240- name = StringPrototypeSlice ( arg , 0 , eq ) ;
241- } else {
242- // `--vfs-mount value`: the value is the next argument, so skip it rather
243- // than counting it as a flag of its own.
244- spaced = true ;
245- }
246- if ( name !== '--vfs-mount' && name !== '--vfs-load' ) continue ;
247- if ( name === '--vfs-load' ) found = seen ;
248- seen ++ ;
249- if ( spaced ) i ++ ;
250- }
251- if ( found === - 1 ) return - 1 ;
252- // Mounts from NODE_OPTIONS are parsed first and so precede the command
253- // line's; `seen` counts only the latter.
254- return mountCount - seen + found ;
255- }
256-
257- // Mounts every --vfs-mount source. Called from prepareExecution() when there is
217+ // Mounts the --vfs-load source. Called from prepareExecution() when there is
258218// no --import, and otherwise from run_main after the --import loop has run; the
259- // guard makes the second call a no-op so a provider registered by either a -r or
260- // an --import preload is available before its source's provider is chosen.
219+ // guard makes the second call a no-op so a provider registered by either a -r
220+ // or an --import preload is available before the source's provider is chosen.
261221function finishVfsMounts ( ) {
262222 if ( vfsMounted ) return ;
263223 vfsMounted = true ;
264224
265- const entries = getOptionValue ( '--vfs-mount ' ) ;
266- if ( entries . length === 0 ) return ;
267- emitExperimentalWarning ( '--vfs-mount ' ) ;
225+ const source = getOptionValue ( '--vfs-load ' ) ;
226+ if ( source === '' ) return ;
227+ emitExperimentalWarning ( '--vfs-load ' ) ;
268228
269229 const fs = require ( 'fs' ) ;
270230 const path = require ( 'path' ) ;
271231 const { selectProvider } = require ( 'internal/vfs/provider_registry' ) ;
272232 const { VirtualFileSystem, kLoadLayer } = require ( 'internal/vfs/file_system' ) ;
273233
274- const loadIndex = getVfsLoadIndex ( entries . length ) ;
275- // [vfs_load_set] is forced off in workers (see node_worker.cc), so a worker
276- // mounts every source, the --vfs-load one at its reserved layer, and runs its
277- // own entry rather than the mount's.
278- const loads = getOptionValue ( '[vfs_load_set]' ) ;
279- for ( let i = 0 ; i < entries . length ; i ++ ) {
280- const resolvedSource = path . resolve ( entries [ i ] ) ;
281- let stats ;
282- try {
283- stats = fs . statSync ( resolvedSource ) ;
284- } catch {
285- throw new ERR_VFS_INVALID_TARGET ( resolvedSource ) ;
286- }
287- if ( ! stats . isDirectory ( ) && ! stats . isFile ( ) ) {
288- throw new ERR_VFS_INVALID_TARGET ( resolvedSource ) ;
289- }
290- const provider = selectProvider ( resolvedSource , stats ) ;
291- if ( provider === null ) {
292- throw new ERR_VFS_INVALID_TARGET ( resolvedSource ) ;
293- }
294- const vfs = new VirtualFileSystem ( provider , {
295- __proto__ : null ,
296- emitExperimentalWarning : false ,
297- [ kLoadLayer ] : i === loadIndex ,
298- } ) ;
299- const mountPoint = vfs . mount ( ) ;
300- // The mount --vfs-load contributed is what the entry is require()d from;
301- // process.argv[1] names the real source instead, since the reserved mount
302- // point is an opaque implementation detail.
303- //
304- // The source is spliced in rather than assigned over argv[1]: the entry
305- // comes from the mount, so nothing was consumed as an entry point and the
306- // first positional argument is the program's own. Overwriting would drop it.
307- if ( i === loadIndex && loads ) {
308- vfsLoadRoot = mountPoint ;
309- ArrayPrototypeSplice ( process . argv , 1 , 0 , resolvedSource ) ;
310- }
234+ const resolvedSource = path . resolve ( source ) ;
235+ let stats ;
236+ try {
237+ stats = fs . statSync ( resolvedSource ) ;
238+ } catch {
239+ throw new ERR_VFS_INVALID_TARGET ( resolvedSource ) ;
240+ }
241+ if ( ! stats . isDirectory ( ) && ! stats . isFile ( ) ) {
242+ throw new ERR_VFS_INVALID_TARGET ( resolvedSource ) ;
243+ }
244+ const provider = selectProvider ( resolvedSource , stats ) ;
245+ if ( provider === null ) {
246+ throw new ERR_VFS_INVALID_TARGET ( resolvedSource ) ;
247+ }
248+ // The source is mounted at the layer reserved for it, so it is at the same
249+ // reserved path in every thread.
250+ const vfs = new VirtualFileSystem ( provider , {
251+ __proto__ : null ,
252+ emitExperimentalWarning : false ,
253+ [ kLoadLayer ] : true ,
254+ } ) ;
255+ const mountPoint = vfs . mount ( ) ;
256+ // A worker inherits the source but not [vfs_load_set] (see node_worker.cc):
257+ // it mounts the same source, and so reaches it at the same reserved path,
258+ // but runs its own entry point.
259+ //
260+ // On the main thread the entry is require()d from the mount point, while
261+ // process.argv[1] reports the source, since the reserved mount point is an
262+ // opaque implementation detail. The source is spliced in rather than
263+ // assigned over argv[1]: the entry comes from the mount, so nothing was
264+ // consumed as an entry point and the first positional argument is the
265+ // program's own. Overwriting would drop it.
266+ if ( getOptionValue ( '[vfs_load_set]' ) ) {
267+ vfsLoadRoot = mountPoint ;
268+ ArrayPrototypeSplice ( process . argv , 1 , 0 , resolvedSource ) ;
311269 }
312270}
313271
0 commit comments