From 84e68f3a7ef7d888af8a580dc52f27ff9209f4ef Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Sun, 18 Feb 2018 22:35:43 -0500 Subject: [PATCH] Make the "second Base copy" trick actually work As was mentioned in #25988, there is a handy trick where you can load a second copy of Base on top of an existing copy. This is useful for at least two reasons: 1. Base printing is available, so things like MethodErrors print nicely 2. Even if the load fails, the resulting (broken) copy of base is inspectable by standard introspection tools from the REPL, as long as you're a bit careful not to mix types from the two copies of Base. However, as I mentioned in #26079, this only actually works until about version.jl, at which point things crash. This is because at that point it tries to use PCRE which uses `Ref(0)`, which is actually an abstract type in Core, even though the type of the constructed object (`RefValue`) is in Base. As a result, the new Base gets the wrong kind of `RefValue` (the one from the original `Base`) and things break. Luckily this is easily fixed by using an explicit `RefValue` call in the relevant places. A second problem we run into is that `module`s nested under our new `Base`, get a default import of the old `Base` (unless we declare the new Base to be the global top module, but that would break the REPL subsequent to loading the new Base, which breaks reason 2 above). I suggest (and implement in this PR) to have the default import be the next topmodule along the parent link chain (as we already do for syntax defined in Base), which makes this work. A small related detail is that in all such modules `import Base: x`, needs to be replaced by `import .Base: x`, to make sure we resolve the identifier `Base` (as imported from our new top module) rather than the global name `Base` (which still refers to the old module). I changed sysimg.jl to avoid loading stdlibs in second Base mode, to avoid having to implement the same changes there. Since the stdlibs are already decoupled from Base, they can already be developed separately fairly easily, so there's not much reason to include them in this trick. For completeness, there's a couple of ways to use this trick, but perhaps the simplest is: ``` cd("base") baremodule NotBase Core.include(NotBase, "sysimg.jl") end ``` from the REPL. --- base/atomics.jl | 4 +-- base/broadcast.jl | 6 ++--- base/docs/Docs.jl | 7 +++--- base/docs/utils.jl | 2 +- base/file.jl | 4 ++- base/filesystem.jl | 4 +-- base/gmp.jl | 4 +-- base/locks.jl | 2 +- base/math.jl | 6 ++--- base/mpfr.jl | 16 ++++++------ base/multidimensional.jl | 10 ++++---- base/multimedia.jl | 4 +-- base/path.jl | 2 +- base/pcre.jl | 16 ++++++------ base/printf.jl | 4 +-- base/refpointer.jl | 53 ++++++++++++++++++++++------------------ base/sort.jl | 20 +++++++-------- base/special/log.jl | 4 +-- base/sysimg.jl | 22 ++++++++++++----- src/toplevel.c | 5 ++-- 20 files changed, 108 insertions(+), 87 deletions(-) diff --git a/base/atomics.jl b/base/atomics.jl index 278d142f0babc..b9a3289b68944 100644 --- a/base/atomics.jl +++ b/base/atomics.jl @@ -2,8 +2,8 @@ using Core.Intrinsics: llvmcall -import Base: setindex!, getindex, unsafe_convert -import Base.Sys: ARCH, WORD_SIZE +import .Base: setindex!, getindex, unsafe_convert +import .Base.Sys: ARCH, WORD_SIZE export Atomic, diff --git a/base/broadcast.jl b/base/broadcast.jl index 8c495c14f8b43..7f00b65530327 100644 --- a/base/broadcast.jl +++ b/base/broadcast.jl @@ -2,11 +2,11 @@ module Broadcast -using Base.Cartesian -using Base: Indices, OneTo, linearindices, tail, to_shape, +using .Base.Cartesian +using .Base: Indices, OneTo, linearindices, tail, to_shape, _msk_end, unsafe_bitgetindex, bitcache_chunks, bitcache_size, dumpbitcache, isoperator, promote_typejoin -import Base: broadcast, broadcast! +import .Base: broadcast, broadcast! export BroadcastStyle, broadcast_indices, broadcast_similar, broadcast_getindex, broadcast_setindex!, dotview, @__dot__ diff --git a/base/docs/Docs.jl b/base/docs/Docs.jl index d524fc0304265..f6b25be7065a5 100644 --- a/base/docs/Docs.jl +++ b/base/docs/Docs.jl @@ -60,8 +60,9 @@ function. include("bindings.jl") -import Base.Meta: quot, isexpr -import Base: Callable, with_output_color +import .Base.Meta: quot, isexpr +import .Base: Callable, with_output_color +using .Base: RefValue import ..CoreDocs: lazy_iterpolate export doc @@ -390,7 +391,7 @@ end function multidoc(__source__, __module__, meta, ex, define) out = Expr(:toplevel) str = docexpr(__source__, __module__, lazy_iterpolate(meta), metadata(__source__, __module__, ex, false)) - ref = Ref{DocStr}() + ref = RefValue{DocStr}() for (n, arg) in enumerate(ex.args) # The first `arg` to be documented needs to also create the docstring for the group. # Subsequent `arg`s just need `ref` to be able to find the docstring without having diff --git a/base/docs/utils.jl b/base/docs/utils.jl index 4d9b2608839fb..a67d88cc263db 100644 --- a/base/docs/utils.jl +++ b/base/docs/utils.jl @@ -2,7 +2,7 @@ # Text / HTML objects -import Base: print, show, ==, hash +import .Base: print, show, ==, hash export HTML, @html_str diff --git a/base/file.jl b/base/file.jl index 8190268220661..b7e4d3b89c282 100644 --- a/base/file.jl +++ b/base/file.jl @@ -27,6 +27,8 @@ export unlink, walkdir +import .Base.RefValue + # get and set current directory """ @@ -36,7 +38,7 @@ Get the current working directory. """ function pwd() b = Vector{UInt8}(uninitialized, 1024) - len = Ref{Csize_t}(length(b)) + len = RefValue{Csize_t}(length(b)) uv_error(:getcwd, ccall(:uv_cwd, Cint, (Ptr{UInt8}, Ptr{Csize_t}), b, len)) String(b[1:len[]]) end diff --git a/base/filesystem.jl b/base/filesystem.jl index 053f6ae292a0f..a6aa8bc33a60e 100644 --- a/base/filesystem.jl +++ b/base/filesystem.jl @@ -38,14 +38,14 @@ export File, S_IRGRP, S_IWGRP, S_IXGRP, S_IRWXG, S_IROTH, S_IWOTH, S_IXOTH, S_IRWXO -import Base: +import .Base: UVError, _sizeof_uv_fs, check_open, close, eof, eventloop, fd, isopen, bytesavailable, position, read, read!, readavailable, seek, seekend, show, skip, stat, unsafe_read, unsafe_write, write, transcode, uv_error, rawhandle, OS_HANDLE, INVALID_OS_HANDLE if Sys.iswindows() - import Base: cwstring + import .Base: cwstring end include("path.jl") diff --git a/base/gmp.jl b/base/gmp.jl index 0048ae5a7c602..62a4fe0dacb8c 100644 --- a/base/gmp.jl +++ b/base/gmp.jl @@ -4,7 +4,7 @@ module GMP export BigInt -import Base: *, +, -, /, <, <<, >>, >>>, <=, ==, >, >=, ^, (~), (&), (|), xor, +import .Base: *, +, -, /, <, <<, >>, >>>, <=, ==, >, >=, ^, (~), (&), (|), xor, binomial, cmp, convert, div, divrem, factorial, fld, gcd, gcdx, lcm, mod, ndigits, promote_rule, rem, show, isqrt, string, powermod, sum, trailing_zeros, trailing_ones, count_ones, base, tryparse_internal, @@ -110,7 +110,7 @@ module MPZ # - a method modifying its input has a "!" appendend to its name, according to Julia's conventions # - some convenient methods are added (in addition to the pure MPZ ones), e.g. `add(a, b) = add!(BigInt(), a, b)` # and `add!(x, a) = add!(x, x, a)`. -using Base.GMP: BigInt, Limb +using .Base.GMP: BigInt, Limb const mpz_t = Ref{BigInt} const bitcnt_t = Culong diff --git a/base/locks.jl b/base/locks.jl index 3cfa467d941fd..94acb61b73e9f 100644 --- a/base/locks.jl +++ b/base/locks.jl @@ -1,6 +1,6 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -import Base: _uv_hook_close, unsafe_convert, +import .Base: _uv_hook_close, unsafe_convert, lock, trylock, unlock, islocked export SpinLock, RecursiveSpinLock, Mutex diff --git a/base/math.jl b/base/math.jl index 223ad1ef565e9..fda5b9bfe92a3 100644 --- a/base/math.jl +++ b/base/math.jl @@ -15,17 +15,17 @@ export sin, cos, sincos, tan, sinh, cosh, tanh, asin, acos, atan, clamp, clamp!, modf, ^, mod2pi, rem2pi, beta, lbeta, @evalpoly -import Base: log, exp, sin, cos, tan, sinh, cosh, tanh, asin, +import .Base: log, exp, sin, cos, tan, sinh, cosh, tanh, asin, acos, atan, asinh, acosh, atanh, sqrt, log2, log10, max, min, minmax, ^, exp2, muladd, rem, exp10, expm1, log1p -using Base: sign_mask, exponent_mask, exponent_one, +using .Base: sign_mask, exponent_mask, exponent_one, exponent_half, uinttype, significand_mask using Core.Intrinsics: sqrt_llvm -using Base: IEEEFloat +using .Base: IEEEFloat @noinline function throw_complex_domainerror(f, x) throw(DomainError(x, string("$f will only return a complex result if called with a ", diff --git a/base/mpfr.jl b/base/mpfr.jl index 2dcc742069814..edb91c9018589 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -7,7 +7,7 @@ export setprecision import - Base: *, +, -, /, <, <=, ==, >, >=, ^, ceil, cmp, convert, copysign, div, + .Base: *, +, -, /, <, <=, ==, >, >=, ^, ceil, cmp, convert, copysign, div, inv, exp, exp2, exponent, factorial, floor, fma, hypot, isinteger, isfinite, isinf, isnan, ldexp, log, log2, log10, max, min, mod, modf, nextfloat, prevfloat, promote_rule, rem, rem2pi, round, show, float, @@ -17,15 +17,15 @@ import cosh, sinh, tanh, sech, csch, coth, acosh, asinh, atanh, atan2, cbrt, typemax, typemin, unsafe_trunc, realmin, realmax, rounding, setrounding, maxintfloat, widen, significand, frexp, tryparse, iszero, - isone, big, beta + isone, big, beta, RefValue -import Base.Rounding: rounding_raw, setrounding_raw +import .Base.Rounding: rounding_raw, setrounding_raw -import Base.GMP: ClongMax, CulongMax, CdoubleMax, Limb +import .Base.GMP: ClongMax, CulongMax, CdoubleMax, Limb -import Base.Math.lgamma_r +import .Base.Math.lgamma_r -import Base.FastMath.sincos_fast +import .Base.FastMath.sincos_fast version() = VersionNumber(unsafe_string(ccall((:mpfr_get_version,:libmpfr), Ptr{Cchar}, ()))) patches() = split(unsafe_string(ccall((:mpfr_get_patches,:libmpfr), Ptr{Cchar}, ())),' ') @@ -40,8 +40,8 @@ function __init__() end end -const ROUNDING_MODE = Ref{Cint}(0) -const DEFAULT_PRECISION = Ref(256) +const ROUNDING_MODE = RefValue{Cint}(0) +const DEFAULT_PRECISION = RefValue(256) # Basic type and initialization definitions diff --git a/base/multidimensional.jl b/base/multidimensional.jl index 2576140929370..5517f449c0e5c 100644 --- a/base/multidimensional.jl +++ b/base/multidimensional.jl @@ -2,14 +2,14 @@ ### Multidimensional iterators module IteratorsMD - import Base: eltype, length, size, start, done, next, first, last, in, getindex, + import .Base: eltype, length, size, start, done, next, first, last, in, getindex, setindex!, IndexStyle, min, max, zero, one, isless, eachindex, ndims, IteratorSize, convert, show - import Base: +, -, * - import Base: simd_outer_range, simd_inner_length, simd_index - using Base: IndexLinear, IndexCartesian, AbstractCartesianIndex, fill_to_length, tail - using Base.Iterators: Reverse + import .Base: +, -, * + import .Base: simd_outer_range, simd_inner_length, simd_index + using .Base: IndexLinear, IndexCartesian, AbstractCartesianIndex, fill_to_length, tail + using .Base.Iterators: Reverse export CartesianIndex, CartesianIndices, LinearIndices diff --git a/base/multimedia.jl b/base/multimedia.jl index d988d4da2e5db..287d2c347ab31 100644 --- a/base/multimedia.jl +++ b/base/multimedia.jl @@ -14,8 +14,8 @@ export AbstractDisplay, display, pushdisplay, popdisplay, displayable, redisplay # defined in sysimg.jl for bootstrapping: # struct MIME{mime} end # macro MIME_str(s) -import Base: MIME, @MIME_str -import Base: show, print, string, convert, repr +import .Base: MIME, @MIME_str +import .Base: show, print, string, convert, repr MIME(s) = MIME{Symbol(s)}() show(io::IO, ::MIME{mime}) where {mime} = print(io, "MIME type ", string(mime)) print(io::IO, ::MIME{mime}) where {mime} = print(io, mime) diff --git a/base/path.jl b/base/path.jl index d2448a083a315..1bb777dd2377d 100644 --- a/base/path.jl +++ b/base/path.jl @@ -62,7 +62,7 @@ Return the current user's home directory. function homedir() path_max = 1024 buf = Vector{UInt8}(uninitialized, path_max) - sz = Ref{Csize_t}(path_max + 1) + sz = RefValue{Csize_t}(path_max + 1) while true rc = ccall(:uv_os_homedir, Cint, (Ptr{UInt8}, Ptr{Csize_t}), buf, sz) if rc == 0 diff --git a/base/pcre.jl b/base/pcre.jl index 4938ffda38c1c..0fdc486988018 100644 --- a/base/pcre.jl +++ b/base/pcre.jl @@ -4,12 +4,14 @@ module PCRE +import ..RefValue + include(string(length(Core.ARGS) >= 2 ? Core.ARGS[2] : "", "pcre_h.jl")) # include($BUILDROOT/base/pcre_h.jl) const PCRE_LIB = "libpcre2-8" -const JIT_STACK = Ref{Ptr{Cvoid}}(C_NULL) -const MATCH_CONTEXT = Ref{Ptr{Cvoid}}(C_NULL) +const JIT_STACK = RefValue{Ptr{Cvoid}}(C_NULL) +const MATCH_CONTEXT = RefValue{Ptr{Cvoid}}(C_NULL) function __init__() try @@ -70,7 +72,7 @@ const OPTIONS_MASK = COMPILE_MASK | EXECUTE_MASK const UNSET = ~Csize_t(0) # Indicates that an output vector element is unset function info(regex::Ptr{Cvoid}, what::Integer, ::Type{T}) where T - buf = Ref{T}() + buf = RefValue{T}() ret = ccall((:pcre2_pattern_info_8, PCRE_LIB), Int32, (Ptr{Cvoid}, Int32, Ptr{Cvoid}), regex, what, buf) @@ -92,8 +94,8 @@ function get_ovec(match_data) end function compile(pattern::AbstractString, options::Integer) - errno = Ref{Cint}(0) - erroff = Ref{Csize_t}(0) + errno = RefValue{Cint}(0) + erroff = RefValue{Csize_t}(0) re_ptr = ccall((:pcre2_compile_8, PCRE_LIB), Ptr{Cvoid}, (Ptr{UInt8}, Csize_t, UInt32, Ref{Cint}, Ref{Csize_t}, Ptr{Cvoid}), pattern, sizeof(pattern), options, errno, erroff, C_NULL) @@ -146,7 +148,7 @@ function substring_number_from_name(re, name) end function substring_length_bynumber(match_data, number) - s = Ref{Csize_t}() + s = RefValue{Csize_t}() rc = ccall((:pcre2_substring_length_bynumber_8, PCRE_LIB), Cint, (Ptr{Cvoid}, UInt32, Ref{Csize_t}), match_data, number, s) rc < 0 && error("PCRE error: $(err_message(rc))") @@ -154,7 +156,7 @@ function substring_length_bynumber(match_data, number) end function substring_copy_bynumber(match_data, number, buf, buf_size) - s = Ref{Csize_t}(buf_size) + s = RefValue{Csize_t}(buf_size) rc = ccall((:pcre2_substring_copy_bynumber_8, PCRE_LIB), Cint, (Ptr{Cvoid}, UInt32, Ptr{UInt8}, Ref{Csize_t}), match_data, number, buf, s) diff --git a/base/printf.jl b/base/printf.jl index 8bfefc8e77c11..8bd35d6a9e64b 100644 --- a/base/printf.jl +++ b/base/printf.jl @@ -1,8 +1,8 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license module Printf -using Base.Grisu -using Base.GMP +using .Base.Grisu +using .Base.GMP ### printf formatter generation ### const SmallFloatingPoint = Union{Float64,Float32,Float16} diff --git a/base/refpointer.jl b/base/refpointer.jl index 8f95c67fc6db7..68200db4061e4 100644 --- a/base/refpointer.jl +++ b/base/refpointer.jl @@ -50,14 +50,8 @@ end RefValue(x::T) where {T} = RefValue{T}(x) isassigned(x::RefValue) = isdefined(x, :x) -Ref(x::Any) = RefValue(x) -Ref{T}() where {T} = RefValue{T}() # Ref{T}() -Ref{T}(x) where {T} = RefValue{T}(x) # Ref{T}(x) convert(::Type{Ref{T}}, x) where {T} = RefValue{T}(x) -Ref(x::Ref, i::Integer) = (i != 1 && error("Ref only has one element"); x) -Ref(x::Ptr{T}, i::Integer) where {T} = x + (i - 1) * Core.sizeof(T) - function unsafe_convert(P::Type{Ptr{T}}, b::RefValue{T}) where T if datatype_pointerfree(RefValue{T}) p = pointer_from_objref(b) @@ -87,7 +81,6 @@ end RefArray(x::AbstractArray{T}, i::Int, roots::Any) where {T} = RefArray{T,typeof(x),Any}(x, i, roots) RefArray(x::AbstractArray{T}, i::Int=1, roots::Nothing=nothing) where {T} = RefArray{T,typeof(x),Nothing}(x, i, nothing) convert(::Type{Ref{T}}, x::AbstractArray{T}) where {T} = RefArray(x, 1) -Ref(x::AbstractArray, i::Integer) = RefArray(x, i) function unsafe_convert(P::Type{Ptr{T}}, b::RefArray{T}) where T if datatype_pointerfree(RefValue{T}) @@ -105,26 +98,38 @@ function unsafe_convert(P::Type{Ptr{Any}}, b::RefArray{Any}) end unsafe_convert(::Type{Ptr{Cvoid}}, b::RefArray{T}) where {T} = convert(Ptr{Cvoid}, unsafe_convert(Ptr{T}, b)) -# convert Arrays to pointer arrays for ccall -function Ref{P}(a::Array{<:Union{Ptr,Cwstring,Cstring}}) where P<:Union{Ptr,Cwstring,Cstring} - return RefArray(a) # effectively a no-op -end -function Ref{P}(a::Array{T}) where P<:Union{Ptr,Cwstring,Cstring} where T - if (!isbits(T) && T <: eltype(P)) - # this Array already has the right memory layout for the requested Ref - return RefArray(a,1,false) # root something, so that this function is type-stable - else - ptrs = Vector{P}(uninitialized, length(a)+1) - roots = Vector{Any}(uninitialized, length(a)) - for i = 1:length(a) - root = cconvert(P, a[i]) - ptrs[i] = unsafe_convert(P, root)::P - roots[i] = root +### +if is_primary_base_module + Ref(x::Any) = RefValue(x) + Ref{T}() where {T} = RefValue{T}() # Ref{T}() + Ref{T}(x) where {T} = RefValue{T}(x) # Ref{T}(x) + + Ref(x::Ref, i::Integer) = (i != 1 && error("Ref only has one element"); x) + Ref(x::Ptr{T}, i::Integer) where {T} = x + (i - 1) * Core.sizeof(T) + + # convert Arrays to pointer arrays for ccall + function Ref{P}(a::Array{<:Union{Ptr,Cwstring,Cstring}}) where P<:Union{Ptr,Cwstring,Cstring} + return RefArray(a) # effectively a no-op + end + function Ref{P}(a::Array{T}) where P<:Union{Ptr,Cwstring,Cstring} where T + if (!isbits(T) && T <: eltype(P)) + # this Array already has the right memory layout for the requested Ref + return RefArray(a,1,false) # root something, so that this function is type-stable + else + ptrs = Vector{P}(uninitialized, length(a)+1) + roots = Vector{Any}(uninitialized, length(a)) + for i = 1:length(a) + root = cconvert(P, a[i]) + ptrs[i] = unsafe_convert(P, root)::P + roots[i] = root + end + ptrs[length(a)+1] = C_NULL + return RefArray(ptrs,1,roots) end - ptrs[length(a)+1] = C_NULL - return RefArray(ptrs,1,roots) end + Ref(x::AbstractArray, i::Integer) = RefArray(x, i) end + cconvert(::Type{Ptr{P}}, a::Array{<:Ptr}) where {P<:Ptr} = a cconvert(::Type{Ref{P}}, a::Array{<:Ptr}) where {P<:Ptr} = a cconvert(::Type{Ptr{P}}, a::Array) where {P<:Union{Ptr,Cwstring,Cstring}} = Ref{P}(a) diff --git a/base/sort.jl b/base/sort.jl index 6030fa70e4334..f56081b982179 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -2,16 +2,16 @@ module Sort -using Base.Order, Base.Checked -using Base: copymutable, linearindices, IndexStyle, viewindexing, IndexLinear, _length - -import - Base.sort, - Base.sort!, - Base.issorted, - Base.sortperm, - Base.Slice, - Base.to_indices +using .Base.Order, .Base.Checked +using .Base: copymutable, linearindices, IndexStyle, viewindexing, IndexLinear, _length + +import .Base: + sort, + sort!, + issorted, + sortperm, + Slice, + to_indices export # also exported by Base # order-only: diff --git a/base/special/log.jl b/base/special/log.jl index e62ddf541705e..1768cbfdd3da3 100644 --- a/base/special/log.jl +++ b/base/special/log.jl @@ -8,8 +8,8 @@ # Does not currently handle floating point flags (inexact, div-by-zero, etc). -import Base.unsafe_trunc -import Base.Math.@horner +import .Base.unsafe_trunc +import .Base.Math.@horner # Float64 lookup table. # to generate values: diff --git a/base/sysimg.jl b/base/sysimg.jl index 14fb16fcb42eb..f5431ba8e19dc 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -3,7 +3,9 @@ baremodule Base using Core.Intrinsics, Core.IR -ccall(:jl_set_istopmod, Cvoid, (Any, Bool), Base, true) + +const is_primary_base_module = ccall(:jl_module_parent, Ref{Module}, (Any,), Base) === Core.Main +ccall(:jl_set_istopmod, Cvoid, (Any, Bool), Base, is_primary_base_module) getproperty(x, f::Symbol) = getfield(x, f) setproperty!(x, f::Symbol, v) = setfield!(x, f, convert(fieldtype(typeof(x), f), v)) @@ -471,10 +473,13 @@ include("docs/basedocs.jl") # Documentation -- should always be included last in sysimg. include("docs/Docs.jl") using .Docs -isdefined(Core, :Compiler) && Docs.loaddocs(Core.Compiler.CoreDocs.DOCS) +if isdefined(Core, :Compiler) && is_primary_base_module + Docs.loaddocs(Core.Compiler.CoreDocs.DOCS) +end end_base_include = time_ns() +if is_primary_base_module function __init__() # for the few uses of Crand in Base: Csrand() @@ -490,15 +495,19 @@ function __init__() end INCLUDE_STATE = 3 # include = include_relative -const tot_time_stdlib = Ref(0.0) +end + +const tot_time_stdlib = RefValue(0.0) + end # baremodule Base -using Base +using .Base # Ensure this file is also tracked pushfirst!(Base._included_files, (@__MODULE__, joinpath(@__DIR__, "sysimg.jl"))) +if Base.is_primary_base_module # load some stdlib packages but don't put their names in Main let # Stdlibs manually sorted in top down order @@ -880,15 +889,16 @@ end @eval @deprecate_stdlib $(Symbol("@code_llvm")) InteractiveUtils true @eval @deprecate_stdlib $(Symbol("@code_native")) InteractiveUtils true end +end empty!(DEPOT_PATH) empty!(LOAD_PATH) let tot_time_userimg = @elapsed (Base.isfile("userimg.jl") && Base.include(Main, "userimg.jl")) -tot_time_precompile = @elapsed Base.include(Base, "precompile.jl") +tot_time_precompile = Base.is_primary_base_module ? (@elapsed Base.include(Base, "precompile.jl")) : 0.0 -tot_time_base = (Base.end_base_include - Base.start_base_include) * 10^(-9) +tot_time_base = (Base.end_base_include - Base.start_base_include) * 10.0^(-9) tot_time = tot_time_base + Base.tot_time_stdlib[] + tot_time_userimg + tot_time_precompile println("Sysimage built. Summary:") diff --git a/src/toplevel.c b/src/toplevel.c index 9ae75a9c8ca6b..f718d2df401fd 100644 --- a/src/toplevel.c +++ b/src/toplevel.c @@ -35,9 +35,10 @@ jl_module_t *jl_internal_main_module = NULL; JL_DLLEXPORT void jl_add_standard_imports(jl_module_t *m) { - assert(jl_base_module != NULL); + jl_module_t *base_module = jl_base_relative_to(m); + assert(base_module != NULL); // using Base - jl_module_using(m, jl_base_module); + jl_module_using(m, base_module); } JL_DLLEXPORT jl_module_t *jl_new_main_module(void)