@@ -288,6 +288,7 @@ function reload(name::AbstractString)
288
288
error (" use `include` instead of `reload` to load source files" )
289
289
else
290
290
# reload("Package") is ok
291
+ unreference_module (Symbol (name))
291
292
require (Symbol (name))
292
293
end
293
294
end
@@ -315,25 +316,84 @@ all platforms, including those with case-insensitive filesystems like macOS and
315
316
Windows.
316
317
"""
317
318
function require (mod:: Symbol )
318
- _require (mod)
319
+ existed = root_module_exists (mod)
320
+ M = _require (mod)
319
321
# After successfully loading, notify downstream consumers
320
322
if toplevel_load[] && myid () == 1 && nprocs () > 1
321
323
# broadcast top-level import/using from node 1 (only)
322
324
@sync for p in procs ()
323
325
p == 1 && continue
324
326
@async remotecall_wait (p) do
325
- if ! isbindingresolved (Main, mod) || ! isdefined (Main, mod)
326
- _require (mod)
327
- end
327
+ _require (mod)
328
+ nothing
328
329
end
329
330
end
330
331
end
331
- for callback in package_callbacks
332
- invokelatest (callback, mod)
332
+ if ! existed
333
+ for callback in package_callbacks
334
+ invokelatest (callback, mod)
335
+ end
336
+ end
337
+ return M
338
+ end
339
+
340
+ const loaded_modules = ObjectIdDict ()
341
+ const module_keys = ObjectIdDict ()
342
+
343
+ function register_root_module (key, m:: Module )
344
+ if haskey (loaded_modules, key)
345
+ oldm = loaded_modules[key]
346
+ if oldm != = m
347
+ name = module_name (oldm)
348
+ warn (" replacing module $name ." )
349
+ end
350
+ end
351
+ loaded_modules[key] = m
352
+ module_keys[m] = key
353
+ nothing
354
+ end
355
+
356
+ register_root_module (:Core , Core)
357
+ register_root_module (:Base , Base)
358
+ register_root_module (:Main , Main)
359
+
360
+ is_root_module (m:: Module ) = haskey (module_keys, m)
361
+
362
+ root_module_key (m:: Module ) = module_keys[m]
363
+
364
+ # This is used as the current module when loading top-level modules.
365
+ # It has the special behavior that modules evaluated in it get added
366
+ # to the loaded_modules table instead of getting bindings.
367
+ baremodule __toplevel__
368
+ using Base
369
+ end
370
+
371
+ # get a top-level Module from the given key
372
+ # for now keys can only be Symbols, but that will change
373
+ root_module (key:: Symbol ) = loaded_modules[key]
374
+
375
+ root_module_exists (key:: Symbol ) = haskey (loaded_modules, key)
376
+
377
+ loaded_modules_array () = collect (values (loaded_modules))
378
+
379
+ function unreference_module (key)
380
+ if haskey (loaded_modules, key)
381
+ m = pop! (loaded_modules, key)
382
+ # need to ensure all modules are GC rooted; will still be referenced
383
+ # in module_keys
384
+ end
385
+ end
386
+
387
+ function register_all (a)
388
+ for m in a
389
+ register_root_module (module_name (m), m)
333
390
end
334
391
end
335
392
336
393
function _require (mod:: Symbol )
394
+ if root_module_exists (mod)
395
+ return root_module (mod)
396
+ end
337
397
# dependency-tracking is only used for one top-level include(path),
338
398
# and is not applied recursively to imported modules:
339
399
old_track_dependencies = _track_dependencies[]
@@ -345,7 +405,7 @@ function _require(mod::Symbol)
345
405
if loading != = false
346
406
# load already in progress for this module
347
407
wait (loading)
348
- return
408
+ return root_module (mod)
349
409
end
350
410
package_locks[mod] = Condition ()
351
411
@@ -364,7 +424,8 @@ function _require(mod::Symbol)
364
424
if JLOptions (). use_compilecache != 0
365
425
doneprecompile = _require_search_from_serialized (mod, path)
366
426
if ! isa (doneprecompile, Bool)
367
- return # success
427
+ register_all (doneprecompile)
428
+ return root_module (mod) # success
368
429
end
369
430
end
370
431
@@ -391,14 +452,17 @@ function _require(mod::Symbol)
391
452
warn (m, prefix= " WARNING: " )
392
453
# fall-through, TODO : disable __precompile__(true) error so that the normal include will succeed
393
454
else
394
- return # success
455
+ register_all (m)
456
+ return root_module (mod) # success
395
457
end
396
458
end
397
459
398
460
# just load the file normally via include
399
461
# for unknown dependencies
462
+ local M
400
463
try
401
- Base. include_relative (Main, path)
464
+ Base. include_relative (__toplevel__, path)
465
+ return root_module (mod)
402
466
catch ex
403
467
if doneprecompile === true || JLOptions (). use_compilecache == 0 || ! precompilableerror (ex, true )
404
468
rethrow () # rethrow non-precompilable=true errors
@@ -411,6 +475,8 @@ function _require(mod::Symbol)
411
475
# TODO : disable __precompile__(true) error and do normal include instead of error
412
476
error (" Module $mod declares __precompile__(true) but require failed to create a usable precompiled cache file." )
413
477
end
478
+ register_all (m)
479
+ return root_module (mod)
414
480
end
415
481
finally
416
482
toplevel_load[] = last
@@ -532,7 +598,7 @@ function create_expr_cache(input::String, output::String, concrete_deps::Vector{
532
598
task_local_storage ()[:SOURCE_PATH ] = $ (source)
533
599
end )
534
600
end
535
- serialize (in, :(Base. include (Main , $ (abspath (input)))))
601
+ serialize (in, :(Base. include (Base . __toplevel__ , $ (abspath (input)))))
536
602
if source != = nothing
537
603
serialize (in, :(delete! (task_local_storage (), :SOURCE_PATH )))
538
604
end
@@ -570,15 +636,9 @@ function compilecache(name::String)
570
636
cachefile:: String = abspath (cachepath, name* " .ji" )
571
637
# build up the list of modules that we want the precompile process to preserve
572
638
concrete_deps = copy (_concrete_dependencies)
573
- for existing in names (Main)
574
- if isdefined (Main, existing)
575
- mod = getfield (Main, existing)
576
- if isa (mod, Module) && ! (mod === Main || mod === Core || mod === Base)
577
- mod = mod:: Module
578
- if module_parent (mod) === Main && module_name (mod) === existing
579
- push! (concrete_deps, (existing, module_uuid (mod)))
580
- end
581
- end
639
+ for (key,mod) in loaded_modules
640
+ if ! (mod === Main || mod === Core || mod === Base)
641
+ push! (concrete_deps, (key, module_uuid (mod)))
582
642
end
583
643
end
584
644
# run the expression and cache the result
@@ -675,7 +735,7 @@ function stale_cachefile(modpath::String, cachefile::String)
675
735
if mod == :Main || mod == :Core || mod == :Base
676
736
continue
677
737
# Module is already loaded
678
- elseif isbindingresolved (Main, mod)
738
+ elseif root_module_exists ( mod)
679
739
continue
680
740
end
681
741
name = string (mod)
0 commit comments