From 9d5a05ef792e32cec8de8d09866e176ea8eaf158 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Wed, 23 Jan 2019 16:36:36 -0500 Subject: [PATCH] separate Base and sysimg, and put less code in top-level files (#30782) --- base/Base.jl | 396 +++++++++++++++++++++++++++++++ base/baseext.jl | 35 +++ base/coreio.jl | 3 + base/expr.jl | 18 +- base/gmp.jl | 2 + base/mpfr.jl | 2 + base/multimedia.jl | 40 +++- base/ntuple.jl | 68 ++++++ base/rational.jl | 2 + base/reinterpretarray.jl | 11 + base/strings/basic.jl | 1 + base/sysimg.jl | 499 +-------------------------------------- base/tuple.jl | 40 ---- 13 files changed, 566 insertions(+), 551 deletions(-) create mode 100644 base/Base.jl create mode 100644 base/baseext.jl create mode 100644 base/ntuple.jl diff --git a/base/Base.jl b/base/Base.jl new file mode 100644 index 0000000000000..b7807495c3366 --- /dev/null +++ b/base/Base.jl @@ -0,0 +1,396 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +baremodule Base + +using Core.Intrinsics, Core.IR + +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) + +# Try to help prevent users from shooting them-selves in the foot +# with ambiguities by defining a few common and critical operations +# (and these don't need the extra convert code) +getproperty(x::Module, f::Symbol) = getfield(x, f) +setproperty!(x::Module, f::Symbol, v) = setfield!(x, f, v) +getproperty(x::Type, f::Symbol) = getfield(x, f) +setproperty!(x::Type, f::Symbol, v) = setfield!(x, f, v) + +getproperty(Core.@nospecialize(x), f::Symbol) = getfield(x, f) +setproperty!(x, f::Symbol, v) = setfield!(x, f, convert(fieldtype(typeof(x), f), v)) + +function include_relative end +function include(mod::Module, path::AbstractString) + local result + if INCLUDE_STATE === 1 + result = _include1(mod, path) + elseif INCLUDE_STATE === 2 + result = _include(mod, path) + elseif INCLUDE_STATE === 3 + result = include_relative(mod, path) + end + result +end +function include(path::AbstractString) + local result + if INCLUDE_STATE === 1 + result = _include1(Base, path) + elseif INCLUDE_STATE === 2 + result = _include(Base, path) + else + # to help users avoid error (accidentally evaluating into Base), this is not allowed + error("Base.include(string) is discontinued, use `include(fname)` or `Base.include(@__MODULE__, fname)` instead.") + end + result +end +const _included_files = Array{Tuple{Module,String},1}() +function _include1(mod::Module, path) + Core.Compiler.push!(_included_files, (mod, ccall(:jl_prepend_cwd, Any, (Any,), path))) + Core.include(mod, path) +end +let SOURCE_PATH = "" + # simple, race-y TLS, relative include + global _include + function _include(mod::Module, path) + prev = SOURCE_PATH + path = normpath(joinpath(dirname(prev), path)) + push!(_included_files, (mod, abspath(path))) + SOURCE_PATH = path + result = Core.include(mod, path) + SOURCE_PATH = prev + result + end +end +INCLUDE_STATE = 1 # include = Core.include + +include("coreio.jl") + +eval(x) = Core.eval(Base, x) +eval(m::Module, x) = Core.eval(m, x) + +# init core docsystem +import Core: @doc, @__doc__, WrappedException, @int128_str, @uint128_str, @big_str, @cmd +if isdefined(Core, :Compiler) + import Core.Compiler.CoreDocs + Core.atdoc!(CoreDocs.docm) +end + +include("exports.jl") + +if false + # simple print definitions for debugging. enable these if something + # goes wrong during bootstrap before printing code is available. + # otherwise, they just just eventually get (noisily) overwritten later + global show, print, println + show(io::IO, x) = Core.show(io, x) + print(io::IO, a...) = Core.print(io, a...) + println(io::IO, x...) = Core.println(io, x...) +end + +""" + time_ns() + +Get the time in nanoseconds. The time corresponding to 0 is undefined, and wraps every 5.8 years. +""" +time_ns() = ccall(:jl_hrtime, UInt64, ()) + +start_base_include = time_ns() + +## Load essential files and libraries +include("essentials.jl") +include("ctypes.jl") +include("gcutils.jl") +include("generator.jl") +include("reflection.jl") +include("options.jl") + +# core operations & types +include("promotion.jl") +include("tuple.jl") +include("expr.jl") +include("pair.jl") +include("traits.jl") +include("range.jl") +include("error.jl") + +# core numeric operations & types +include("bool.jl") +include("number.jl") +include("int.jl") +include("operators.jl") +include("pointer.jl") +include("refvalue.jl") +include("refpointer.jl") +include("checked.jl") +using .Checked + +# array structures +include("indices.jl") +include("array.jl") +include("abstractarray.jl") +include("subarray.jl") +include("views.jl") +include("baseext.jl") + +include("ntuple.jl") + +include("abstractdict.jl") + +include("iterators.jl") +using .Iterators: zip, enumerate +using .Iterators: Flatten, Filter, product # for generators + +include("namedtuple.jl") + +# numeric operations +include("hashing.jl") +include("rounding.jl") +using .Rounding +include("float.jl") +include("twiceprecision.jl") +include("complex.jl") +include("rational.jl") +include("multinverses.jl") +using .MultiplicativeInverses +include("abstractarraymath.jl") +include("arraymath.jl") + +# SIMD loops +include("simdloop.jl") +using .SimdLoop + +# map-reduce operators +include("reduce.jl") + +## core structures +include("reshapedarray.jl") +include("reinterpretarray.jl") +include("bitarray.jl") +include("bitset.jl") + +if !isdefined(Core, :Compiler) + include("docs/core.jl") + Core.atdoc!(CoreDocs.docm) +end + +include("multimedia.jl") +using .Multimedia + +# Some type +include("some.jl") + +include("dict.jl") +include("abstractset.jl") +include("set.jl") + +include("char.jl") +include("strings/basic.jl") +include("strings/string.jl") +include("strings/substring.jl") + +# For OS specific stuff +include(string((length(Core.ARGS)>=2 ? Core.ARGS[2] : ""), "build_h.jl")) # include($BUILDROOT/base/build_h.jl) +include(string((length(Core.ARGS)>=2 ? Core.ARGS[2] : ""), "version_git.jl")) # include($BUILDROOT/base/version_git.jl) + +include("osutils.jl") +include("c.jl") + +# Core I/O +include("io.jl") +include("iostream.jl") +include("iobuffer.jl") + +# strings & printing +include("intfuncs.jl") +include("strings/strings.jl") +include("parse.jl") +include("shell.jl") +include("regex.jl") +include("show.jl") +include("arrayshow.jl") + +# multidimensional arrays +include("cartesian.jl") +using .Cartesian +include("multidimensional.jl") +include("permuteddimsarray.jl") +using .PermutedDimsArrays + +include("broadcast.jl") +using .Broadcast +using .Broadcast: broadcasted, broadcasted_kwsyntax, materialize, materialize! + +# missing values +include("missing.jl") + +# version +include("version.jl") + +# system & environment +include("sysinfo.jl") +include("libc.jl") +using .Libc: getpid, gethostname, time + +const DL_LOAD_PATH = String[] +if Sys.isapple() + push!(DL_LOAD_PATH, "@loader_path/julia") + push!(DL_LOAD_PATH, "@loader_path") +end + +include("env.jl") + +# Scheduling +include("libuv.jl") +include("event.jl") +include("task.jl") +include("threads.jl") +include("lock.jl") +include("weakkeydict.jl") + +# Logging +include("logging.jl") +using .CoreLogging + +# functions defined in Random +function rand end +function randn end + +# I/O +include("stream.jl") +include("filesystem.jl") +using .Filesystem +include("process.jl") +include("grisu/grisu.jl") +include("methodshow.jl") +include("secretbuffer.jl") + +# core math functions +include("floatfuncs.jl") +include("math.jl") +using .Math +const (√)=sqrt +const (∛)=cbrt + +INCLUDE_STATE = 2 # include = _include (from lines above) + +# reduction along dims +include("reducedim.jl") # macros in this file relies on string.jl +include("accumulate.jl") + +# basic data structures +include("ordering.jl") +using .Order + +# Combinatorics +include("sort.jl") +using .Sort + +# Fast math +include("fastmath.jl") +using .FastMath + +function deepcopy_internal end + +# enums +include("Enums.jl") +using .Enums + +# BigInts and BigFloats +include("gmp.jl") +using .GMP + +include("mpfr.jl") +using .MPFR + +include("combinatorics.jl") + +# more hashing definitions +include("hashing2.jl") + +# irrational mathematical constants +include("irrationals.jl") +include("mathconstants.jl") +using .MathConstants: ℯ, π, pi + +# (s)printf macros +include("printf.jl") +# import .Printf + +# metaprogramming +include("meta.jl") + +# concurrency and parallelism +include("channels.jl") + +# utilities +include("deepcopy.jl") +include("download.jl") +include("summarysize.jl") +include("errorshow.jl") + +# Stack frames and traces +include("stacktraces.jl") +using .StackTraces + +include("initdefs.jl") + +# worker threads +include("threadcall.jl") + +# code loading +include("uuid.jl") +include("loading.jl") + +# misc useful functions & macros +include("util.jl") + +include("asyncmap.jl") + +# deprecated functions +include("deprecated.jl") + +# Some basic documentation +include("docs/basedocs.jl") + +include("client.jl") + +# Documentation -- should always be included last in sysimg. +include("docs/Docs.jl") +using .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__() + # try to ensuremake sure OpenBLAS does not set CPU affinity (#1070, #9639) + if !haskey(ENV, "OPENBLAS_MAIN_FREE") && !haskey(ENV, "GOTOBLAS_MAIN_FREE") + ENV["OPENBLAS_MAIN_FREE"] = "1" + end + # And try to prevent openblas from starting too many threads, unless/until specifically requested + if !haskey(ENV, "OPENBLAS_NUM_THREADS") && !haskey(ENV, "OMP_NUM_THREADS") + cpu_threads = Sys.CPU_THREADS::Int + if cpu_threads > 8 # always at most 8 + ENV["OPENBLAS_NUM_THREADS"] = "8" + elseif haskey(ENV, "JULIA_CPU_THREADS") # or exactly as specified + ENV["OPENBLAS_NUM_THREADS"] = cpu_threads + end # otherwise, trust that openblas will pick CPU_THREADS anyways, without any intervention + end + # for the few uses of Libc.rand in Base: + Libc.srand() + # Base library init + reinit_stdio() + Multimedia.reinit_displays() # since Multimedia.displays uses stdout as fallback + # initialize loading + init_depot_path() + init_load_path() + nothing +end + +INCLUDE_STATE = 3 # include = include_relative +end + +const tot_time_stdlib = RefValue(0.0) + +end # baremodule Base diff --git a/base/baseext.jl b/base/baseext.jl new file mode 100644 index 0000000000000..4f60be88f603d --- /dev/null +++ b/base/baseext.jl @@ -0,0 +1,35 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +# extensions to Core types to add features in Base + +# hook up VecElement constructor to Base.convert +VecElement{T}(arg) where {T} = VecElement{T}(convert(T, arg)) +convert(::Type{T}, arg) where {T<:VecElement} = T(arg) +convert(::Type{T}, arg::T) where {T<:VecElement} = arg + +# ## dims-type-converting Array constructors for convenience +# type and dimensionality specified, accepting dims as series of Integers +Vector{T}(::UndefInitializer, m::Integer) where {T} = Vector{T}(undef, Int(m)) +Matrix{T}(::UndefInitializer, m::Integer, n::Integer) where {T} = Matrix{T}(undef, Int(m), Int(n)) +Array{T,N}(::UndefInitializer, d::Vararg{Integer,N}) where {T,N} = Array{T,N}(undef, convert(Tuple{Vararg{Int}}, d)) +# type but not dimensionality specified, accepting dims as series of Integers +Array{T}(::UndefInitializer, m::Integer) where {T} = Array{T,1}(undef, Int(m)) +Array{T}(::UndefInitializer, m::Integer, n::Integer) where {T} = Array{T,2}(undef, Int(m), Int(n)) +Array{T}(::UndefInitializer, m::Integer, n::Integer, o::Integer) where {T} = Array{T,3}(undef, Int(m), Int(n), Int(o)) +Array{T}(::UndefInitializer, d::Integer...) where {T} = Array{T}(undef, convert(Tuple{Vararg{Int}}, d)) +# dimensionality but not type specified, accepting dims as series of Integers +Vector(::UndefInitializer, m::Integer) = Vector{Any}(undef, Int(m)) +Matrix(::UndefInitializer, m::Integer, n::Integer) = Matrix{Any}(undef, Int(m), Int(n)) +# Dimensions as a single tuple +Array{T}(::UndefInitializer, d::NTuple{N,Integer}) where {T,N} = Array{T,N}(undef, convert(Tuple{Vararg{Int}}, d)) +Array{T,N}(::UndefInitializer, d::NTuple{N,Integer}) where {T,N} = Array{T,N}(undef, convert(Tuple{Vararg{Int}}, d)) +# empty vector constructor +Vector() = Vector{Any}(undef, 0) + +# Array constructors for nothing and missing +# type and dimensionality specified +Array{T,N}(::Nothing, d...) where {T,N} = fill!(Array{T,N}(undef, d...), nothing) +Array{T,N}(::Missing, d...) where {T,N} = fill!(Array{T,N}(undef, d...), missing) +# type but not dimensionality specified +Array{T}(::Nothing, d...) where {T} = fill!(Array{T}(undef, d...), nothing) +Array{T}(::Missing, d...) where {T} = fill!(Array{T}(undef, d...), missing) diff --git a/base/coreio.jl b/base/coreio.jl index da955e838a015..d2be652731e43 100644 --- a/base/coreio.jl +++ b/base/coreio.jl @@ -4,6 +4,9 @@ print(xs...) = print(stdout::IO, xs...) println(xs...) = println(stdout::IO, xs...) println(io::IO) = print(io, '\n') +function show end +function repr end + struct DevNull <: IO end const devnull = DevNull() isreadable(::DevNull) = false diff --git a/base/expr.jl b/base/expr.jl index c27d5bc6b3b05..c6a02e4571692 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -266,7 +266,7 @@ function pushmeta!(ex::Expr, sym::Symbol, args::Any...) end inner = ex - while inner.head == :macrocall + while inner.head === :macrocall inner = inner.args[end]::Expr end @@ -284,7 +284,7 @@ popmeta!(body, sym) = _getmeta(body, sym, true) peekmeta(body, sym) = _getmeta(body, sym, false) function _getmeta(body::Expr, sym::Symbol, delete::Bool) - body.head == :block || return false, [] + body.head === :block || return false, [] _getmeta(body.args, sym, delete) end _getmeta(arg, sym, delete::Bool) = (false, []) @@ -319,19 +319,19 @@ function findmetaarg(metaargs, sym) end function is_short_function_def(ex) - ex.head == :(=) || return false + ex.head === :(=) || return false while length(ex.args) >= 1 && isa(ex.args[1], Expr) - (ex.args[1].head == :call) && return true - (ex.args[1].head == :where || ex.args[1].head == :(::)) || return false + (ex.args[1].head === :call) && return true + (ex.args[1].head === :where || ex.args[1].head === :(::)) || return false ex = ex.args[1] end return false end function findmeta(ex::Expr) - if ex.head == :function || is_short_function_def(ex) + if ex.head === :function || is_short_function_def(ex) body::Expr = ex.args[2] - body.head == :block || error(body, " is not a block expression") + body.head === :block || error(body, " is not a block expression") return findmeta_block(ex.args) end error(ex, " is not a function expression") @@ -343,9 +343,9 @@ function findmeta_block(exargs, argsmatch=args->true) for i = 1:length(exargs) a = exargs[i] if isa(a, Expr) - if (a::Expr).head == :meta && argsmatch((a::Expr).args) + if (a::Expr).head === :meta && argsmatch((a::Expr).args) return i, exargs - elseif (a::Expr).head == :block + elseif (a::Expr).head === :block idx, exa = findmeta_block(a.args, argsmatch) if idx != 0 return idx, exa diff --git a/base/gmp.jl b/base/gmp.jl index dea7da7edd108..ff85e670d3c71 100644 --- a/base/gmp.jl +++ b/base/gmp.jl @@ -394,6 +394,8 @@ function big end big(::Type{<:Integer}) = BigInt big(::Type{<:Rational}) = Rational{BigInt} +big(n::Integer) = convert(BigInt, n) + # Binary ops for (fJ, fC) in ((:+, :add), (:-,:sub), (:*, :mul), (:fld, :fdiv_q), (:div, :tdiv_q), (:mod, :fdiv_r), (:rem, :tdiv_r), diff --git a/base/mpfr.jl b/base/mpfr.jl index aaf3e9783bf62..7b35d436b690f 100644 --- a/base/mpfr.jl +++ b/base/mpfr.jl @@ -355,6 +355,8 @@ promote_rule(::Type{BigFloat}, ::Type{<:AbstractFloat}) = BigFloat big(::Type{<:AbstractFloat}) = BigFloat +big(x::AbstractFloat) = convert(BigFloat, x) + function (::Type{Rational{BigInt}})(x::AbstractFloat) isnan(x) && return zero(BigInt) // zero(BigInt) isinf(x) && return copysign(one(BigInt),x) // zero(BigInt) diff --git a/base/multimedia.jl b/base/multimedia.jl index 9e17f05d7312b..1f207345dc7fd 100644 --- a/base/multimedia.jl +++ b/base/multimedia.jl @@ -2,6 +2,8 @@ module Multimedia +import .Base: show, print, convert, repr + export AbstractDisplay, display, pushdisplay, popdisplay, displayable, redisplay, MIME, @MIME_str, istextmime, showable, TextDisplay @@ -11,11 +13,39 @@ export AbstractDisplay, display, pushdisplay, popdisplay, displayable, redisplay # that Julia's dispatch and overloading mechanisms can be used to # dispatch show and to add conversions for new types. -# 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 +""" + MIME + +A type representing a standard internet data format. "MIME" stands for +"Multipurpose Internet Mail Extensions", since the standard was originally +used to describe multimedia attachments to email messages. + +A `MIME` object can be passed as the second argument to [`show`](@ref) to +request output in that format. + +# Examples +```jldoctest +julia> show(stdout, MIME("text/plain"), "hi") +"hi" +``` +""" +struct MIME{mime} end + +""" + @MIME_str + +A convenience macro for writing [`MIME`](@ref) types, typically used when +adding methods to `show`. +For example the syntax `show(io::IO, ::MIME"text/html", x::MyType) = ...` +could be used to define how to write an HTML representation of `MyType`. +""" +macro MIME_str(s) + :(MIME{$(Expr(:quote, Symbol(s)))}) +end + +# fallback text/plain representation of any type: +show(io::IO, ::MIME"text/plain", x) = show(io, x) + 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/ntuple.jl b/base/ntuple.jl new file mode 100644 index 0000000000000..908b3062d1e95 --- /dev/null +++ b/base/ntuple.jl @@ -0,0 +1,68 @@ +# This file is a part of Julia. License is MIT: https://julialang.org/license + +# `ntuple`, for constructing tuples of a given length + +""" + ntuple(f::Function, n::Integer) + +Create a tuple of length `n`, computing each element as `f(i)`, +where `i` is the index of the element. + +# Examples +```jldoctest +julia> ntuple(i -> 2*i, 4) +(2, 4, 6, 8) +``` +""" +function ntuple(f::F, n::Integer) where F + t = n == 0 ? () : + n == 1 ? (f(1),) : + n == 2 ? (f(1), f(2)) : + n == 3 ? (f(1), f(2), f(3)) : + n == 4 ? (f(1), f(2), f(3), f(4)) : + n == 5 ? (f(1), f(2), f(3), f(4), f(5)) : + n == 6 ? (f(1), f(2), f(3), f(4), f(5), f(6)) : + n == 7 ? (f(1), f(2), f(3), f(4), f(5), f(6), f(7)) : + n == 8 ? (f(1), f(2), f(3), f(4), f(5), f(6), f(7), f(8)) : + n == 9 ? (f(1), f(2), f(3), f(4), f(5), f(6), f(7), f(8), f(9)) : + n == 10 ? (f(1), f(2), f(3), f(4), f(5), f(6), f(7), f(8), f(9), f(10)) : + _ntuple(f, n) + return t +end + +function _ntuple(f, n) + @_noinline_meta + (n >= 0) || throw(ArgumentError(string("tuple length should be ≥0, got ", n))) + ([f(i) for i = 1:n]...,) +end + +# inferrable ntuple (enough for bootstrapping) +ntuple(f, ::Val{0}) = () +ntuple(f, ::Val{1}) = (@_inline_meta; (f(1),)) +ntuple(f, ::Val{2}) = (@_inline_meta; (f(1), f(2))) +ntuple(f, ::Val{3}) = (@_inline_meta; (f(1), f(2), f(3))) + +@inline function ntuple(f::F, ::Val{N}) where {F,N} + N::Int + (N >= 0) || throw(ArgumentError(string("tuple length should be ≥0, got ", N))) + if @generated + quote + @nexprs $N i -> t_i = f(i) + @ncall $N tuple t + end + else + Tuple(f(i) for i = 1:N) + end +end + +@inline function fill_to_length(t::Tuple, val, ::Val{N}) where {N} + M = length(t) + M > N && throw(ArgumentError("input tuple of length $M, requested $N")) + if @generated + quote + (t..., $(fill(:val, N-length(t.parameters))...)) + end + else + (t..., fill(val, N-M)...) + end +end diff --git a/base/rational.jl b/base/rational.jl index 73d9aa0d5b00f..b6542a8f05b27 100644 --- a/base/rational.jl +++ b/base/rational.jl @@ -101,6 +101,8 @@ end Rational(x::Float64) = Rational{Int64}(x) Rational(x::Float32) = Rational{Int}(x) +big(q::Rational) = big(numerator(q))//big(denominator(q)) + big(z::Complex{<:Rational{<:Integer}}) = Complex{Rational{BigInt}}(z) promote_rule(::Type{Rational{T}}, ::Type{S}) where {T<:Integer,S<:Integer} = Rational{promote_type(T,S)} diff --git a/base/reinterpretarray.jl b/base/reinterpretarray.jl index 8d7a175d8252d..d8f786a515d98 100644 --- a/base/reinterpretarray.jl +++ b/base/reinterpretarray.jl @@ -45,6 +45,17 @@ struct ReinterpretArray{T,N,S,A<:AbstractArray{S, N}} <: AbstractArray{T, N} end end +# Definition of StridedArray +StridedFastContiguousSubArray{T,N,A<:DenseArray} = FastContiguousSubArray{T,N,A} +StridedReinterpretArray{T,N,A<:Union{DenseArray,StridedFastContiguousSubArray}} = ReinterpretArray{T,N,S,A} where S +StridedReshapedArray{T,N,A<:Union{DenseArray,StridedFastContiguousSubArray,StridedReinterpretArray}} = ReshapedArray{T,N,A} +StridedSubArray{T,N,A<:Union{DenseArray,StridedReshapedArray,StridedReinterpretArray}, + I<:Tuple{Vararg{Union{RangeIndex, AbstractCartesianIndex}}}} = SubArray{T,N,A,I} +StridedArray{T,N} = Union{DenseArray{T,N}, StridedSubArray{T,N}, StridedReshapedArray{T,N}, StridedReinterpretArray{T,N}} +StridedVector{T} = Union{DenseArray{T,1}, StridedSubArray{T,1}, StridedReshapedArray{T,1}, StridedReinterpretArray{T,1}} +StridedMatrix{T} = Union{DenseArray{T,2}, StridedSubArray{T,2}, StridedReshapedArray{T,2}, StridedReinterpretArray{T,2}} +StridedVecOrMat{T} = Union{StridedVector{T}, StridedMatrix{T}} + function check_readable(a::ReinterpretArray{T, N, S} where N) where {T,S} # See comment in check_writable if !a.readable && !array_subpadding(T, S) diff --git a/base/strings/basic.jl b/base/strings/basic.jl index 3e3b76950b880..615572e50d824 100644 --- a/base/strings/basic.jl +++ b/base/strings/basic.jl @@ -203,6 +203,7 @@ string(s::AbstractString) = s (::Type{Vector{T}})(s::AbstractString) where {T<:AbstractChar} = collect(T, s) Symbol(s::AbstractString) = Symbol(String(s)) +Symbol(x...) = Symbol(string(x...)) convert(::Type{T}, s::T) where {T<:AbstractString} = s convert(::Type{T}, s::AbstractString) where {T<:AbstractString} = T(s) diff --git a/base/sysimg.jl b/base/sysimg.jl index 970eda3bd15c8..bfd57c28f2858 100644 --- a/base/sysimg.jl +++ b/base/sysimg.jl @@ -1,506 +1,11 @@ # This file is a part of Julia. License is MIT: https://julialang.org/license -baremodule Base - -using Core.Intrinsics, Core.IR - -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) - -# Try to help prevent users from shooting them-selves in the foot -# with ambiguities by defining a few common and critical operations -# (and these don't need the extra convert code) -getproperty(x::Module, f::Symbol) = getfield(x, f) -setproperty!(x::Module, f::Symbol, v) = setfield!(x, f, v) -getproperty(x::Type, f::Symbol) = getfield(x, f) -setproperty!(x::Type, f::Symbol, v) = setfield!(x, f, v) - -getproperty(Core.@nospecialize(x), f::Symbol) = getfield(x, f) -setproperty!(x, f::Symbol, v) = setfield!(x, f, convert(fieldtype(typeof(x), f), v)) - -function include_relative end -function include(mod::Module, path::AbstractString) - local result - if INCLUDE_STATE === 1 - result = _include1(mod, path) - elseif INCLUDE_STATE === 2 - result = _include(mod, path) - elseif INCLUDE_STATE === 3 - result = include_relative(mod, path) - end - result -end -function include(path::AbstractString) - local result - if INCLUDE_STATE === 1 - result = _include1(Base, path) - elseif INCLUDE_STATE === 2 - result = _include(Base, path) - else - # to help users avoid error (accidentally evaluating into Base), this is not allowed - error("Base.include(string) is discontinued, use `include(fname)` or `Base.include(@__MODULE__, fname)` instead.") - end - result -end -const _included_files = Array{Tuple{Module,String},1}() -function _include1(mod::Module, path) - Core.Compiler.push!(_included_files, (mod, ccall(:jl_prepend_cwd, Any, (Any,), path))) - Core.include(mod, path) -end -let SOURCE_PATH = "" - # simple, race-y TLS, relative include - global _include - function _include(mod::Module, path) - prev = SOURCE_PATH - path = normpath(joinpath(dirname(prev), path)) - push!(_included_files, (mod, abspath(path))) - SOURCE_PATH = path - result = Core.include(mod, path) - SOURCE_PATH = prev - result - end -end -INCLUDE_STATE = 1 # include = Core.include - -include("coreio.jl") - -eval(x) = Core.eval(Base, x) -eval(m::Module, x) = Core.eval(m, x) - -VecElement{T}(arg) where {T} = VecElement{T}(convert(T, arg)) -convert(::Type{T}, arg) where {T<:VecElement} = T(arg) -convert(::Type{T}, arg::T) where {T<:VecElement} = arg - -# init core docsystem -import Core: @doc, @__doc__, WrappedException, @int128_str, @uint128_str, @big_str, @cmd -if isdefined(Core, :Compiler) - import Core.Compiler.CoreDocs - Core.atdoc!(CoreDocs.docm) -end - -include("exports.jl") - -if false - # simple print definitions for debugging. enable these if something - # goes wrong during bootstrap before printing code is available. - # otherwise, they just just eventually get (noisily) overwritten later - global show, print, println - show(io::IO, x) = Core.show(io, x) - print(io::IO, a...) = Core.print(io, a...) - println(io::IO, x...) = Core.println(io, x...) -end - -""" - time_ns() - -Get the time in nanoseconds. The time corresponding to 0 is undefined, and wraps every 5.8 years. -""" -time_ns() = ccall(:jl_hrtime, UInt64, ()) - -start_base_include = time_ns() - -## Load essential files and libraries -include("essentials.jl") -include("ctypes.jl") -include("gcutils.jl") -include("generator.jl") -include("reflection.jl") -include("options.jl") - -# core operations & types -include("promotion.jl") -include("tuple.jl") -include("pair.jl") -include("traits.jl") -include("range.jl") -include("expr.jl") -include("error.jl") - -# core numeric operations & types -include("bool.jl") -include("number.jl") -include("int.jl") -include("operators.jl") -include("pointer.jl") -include("refvalue.jl") -include("refpointer.jl") -include("checked.jl") -using .Checked - -# vararg Symbol constructor -Symbol(x...) = Symbol(string(x...)) - -# array structures -include("indices.jl") -include("array.jl") -include("abstractarray.jl") -include("subarray.jl") -include("views.jl") - -# ## dims-type-converting Array constructors for convenience -# type and dimensionality specified, accepting dims as series of Integers -Vector{T}(::UndefInitializer, m::Integer) where {T} = Vector{T}(undef, Int(m)) -Matrix{T}(::UndefInitializer, m::Integer, n::Integer) where {T} = Matrix{T}(undef, Int(m), Int(n)) -Array{T,N}(::UndefInitializer, d::Vararg{Integer,N}) where {T,N} = Array{T,N}(undef, convert(Tuple{Vararg{Int}}, d)) -# type but not dimensionality specified, accepting dims as series of Integers -Array{T}(::UndefInitializer, m::Integer) where {T} = Array{T,1}(undef, Int(m)) -Array{T}(::UndefInitializer, m::Integer, n::Integer) where {T} = Array{T,2}(undef, Int(m), Int(n)) -Array{T}(::UndefInitializer, m::Integer, n::Integer, o::Integer) where {T} = Array{T,3}(undef, Int(m), Int(n), Int(o)) -Array{T}(::UndefInitializer, d::Integer...) where {T} = Array{T}(undef, convert(Tuple{Vararg{Int}}, d)) -# dimensionality but not type specified, accepting dims as series of Integers -Vector(::UndefInitializer, m::Integer) = Vector{Any}(undef, Int(m)) -Matrix(::UndefInitializer, m::Integer, n::Integer) = Matrix{Any}(undef, Int(m), Int(n)) -# Dimensions as a single tuple -Array{T}(::UndefInitializer, d::NTuple{N,Integer}) where {T,N} = Array{T,N}(undef, convert(Tuple{Vararg{Int}}, d)) -Array{T,N}(::UndefInitializer, d::NTuple{N,Integer}) where {T,N} = Array{T,N}(undef, convert(Tuple{Vararg{Int}}, d)) -# empty vector constructor -Vector() = Vector{Any}(undef, 0) - -# Array constructors for nothing and missing -# type and dimensionality specified -Array{T,N}(::Nothing, d...) where {T,N} = fill!(Array{T,N}(undef, d...), nothing) -Array{T,N}(::Missing, d...) where {T,N} = fill!(Array{T,N}(undef, d...), missing) -# type but not dimensionality specified -Array{T}(::Nothing, d...) where {T} = fill!(Array{T}(undef, d...), nothing) -Array{T}(::Missing, d...) where {T} = fill!(Array{T}(undef, d...), missing) - -include("abstractdict.jl") - -include("iterators.jl") -using .Iterators: zip, enumerate -using .Iterators: Flatten, Filter, product # for generators - -include("namedtuple.jl") - -# numeric operations -include("hashing.jl") -include("rounding.jl") -using .Rounding -include("float.jl") -include("twiceprecision.jl") -include("complex.jl") -include("rational.jl") -include("multinverses.jl") -using .MultiplicativeInverses -include("abstractarraymath.jl") -include("arraymath.jl") - -# define MIME"foo/bar" early so that we can overload 3-arg show -""" - MIME - -A type representing a standard internet data format. "MIME" stands for -"Multipurpose Internet Mail Extensions", since the standard was originally -used to describe multimedia attachments to email messages. - -A `MIME` object can be passed as the second argument to [`show`](@ref) to -request output in that format. - -# Examples -```jldoctest -julia> show(stdout, MIME("text/plain"), "hi") -"hi" -``` -""" -struct MIME{mime} end - -""" - @MIME_str - -A convenience macro for writing [`MIME`](@ref) types, typically used when -adding methods to `show`. -For example the syntax `show(io::IO, ::MIME"text/html", x::MyType) = ...` -could be used to define how to write an HTML representation of `MyType`. -""" -macro MIME_str(s) - :(MIME{$(Expr(:quote, Symbol(s)))}) -end -# fallback text/plain representation of any type: -show(io::IO, ::MIME"text/plain", x) = show(io, x) - -# SIMD loops -include("simdloop.jl") -using .SimdLoop - -# map-reduce operators -include("reduce.jl") - -## core structures -include("reshapedarray.jl") -include("reinterpretarray.jl") -include("bitarray.jl") -include("bitset.jl") - -if !isdefined(Core, :Compiler) - include("docs/core.jl") - Core.atdoc!(CoreDocs.docm) -end - -# Some type -include("some.jl") - -include("dict.jl") -include("abstractset.jl") -include("set.jl") - -include("char.jl") -include("strings/basic.jl") -include("strings/string.jl") -include("strings/substring.jl") - -# Definition of StridedArray -StridedFastContiguousSubArray{T,N,A<:DenseArray} = FastContiguousSubArray{T,N,A} -StridedReinterpretArray{T,N,A<:Union{DenseArray,StridedFastContiguousSubArray}} = ReinterpretArray{T,N,S,A} where S -StridedReshapedArray{T,N,A<:Union{DenseArray,StridedFastContiguousSubArray,StridedReinterpretArray}} = ReshapedArray{T,N,A} -StridedSubArray{T,N,A<:Union{DenseArray,StridedReshapedArray,StridedReinterpretArray}, - I<:Tuple{Vararg{Union{RangeIndex, AbstractCartesianIndex}}}} = SubArray{T,N,A,I} -StridedArray{T,N} = Union{DenseArray{T,N}, StridedSubArray{T,N}, StridedReshapedArray{T,N}, StridedReinterpretArray{T,N}} -StridedVector{T} = Union{DenseArray{T,1}, StridedSubArray{T,1}, StridedReshapedArray{T,1}, StridedReinterpretArray{T,1}} -StridedMatrix{T} = Union{DenseArray{T,2}, StridedSubArray{T,2}, StridedReshapedArray{T,2}, StridedReinterpretArray{T,2}} -StridedVecOrMat{T} = Union{StridedVector{T}, StridedMatrix{T}} - -# For OS specific stuff -include(string((length(Core.ARGS)>=2 ? Core.ARGS[2] : ""), "build_h.jl")) # include($BUILDROOT/base/build_h.jl) -include(string((length(Core.ARGS)>=2 ? Core.ARGS[2] : ""), "version_git.jl")) # include($BUILDROOT/base/version_git.jl) - -include("osutils.jl") -include("c.jl") - -# Core I/O -include("io.jl") -include("iostream.jl") -include("iobuffer.jl") - -# strings & printing -include("intfuncs.jl") -include("strings/strings.jl") -include("parse.jl") -include("shell.jl") -include("regex.jl") -include("show.jl") -include("arrayshow.jl") - -# multidimensional arrays -include("cartesian.jl") -using .Cartesian -include("multidimensional.jl") -include("permuteddimsarray.jl") -using .PermutedDimsArrays - -include("broadcast.jl") -using .Broadcast -using .Broadcast: broadcasted, broadcasted_kwsyntax, materialize, materialize! - -# define the real ntuple functions -@inline function ntuple(f::F, ::Val{N}) where {F,N} - N::Int - (N >= 0) || throw(ArgumentError(string("tuple length should be ≥0, got ", N))) - if @generated - quote - @nexprs $N i -> t_i = f(i) - @ncall $N tuple t - end - else - Tuple(f(i) for i = 1:N) - end -end -@inline function fill_to_length(t::Tuple, val, ::Val{N}) where {N} - M = length(t) - M > N && throw(ArgumentError("input tuple of length $M, requested $N")) - if @generated - quote - (t..., $(fill(:val, N-length(t.parameters))...)) - end - else - (t..., fill(val, N-M)...) - end -end - -# missing values -include("missing.jl") - -# version -include("version.jl") - -# system & environment -include("sysinfo.jl") -include("libc.jl") -using .Libc: getpid, gethostname, time - -const DL_LOAD_PATH = String[] -if Sys.isapple() - push!(DL_LOAD_PATH, "@loader_path/julia") - push!(DL_LOAD_PATH, "@loader_path") -end - -include("env.jl") - -# Scheduling -include("libuv.jl") -include("event.jl") -include("task.jl") -include("threads.jl") -include("lock.jl") -include("weakkeydict.jl") - -# Logging -include("logging.jl") -using .CoreLogging - -# functions defined in Random -function rand end -function randn end - -# I/O -include("stream.jl") -include("filesystem.jl") -using .Filesystem -include("process.jl") -include("grisu/grisu.jl") -include("methodshow.jl") -include("secretbuffer.jl") - -# core math functions -include("floatfuncs.jl") -include("math.jl") -using .Math -const (√)=sqrt -const (∛)=cbrt - -INCLUDE_STATE = 2 # include = _include (from lines above) - -# reduction along dims -include("reducedim.jl") # macros in this file relies on string.jl -include("accumulate.jl") - -# basic data structures -include("ordering.jl") -using .Order - -# Combinatorics -include("sort.jl") -using .Sort - -# Fast math -include("fastmath.jl") -using .FastMath - -function deepcopy_internal end - -# enums -include("Enums.jl") -using .Enums - -# BigInts and BigFloats -include("gmp.jl") -using .GMP - -include("mpfr.jl") -using .MPFR -big(n::Integer) = convert(BigInt,n) -big(x::AbstractFloat) = convert(BigFloat,x) -big(q::Rational) = big(numerator(q))//big(denominator(q)) - -include("combinatorics.jl") - -# more hashing definitions -include("hashing2.jl") - -# irrational mathematical constants -include("irrationals.jl") -include("mathconstants.jl") -using .MathConstants: ℯ, π, pi - -# (s)printf macros -include("printf.jl") -# import .Printf - -# metaprogramming -include("meta.jl") - -# concurrency and parallelism -include("channels.jl") - -# utilities -include("deepcopy.jl") -include("download.jl") -include("summarysize.jl") -include("errorshow.jl") - -# Stack frames and traces -include("stacktraces.jl") -using .StackTraces - -include("initdefs.jl") - -# worker threads -include("threadcall.jl") - -# code loading -include("uuid.jl") -include("loading.jl") - -# misc useful functions & macros -include("util.jl") - -include("asyncmap.jl") - -include("multimedia.jl") -using .Multimedia - -# deprecated functions -include("deprecated.jl") - -# Some basic documentation -include("docs/basedocs.jl") - -include("client.jl") - -# Documentation -- should always be included last in sysimg. -include("docs/Docs.jl") -using .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__() - # try to ensuremake sure OpenBLAS does not set CPU affinity (#1070, #9639) - if !haskey(ENV, "OPENBLAS_MAIN_FREE") && !haskey(ENV, "GOTOBLAS_MAIN_FREE") - ENV["OPENBLAS_MAIN_FREE"] = "1" - end - # And try to prevent openblas from starting too many threads, unless/until specifically requested - if !haskey(ENV, "OPENBLAS_NUM_THREADS") && !haskey(ENV, "OMP_NUM_THREADS") - cpu_threads = Sys.CPU_THREADS::Int - if cpu_threads > 8 # always at most 8 - ENV["OPENBLAS_NUM_THREADS"] = "8" - elseif haskey(ENV, "JULIA_CPU_THREADS") # or exactly as specified - ENV["OPENBLAS_NUM_THREADS"] = cpu_threads - end # otherwise, trust that openblas will pick CPU_THREADS anyways, without any intervention - end - # for the few uses of Libc.rand in Base: - Libc.srand() - # Base library init - reinit_stdio() - Multimedia.reinit_displays() # since Multimedia.displays uses stdout as fallback - # initialize loading - init_depot_path() - init_load_path() - nothing -end - -INCLUDE_STATE = 3 # include = include_relative -end - -const tot_time_stdlib = RefValue(0.0) - -end # baremodule Base +Core.include(Main, "Base.jl") using .Base # Ensure this file is also tracked +pushfirst!(Base._included_files, (@__MODULE__, joinpath(@__DIR__, "Base.jl"))) pushfirst!(Base._included_files, (@__MODULE__, joinpath(@__DIR__, "sysimg.jl"))) # set up depot & load paths to be able to find stdlib packages diff --git a/base/tuple.jl b/base/tuple.jl index c8cf96b13502f..d9457f5cc839e 100644 --- a/base/tuple.jl +++ b/base/tuple.jl @@ -120,46 +120,6 @@ end ## mapping ## -""" - ntuple(f::Function, n::Integer) - -Create a tuple of length `n`, computing each element as `f(i)`, -where `i` is the index of the element. - -# Examples -```jldoctest -julia> ntuple(i -> 2*i, 4) -(2, 4, 6, 8) -``` -""" -function ntuple(f::F, n::Integer) where F - t = n == 0 ? () : - n == 1 ? (f(1),) : - n == 2 ? (f(1), f(2)) : - n == 3 ? (f(1), f(2), f(3)) : - n == 4 ? (f(1), f(2), f(3), f(4)) : - n == 5 ? (f(1), f(2), f(3), f(4), f(5)) : - n == 6 ? (f(1), f(2), f(3), f(4), f(5), f(6)) : - n == 7 ? (f(1), f(2), f(3), f(4), f(5), f(6), f(7)) : - n == 8 ? (f(1), f(2), f(3), f(4), f(5), f(6), f(7), f(8)) : - n == 9 ? (f(1), f(2), f(3), f(4), f(5), f(6), f(7), f(8), f(9)) : - n == 10 ? (f(1), f(2), f(3), f(4), f(5), f(6), f(7), f(8), f(9), f(10)) : - _ntuple(f, n) - return t -end - -function _ntuple(f, n) - @_noinline_meta - (n >= 0) || throw(ArgumentError(string("tuple length should be ≥0, got ", n))) - ([f(i) for i = 1:n]...,) -end - -# inferrable ntuple (enough for bootstrapping) -ntuple(f, ::Val{0}) = () -ntuple(f, ::Val{1}) = (@_inline_meta; (f(1),)) -ntuple(f, ::Val{2}) = (@_inline_meta; (f(1), f(2))) -ntuple(f, ::Val{3}) = (@_inline_meta; (f(1), f(2), f(3))) - # 1 argument function map(f, t::Tuple{}) = () map(f, t::Tuple{Any,}) = (f(t[1]),)